render_tile: cache per-tile label signature and skip writes on unchanged tiles (#333) - #340
Conversation
…ged tiles (#333) render_world re-runs render_tile for every tile on every tick, and the three label writes (icon_label.text, amount_label.text, progress_label.text) plus the amount visibility flag were unconditional. Godot's Label.text setter marks the control dirty even when the string is identical, so an idle colony pushed the same ~320+ label writes per tick for no visual change. The stylebox override in the same function was already change-gated via a view["style"] cache; this applies the same pattern to the label writes. The render signature is [tile_icon(...), tile_amount_text(...), hover match]. All three inputs that affect the labels (kind/resource/pending-build/frame flow through tile_icon, amount flows through tile_amount_text, hover flows through hover_tile_index) are part of the signature, so hover amount visibility, build-preview icon, and foundation blink still update promptly. Tests/test_tile_render.gd: new _test_render_tile_label_sig_skip exercises the skip path, the cache miss on amount/icon/hover changes, and value-based signature identity (same value → same signature, not "did we change since last render"). Fixes #333 Signed-off-by: Saffron <263493777+itsmiso-ai@users.noreply.github.com>
There was a problem hiding this comment.
AI Automated Review
Full PR review.
Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — escalated (fast_low_confidence)
Recommendation: Approve
This PR implements a per-tile label-signature cache in render_tile() to eliminate redundant label writes on idle colonies. The change is well-scoped, thoroughly tested, and CI-green across all platforms.
Changes
scripts/main.gd (render_tile) — Computes icon/amount text and visibility into a signature array, caches it per tile in tile_views, and returns early when the signature is unchanged. The existing stylebox gating (already change-gated) is preserved; the three label writes plus visibility flag are now gated behind the new signature check. This eliminates ~320+ dirty-control redraws per tick on an idle colony (issue PR 333 root cause).
tests/test_tile_render.gd — Adds _test_render_tile_label_sig_skip() covering:
- First render populates cache and writes labels
- Unchanged tile skip path (sentinels survive)
- Amount mutation causes cache miss and re-writes
- Return-to-same-state signature stability
- Hover visibility change triggers writes
- Hover-stable tile re-skip
Standards Compliance
- Cache-as-
tile_viewsdict key: The pattern mirrors the existingstylecache key on the same dict (view.get("style") != style), established by prior render-cost audits (PR 179, PR 292, PR 299). - Issue-driven scope: Issue PR 333 named
scripts/main.gdas the sole expected file; the diff touches exactly that file for the implementation. - No regressions from regressions listed in AGENTS.md: No sidebar UI, no persistent layout, no high-attention UX — purely a tick-cost optimization with no user-visible behavior change.
- Test trap compliance:
assert_eqis called with 3 args throughout (actual, expected, name); sentinel-overwrite pattern verifies skip path without depending on return-value inspection.
Linked Issue Fit
Issue PR 333 acceptance criteria:
- ✓ "A tile whose state is unchanged skips label writes (per-tile cached render signature)" — implemented via
label_sigcache compared before writes - ✓ "No visual regression: hover amount visibility, build-preview icon, and foundation blink still update promptly" —
hover_tile_indexis part of the signature; build/foundation blink are unaffected (different render paths) - ✓ "Coverage via a main-level test or extension of
tests/test_tile_render.gd" — new_test_render_tile_label_sig_skip()extends the existing suite with skip and mutation paths
Tool Harness Findings
Tool reads verified render_tile() in context — the function is preceded by render_world() (which iterates tile_views and calls render_tile per index) and the stylebox gating comment explains the rationale for change-gating. The full implementation read from the tool matches the diff exactly. No discrepancies.
Unknowns / Needs Verification
None. The diff, tool read, and CI results are internally consistent and sufficient.
Approve per-tile label signature cache in render_tile to skip redundant label writes, with tests verifying skip and mutation paths.
Fixes #333
Opened by foreman on review GO (workload wl-misospace-windowstead-333).