Build a shared monster raid
This example builds a real-time raid in which several members attack the same monster until its health reaches zero. Webspace's shared-resource processor applies attacks, health changes, and per-action rewards together on the server.
Before you begin
- You need permission to deploy schemas and APIs.
- Members must have the real-time
sendandreceivepermissions. - Restrict the raid-target creation API to administrators.
Start with the complete schema
Download the shared-resource game schema (.sfn). It includes the columns and permissions for all three tables used in this guide, together with the shared-resource processor configuration.
- Download the file, upload it to a team or personal folder, and open it in the schema editor.
- In the
API Builddeployment settings, review theDatabase identifier. Change the defaultresource_gameto a new identifier such asmonster_raid_team_aso it does not conflict with an existing database. - Review the permissions and processor settings, then deploy the schema.
This file is a backend structure example for a shared resource. Its includeClient setting is false, so it does not generate a game interface or include an initial monster record. Build the interface separately with the APIs and WebSocket events below, and create the raid target before playing.
Separate the data into three tables
The shared-resource structure separates three types of data.
| Table | Stored data |
|---|---|
game_resources | Monster code, status, current and maximum health, version, and reward item |
game_actions | Action ID, acting member, applied damage, resulting health, and reward quantity |
game_inventory | Each member's items and accumulated quantities |
The action ID in game_actions identifies retries. Sending the same action ID again does not apply health changes or rewards twice.
Configure the real-time processor
Enable the real-time feature and select shared-resource as its event processor. With the default table names, the processor configuration has this shape:
{
"resourcesTable": "game_resources",
"actionsTable": "game_actions",
"inventoryTable": "game_inventory",
"actionPower": 1,
"rewardPerAction": 1,
"maxClientAmount": 1,
"broadcast": "namespace"
}
With broadcast set to namespace, clients connected to the same Webspace real-time namespace receive the result event. Set it to actor to return results only to the member who acted.
Create a raid target
Call game_resources/create as an administrator to create the monster.
{
"code": "RAID-1",
"kind": "monster",
"status": "active",
"current_value": 10000,
"max_value": 10000,
"version": 0,
"reward_item_code": "monster-core"
}
When the page opens, read the current health and version from the game_resources API. Read it again after a new connection or reconnection so the interface uses the current server state.
Send an attack over WebSocket
After an authenticated member subscribes to the real-time connection, send a resource-game.act event.
{
"type": "webspace:send",
"data": {
"dbName": "monster_raid_team_a",
"event": "resource-game.act",
"payload": {
"actionId": "attack-00000001",
"resourceCode": "RAID-1",
"amount": 1
}
}
}
Use the Database identifier selected during deployment as dbName.
Create an actionId of 8–80 ASCII letters, numbers, underscores, or hyphens. amount defaults to 1 when omitted. When included, it must be an integer within the processor's maxClientAmount limit.
The server returns resource-game.action-applied after processing the action.
{
"actionId": "attack-00000001",
"resourceId": 1,
"currentValue": 9999,
"version": 1,
"rewardQuantity": 1,
"duplicate": false
}
Update the health display only after receiving this result. A client request that sends resource-game.action-applied directly is rejected.
Display health and rewards
- Confirm that
resourceIdbelongs to the monster currently displayed. - Confirm that
versionis newer than the previous result. - Update the health display from
currentValue. - Show the shared completion state when
currentValuereaches zero. - Reload personal items from
game_inventory/list.
Apply owner-only read access to game_inventory, so members can read only their own data. Do not infer another member's inventory from rewardQuantity in a shared event.
Notes
- Attack strength and rewards come from the server's processor configuration, not client values.
- The resource change, action record, and reward update run in one transaction.
- The shared structure provides per-action rewards. Kill rankings and kill-only rewards require a separate design.
- Do not treat a delayed response as success. Retry with the same
actionIdto avoid applying the action twice.