Skip to content

The office as a persistent visual loop: it is WATCH-only, permanently 'decent', hardcoded to tier 1, and buying furniture changes no pixel #1319

Description

@PipFoweraker

From: coordination seat. Source: Pip voice memo 2026-08-24_084241__c2b0170e, on the opening of the game. Transcribed locally; quotes are ASR output, lightly de-stuttered.

This memo revisits pdoom1#1229, which Pip filed as "explicitly not now". It is not a duplicate of it: pdoom1#1229 is a design thread about direction (people behaviours, trash, janitors, an XCOM-style network view). This is a request for a specific loop, and every piece of it is either already built and unwired, or blocked on promoting art that already exists.


The loop he described

"what would be cool about having sim on both screens is as soon as we get in we have like our shitty office space right which means okay let's figure out how we can represent shitty office space and then think about the upgrades and think hey how can we show that like when you do things things in the office change visually"

"here's how we can show that clicking buttons allows things to be like bought, maybe like delivered by a delivery person with a trolley or something, and then like installed and like starts affecting the office, because I think that gives us like a cool visual loop"

"the baseline of having the office beyond all of the things continuously lets players have something that they look at and kind of get more feedback from"

And the shape of the room:

"maybe we want to zoom it in, maybe when you make the office floor plan smaller to start with and make it an irregular shape, put a door in, put windows in, maybe we can make some cosmetic differences between the for-profit and non-profit versions of the game, so players get some like visual feedbacks"

Four asks: the office is always on screen; it starts shitty; purchases physically arrive and install; the room is small, irregular, has a door and windows, and looks different per org form.


Grounding: three of the four are unwired code, not missing code

1. "Sim on both screens" -- the office is WATCH-only today

godot/scripts/ui/main_ui.gd:402-404:

screen_mode.register_plan_only(plan_screen)     # the whole PLAN screen (hand, upgrades, verbs)
screen_mode.register_watch_only(watch_screen)   # the whole WATCH screen (the feed)
screen_mode.register_watch_only(watch_bar)      # the playback control strip

OfficeFloor is instanced inside watch_screen (godot/scripts/ui/watch_screen.gd:25-33, preload("res://scenes/ui/office_floor/office_floor.tscn")), so it disappears the moment the player switches to PLAN, which is the mode the game opens in. The player plans a month looking at nothing.

What is on both screens is InstrumentPanel (godot/scripts/ui/instrument_panel.gd): the doom gauge, the numeric doom, the roster, the committed queue -- and scenes/ui/office_cat.tscn. Today the only living thing the player can watch continuously is the cat. There is also a static backdrop, assets/images/backgrounds/office_wide_day.webp at modulate = Color(0.35,0.35,0.35,1) under a scrim (scenes/main.tscn:38-49). Wallpaper, not sim.

Moving it is cheap and safe by construction: watch_screen.gd:25-29 states the contract -- "A PURE VIEW (ADR-0006): the walker COUNT mirrors the live staff count... It reads a value snapshot and never writes game state, so it cannot touch determinism/replay; its wander uses a private cosmetic RNG, never the seeded sim stream." A pure view can be mounted in two places or above the mode split without touching the sim. ScreenModeController (godot/scripts/ui/screen_mode.gd:10-15) is explicitly a visibility-toggling scaffold, not a reparenting one, so this is a registration change plus a mount point.

2. "Shitty office space" -- the tier machinery is built and nothing calls it

The canonical ladder is scummy / decent / premium, ruled 2026-07-26, and it is already in the data schema. godot/data/office/props_manifest.json _schema.style_tags: "office quality tiers this art serves, from the canonical ladder... Tag only the tiers the art was AUTHORED for. Renderers fall back to the decent art unchanged where a tier-variant is missing (no tinting hacks). Tier-variant entries use the id convention <base_id>_<tier>."

The renderer honours it: godot/scripts/ui/office_floor/office_floor.gd:490-496 and :690-696, set_office_style(style) -> _office_style -> prefer manifest variant "<id>_<style>". godot/scripts/core/prop_catalogue.gd:139-157 exposes style_tags() and a by-tag lookup.

set_office_style() is called by exactly one caller in the repo, and it is the dev sandbox. Nothing in the shipped path ever sets it, so _office_style stays "", which :693 treats as decent. The office is permanently decent and can never look shitty.

The same disconnection shows up twice more in the same view:

  • office_floor.gd:100 declares @export var office_tier: int = 0 and nothing in the repo ever assigns it.
  • watch_screen.gd:81 hardcodes office_floor.set_tier(1).

Meanwhile godot/scripts/core/office.gd:148 does set state.office_tier when a lease is signed. The sim knows which office you are in; the view is pinned to tier 1 and cannot be told. Signing a bigger office changes nothing on screen.

The other half of the gap is art, and here is the measurement:

  • godot/data/office/props_manifest.json holds 3 props -- filing_cabinet, server_cluster, water_cooler -- all three tagged ["decent"]. Zero props are tagged scummy.
  • godot/assets/office_floor/props/ holds those same 3 PNGs and nothing else. godot/assets/office_floor/tilesets/ holds one file, floor_concrete.png.
  • godot/scripts/ui/office_floor/office_sandbox.gd:170-171 asks for floor_lino / wall_scummy / wall_decent by filename substring. None of those exist under godot/assets/. The sandbox comment at :162 says "Only scummy + decent have art today" -- that is true of art_source/, not of the promoted assets, and the distinction is the whole blocker.
  • art_source/ holds 4,457 PNG. godot/assets/ holds 489 PNG+webp. The tables and desks visible in the shipped office are drawn procedurally (draw_circle / draw_rect, office_floor.gd:722-731), not art.

