# 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](guide:combat)). ## Turn it on ```text 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 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: ```text 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 `consumables` collection, `{ "item": "water_bottle", "restores": { "thirst": 40 } }`, applied when `inventory.used` fires; - 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 the `rest` action; time passes on `world.clock` when installed; - another kit: `setSupply(need, perSecond, source)` and `setDrain(need, multiplier, source)`; - equipment: a worn piece with the stat `_max` (for example `oxygen_max`) raises that maximum. Stages name thresholds with effects: ```json { "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..stage`, and each effect is `need..fx.` (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.`, `need..max`, `need..stage`, `need..fx.`. - Script verbs: actions `restore_need`, `set_need`, `pause_needs`, `rest`; condition `need_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 | ```json { "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 has `drain` 0. - A used item restores nothing: no `consumables` document names that item. - Health does not drop at zero: `damage` is 0, or a tap of `need.deplete` set it to 0. - A source feeds nobody: the player is outside its `radius`, or a tap of `need.feed` cancelled 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.