← All projects

Published by KnownBetter Studios → This page is the engineering case study.

Marjorie's Manor

In development

A cozy game about running a Victorian rooming house, where helping each tenant move on with their life is the whole point, and it costs you their rent.

GameGodotNarrativeCozyManagement

At a glance

  • Outcome: You inherit a manor, its debts and its tenants. Building relationships moves each tenant’s story forward, finishing a story costs you their rent, and what you notice about the house is what the long arc turns on. The product page and art direction live at KnownBetter Studios.
  • Status: In development. As of September 3, 2026 the 3D prototype has been retired and the game rebuilt as a 2.5D isometric Godot build: 21 rooms of gray blockout, tenants on schedules, talk and gifts, build mode, rent and bills, the attic, a journal, an observation system, four tenant arcs, an endgame, a tutorial and three save slots. Hand-drawn art by co-creator Sarah replaces the blockouts as it lands, and a Kickstarter is planned for 2027 once the vertical slice is playable.
  • Role: Systems, data model, save format and the verifier discipline; implementation is AI-assisted and reviewed. The art direction is Sarah’s.
  • Stack & libraries: Godot 4.6 with GDScript, Dialogic 2.0 alpha for dialogue. TileMapLayer floors and Y-sorted Node2D props in 2:1 dimetric, AStarGrid2D pathing, no physics. Eleven autoload managers read nine JSON content files.
  • Source: Private.
  • Validation: 35 headless verifier scripts, 6,173 checks in all, run by one shell script after a clean boot; the whole suite passed against the last commit on September 11, 2026. Verifiers are 11,385 of the 25,971 lines of GDScript. A balance sim drives the real managers through six months for four player archetypes, and its verdicts set the economy constants.
  • Limitations: No art: every surface is a gray prism. No title screen and no builds. The featured arc has been walked headless from a new game, but the in-engine fresh-save playthrough on the roadmap is still unchecked. A local co-op layer (a second actor, workstation jobs, save v6) sits uncommitted in the working tree as of September 11. Rent, bills, the observation tier thresholds and Iris’s birthday are still constants in GDScript.

The mechanism the data model has to carry

Rent is the live tenant count times $300 a month against $600 of flat bills. It accrues into the mailbox until collected, and one odd job a day pays $25 to $50. Finishing a tenant’s story is the thing that costs you: three of the 22 quest beats mark a departure, and there is no separate move-out system, because leaving is the final beat’s effect.

Decoration decides who arrives. Every furniture item carries weighted style tags, a room is scored as points and share per style, and leaving build mode in a vacant apartment moves in the first un-housed tenant whose rule holds. The rules are rows in tenant_data.json: Jasper wants half the room and six points of vintage, Zoe the same in minimalist, Iris any room with three points of anything. In the prototype those thresholds were constants; now a new tenant with a new taste is a row.

Noticing as a third currency

The rebuild added a system the prototype didn’t have. Every room and every tenant is an observation subject, 21 in all, each with three to five facets that open under a window: an hour, a place, a finished objective, or another subject’s tier. Standing in a room pays one point a chunk; a watch spot or the tenant menu’s Pay Attention spends the chunk to mark a facet outright. Points and facets lift a subject through Noticed, Familiar and Understood. The permanent floor is saved; the session tier is rebuilt one lower on load, so a returning player re-sees the house.

A tier does three things. It is a quest trigger, observation_tier, on four of the 22 beats, so a story can wait on what you noticed rather than what you said. It grows a journal page stage by stage: 21 staged entries with 68 margin lines, derived from the manager at draw time and never copied into the journal. And it branches dialogue: 13 of the 37 Dialogic timelines carry an if on a tier or on whether a noticing is waiting to be shared. One function, is_facet_in_window, answers for both the passive and the active rate, so the two can’t disagree about a gate.

Verified by scripts

There is no test framework. Each verifier is a SceneTree script that boots the real autoloads, drives them through the real hooks and prints N checks, M failures; the runner reads that line rather than the exit code, because two verifiers run real Dialogic timelines and crash on the addon’s teardown after printing. Verifiers landed alongside the roadmap steps, 35 across the four rebuild phases.

The acceptance verifiers are the ones worth naming. g4_acceptance_verify starts a new game and plays the featured arc end to end with nothing forced: furniture bought from the week’s thrift rotation, a gift picked from a tree, items out of attic boxes, sixteen days standing in a hallway. It asserts the whole thing costs 19 game days, connects debug_command_executed and checks it never fired, and sweeps its own source for ten named shortcuts. g4_prose_verify runs every timeline through Dialogic twice, once with nothing noticed and once with every subject Familiar, so both sides of every branch execute and every speaker resolves. The save verifier builds a v1, v2, v3 and v4 payload and pushes each through the migration chain to v5, asserting what each step seeds and what it must leave alone.

What’s data and what isn’t

Nine JSON files hold the content: rooms (21 rooms, 55 props and the door table), palettes, tenants, quests and objectives, attic items, forage, journal entries, observation subjects and the furniture catalog. A prop’s behaviour is picked from its type field, eleven types from mailbox to story_door, so the endgame’s one-way doors and walk-in triggers are rows, and adding a room is one registry entry plus a bare scene. A fourth tenant arc from the four existing trigger types is content work; a fifth trigger type is still a code change.

The rebuild kept the manager layer and the tenant, beat and furniture schemas from the prototype and threw away the scenes, the camera and the asset packs, which were purged from history with git filter-repo.