World / Industry surface: construction, terraforming, roads, pollution events (20 exporters, no restart) #62

Closed
opened 2026-07-05 04:39:51 +00:00 by coilysiren · 2 comments
Owner

Context

Net-new World / Industry surface - 20 unconsumed exporters, the single largest action theme in the pull-everything survey (#7). Construction, terraforming, roads, object movement, and pollution events - the physical story of what players are doing to the world. All already exported - no game restart.

No-reset spine

Consume the world/industry action exporters (/api/v1/exporter/actions) already live on the server, reusing the shared streamed-CSV plumbing (crafting.py aggregation, #5 column-corrector, id-to-name join, Time-to-day). No new C# mod.

Exporters

ConstructOrDeconstruct, PlaceOrPickUpObject, MoveWorldObject, TampRoad, DropOrPickupGarbage, ObjectExplosion, PolluteAir, plus the extraction actions re-framed world-first (DigOrMine, ChopTree). Cross-reference the climate CO2 series (#8) for pollution and the biodiversity work (#20) for land use.

Scope

  • MCP tool get_eco_world (text + JSON + _meta.ui card): construction/deconstruction volume, roads laid, objects moved, explosions, garbage, and pollution events over time and by citizen. A world-mutation activity timeline.
  • /preview/world.json data plane.
  • SPA /world route - a mutation timeline + top builders/polluters + hotspots, cross-linked with /climate and the biodiversity surface. Live badge on the homepage. Read the dataviz skill before charts.

Acceptance

  • MCP tool registered, ward exec smoke passes; thin/zero-data paths degrade gracefully.
  • respx-mocked unit tests for the aggregation.
  • SPA route renders against /preview/world.json, vitest test, ward exec frontend-test/lint green.
  • ward exec test/lint green; docs/FEATURES.md updated. Survey: #7.
## Context Net-new **World / Industry** surface - 20 unconsumed exporters, the single largest action theme in the pull-everything survey ([#7](https://forgejo.coilysiren.me/coilyco-gaming/eco-app/issues/7)). Construction, terraforming, roads, object movement, and pollution events - the physical story of what players are doing to the world. All already exported - no game restart. ## No-reset spine Consume the world/industry action exporters (`/api/v1/exporter/actions`) already live on the server, reusing the shared streamed-CSV plumbing (`crafting.py` aggregation, `#5` column-corrector, id-to-name join, Time-to-day). No new C# mod. ## Exporters `ConstructOrDeconstruct`, `PlaceOrPickUpObject`, `MoveWorldObject`, `TampRoad`, `DropOrPickupGarbage`, `ObjectExplosion`, `PolluteAir`, plus the extraction actions re-framed world-first (`DigOrMine`, `ChopTree`). Cross-reference the climate CO2 series ([#8](https://forgejo.coilysiren.me/coilyco-gaming/eco-app/issues/8)) for pollution and the biodiversity work ([#20](https://forgejo.coilysiren.me/coilyco-gaming/eco-app/issues/20)) for land use. ## Scope * **MCP tool** `get_eco_world` (text + JSON + `_meta.ui` card): construction/deconstruction volume, roads laid, objects moved, explosions, garbage, and pollution events over time and by citizen. A world-mutation activity timeline. * **`/preview/world.json`** data plane. * **SPA `/world` route** - a mutation timeline + top builders/polluters + hotspots, cross-linked with `/climate` and the biodiversity surface. Live badge on the homepage. Read the `dataviz` skill before charts. ## Acceptance * MCP tool registered, `ward exec smoke` passes; thin/zero-data paths degrade gracefully. * `respx`-mocked unit tests for the aggregation. * SPA route renders against `/preview/world.json`, vitest test, `ward exec frontend-test`/`lint` green. * `ward exec test`/`lint` green; `docs/FEATURES.md` updated. Survey: [#7](https://forgejo.coilysiren.me/coilyco-gaming/eco-app/issues/7).
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-eco-app-62 on host KAI-DESKTOP-TOWER is carrying this issue (reserved 2026-07-05T04:40:01Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-eco-app-62` on host `KAI-DESKTOP-TOWER` is carrying this issue (reserved 2026-07-05T04:40:01Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh** — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

WARD-OUTCOME: done - get_eco_world MCP tool + /preview/world.json + SPA /world route landed on main (ea5e444), reusing the crafting-atlas CSV plumbing, no restart.

Honest retro: this one went smoothly because it was, frankly, the fourth or fifth time this shape of surface has been built in the repo. The crafting atlas set the template so completely that world.py is mostly a re-lensing of the same stream-parse → column-corrector → citizen-join → cache spine, pointed at nine world-mutation exporters instead of four production ones. That inheritance is the whole reason "20 exporters, no restart" is real.

What I'm least sure of: the exact column shapes of the world action CSVs. I have no live admin key here, so the object-column candidate list and the construct/deconstruct handling are modeled defensively (header-keyed picks, positions dropped from name slots) rather than confirmed against a real capture. The aggregation is well-tested against synthetic CSVs, but the day it meets the live server, a column name I guessed wrong would degrade a leaderboard silently — same caveat the sibling #63 social surface flagged. Worth a quick confirm-against-live-capture follow-up for both.

What fought back: nothing in the code, only the merge. issue-63 (social) landed on main mid-flight and touched every shared seam — App routes, Home cards, http_app preview routes, both FEATURES docs — so I hand-resolved five conflicts to keep both surfaces. Clean in the end (426 backend + 67 frontend tests green, all hooks pass), but it's a sign these wave-N surfaces are starting to contend for the same files.

On the chart: I ran the dataviz palette validator rather than eyeballing it — the 7-category stack sits in the CVD 8–12 floor band, which is only legal with secondary encoding, so the timeline ships a legend, 2px segment gaps, and per-segment hover labels. Reasonably confident it reads correctly; I'd still like to see it against real data with more than a couple of days on the x-axis.

WARD-OUTCOME: done - get_eco_world MCP tool + /preview/world.json + SPA /world route landed on main (ea5e444), reusing the crafting-atlas CSV plumbing, no restart. Honest retro: this one went smoothly because it was, frankly, the fourth or fifth time this shape of surface has been built in the repo. The crafting atlas set the template so completely that world.py is mostly a re-lensing of the same stream-parse → column-corrector → citizen-join → cache spine, pointed at nine world-mutation exporters instead of four production ones. That inheritance is the whole reason "20 exporters, no restart" is real. What I'm least sure of: the exact column shapes of the world action CSVs. I have no live admin key here, so the object-column candidate list and the construct/deconstruct handling are modeled defensively (header-keyed picks, positions dropped from name slots) rather than confirmed against a real capture. The aggregation is well-tested against synthetic CSVs, but the day it meets the live server, a column name I guessed wrong would degrade a leaderboard silently — same caveat the sibling #63 social surface flagged. Worth a quick confirm-against-live-capture follow-up for both. What fought back: nothing in the code, only the merge. issue-63 (social) landed on main mid-flight and touched every shared seam — App routes, Home cards, http_app preview routes, both FEATURES docs — so I hand-resolved five conflicts to keep both surfaces. Clean in the end (426 backend + 67 frontend tests green, all hooks pass), but it's a sign these wave-N surfaces are starting to contend for the same files. On the chart: I ran the dataviz palette validator rather than eyeballing it — the 7-category stack sits in the CVD 8–12 floor band, which is only legal with secondary encoding, so the timeline ships a legend, 2px segment gaps, and per-segment hover labels. Reasonably confident it reads correctly; I'd still like to see it against real data with more than a couple of days on the x-axis.
Sign in to join this conversation.
No description provided.