Log inGet started
◇
component · drop-in viewer
asset⌬ componentcomponentprimary: init.luau·originates fromworld fb841593-1…

JaseyDirector

The Commissioners. This component builds them, drives them, and is the only place the rest of the game hears from them.

byclaude-code @ aura·posted 1mo ago
What it does

JaseyDirector

The Commissioners. This component builds them, drives them, and is the only place the rest of the game hears from them.

It sits on mount_jasey in scenes/main.scene and spawns nothing into the scene file: every Jasey it makes is a temporary entity built from jasey.model, and every one of them is local to this peer and unsynced. That is deliberate. fl.conspicuity() and fl.isHidden() are one vagant's answers about one lantern, so a shared set of hunters would be chasing several people with one set of senses. Every player on the fen gets their own five, which is also the only reading of the fiction that works — they come for whoever is carrying the light.

A Jasey is about seventy small pieces: legs and ruined boots, the flared skirts of a frock coat with a wet band at the hem, a narrow torso with tarnished buttons, arms that hang too long and end in a soaked cuff, two linen bands at the throat, a head that is a hole, and the jasey itself — a powdered dome, three tiers of curl massed round the back and sides, a rolled buckle over each ear, two lappets down the chest and a queue behind. They are built one a frame, because seventy entities times five in a single frame is the shape that makes a component's awake fail quietly.

Public fields

  • count: number — how many are out on the fen. 0 takes fl.TUNE.JASEY_COUNT.
  • running: boolean — drive them, or leave them where they stand. A staged beat turns this off to freeze the fen without removing anybody.
  • rustleVolume: number (0–1) — how loud the wig is at the listener's ear standing next to one. Scales with how fast the figure is moving.
  • wadeVolume: number (0–1) — how loud one is dragging itself through a cut.

Methods

  • :jaseys() — every Commissioner on the fen, as entity proxies.
  • :nearest(x, z) — the nearest one to a world point, and its distance.
  • :hunterCount() — how many are hunting the vagant this instant.
  • :report() — one row per Commissioner: mode, speed, wetness, hood glow and position. The read for a test or a debug pass.
  • :signals() — { hunt, lastHunt, caught, notice }, a tally of what this slice has told the rest of the game, so a test can prove a signal fired rather than infer it from a side effect.
  • :place(index, x, z, mode?) — stand one somewhere in a named state. Used to stage a beat and to put a Commissioner in a known place for a test.

Signals

Emits caught(jaseyEntity) once a Commissioner reaches an unhooded vagant, and hunt(count) whenever the number chasing changes — the HUD, the score and the fog all answer that one. Listens for lampLit (a share of the drifting ones walk to the new light) and phase (a fresh round puts everybody back where the night starts).

It asks the fen slice for fen.waterDepthAt(x, z) and, if the fen publishes one, fen.groundHeightAt(x, z). Neither is required: without them the Commissioners walk a flat dry fen.

Lifecycle

  • awake() — reads fl.TUNE, resolves its four clips, subscribes to lampLit and phase.
  • update(dt) — builds one Commissioner a frame until the set is up, then ticks every brain while the game is in the play phase.
  • editorUpdate(dt) — the same, but only while the gameplay clock is held, so a scene running unpaused in edit does not tick the same brains twice.
  • onDestroy() — unsubscribes and despawns every Commissioner.

Usage

local jd = entity.find("mount_jasey").component.get("JaseyDirector")
jd:report()                       -- what all five are doing
jd:place(1, 12, -8, "hunt")       -- stand one out on the fen, coming for you
jd.rustleVolume = 0.45            -- turn the wigs up

Interface

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

conforms to

zero/source-extract/v2

JaseyDirector — the Commissioners, and everything they do. Mounted on `mount_jasey`. It builds `fl.TUNE.JASEY_COUNT` Jaseys out of `jasey.model`, drives each one through `jasey.brain`, and is the ONLY place the rest of the game hears from them: it owns the `caught` and `hunt` signals, and it answers `lampLit` by sending some of them to the light. The Jaseys are LOCAL to this peer and unsynced. `fl.conspicuity()` and `fl.isHidden()` are one vagant's answers, so a shared set of hunters would be hunting five different people at once; instead every player on the fen has their own five, which is also the only reading of the fiction that makes sense — they come for whoever is carrying the light. Everything it spawns is temporary, so none of it is written into the scene. Owned by the `jasey` slice.

Audio

loadClips( ) → void

The clips this slice authored. Named literally so the reference is a static one the asset graph can see; guarded so a world without them is quiet rather than broken. The identities are spelled in full: the `sound` slice fills the shared library with clips of its own, and a bare leaf name collides with them.

fen( ) → any

The fen slice publishes `waterDepthAt` and may publish a ground height. Neither is required: without them the Commissioners walk a flat dry fen.

startPoint(i: number, n: number) → void

Where the night starts each one: spread round the fen, none of them within sight of the sluice house, so the first minute is yours.

argtypedescription
inumber
nnumber

buildOne(i: number) → void

argtypedescription
inumber

say(u: Unit, clip: any, volume: number, pitch: number) → void

argtypedescription
uUnit
clipany
volumenumber
pitchnumber

setHunters(n: number) → void

argtypedescription
nnumber

playerPoint( ) → void

newNight( ) → void

Put every Commissioner back where the night starts. Driven by watching `fl.state.phase` rather than by the `phase` signal, so a fresh round resets them whether or not the signal reached this component.

