Log inGet started
▣
module · drop-in viewer
asset⌬ modulemoduleprimary: init.luau·originates fromworld e339ab22-c…

PlayerState

Everything the player *is*, as plain data: one table plus the rules that govern it. No entities, no input, no engine — so the survival numbers can be reasoned about on their own, and the interface reads the same values the simulation runs on rather than a copy that drifts.

by◐aiden·posted 1d ago
What it does

game.systems.PlayerState

Everything the player is, as plain data: one table plus the rules that govern it. No entities, no input, no engine — so the survival numbers can be reasoned about on their own, and the interface reads the same values the simulation runs on rather than a copy that drifts.

local PlayerState = require("game.systems.PlayerState")
local state = PlayerState.new()

What is in it

  • new() — health, stamina, torch and battery, what is carried, clues, the objective index, the power, and whether the run has ended.
  • Movement — spendStamina, canStartSprint.
  • The torch — useTorch, torchLow, replaceBattery.
  • Carrying — has, give (a unique item already taken is not taken again, which is what stops two peers pocketing the same key), addClue, clueCount, requiredCluesFound.
  • Damage — damage (returns true when it is fatal), heal.
  • The objective chain — objectiveMet(state, step) says what each step waits for, and syncObjective walks the chain forward as far as the player has actually got. It only ever moves on.
  • ending(state) — which ending the run earned, from the clues found and whether the secret room was opened.

The co-op split

toShared and applyShared state, once, what the whole session agrees on — a door, a key, an objective, the power — against what is only yours: your stamina, your health, your torch. Mixing the two is how a co-op game desynchronises, so the split is a function rather than a judgement at each call site.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

strict

new( ) → State

spendStamina(state: State, dt: number, sprinting: boolean) → boolean

Sprinting costs stamina and stops when it runs out; standing still puts it back. Returns whether the sprint is still allowed, so the caller slows the player the moment it is not.

argtypedescription
stateState
dtnumber
sprintingboolean

canStartSprint(state: State) → boolean

argtypedescription
stateState

useTorch(state: State, dt: number) → boolean

The loop's real clock. It burns whether or not the player is being careful, and a dying beam is the house's way of hurrying them.

argtypedescription
stateState
dtnumber

torchLow(state: State) → boolean

argtypedescription
stateState

replaceBattery(state: State) → boolean

A replacement battery. Only counts if one is carried, and it uses the one it spends up, so the empty slot is freed by using it.

argtypedescription
stateState

has(state: State, itemId: string) → boolean

argtypedescription
stateState
itemIdstring

definition(itemId: string) → any

One lookup for what an item IS, so the rules about it live in one place.

argtypedescription
itemIdstring

give(state: State, itemId: string) → boolean

argtypedescription
stateState
itemIdstring

consume(state: State, itemId: string) → boolean

Spend one of something. Frees its slot when the last one goes, which is how USING an item gives the player room again.

argtypedescription
stateState
itemIdstring

slots(state: State) → void

The row the interface draws: one entry per slot, the item's own name or an empty string, so an empty slot is a slot and not a missing one.

argtypedescription
stateState

slotsUsed(state: State) → number

argtypedescription
stateState

addClue(state: State, clueId: string) → boolean

argtypedescription
stateState
clueIdstring

clueCount(state: State) → number

argtypedescription
stateState

requiredCluesFound(state: State) → number

The required clues, not any clue: the ending turns on whether the player understood the house, and a stray note is not understanding.

argtypedescription
stateState

damage(state: State, amount: number) → boolean

argtypedescription
stateState
amountnumber

heal(state: State, amount: number) → void

argtypedescription
stateState
amountnumber

currentObjective(state: State) → any

argtypedescription
stateState

objectiveDone(state: State, id: string) → boolean

argtypedescription
stateState
idstring

advanceFrom(state: State, id: string) → boolean

Advance to the step after `id`, if that is where the player is. Steps are ordered, so this can only ever move forward.

argtypedescription
stateState
idstring

ending(state: State) → string

argtypedescription
stateState

objectiveMet(state: State, step: any) → boolean

What each step WAITS FOR, in one table. The chain is only worth tracking if finishing a step is something the game can see, so every one of these reads a fact the player actually produced: an item in hand, a clue read, the power on.

argtypedescription
stateState
stepany

syncObjective(state: State) → boolean

Walk the chain forward as far as the player has actually got. Steps are ordered, so this only ever moves on; it never goes back.

argtypedescription
stateState

toShared(state: State) → void

What the whole session shares, and what is only yours. A door, a key, an objective and the power are facts about the RUN, and every peer must agree on them; stamina, health and a torch are facts about a person. Mixing the two is how a co-op game desynchronises, so the split is a function here rather than a judgement at each call site.

argtypedescription
stateState

applyShared(state: State, shared: any) → void

argtypedescription
stateState
sharedany
⌬ Types
State = {

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

7items
▣
module · born here
❒asset
# game.GameRules The constants and rules of **The House That Knows You** — the one module every part of the game reads, so two systems written in different sessions agree on what a room is called, how loud a sprint is, how long a torch battery lasts and which ending the player earned. It holds **no behaviour and no entities**: pure data plus a handful of pure functions. Require it and read it; never write to it. ```lua local RULES = require("game.GameRules") ``` ## What is in it - **`ART_DIRECTION`** — the one sentence every generation prompt reuses word for word, and **`REFERENCES`** — the pictures the game is judged against. - **`PALETTE`** — that sentence as numbers, for the interface and for materials. - **`HOUSE`** — the wall height, the wall thickness, the doorway size, the room module, the storey height and the player's own dimensions. Every prop in the game is sized against these. - **`AREAS`** / **`AREA_BY_ID`** — the twelve areas, each with its floor, its nominal centre on the ground plan and the item that unlocks it. - **`OBJECTIVES`** — the twelve-step chain, in order, each naming the area it happens in and the item it needs. - **`ITEMS`**, **`REQUIRED_CLUES`**, **`CLUE_COUNT_FOR_TRUTH`** — what can be picked up, and what the ending is decided on. - **`ENDINGS`** and **`selectEnding(cluesFound, secretRoomOpened)`** — the three endings and the rule that picks one, stated once so the interface and the systems cannot disagree. - **`SURVIVAL`** — speeds, stamina, health, torch battery, interaction ranges. - **`DIFFICULTY`** — easy, normal, nightmare. These change the monster's persistence, reach and the supply density **only**; all three run the same monster logic. - **`MONSTERS`** and **`MONSTER_STATES`** — THE RESIDENT and THE BROODMOTHER, and the states both run: patrol, investigate, chase, search, attack, recover. - **`NOISE`** — the interface between what a player *does* and what a monster *hears*. A system emits a noise id; the monster AI turns it into a reach. Nothing else may write a raw radius. - **`SPIDERS`** — the baby-spider event: five presses, six seconds, the slow-motion tutorial, the prompts, the damage. - **`ENDLESS`** / **`endlessDifficultyFor(floor)`** — Endless Nightmare, and a floor number that never stops climbing. - **`MODES`**, **`MAX_PLAYERS`**, **`DATA`** — the game modes and the keys shared state lives under. ## Who calls it Every slice: the house builder, both monsters, the survival systems, the interface and the audio director. Every component that runs in play reads its numbers from here rather than carrying its own copy.
▲ 0↑ born
backing path · game/systems/PlayerState.module

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported. This asset, its contents, and its direct deps are clean as of the latest commit.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.