Introduction to rotating shop items
The Extend Override and Events handler is currently available for Closed Beta partners only. Please submit a ticket if you're interested to apply as a Closed Beta partner.
Overview
AccelByte Gaming Services (AGS) has the capability to let you define and customize your own rules for the Rotation Period and Total Items per Rotation for e-commerce platform services.
There are two functions on the contract as shown in the snippet below:
service SectionService {
/**
GetRotationItems: get current rotation items, this method will be called by rotation type is CUSTOM
*/
rpc GetRotationItems(GetRotationItemsRequest) returns (GetRotationItemsResponse);
/**
Backfill method trigger condition:
1. Rotation type is FIXED_PERIOD
2. Bulkfill type is CUSTOM
3. User already owned any one of current rotation items.
*/
rpc Backfill(BackfillRequest) returns (BackfillResponse);
}
GetRotationItems
This method will be called by the AGS platform e-commerce service for a store display section with rotation type CUSTOM. The function is called when users are trying to fetch active display sections. The developer can implement logic that determines what to show for that specified in-game store section for the particular user's request.
In this example, we'll implement the logic for GetRotationItems
to return different items that will be rotated every hour.
- Go
- Python
- C#
func (s SectionServiceServer) GetRotationItems(ctx context.Context, request *pb.GetRotationItemsRequest) (*pb.GetRotationItemsResponse, error) {
inputCount := len(request.GetSectionObject().GetItems())
currentPoint := time.Now().Hour()
selectedIndex := int(math.Floor((float64(inputCount) / float64(upperLimit)) * float64(currentPoint)))
selectedItem := request.GetSectionObject().GetItems()[selectedIndex]
responseItems := []*pb.SectionItemObject{
{
ItemId: selectedItem.ItemId,
ItemSku: selectedItem.ItemSku,
},
}
resp := pb.GetRotationItemsResponse{
Items: responseItems,
ExpiredAt: 0,
}
return &resp, nil
}
async def GetRotationItems(self, request : GetRotationItemsRequest, context):
"""*
GetRotationItems: get current rotation items, this method will be called by rotation type is CUSTOM
"""
self.log_payload(f'{self.GetRotationItems.__name__} request: %s', request)
items : List[SectionItemObject] = request.sectionObject.items
input_count : int = len(items)
current_point : float = float(datetime.now().hour)
selected_index : int = int(math.floor((input_count/self.upper_limit)*current_point))
selected_item : SectionItemObject = items[selected_index]
response_items : List[SectionItemObject] = [selected_item]
response : GetRotationItemsResponse = GetRotationItemsResponse(expiredAt=0, items=response_items)
self.log_payload(f'{self.GetRotationItems.__name__} response: %s', response)
return response
public override Task<GetRotationItemsResponse> GetRotationItems(GetRotationItemsRequest request, ServerCallContext context)
{
List<SectionItemObject> items = new List<SectionItemObject>(request.SectionObject.Items);
float inputCount = items.Count;
float currentPoint = DateTime.Now.Hour;
int selectedIndex = (int)Math.Floor((inputCount / _UpperLimit) * currentPoint);
SectionItemObject selectedItem = items[selectedIndex];
GetRotationItemsResponse response = new GetRotationItemsResponse();
response.ExpiredAt = 0;
response.Items.Add(selectedItem);
return Task.FromResult(response);
}
Backfill
Backfill is called when the section rotation type is FIXED_PERIOD
, the backfill type is CUSTOM, and there's already an owned item in the current item rotation. One of the use cases for this is you can implement the replacement logic for those owned items.
In this example, we'll replace items that are already owned by a new random item ID in its current index.
- Go
- Python
- C#
func (s SectionServiceServer) Backfill(ctx context.Context, request *pb.BackfillRequest) (*pb.BackfillResponse, error) {
var newItems []*pb.BackfilledItemObject
for _, item := range request.GetItems() {
if item.Owned {
// if an item is owned by user, then replace it with new item id.
// item id will be generated randomly for example purpose.
newItem := &pb.BackfilledItemObject{
ItemId: strings.ReplaceAll(uuid.NewString(), "-", ""),
Index: item.Index,
}
newItems = append(newItems, newItem)
}
}
resp := &pb.BackfillResponse{BackfilledItems: newItems}
return resp, nil
}
async def Backfill(self, request : BackfillRequest, context):
"""*
Backfill method trigger condition:
1. Rotation type is FIXED_PERIOD
2. Backfill type is CUSTOM
3. User already owned any one of current rotation items.
"""
self.log_payload(f'{self.Backfill.__name__} request: %s', request)
new_items : List[BackfilledItemObject] = []
item : RotationItemObject
for item in request.items:
if item.owned:
new_item : BackfilledItemObject = BackfilledItemObject(itemId=str(uuid.uuid4()).replace("-",""), index=item.index)
new_items.append(new_item)
response : BackfillResponse = BackfillResponse(backfilledItems=new_items)
self.log_payload(f'{self.Backfill.__name__} response: %s', response)
return response
public override Task<BackfillResponse> Backfill(BackfillRequest request, ServerCallContext context)
{
BackfillResponse response = new BackfillResponse();
foreach (var item in request.Items)
{
if (item.Owned)
{
BackfilledItemObject newItem = new BackfilledItemObject()
{
ItemId = Guid.NewGuid().ToString().Replace("-", ""),
Index = item.Index
};
response.BackfilledItems.Add(newItem);
}
}
return Task.FromResult(response);
}