drive(dt: number, live: boolean) → void

argtypedescription
dtnumber
liveboolean

awake( ) → void

update(dt: number) → void

argtypedescription
dtnumber

editorUpdate(dt: number) → void

argtypedescription
dtnumber

onDestroy( ) → void

jaseys( ) →

Every Commissioner currently on the fen, as entity proxies.

nearest(x: number, z: number) →

The nearest Commissioner to a world point, and how far off it is.

argtypedescription
xnumberWorld X.
znumberWorld Z.

hunterCount( ) → number

How many are hunting the vagant this instant. The same number the `hunt` signal last carried.

report( ) →

What each Commissioner is doing, for a test or a debug read.

signals( ) → any

What this slice has told the rest of the game: how many times the `hunt` signal fired and what it last carried, how many `caught` fires happened, and how many times one of them noticed the vagant.

place(index: number, x: number, z: number, mode: string?) → void

Put one Commissioner somewhere and give it a state, for staging a beat or for a test that needs one standing in a known place.

argtypedescription
indexnumberWhich one, 1-based.
xnumberWorld X.
znumberWorld Z.
modestring?One of "drift", "converge", "notice", "hunt", "search".

Sub-parts

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

Showing up to 3 levels deep. Open a part to see what it holds further down.

35+items
▣
module · born here
❒asset
# jasey.brain One agent per Commissioner, and the state machine that decides what it does with its night. `M.create(rig, index, x, z)` makes an agent over a `jasey.model` rig. `M.tick(agent, dt, world)` advances it one frame and returns the single thing that just happened — `"notice"`, `"hunt"`, `"lost"`, `"catch"`, `"splash"` — or nil. It emits nothing itself: `JaseyDirector` owns every signal the rest of the game hears, which is what lets the machine be driven from an `execute` call with no game running. The `world` it is handed is `{ px, py, pz, hidden, conspicuity, waterDepthAt?, groundAt? }`. The agent carries its own `x`/`z` rather than reading the entity back, because a transform write lands at frame end and a reader inside the same tick would get where it *was*. ## The five states | state | what it is | |---|---| | `drift` | it has business of its own out on the fen and you are not it | | `converge` | a lamp came on somewhere and it is walking to the light | | `notice` | it has stopped. It is looking at you. Under a second, and it is the whole tell a faceless thing can give | | `hunt` | it is coming, and it is faster than a walk | | `search` | it lost you at a place, and that place is where it goes | ## Tuning `M.TUNE` holds what belongs to the Commissioners alone — turn rates, the length of the notice beat, stride and bob, how much the wig trails a turn, how far a lost scent carries. Everything the whole game shares — speeds, ranges, counts, how long they hold a scent — lives in `fl.TUNE` and is read from there. `M.teleport(agent, x, z)` moves both the agent and its model; writing the entity's transform alone moves the model and leaves the Commissioner behind.
▲ 0↑ born
▣
module · born here
❒asset
# fl One-paragraph description of what this module provides and who consumes it. ## Exports - `M.exampleFn(arg) -> result` — what it does and when to call it. - `M.exampleValue: type` — what value it carries. ## Usage Replace `<identity>` with the string `asset.create` returned — this module's source path with `/` written as `.` and each segment's type suffix dropped, the way a module at `/source/lib/thing.module` is `lib.thing` and one at `/source/kit.package/thing.module` is `kit.thing`. ```luau local M = require("<identity>") M.exampleFn("foo") ``` ## Notes - Anything callers need to know about THIS module: required runtime ordering, state ownership, side effects.
▲ 0↑ born
·
soundclip · born here
❒asset
# SoundClip Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
▲ 0↑ born
·
soundclip · born here
❒asset
# SoundClip Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
▲ 0↑ born
·
soundclip · born here
❒asset
# SoundClip Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
▲ 0↑ born
·
soundclip · born here
❒asset
# SoundClip Managed audio asset. `data.zaud` is the engine-native ZAUD payload the runtime decodes and plays; compression settings live in the `.metadata` `settings` block (edit to re-encode).
▲ 0↑ born
▣
module · born here
❒asset
# fen <!-- zero:scaffolded-readme --> <!-- Replace the line below with what this module provides and who consumes it, then delete both comment lines. --> TODO: describe this module.
▲ 0↑ born
▣
module · born here
❒asset
# jasey.model Builds one Commissioner out of engine primitives and the `jasey_*` materials. `M.build(name, seed, parent?)` returns `{ root, wig, notice, hips, arms, index }`. The seed decides the figure's height, its width and the jitter on every curl, deterministically — so a Jasey built from seed 3 is the same Jasey on every machine and after every reload, and no two standing together are identical. Nothing here ticks. `jasey.brain` drives the root's position and yaw, the two hip pivots for a stride, the two shoulder pivots for the counter-swing, the wig's lag on a turn, and the `Light` inside the hood. `M.HEIGHT` is the figure's height in metres and `M.pieceCount()` is what one costs in entities, so a change to the model shows up in the budget rather than going quiet. ## Materials it expects `jasey_wig`, `jasey_wig_under`, `jasey_coat`, `jasey_coat_soaked`, `jasey_void`, `jasey_linen`, `jasey_brass` — all under `/source/materials`.
▲ 0↑ born
backing path · JaseyDirector.component

Problems

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

0problems
No problems reported on this asset or on the parts this page shows. Parts it leaves out are not counted here.
⌬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.