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.
- INeedsService — LoadOrCreateAsync(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.