Resource nodes

Usage guide of resource.nodes: ore veins, bushes and crystals that give items, need tools, run out and grow back; seeded scatter, service, events, hooks and the resource_nodes collection.

Source: module-kits:kits/resource_nodes/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs resource-nodesMCP tool: gripforge_docs { "topic": "resource-nodes" }

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.

Turn it on #

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 #

<!-- test: kits/game_engine/host/tests/resource_nodes.rs::a_node_runs_out_then_grows_back_or_is_removed -->

{ "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 #

FieldTypeDefaultMeaning
id, name, itemstringrequiredThe node id, its name, the item given.
countinteger 1 to 9991Units per gather.
usesinteger 1 to 9991Gathers before the node runs out.
respawnSecondsnumber 0 to 86400noneSeconds to grow back; 0 or absent: gone for good.
toolstringnoneAn item the player must hold to gather (a pickaxe); never consumed.
sizenumber 0.1 to 200.8Size of the stand-in box in metres.
extractablebooleanfalseA 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 #

SettingTypeDefaultMeaning
scatterlist (up to 40)[]Nodes spread over the ground when the game starts.
seedinteger1Changes where the scattered nodes land.
clearSpawnnumber 0 to 1004No scattered node closer than this (metres) to where the player starts.
gatherLabelstringGather {name}Prompt of a node.
toolLabelstring{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.
NameDetail
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.gatheredVariable (number): resources gathered.

It listens to interaction.requested, entity.spawned and inventory.changed.

Hooks and modding #

HookPayloadMutableCancelled
resource.harvest{ node, entity, item, count, left }countNothing gathered; resource.blocked with reason refused.
resource.extract{ node, entity, item, count, left, consume }countextract answers null, nothing drawn.
resource.deplete{ node, entity, respawnSeconds }respawnSecondsNot cancellable (0: gone for good).
resource.respawn{ node, entity, item }noneThe node waits its respawnSeconds again.
{ "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.