Survival needs
Usage guide of survival.needs: named gauges (oxygen, water, food, warmth, sanity) that drain, hurt at zero and come back from items, world sources, rest and other kits, with stages, settings, service, events and hooks.
Survival needs (survival.needs) #
What it is for #
Gauges the player must keep up. The kit does not know what oxygen or hunger is: a need is a name, a maximum, a drain and what it costs at zero. Oxygen on a hostile planet, warmth in a blizzard or sanity in a haunted house are the same thing with other numbers. Each drains over time, hurts at zero (through combat.damage when the game has combat), and comes back from consumed items, sources in the world, rest, or another kit. The HUD draws the gauges. Where the player's health lives is for the combat kits (see Combat).
Turn it on #
gripforge_gamekit_install { project_id: "gkp_…", id: "survival.needs" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "survival.needs",
config: { "needs": [
{ "id": "thirst", "label": "Water", "max": 100, "drain": 0.2, "damage": 3, "lowAt": 0.25 },
{ "id": "warmth", "max": 100, "drain": 0.5, "damage": 2 } ] } }
It requires only game.engine. Without a configuration the three default needs are oxygen, thirst and hunger.
First example #
<!-- test: kits/game_engine/host/tests/parity.rs::rust_host_matches_the_typescript_traces (fixture survival.needs.gauges) --> The parity scenario runs the gauges with a vent (need_source giving air back to a player near it), a fire (need_source for warmth) and a bed (rest_spot). It reads needs(), takes some air away with restore("air", -5), reads value, ratio, max and stage, and also reads an unknown need:
restore ["air", -5] -> the gauge loses 5 units
value ["air"] -> its current value
stage ["food"] -> { id, label, effects } or null
Settings and defaults #
| Setting | Default | Meaning |
|---|---|---|
needs | oxygen, thirst, hunger | the gauges of the game (1 to 12) |
paused | false | start with the gauges frozen (a tutorial, a safe hub) |
refillOnRespawn | true | back to the start values when the player comes back to life |
restLabel | Sleep | prompt of a rest spot without its own label |
Each entry of needs:
| Field | Meaning |
|---|---|
id | lowercase id (oxygen, thirst, hunger, warmth, sanity...) |
label, color | HUD name and colour |
max, start | maximum and value at the start and after a respawn (default: max) |
drain | units lost per second |
damage | health lost per second while the need is at zero |
lowAt | share of the maximum under which the need is low |
stages | up to 8 thresholds { id, below, label?, effects? } |
The defaults: oxygen (max 100, drain 0.9, damage 12), thirst (drain 0.2, damage 3), hunger (drain 0.12, damage 2), all with lowAt 0.25.
Ways to get a need back:
- an item: a document of the
consumablescollection,{ "item": "water_bottle", "restores": { "thirst": 40 } }, applied wheninventory.usedfires; - a source in the world: an entity with
need_source { need, perSecond, radius }(default radius 4 m) refills the player standing in reach; - rest:
rest_spot { hours, restore, label }on furniture, or therestaction; time passes onworld.clockwhen installed; - another kit:
setSupply(need, perSecond, source)andsetDrain(need, multiplier, source); - equipment: a worn piece with the stat
<need>_max(for exampleoxygen_max) raises that maximum.
Stages name thresholds with effects:
{ "id": "sanity", "max": 100, "drain": 0, "stages": [
{ "id": "uneasy", "below": 0.6, "effects": { "vignette": 0.25 } },
{ "id": "panic", "below": 0.15, "effects": { "vignette": 0.8, "heartbeat": 2 } } ] }
The deepest stage reached is the variable need.<id>.stage, and each effect is need.<id>.fx.<name> (0 when the stage does not set it).
Services, events, variables #
survival.needs(service):needs(),value(id),max(id),ratio(id),restore(id, amount, source?),set(id, value),setMax(id, max, refill?),setDrain(id, multiplier, source),setSupply(id, perSecond, source),pause(on?),refill(),rest({ hours?, restore? }),stage(id).- Events:
need.low,need.depleted,need.recovered,need.restored,need.stage(need,stage,from),need.rested(hours,entity). - Variables:
need.<id>,need.<id>.max,need.<id>.stage,need.<id>.fx.<name>. - Script verbs: actions
restore_need,set_need,pause_needs,rest; conditionneed_below(need,ratio).
Hooks and modding #
Each hook is asked when the decision is taken, never every tick.
| Hook | Payload | Effect |
|---|---|---|
need.restore | need, entity, amount, source, value, max | mutable amount; cancelled: nothing restored |
need.feed | need, entity, source, perSecond | mutable perSecond; cancelled: that source gives this player nothing until they leave and return |
need.decay | need, entity, source, multiplier | mutable multiplier; cancelled: the previous multiplier stays |
need.deplete | need, entity, damage | mutable damage (0: no harm this time); cancelled: no need.depleted and no damage until the need has recovered and emptied again |
{ "id": "big_sips", "hook": "need.restore", "match": { "need": "thirst" }, "mul": { "amount": 1.5 } }
A mod may override needs, paused, refillOnRespawn and restLabel, and add to, patch or remove from consumables.
Engines #
The web player and the native kit host run the same rules. With several players (co-op), every player entity has its own gauges, stages and damage in the component survival.needs; the service acts on the current player and the variables show the HUD player's. A solo game saves exactly as before. The gauges HUD view draws one bar per need and names the stage.
When it does not do what you expect #
- A gauge does not move: the game is
paused, the player is dead (nothing drains while dead), or the need hasdrain0. - A used item restores nothing: no
consumablesdocument names that item. - Health does not drop at zero:
damageis 0, or a tap ofneed.depleteset it to 0. - A source feeds nobody: the player is outside its
radius, or a tap ofneed.feedcancelled it.
Limits #
- It manages gauges, not the player's health or items: damage goes through the combat kit, items through the inventory.
- Hooks do not see what is taken away (a negative amount) nor what flows per second.
Versions #
Kit 1.4.1, service contract 1.3.0. 1.4.0: the game.engine hook contract; 1.3.0: several players; 1.2.0: stages; 1.1.0: rest; 1.0.0: first release.