# Gatherable resources in your world (resource.nodes) ## What it is for `resource.nodes` manages the resource points of the world: ore veins, bushes, wrecks, crystals. A node gives an item a number of times, may need a tool, runs out and grows back. Nodes are placed by hand (a component on any entity) or scattered over the ground from a seed. The kit does not know what iron or berries are: a node is a document of the `resource_nodes` collection, and the item it gives belongs to `inventory.items`. Every node is an entity, so the save keeps what is left of it. Good for survival, crafting, farming, and any game where resources are collected. Machines can draw from nodes too: see [Extraction](guide:resource-extraction). ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "resource.nodes" } gripforge_gamekit_configure { project_id: "gkp_…", id: "resource.nodes", config: { "seed": 7, "scatter": [ { "node": "iron_vein", "count": 30, "radius": 80 } ] } } ``` It requires `game.engine`. With `interaction.system` a node shows a prompt and using it gathers; with `inventory.items` the item goes into the bag. Without an inventory `resource.gathered` is still emitted, so another kit can act on it. Targets: web and the Rust kit host. ## First example ```json { "id": "rock", "name": "Rock", "item": "stone", "count": 2, "uses": 2, "respawnSeconds": 0.5 } ``` Spawning this node and calling `gather` answers `{ ok: true, item: "stone", count: 2 }`. After the second use the third call answers reason `depleted`, and the node is hidden (tags `hidden`, `depleted`). After `respawnSeconds`, `resource.respawned` fires and it is back with its uses. A node with no `respawnSeconds` (a bush) is removed from the world when it runs out. `resource.gathered` counts the units taken. ## Data: the resource_nodes collection | Field | Type | Default | Meaning | |---|---|---|---| | `id`, `name`, `item` | string | required | The node id, its name, the item given. | | `count` | integer 1 to 999 | `1` | Units per gather. | | `uses` | integer 1 to 999 | `1` | Gathers before the node runs out. | | `respawnSeconds` | number 0 to 86400 | none | Seconds to grow back; 0 or absent: gone for good. | | `tool` | string | none | An item the player must hold to gather (a pickaxe); never consumed. | | `size` | number 0.1 to 20 | `0.8` | Size of the stand-in box in metres. | | `extractable` | boolean | `false` | A machine standing on it may draw from it (`resource.extraction`). | Models come from the asset slot `resource_node`, variant = the node id; without one a stand-in box is shown. ## Placing nodes - Scattered (setting `scatter`): the same seed gives the same world. An entry takes `node`, `count` (required, up to 400), `center` (`[x, z]`, default where the player starts), `radius` (default most of the world), `spacing` (least distance to any other node, default 2.5) and `world` (spread in that world only, on the first tick spent there, with `travel.worlds`). Unknown node ids are skipped. - By hand: an archetype with the component `resource_node { node }`, a project spawn of kind `resource` carrying `resource.node`, the action `spawn_resource { node, at }`, or the service `spawn`. ## Settings and defaults | Setting | Type | Default | Meaning | |---|---|---|---| | `scatter` | list (up to 40) | `[]` | Nodes spread over the ground when the game starts. | | `seed` | integer | `1` | Changes where the scattered nodes land. | | `clearSpawn` | number 0 to 100 | `4` | No scattered node closer than this (metres) to where the player starts. | | `gatherLabel` | string | `Gather {name}` | Prompt of a node. | | `toolLabel` | string | `{name} — needs {tool}` | Prompt when the tool is missing. | ## Service, events and variables Service `resource.nodes`: - `types()`, `nodes()`: the node documents; the placed nodes with `entity`, `node`, `left`, `depleted`, `position`. - `gather(entity)`: `{ ok, reason?, item?, count? }`; reasons include `unknown`, `depleted`, `tool`, `full`, `refused`. - `spawn(node, at, yaw?)`, `deplete(entity)`, `restore(entity)`. - `scope(id)`, `scopeId()`: the world scatter used by `travel.worlds`. - `extract(entity, { consume? })`: `{ item, count, left }` or null, for machines. | Name | Detail | |---|---| | `resource.gathered` | `{ node, entity, item, count, left }`: the player took units; `left` is the gathers before it runs out. | | `resource.blocked` | `{ node, entity, reason, tool }`: reason `tool`, `full` or `refused`. | | `resource.depleted` | `{ node, entity, respawnSeconds }` (0: for good). | | `resource.respawned` | `{ node, entity }`. | | `resource.extracted` | `{ node, entity, item, count, left }`: a machine drew one gather. | | `resource.gathered` | Variable (number): resources gathered. | It listens to `interaction.requested`, `entity.spawned` and `inventory.changed`. ## Hooks and modding | Hook | Payload | Mutable | Cancelled | |---|---|---|---| | `resource.harvest` | `{ node, entity, item, count, left }` | `count` | Nothing gathered; `resource.blocked` with reason `refused`. | | `resource.extract` | `{ node, entity, item, count, left, consume }` | `count` | `extract` answers null, nothing drawn. | | `resource.deplete` | `{ node, entity, respawnSeconds }` | `respawnSeconds` | Not cancellable (0: gone for good). | | `resource.respawn` | `{ node, entity, item }` | none | The node waits its `respawnSeconds` again. | ```json { "id": "rich_veins", "hook": "resource.harvest", "match": { "node": "iron_vein" }, "mul": { "count": 2 } } ``` A mod may override `scatter`, `seed`, `clearSpawn`, `gatherLabel` and `toolLabel`, and add, patch or remove documents of `resource_nodes`. ## When it does not do what you expect - Nothing is gathered, `resource.blocked` with `tool`: the player does not hold the item named by `tool`. - `full`: the bag has no room for the item. - No node appears: check the node id in `scatter`, and that the first tick has run. - The same node layout in every game: that is the seed; change `seed`. ## Limits - No stand-in model beyond a box: provide a `resource_node` asset per node. - A node gives one item type. ## Versions Kit 1.3.1; service `resource.nodes` 1.2.0. Worlds since 1.1.0, extraction since 1.2.0, hooks and moddable data since 1.3.0.