Decide and apply the unit of BuildingType.build_time #88

Closed
opened 2026-09-12 08:21:05 +01:00 by liamjd · 1 comment
Owner

BuildingType.build_time is an int with no unit, and the authored values (ore_mine 10, warehouse 5, sensor_tower 3) predate #65's clock. Under any tick reading, 10 is one second.

Two things need deciding together, because #70 (ConstructionTask) and #75 (pawn work loop) will bake whichever answer they find into the task they create.

The unit is labour, not elapsed time

#66 already settled this without naming it: Task.work(ctx: Dictionary, ticks: int) decrements work_remaining: float, so work is denominated in pawn-ticks — one pawn working one tick. Elapsed days are then an output of how many pawns are assigned, not an input.

So "a Mine takes 10 in-game days" is ambiguous and needs pinning:

  • 10 pawn-days (12,000 work-ticks at 1200 ticks/day) — 10 days with one pawn, 3.3 days with three.
  • 10 elapsed days with a realistic crew — if that crew is three, 4,000 work-ticks.

Recommend the first. Labour is the honest unit for a Settlers-style game, and it turns "how fast do I want this" into a staffing decision rather than a constant. It is a 3x difference in pacing, so it is a decision rather than a detail.

Author in days, store in ticks

Raw work-ticks in the .tres (build_time = 12000) are unpleasant to author and impossible to eyeball across twenty facilities when balancing.

Prefer build_days: float on BuildingType, converted once at task creation via GameClock.TICKS_PER_DAY. Authoring stays human, the simulation stays integer.

AC:

  • BuildingType carries build effort in a named, documented unit; the docstring says whether it is pawn-ticks or elapsed
  • ore_mine.tres, warehouse.tres and sensor_tower.tres restated in that unit, preserving their existing 10 / 5 / 3 relative ratios unless balance says otherwise
  • Conversion to work-ticks happens in one place, not at each call site
  • building_type_card.gd:27 prints a unit rather than a bare number ("Build time: 10 days", not "Build time: 10")
  • Unit test: a BuildingType authored at N days yields the expected work_remaining on the task it produces

Depends on #87 for TICKS_PER_DAY. Blocks nothing outright, but #70 should not land before it or the conversion gets written twice.

`BuildingType.build_time` is an int with no unit, and the authored values (`ore_mine` 10, `warehouse` 5, `sensor_tower` 3) predate #65's clock. Under any tick reading, 10 is one second. Two things need deciding together, because #70 (ConstructionTask) and #75 (pawn work loop) will bake whichever answer they find into the task they create. ## The unit is labour, not elapsed time #66 already settled this without naming it: `Task.work(ctx: Dictionary, ticks: int)` decrements `work_remaining: float`, so work is denominated in **pawn-ticks** — one pawn working one tick. Elapsed days are then an *output* of how many pawns are assigned, not an input. So "a Mine takes 10 in-game days" is ambiguous and needs pinning: - **10 pawn-days** (12,000 work-ticks at 1200 ticks/day) — 10 days with one pawn, 3.3 days with three. - **10 elapsed days with a realistic crew** — if that crew is three, 4,000 work-ticks. Recommend the first. Labour is the honest unit for a Settlers-style game, and it turns "how fast do I want this" into a staffing decision rather than a constant. It is a 3x difference in pacing, so it is a decision rather than a detail. ## Author in days, store in ticks Raw work-ticks in the `.tres` (`build_time = 12000`) are unpleasant to author and impossible to eyeball across twenty facilities when balancing. Prefer `build_days: float` on `BuildingType`, converted once at task creation via `GameClock.TICKS_PER_DAY`. Authoring stays human, the simulation stays integer. AC: - [ ] `BuildingType` carries build effort in a named, documented unit; the docstring says whether it is pawn-ticks or elapsed - [ ] `ore_mine.tres`, `warehouse.tres` and `sensor_tower.tres` restated in that unit, preserving their existing 10 / 5 / 3 relative ratios unless balance says otherwise - [ ] Conversion to work-ticks happens in one place, not at each call site - [ ] `building_type_card.gd:27` prints a unit rather than a bare number ("Build time: 10 days", not "Build time: 10") - [ ] Unit test: a BuildingType authored at N days yields the expected `work_remaining` on the task it produces Depends on #87 for `TICKS_PER_DAY`. Blocks nothing outright, but #70 should not land before it or the conversion gets written twice.
Author
Owner

#87 has now fixed the calendar constants, so the two loose ends here can be tied off.

