Denominate build effort in pawn-days #107

Merged
liamjd merged 1 commit from 88-build-time-unit into main 2026-09-17 08:54:42 +01:00
Owner

Closes #88.

BuildingType.build_time was an int with no unit, and its authored values predate the clock — under any tick reading, 10 was one second.

The decisions

The unit is pawn-days — one pawn working for one day. #66 settled this without naming it, by making Task.work_remaining count work-ticks: elapsed time is an output of how many pawns are assigned, not an input. A 10 pawn-day mine is 10 days with one pawn and 3.3 with three.

Authored in days, stored in ticks. build_days: float on BuildingType; build_work_ticks() is the single conversion site, wrapping GameCalendar.days_to_ticks() so that #70 and the tooltip do not each write the arithmetic. Most of this was already in place — #87 landed days_to_ticks() and its tests, documented "see #88" — so this PR is mostly the application of a decision already made.

The 10 / 5 / 3 ratios are preserved, per the balance table in #88's comment. colony_rocket.tres now states build_days = 0.0 explicitly: the Colony Centre lands already built, and an inherited default could not say whether the zero was deliberate.

The tooltip says "Build time: 10 pawn-days", not "10 days". The familiar wording reads as elapsed time, and every crewed build would beat it — a promise the game then breaks. Buildings with build_days == 0.0 show no build-time line at all rather than "Build time: 0".

Scope note: one AC deferred

#88's last AC asks that "a BuildingType authored at N days yields the expected work_remaining on the task it produces". ConstructionTask does not exist yet — entities/tasks/ holds only task.gd and task_manager.gd, and the task type is #70. The conversion is tested directly instead, and the deferral is recorded in the test file's docstring. #70 has been commented so it picks up the assertion.

Also updated #70's stale AC by comment: it says work_remaining starts at type.build_time ticks, which was wrong on the field name and on the unit twice over.

Verification

  • New test/unit/test_building_type.gd — 12 tests: the conversion, the accessor agreeing with GameCalendar rather than reimplementing it, the authored catalogue's values and their work-tick equivalents, the rocket's zero, tooltip pluralisation and decimal formatting, and two tests that build the real card and read back the rendered tooltip text.

  • Full suite headless — 463 tests, 462 passing, 1 pre-existing pending (#85 placeholder). No orphans.

  • Tooltip appearance verified manually, headed, by hovering the placement palette. get_parsed_text() only proves the string, and a tooltip needs a hover to appear at all, so this could not be automated - gl_compatibility draws nothing headless. "pawn-days" is a longer line than the bare number it replaced, so the panel was checked by eye rather than assumed.

Incidental: a stale build_time reference in test_game_clock.gd's header comment now reads "a duration of 600 ticks".

🤖 Generated with Claude Code

Closes #88. `BuildingType.build_time` was an `int` with no unit, and its authored values predate the clock — under any tick reading, 10 was one second. ## The decisions **The unit is pawn-days** — one pawn working for one day. #66 settled this without naming it, by making `Task.work_remaining` count work-ticks: elapsed time is an *output* of how many pawns are assigned, not an input. A 10 pawn-day mine is 10 days with one pawn and 3.3 with three. **Authored in days, stored in ticks.** `build_days: float` on `BuildingType`; `build_work_ticks()` is the single conversion site, wrapping `GameCalendar.days_to_ticks()` so that #70 and the tooltip do not each write the arithmetic. Most of this was already in place — #87 landed `days_to_ticks()` and its tests, documented "see #88" — so this PR is mostly the application of a decision already made. **The 10 / 5 / 3 ratios are preserved**, per the balance table in #88's comment. `colony_rocket.tres` now states `build_days = 0.0` **explicitly**: the Colony Centre lands already built, and an inherited default could not say whether the zero was deliberate. **The tooltip says "Build time: 10 pawn-days"**, not "10 days". The familiar wording reads as elapsed time, and every crewed build would beat it — a promise the game then breaks. Buildings with `build_days == 0.0` show no build-time line at all rather than "Build time: 0". ## Scope note: one AC deferred #88's last AC asks that "a BuildingType authored at N days yields the expected `work_remaining` on the task it produces". **`ConstructionTask` does not exist yet** — `entities/tasks/` holds only `task.gd` and `task_manager.gd`, and the task type is #70. The conversion is tested directly instead, and the deferral is recorded in the test file's docstring. #70 has been commented so it picks up the assertion. Also updated #70's stale AC by comment: it says `work_remaining` starts at `type.build_time` **ticks**, which was wrong on the field name and on the unit twice over. ## Verification - New `test/unit/test_building_type.gd` — 12 tests: the conversion, the accessor agreeing with `GameCalendar` rather than reimplementing it, the authored catalogue's values and their work-tick equivalents, the rocket's zero, tooltip pluralisation and decimal formatting, and two tests that build the real card and read back the rendered tooltip text. - Full suite headless — 463 tests, 462 passing, 1 pre-existing pending (#85 placeholder). No orphans. - **Tooltip appearance verified manually, headed, by hovering the placement palette.** `get_parsed_text()` only proves the string, and a tooltip needs a hover to appear at all, so this could not be automated - `gl_compatibility` draws nothing headless. "pawn-days" is a longer line than the bare number it replaced, so the panel was checked by eye rather than assumed. Incidental: a stale `build_time` reference in `test_game_clock.gd`'s header comment now reads "a duration of 600 ticks". 🤖 Generated with [Claude Code](https://claude.com/claude-code)
BuildingType.build_time was an int with no unit, and its authored values
predate the clock: under any tick reading, 10 was one second.

Renamed to build_days: float, documented as pawn-days - one pawn working
one day. #66 settled that unit without naming it, by making
Task.work_remaining count work-ticks, so elapsed time is an output of how
many pawns are assigned rather than an input.

build_work_ticks() is the single conversion site, wrapping
GameCalendar.days_to_ticks() so #70 and the tooltip do not each write the
arithmetic. The 10 / 5 / 3 ratios are preserved; colony_rocket now states
0.0 explicitly, because the Colony Centre lands already built and an
inherited default could not say whether that was deliberate.

The tooltip says "Build time: 10 pawn-days" rather than "10 days": a crew
of three finishes that mine in well under ten days, and the familiar
wording would read as a promise the game then breaks.

Closes #88

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
liamjd merged commit 94b4ad002c into main 2026-09-17 08:54:42 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
liamjd/UntitledColonyBuilder!107
No description provided.