Friday turned into a GoMud day — one small structural feature in the engine itself, and a chunkier scripting effort to make the cackalackycon booths behave the way I've been wanting them to.
GoMud
The engine change was per-zone death recovery rooms. Up until now, dying anywhere in the world sent you to the global death room, which is fine as a default but really limiting for themed zones. The cackalackycon area in particular wants its own recovery room — somewhere narratively appropriate, not the generic afterlife.
The implementation was small enough that I almost talked myself out of it being worth a feature: added a DeathRecoveryRoom field to ZoneConfig, taught suicide.go to check the dying player's current zone for an override before falling back to the global room, and set deathrecoveryroom: 2002 in the cackalackycon zone-config. Three files, thirteen lines. But it's the kind of thing that unlocks a lot of zone-specific worldbuilding without needing engine changes per zone.
The bigger work was scripting: per-user persistent booth unlocks for the lockpick booths in rooms 2020 and 2060-2063. The old behavior was global — once anyone picked a booth's lock, it stayed unlocked for everyone, which completely defeats the point of having lockpicking as a per-player skill check. Now each booth starts locked, and unlock state is stored on the player's persistent data so it survives restarts and only applies to the player who actually picked it.
The trickiest piece was the onCommand handler in 2020.js, which has to intercept go [booth#] commands and decide whether to allow passage. The logic ended up being: allow if the player has the permanent unlock flag, OR if they just picked the lock this session (temp flag set, and the exit is currently in its unlocked state). Otherwise it denies with the locked-door message. The "just picked it" case matters because there's a brief window after a successful pick where the temp flag exists but the permanent one hasn't been written yet — without that branch you'd get a weird denial immediately after a successful pick.
A useful realization while wiring this up: persistent player data is the right home for this kind of state, not room state. Rooms are global; players aren't. Anything that should feel personal to a character belongs on the character.
hackerlabs.dev
Just the routine publish of yesterday's journal. Nothing exciting on the blog side today.
Two features both about scoping things correctly — death rooms scoped to zones, lock state scoped to players. Feels like a coherent day in retrospect, even though that wasn't the plan when I sat down.