So: "represent shitty office space" is a promotion job plus one line that calls set_office_style, not a rendering project.

3. "Delivered and installed" -- the upgrades have no physical existence at all

godot/scripts/core/upgrades.gd is 7 upgrades hardcoded in GDScript (no JSON, unlike actions):

id cost category
upgrade_computer 200,000 infrastructure
comfy_chairs 0 office
secure_cloud 160,000 infrastructure
accounting_software 0 management
hpc_cluster 800,000 infrastructure
research_automation 600,000 research
supply_automation 25,000 office

Two of the seven are priced 0 and labelled "Flavor only for now -- no mechanical effect (#970)" after pdoom1#1004 parked them. Three of them are literally furniture -- chairs, a computer, an HPC cluster -- and none of them changes a pixel. Buying one is a number going down.

The delivery mechanic is already designed elsewhere: pdoom1#804 (procurement and equipment lead-time) has the two-clock model, the reusable-inventory rule, and the ruling that "Ordering equipment should cost ~0 Attention (money + a lead-time timer)". The delivery-person-with-a-trolley is the visual expression of pdoom1#804's timer, and building them together is cheaper than building either alone.

4. Floorplan, door, windows, org form -- and why this is render-only

godot/scripts/core/office.gd:25-27 states the constraint and pre-empts the work:

"SIM/RENDER BOUNDARY (ADR-0018): floorplan. in offices.json is RENDER-ONLY. Nothing in this file (or any sim path) reads floorplan -- the sim reads hire_cap. floorplan() is exposed purely so office_floor.gd can size itself off the signed lease later."*

"Later" is what this memo is asking for. office_floor.gd does not currently read the signed lease at all. Tier 0 is "Bedroom / basement", hire_cap: 2, rent 0 (godot/data/office/offices.json), so the starter room should be small; it is not, because nothing reads it.

Note also that godot/data/office/offices.json carries "upgrades": [] -- an empty per-office upgrade array with no producer and no consumer. If office-attached upgrades are the shape wanted, the slot is already cut.

And org_type is real and already invisible. godot/autoload/game_config.gd:16 -- var org_type: String = "nonprofit" # "nonprofit" | "for_profit" (DQ-19). It is a live pregame choice (godot/scripts/ui/pregame_setup.gd:179-203), it reaches the sim (godot/scripts/game_manager.gd:104-105, godot/scripts/core/game_state.gd:205-208), and FinanceEngine prices off it (godot/data/balance/defaults.json:187-189, for_profit borrows at 0.9x; vc_equity is for-profit-only at :245). Today the only way a player can tell which one they picked is the loan terms. Note godot/scripts/ui/config_confirmation.gd:72 forces nonprofit for the featured league, so for-profit is a custom-setup path only.

ADR-0018 is what makes all four of these safe to do now: render-only changes cannot fork the ladder. That is the opposite of the tempo work in pdoom1#1044, which is an epoch bump. Worth keeping crisp, because it means this can ship inside a league.

And ADR-0018 is also the wall. docs/game-design/decisions/ADR-0018-render-only-office-doctrine.md (status DRAFT, 2026-07-27) records Pip verbatim: "No spatial fact will ever become a gameplay input." Everything in this issue is on the render side of that line and stays there. If any of it starts wanting to read a coordinate back into the sim -- a delivery that must physically reach a spot before the upgrade applies, say -- stop and raise it, do not quietly cross. The install animation must be a consequence of the purchase, never a precondition for it.


Suggested cut, cheapest first

  1. Mount OfficeFloor above the PLAN/WATCH split so it is on screen continuously. One registration change; pure view, no sim risk.
  2. Call set_office_style() from game state -- tier 0 lease -> scummy, tier 1 -> decent. One line plus the mapping. Renders identically to today until (3) lands, because of the documented decent-fallback.
  3. Promote scummy art: a lino floor, a scummy wall, and <id>_scummy variants of the three existing props. This is the promotion pipeline in pdoom1#951 / pdoom1#1093, pointed at a named list instead of a backlog.
  4. Read office.floorplan() in office_floor.gd so the starter room is small and irregular, with a door and windows. The accessor was built for this.
  5. Delivery-and-install for upgrades, built as the visible half of pdoom1#804: purchase -> lead time -> a walker arrives with the object -> the prop appears on the floor. Start with the three that are furniture. comfy_chairs costs 0 and has no mechanical effect, which makes it the ideal first one: nothing can regress.
  6. Cosmetic org-form differences -- render-only, per ADR-0018. Scope is Pip's call; the memo says "cosmetic differences", not what they are.

Not resolved here

  • Zoom. "maybe we want to zoom it in" -- said with "maybe", and no camera work is specified. Not scoped.
  • What the for-profit office looks like. The memo asks for a difference, not a design.
  • pdoom1#1229 is top-down, not isometric (one isometric hit in the whole tree, a parenthetical comment at office_floor/render_grid.gd:57). Nothing here changes that, and nothing here should.

Related: pdoom1#1229 (the parent design thread), pdoom1#804 (procurement lead-time -- the delivery mechanic), pdoom1#1004 (the three parked upgrades), pdoom1#471 and pdoom1#467 (office cosmetics / outfitting), pdoom1#475 (upgrades system overhaul), pdoom1#791 and docs/game-design/OFFICE_ECONOMY_PROPOSAL.md (office economy), pdoom1#951 and pdoom1#1093 (art promotion and the review backlog), pdoom1#707 (post-promotion UI consistency sweep), ADR-0006, ADR-0018.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions