Collect and train characters

Recruit characters in the forest, draw characters, give them experience, and build a three-slot party.

Let players earn a knight by completing the forest quest, and draw either a knight or a mage. Each character has its own identity, so players can train two knights separately and put both in their party.

1. Set up character types and inventory capacity

Add Characters from Add features. Under Tables → Characters, edit the following three tables. Select a cell and press Enter to edit it; double-click an array cell to edit its entries.

TableRowValues
Character slots (CharacterCollection)Click Add row; no ID is neededInitial capacity 20, maximum capacity 100
Character experience (CharacterExperience)Click Add row; no ID is neededAdd 1, 10, and 20 to the Experience thresholds, in that order. Set both the initial and maximum level caps to 4
Character (Character)Add a row with ID knightSort order 1
Character (Character)Add a row with ID mageSort order 2

Deploy from Publish → Calculate server differences, then click Update the Unity project. Owned characters are stored in the Character namespace, and experience in CharacterExperience.

Download the character settings template. In the management console, open the Tokyo region and go to Deploy → Stack list → Create stack. Enter adventure-characters as the name, select the downloaded file under Template data, and create the stack.

This stack contains settings for character inventory, experience, draws, and party formation. Keep using your existing adventure-game stack.

DataNamespaceSetting name
Owned charactersadventure-characterInventory Character, Item knight / mage
Experienceadventure-character-experienceExperience Experience
Character drawsadventure-character-gachaLottery normal, Showcase Showcase, product normal
Party Formationadventure-character-formationMold CharacterFormation, save slot 0

The initial inventory capacity is 20, the maximum is 100, and each character occupies a stack of one. allowMultipleStacks is true, allowing players to own multiple characters of the same type.

Add a knight to the forest completion rewards

Under Tables → Quests → Quest, open Completion rewards for forest. Keep the coin, mission counter, and potion actions, then click Add item → Not set. Select AcquireItemSetByUserId and enter the following values.

FieldValue
namespaceNameCharacter
userId#{userId}
inventoryNameCharacter
itemNameknight
acquireCount1

Save and deploy the changes to the server.

Open the current template for adventure-game. Under main → forest → contents → completeAcquireActions, append the following entry. Keep the existing coin, mission counter, and potion entries. Update the stack using the entire modified template.

- action: Gs2Inventory:AcquireItemSetByUserId
  request: |-
    {"namespaceName":"adventure-character","userId":"#{userId}","inventoryName":"Character","itemName":"knight","acquireCount":1}

Show owned characters in Unity

Stop Play Mode in Unity and uncheck Adventure Items on Extensions. Keep the adventure panel on the left.

Place AdventureCharacters.cs in Assets/AdventureExtensions, then add Adventure Characters to Extensions. It uses the signed-in Gs2ClientHolder and Gs2GameSessionHolder.

Place AdventureCharacters.cs in Assets/AdventureExtensions, then add Adventure Characters to Extensions. Assign the scene’s AdventureLogin to Login.

Enter Play Mode, then start and complete a new forest quest on the left. The list on the right shows knight and an identifier for that individual character. Complete the forest again to see two separate knight entries. After deployment, the new reward can take up to five minutes to take effect. If no knight is added, wait a little, then start and complete another forest quest.

The following call loads the initial list. After that, SubscribeItemSets() receives additions and removals. ItemName identifies the character type, while ItemSetId identifies each individual character.

var inventory = Client.Inventory.Namespace(InventoryNamespace)
    .Me(Session).Inventory("Character");
await foreach (var item in inventory.ItemSetsAsync())
{
    if (item != null) owned.Add(item);
}

2. Draw a character for 20 coins

Add Character Gacha from Add features. Under Tables → Character Gacha, create the rows in the following order.

TableIDValues
Rarity (GachaRarity)commonID only
Gacha (Gacha)normalLeave the schedule empty
Rarity rate (GachaRarityRate)Add a rowGacha normal, rarity common, draw weight 1
Character rate (CharacterRate)Add a rowRarity common, character knight, draw weight 1
Character rate (CharacterRate)Add another rowRarity common, character mage, draw weight 1

In the rate tables, selecting the referenced entries sets the ID automatically. Do not enter an ID yourself.

Open Cost per draw for normal and add one WithdrawByUserId action. Set namespaceName = Currency, userId = #{userId}, slot = 0, withdrawCount = 20, and paidOnly = false. Save, then update the server and Unity project.

These settings are already in the LotteryMaster and ShowcaseMaster of the characters.json you deployed. Both prizes have a weight of 1. The product consumes 20 coins and uses Gs2Lottery:DrawByUserId as its acquisition action.

Collect at least 20 coins in the adventure panel on the left, then click Draw a character for 20 coins on the right. A knight or mage is added to the list. Check that the coin balance on the left decreases by 20.

The purchase uses Showcase, whose acquisition action performs the Lottery draw.

private async UniTask Draw(string requestId)
{
    var transaction = await Client.Showcase.Namespace(GachaNamespace).Me(Session)
        .Showcase("Showcase").DisplayItem("normal").BuyAsync(
            1, speculativeExecute: false, duplicationAvoider: requestId);
    if (transaction != null) await transaction.WaitAsync(all: true);
}

3. Give experience to a selected character

Training uses Exchange to spend 10 coins and grant 10 experience in one operation.

Download the training settings for Studio characters. In the management console, open Deploy → Create stack, name it adventure-character-training, and select the file under Template data. This template references the Currency and CharacterExperience namespaces created by Studio.

Download the training settings for SDK characters. Open Deploy → Create stack, name it adventure-character-training, and select the file under Template data. This template references adventure-coin and adventure-character-experience.

  1. Select the character you want to train from the list on the right.
  2. Click Read selected character’s experience and note the current value.
  3. Click Add 10 experience for 10 coins. The experience display updates automatically and increases by 10.
  4. Select another character and read its experience to check that it has not increased.

Pass the ItemSetId selected when the button was clicked to Train(). The code appends :level to identify where that character’s experience is stored. The config value fills #{propertyId} in the template.

private async UniTask Train(string itemSetId, string requestId)
{
    var transaction = await Client.Exchange.Namespace("adventure-character-training").Me(Session).Exchange()
        .ExchangeAsync("train", 1, config: new[] {
            new Gs2.Unity.Gs2Exchange.Model.EzConfig { Key = "propertyId", Value = itemSetId + ":level" }
        }, speculativeExecute: false, duplicationAvoider: requestId);
    if (transaction != null) await transaction.WaitAsync(all: true);
}

4. Save a three-slot party

Add Party Formation from Add features. Under Tables → Party Formation, enter the following settings, then update the server and Unity project.

TableRowValues
Formation (CharacterFormation)Click Add row; no ID is neededInitial save slots 1, maximum save slots 1
Formation slot (CharacterFormationSlot)Add slot1, slot2, and slot3Placement condition .* for every row

The FormationMaster in characters.json already defines three slots. Use save slot 0 of CharacterFormation.

  1. Click Load party, select a character from the list, then click Put selected character in slot 1.
  2. Select another character and put it in slot 2. If you own a third character, put it in slot 3. You can save the party with empty slots.
  3. Click Save party.
  4. Stop and restart Play Mode, log in as the same player, then click Load party. Each slot shows the same character ID as before.

To save, the code calls Inventory’s GetItemWithSignatureAsync() to obtain a signature proving ownership, then passes it to Formation’s SetFormAsync(). It also checks that the same individual character is not placed in two slots.

Next: Connect players