Timed Objects - Mining, Fishing and Treasure Chests
How to create objects the players interact with for a while to get an item, like rocks to mine or fishing spots, and one-time rewards like treasure chests.
How it works in the game
A timed object is a game object with the timing class type. When a player clicks it (or walks into it), a progress bar is shown under the object and, if the player stays until the bar is completed, the server gives the player an item. The timing is cancelled when the player moves, gets hurt or walks away from the object, depending on the object configuration.
The sample data includes three examples in the room reldens-forest-level-1:
- Fishing spots (fish_spawn_forest_1 to fish_spawn_forest_6) - 10 seconds of fishing give a fish item (a consumable that restores 10 HP), while a fishing rod animation is shown on the player.
- Mining rocks (rock_forest_1) - up to 10 rocks spawned in the merge-respawn-area-mining-rocks map layer; 5 seconds of mining give an ore item, the rock disappears and a new one respawns 30 seconds later.
- Treasure chest (chest_forest_1) - not a timed object but a one-time reward: the first time each player opens it they get a coin, and the chest stays empty for that player after that (see Quests Progress).
Setting up a fishing spot in the admin panel
- Log in to the admin panel at /reldens-admin (the path can be changed with the RELDENS_ADMIN_ROUTE_PATH environment variable).
- Open Items & Inventory > Items and check that the reward item exists (the sample data uses fish).
- Open Game Objects > Objects and click Create New (or Duplicate on an existing fishing spot).
- Select the Room ID, the Layer Name and set the Tile Index where the object is placed (the Pick in map button opens the room map to click the tile).
- Set Class Type to timing, a unique Object Class Key and the Client Key of the sprite (the object asset, see Object Sprites and Assets).
- Fill the Private Params (server side) and Client Params (sent to the client) as described below, check Enabled and click Save.
- Restart the server to load the new object.
The sample fishing spot uses these values:
// Private Params
{
"runOnAction": true,
"collisionType": 2,
"cancelOnMove": true,
"cancelOnHit": true,
"cancelOnOutOfRange": false,
"rewards": [{"key": "fish", "rate": 100}]
}
// Client Params
{
"timingDuration": 10000,
"isInteractive": true,
"classKey": "fish_spawn_forest_1",
"frameStart": 0,
"frameEnd": 2,
"autoStart": true,
"repeat": -1,
"ui": false
}
Mining rocks with respawn
The mining rocks are not placed one by one: a single object with the multiple class type spawns the rocks in a map layer and respawns them after they are mined, like the enemies (see Enemy Respawn Flow).
- Layer Name is the map layer where the rocks can appear (merge-respawn-area-mining-rocks) and the Tile Index is empty.
- The private param childObjectClassKey (rock_forest_1) is the custom server class used for every rock, and itemKey (ore) is the item given when a rock is mined.
- shouldRespawn, hasState and interactionArea (48 pixels) complete the private params, and the client params set timingDuration to 5000.
- The amount of rocks and the respawn time are set in Respawn > Respawn Areas: the sample row for this object has instances_limit 10, respawn_time 30000 and the same layer.
Treasure chest
The chest is a regular npc object (class type 3) with a custom class that checks the quest progress of the player before giving the reward:
- The first time a player opens it, the chest adds a coins item to the player inventory, saves a quests_progress row with the chest key and shows "You found a coin!".
- When the row already exists, the chest only shows "The chest is empty.".
- The client plays the chest_forest_1_open animation (defined in the animations client param) and keeps the looted chests open for that player.
Configuration reference
Private params of the timing objects:
- runOnAction - start the timing when the player clicks the object.
- runOnHit - start the timing when the player collides with the object.
- cancelOnMove - cancel when the player position changes.
- cancelOnHit - cancel when the player affected property decreases (the property set in the client/actions/skills/affectedProperty config, the HP by default).
- cancelOnOutOfRange - cancel when the player leaves the object interaction range.
- rewards - list of {"key": "item_key", "rate": percentage}. On completion a number from 0 to 99 is rolled and the first reward whose accumulated rate is greater than the roll is given, so the rates should add up to 100 or less (with less than 100 the player can finish without a reward).
Client params:
- timingDuration - duration in milliseconds, used by the server timer and by the progress bar.
- isInteractive - makes the sprite clickable.
- classKey - the client custom class used for the object (see below).
- progressBarWidth (32), progressBarHeight (4), progressBarOffsetY (8), progressBarBgColor (0x333333) and progressBarFillColor (0x4488ff) - optional progress bar size, position and colors.
The server checks the cancel conditions every 100 milliseconds while the timing runs, and only one player at a time can use the same object.
Code integration (advanced)
- Server class: TimingObject (lib/objects/server/object/type/timing-object.js), it extends the NPC object and sends the timingStart, timingCancel and timingComplete messages (with rewarded and itemKey) to the player.
- Client class: TimingObject (lib/objects/client/object/type/timing-object.js), it sends the interaction and draws the progress bar. It is not used automatically: register a client custom class for the object classKey that extends it, like the theme does.
- Object classes are resolved from the custom classes first: the server uses server/customClasses/objects/[object class key] (or [childObjectClassKey] for the objects spawned by a multiple object) and falls back to the class type, the client uses client/customClasses/objects/[classKey].
The examples are registered by the theme plugins:
// theme/plugins/server-plugin.js, on reldens.beforeInitializeManagers
customClasses.objects['rock_forest_1'] = RockObject;
customClasses.objects['chest_forest_1'] = TreasureChest;
// theme/plugins/client-plugin.js, on reldens.beforeJoinGame
customClasses.objects['rock_forest_1'] = Rock;
customClasses.objects['fish_spawn_forest_1'] = FishSpawn;
customClasses.objects['chest_forest_1'] = TreasureChestClient;
- RockObject (theme/plugins/objects/server/rock-object.js) overrides completeTiming() to give the itemKey item, disable the rock body and run the respawn.
- Rock and FishSpawn extend ToolTimingObject (theme/plugins/objects/client/tool-timing-object.js), which shows a pickaxe or a fishing rod animation on the player while the timing runs.
- TreasureChest (theme/plugins/objects/server/treasure-chest.js) and TreasureChestClient implement the chest reward and the open animation.
reldens