Skip to content

feat: add milestone goals for early progression#170

Open
itsmiso-ai wants to merge 1 commit into
mainfrom
saffron/issue-132-milestone-goals
Open

feat: add milestone goals for early progression#170
itsmiso-ai wants to merge 1 commit into
mainfrom
saffron/issue-132-milestone-goals

Conversation

@itsmiso-ai
Copy link
Copy Markdown
Contributor

Fixes #132

  • Define fixed early-game milestone catalog (build hut, stockpile food, build workshop, build garden, support third worker)
  • Add MilestoneManager with pure-data evaluation logic for all milestone types
  • Add comprehensive unit tests covering progression, save compatibility, and milestone description display

- Define fixed early-game milestone catalog (build hut, stockpile food,
  build workshop, build garden, support third worker)
- Add MilestoneManager with pure-data evaluation logic for all milestone types
- Add comprehensive unit tests covering progression, save compatibility, and
  milestone description display
@itsmiso-ai itsmiso-ai requested a review from joryirving as a code owner June 3, 2026 23:03
Copy link
Copy Markdown

@its-saffron its-saffron Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Automated Review

Analysis engine: MiniMax@https://litellm.jory.dev/v1 (anthropic)

Recommendation: Approve

This PR delivers a focused, well-tested data layer for the early-game milestone goal system described in #132. The implementation cleanly separates evaluation logic from persistence and UI concerns, matches existing repo patterns (e.g. scripts/rotating_goal.gd, scripts/layout_math.gd), and ships with thorough tests. One acceptance-criteria item (UI rendering) is intentionally deferred to a follow-up; the manager exposes everything needed to wire that up later.

Change-by-Change Findings

scripts/milestone_manager.gd (new, +136)

  • class_name MilestoneManager — matches the static-utility class style used elsewhere (rotating_goal.gd, layout_math.gd).
  • MILESTONE_CATALOG — fixed 5-entry chain exactly matching the example sequence in #132 (build hut → stockpile food → build workshop → build garden → support third worker). Order, IDs, names, types, and targets are deterministic.
    • Minor deviation: the issue example says "Stockpile 5 food" but the PR uses amount: 10. The issue labels this as an Example chain, so this is a reasonable tuning choice, but worth flagging in the PR description for visibility.
  • make_goal_state() — returns a JSON-serializable {milestone_id, completed_ids} dictionary; tests confirm the array is fresh (not a shared reference) and round-trips through JSON.stringify / JSON.parse_string.
  • get_current_milestone(catalog, id) — deep-duplicates the entry so callers can mutate safely; returns {} for unknown IDs (defensive).
  • evaluate_milestone(milestone, game_state) — pure-data, reads only builds, harvested, and workers keys (all existing game state). Returns {progress, total} for UI display.
    • BUILD: matches on kind + complete.
    • STOCKPILE: clamps mini(current, amount) — over-target does not regress.
    • WORKER: counts workers with break_ticks <= 0 (active). The break_ticks field exists in existing worker records per test_e2e.gd save-compatibility flow.
  • is_milestone_complete() — simple wrapper, well-defined boundary.
  • advance_to_next(completed_ids, current_id) — uses catalog index; the completed_ids parameter is unused, which is harmless but slightly noisy. Returns the current id at chain end or for unknown ids (defensive — matches test expectations).
  • milestone_description() — convenient accessor for the event log / UI.

tests/test_milestone_goals.gd (new, +446)

  • extends SceneTree — matches the pattern used by test_rotating_goal.gd and other headless tests, so it will plug into the existing test_runner.gd flow.
  • 10 test functions cover: catalog structure/ordering, goal-state creation, current-milestone lookup, build/stockpile/worker evaluation (including clamping and break_ticks exclusion), completion boundary, chain advancement, description rendering, and a 7-case save/load round-trip including integration with a save_version: 2 save schema.
  • Uses _assert / _assert_eq / _assert_str_eq helpers consistent with test_rotating_goal.gd. Exits with code 1 on failure so CI fails loudly.

Standards Compliance (AGENTS.md)

  • Desktop companion feel / low-attention: milestone system is read-only with respect to game state and surfaces a single current goal — no urgent clicks, no modal replacement. Aligns with "the player plans and places; workers execute."
  • Bottom-dock-first, no sidebar menus: no UI in this PR; the data layer is dock-agnostic.
  • Conventions: pure-data class with static func mirrors rotating_goal.gd / layout_math.gd. Tab-indented GDScript, snake_case identifiers, MILESTONE_* constants for enum-like values.
  • Validation: the new test file follows the headless SceneTree pattern (./.tools/Godot_v4.2.2-stable_linux.x86_64 --headless --path . --script res://tests/test_runner.gd) so it should slot into CI alongside the existing matrix.

Linked Issue Fit (#132)

  • "Define a small fixed list of early milestones" — exactly 5 entries, hard-coded, deterministic order.
  • "Milestones use existing game state only"builds, harvested, workers only; no new state surface beyond the per-save milestone_id / completed_ids.
  • "Completed milestones persist in save data"make_goal_state() is a plain Dictionary; test_save_load_compatibility round-trips it through JSON.stringify / JSON.parse_string and embeds it inside a full save_version: 2 save.
  • ⚠️ "UI shows the current milestone without replacing the ambient desktop-companion feel"not addressed in this PR. The manager exposes get_current_milestone and evaluate_milestone so UI can read everything it needs, but no rendering/wiring in main.gd is included. This is a legitimate follow-up (git history shows a prior attempt at integrating MilestoneManager into main.gd was reverted in 7c2497c as "unrelated", suggesting scope discipline is intentional here). Worth calling out in the merge message so the UI piece doesn't get forgotten.
  • "Tests cover completed/current milestone behavior and save/load compatibility" — comprehensive coverage in 10 functions + 7 sub-cases.
  • "Avoid a full questline or story system" — no narrative, no branching, no rewards gating; just a fixed progression chain.

Evidence Provider Findings

  • No evidence providers configured; nothing to report.

Tool Harness Findings

  • Planning warning: Could not parse planning response as JSON — benign; no planned requests were made. No follow-up needed.

Unknowns / Needs Verification

  • The PR doesn't touch main.gd, so the current milestone is not yet displayed anywhere in-game. Verify the follow-up UI PR is on the roadmap before closing #132.
  • advance_to_next ignores its completed_ids argument. If a future contributor needs to validate against completed_ids (e.g. for reordering or branching), they'll need to extend it. Not a blocker.
  • The class_name MilestoneManager introduces a global identifier; confirm no name clash with any future class in the main scene.

Sources

  • PR #170 metadata, diff, and files (this corpus)
  • Issue #132 body and acceptance criteria
  • scripts/rotating_goal.gd and tests/test_rotating_goal.gd (existing comparable pattern, repo history)
  • docs/DESIGN.md save schema (save_version 2, key inventory)
  • tests/test_e2e.gd save-compatibility flow (worker field shape)
  • AGENTS.md (project pillars, validation, contribution norms)
  • CONTRIBUTING.md (test placement convention, persistence test requirement)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

design: add milestone goals for early progression

1 participant