TICKS_PER_DAY moved off GameClock to GameCalendar (common/game_calendar.gd), so the conversion described above reads GameCalendar.TICKS_PER_DAY. GameClock stays a pure tick source and never learns the calendar exists.

The unit recommendation here is right, and days is the correct magnitude. Worth stating why, since "hours" looks tempting until you remember the unit is labour: 10 pawn-hours would be 500 work-ticks, which at a crew of three is 17 real seconds to build a mine. Pawn-days it is.

What the 10-day orbit does to the authored values

A day is 1,200 ticks, a month (one orbit) is 10 days, a 60-day contract is 72,000 ticks = 2 hours at 1x.

Facility build_days work-ticks 1 pawn 3 pawns 3 pawns @1x
ore_mine 10 12,000 10 d (one full orbit) 3.3 d 6.7 min
warehouse 5 6,000 5 d 1.7 d 3.3 min
sensor_tower 3 3,600 3 d 1.0 d 2.0 min

Those read plausibly, which is the argument for keeping the existing 10 / 5 / 3 ratios rather than rebalancing blind.

A labour budget for the whole contract

The ratios also survive the sanity check the other way round. At ~10 pawns over 60 days the run contains roughly 600 pawn-days of labour in total. A colony of 15-25 buildings at 3-10 pawn-days each spends 100-200 of that on construction - call it a quarter of the run's labour, leaving the rest for hauling, processing and threat response. That feels like the right split for a Settlers-style game where haulage is the real cost.

If a later playtest says construction dominates, this table is the thing to move, and moving it does not touch the calendar.

One caveat on the unit

A pawn-day is nominal, not effective. A pawn assigned to a build spends part of its time walking to the site and hauling materials, so a 10 pawn-day mine with three pawns will take meaningfully longer than 3.3 days once #73 (HaulTask) and #75 (work loop) are real. Not a reason to change the unit - work_remaining should mean work actually performed - but it means the elapsed-time column above is a floor, and balance numbers taken before those two issues land will read optimistic.

Values in the .tres files are placeholders and free to restate; confirmed in conversation.

#87 has now fixed the calendar constants, so the two loose ends here can be tied off. **`TICKS_PER_DAY` moved off `GameClock`** to `GameCalendar` (`common/game_calendar.gd`), so the conversion described above reads `GameCalendar.TICKS_PER_DAY`. `GameClock` stays a pure tick source and never learns the calendar exists. **The unit recommendation here is right, and days is the correct magnitude.** Worth stating why, since "hours" looks tempting until you remember the unit is labour: 10 pawn-*hours* would be 500 work-ticks, which at a crew of three is 17 real seconds to build a mine. Pawn-days it is. ## What the 10-day orbit does to the authored values A day is 1,200 ticks, a month (one orbit) is 10 days, a 60-day contract is 72,000 ticks = 2 hours at 1x. | Facility | build_days | work-ticks | 1 pawn | 3 pawns | 3 pawns @1x | |---|---|---|---|---|---| | ore_mine | 10 | 12,000 | 10 d (one full orbit) | 3.3 d | 6.7 min | | warehouse | 5 | 6,000 | 5 d | 1.7 d | 3.3 min | | sensor_tower | 3 | 3,600 | 3 d | 1.0 d | 2.0 min | Those read plausibly, which is the argument for keeping the existing 10 / 5 / 3 ratios rather than rebalancing blind. ## A labour budget for the whole contract The ratios also survive the sanity check the other way round. At ~10 pawns over 60 days the run contains roughly **600 pawn-days of labour in total**. A colony of 15-25 buildings at 3-10 pawn-days each spends 100-200 of that on construction - call it a quarter of the run's labour, leaving the rest for hauling, processing and threat response. That feels like the right split for a Settlers-style game where haulage is the real cost. If a later playtest says construction dominates, this table is the thing to move, and moving it does not touch the calendar. ## One caveat on the unit A pawn-day is nominal, not effective. A pawn assigned to a build spends part of its time walking to the site and hauling materials, so a 10 pawn-day mine with three pawns will take meaningfully longer than 3.3 days once #73 (HaulTask) and #75 (work loop) are real. Not a reason to change the unit - `work_remaining` should mean work actually performed - but it means the elapsed-time column above is a floor, and balance numbers taken before those two issues land will read optimistic. Values in the `.tres` files are placeholders and free to restate; confirmed in conversation.
Sign in to join this conversation.
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#88
No description provided.