Skip to content

Generated reference. This page mirrors Code/Needs/README.md, this module's source-of-truth documentation (Standards/02_DOCUMENTATION_STANDARDS.md §1). Edit it there, not here -- this file is regenerated on every docs build and any local edit is silently overwritten.

Needs

Purpose. One generic model for an ambient per-character resource that decays passively and is restored by discrete events — Hunger, Thirst, Temperature, and Disease, all as pure configuration. See 14_NEEDS_FRAMEWORK.md.

Responsibilities. - NeedDefinition — content, not code: Id, DisplayName, Max, Initial, DepletionSeconds. A satiation value (Max = satisfied, 0 = empty), deliberately inverted from the legacy source's starvation polarity — see 14_NEEDS_FRAMEWORK.md §1. - NeedsConfiguration — the operator-facing GameResource, List<NeedDefinition> Definitions, seeded with four entries (Hunger, Thirst, Temperature, Disease — Milestone 12, see 14_NEEDS_FRAMEWORK.md §2.1 for the defaults and reasoning behind the three added this pass). PostLoad validates every entry: non-empty Id, no duplicate Id, Max > 0, DepletionSeconds > 0. - INeedsService / NeedsStore — the values themselves: LoadOrCreateAsync, GetValue, Tick, RestoreAsync. NeedsStore is the one implementation; nothing else writes a character's need values. Mirrors IInteractionRunner's ticked-singleton shape, not IInventoryService's caller-holds-a-domain-object shape — see 14_NEEDS_FRAMEWORK.md §3. - CharacterNeedsComponent — the [Sync(FromHost)] replication surface a HUD panel reads, same poll-and-assign shape as CharacterEconomyComponent/CharacterInventoryComponent. - NeedsBar.razor — a minimal HUD panel (one text line per need). Not registered against IHudRegistry -- it's a PanelComponent (resolves the local player's CharacterNeedsComponent via Applejack.Movement.LocalPawn), and that registry only accepts TPanel : Panel, new(). Follows MoneyDisplay's scene-placed pattern; not yet scene-placed itself. See Code/Ui/README.md's "Panel-vs-PanelComponent" entry. - NeedsModule — registers NeedsConfiguration and INeedsService. - Persistence of need values under needs/{characterId} (08_DATA_MODEL.md §8).

Not responsible for. - Temperature's environmental-source mechanic (weather, indoor/outdoor detection) and Disease's transmission/infection mechanic (proximity-based spread). Both needs exist and decay/restore like every other need, but that decay is a flat placeholder for each until those separately-scoped mechanics exist — see 14_NEEDS_FRAMEWORK.md §6. Disease's real restore-side content (a cure item) is Medical's (Milestone 15), not this module's — see 14_NEEDS_FRAMEWORK.md §2.1. - Damage while starving, the vehicle-double-damage penalty, and the suicide/respawn anti-exploit (Legacy/08_NEEDS_AND_STATE.md §2) — all need a Health service that does not exist in this codebase yet. - Stamina — its legacy drain is event-driven (sprinting) with a resting restore, not a passive decay toward empty, so it does not fit this framework's model as built. Deferred until a Movement system exists to drive it and give its real consequence (speed scaling) meaning. - The six physical states (Incapacitated, Exhausted, Knocked out, Tied, Arrested, Sleeping) — Crime/Law's mechanisms, not this module's. - Persisting decay accumulated between the last RestoreAsync and a server stop — Tick never persists (write-amplification no other ambient system in this codebase performs; see 14_NEEDS_FRAMEWORK.md §4). The same already-accepted gap as the still-missing shutdown/disconnect hook (Code/Core/Modules/ApplejackBootstrap.cs's own header comment).

Dependencies. Core (IServiceRegistry, IServiceResolver, IPersistenceBackend, ISchemaRegistry, IGameLog), Character (CharacterId, the key every need value is stored under). NeedsBar.razor itself depends on Movement (LocalPawn), not NeedsModule.

Public API. - INeedsServiceLoadOrCreateAsync(CharacterId), GetValue(CharacterId, string), Tick(CharacterId, TimeSpan), RestoreAsync(CharacterId, string, float). - NeedDefinition, NeedsConfiguration. - NeedValueView, CharacterNeedsComponent.

Events published. None yet — a NeedDepleted/NeedRestored pair is natural once a consumer (Health, an achievement system) needs to react, deferred until that consumer exists, following Inventory's README's identical deferral.

Persistence. NeedsDocument { CharacterId, Values: Dictionary<string, float> } under needs/{characterId}, schema version 1.

Not unit-tested. NeedsConfiguration.PostLoad's validation (empty/duplicate Id, non-positive Max/DepletionSeconds) has no test. Checked first: no GameResource.PostLoad override anywhere in this codebase has one either (ItemDefinition, PersistenceConfiguration, DoorConfiguration) — PostLoad is engine-invoked only (Code/Core/Configuration/ModuleConfigurationContext.cs's own comment: "NOT called here manually, and deliberately so"), and nothing calls it manually from a test. ItemLoadException is tested, but only via ItemRegistry.ResolveInheritance, a plain method with no PostLoad involved (UnitTests/Items/ItemRegistryTests.cs). Following that precedent rather than inventing a new technique (reflection-invoking a protected method) this codebase has never used.

Future improvements. - Temperature's real environmental-source mechanic (weather/indoor-outdoor detection) and Disease's real transmission mechanic, replacing each need's current flat placeholder decay, once those systems exist. - A real Disease-restoring item (Medical, Milestone 15). - Stamina, once Movement exists to drive its event-based drain. - NeedDepleted/NeedRestored events once a real consumer exists.