Skip to content

Flash the nuke warning circle red iff the strike marks you a traitor - #5435

Open
evanpelle wants to merge 1 commit into
mainfrom
flash-traitor-target-indicator
Open

evanpelle wants to merge 1 commit into
mainfrom
flash-traitor-target-indicator

Conversation

@evanpelle

Copy link
Copy Markdown
Collaborator

Summary

  • The nuke blast-radius preview showed the same solid-red warning whether the blast would betray a real ally or just clip a traitor, so you couldn't tell if nuking a traitor was safe.
  • Betraying a traitor (or disconnected) ally breaks the alliance but does not mark you a traitor (GameImpl.breakAlliance), so the preview now excludes traitor allies from the alliance-break check — nuking a traitor shows the normal white circle.
  • The warning itself is now a red↔white flash (~2 Hz) instead of solid red, so "this strike will mark you a traitor" is unmistakable and visually distinct from anything else on the map.

Test plan

  • npx vitest tests/client/controllers/BuildPreviewController.test.ts --run (11 passed)
  • npx tsc --noEmit, npm run lint, Prettier check — all clean
  • Not verified visually in a live match (requires staging a traitor ally); worth a quick in-game look

🤖 Generated with Claude Code

…itor

Betraying a traitor (or disconnected) ally breaks the alliance but does
not mark you a traitor (GameImpl.breakAlliance), yet the nuke preview
showed the same solid-red warning either way — you couldn't tell whether
clipping someone's pixels was a real betrayal or a safe strike.

The ghost preview now excludes traitor allies from the alliance-break
check, and the range circle flashes red<->white (~2 Hz) iff the blast
would hit a non-traitor ally and mark you a traitor. Nuking a traitor
safely shows the normal white circle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 8cec18f5-242a-425d-92ec-660da16f8ca4

📥 Commits

Reviewing files that changed from the base of the PR and between 3e3b962 and 0bcedbe.

📒 Files selected for processing (3)
  • src/client/controllers/BuildPreviewController.ts
  • src/client/render/gl/passes/RangeCirclePass.ts
  • src/client/render/types/Renderer.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


Walkthrough

The build preview now warns only when a nuke would break an alliance and mark the player as a traitor. Disconnected and traitor allies do not trigger this warning. Warning circles now flash between red and white.

Changes

Alliance warning preview

Layer / File(s) Summary
Traitor-marking warning state
src/client/controllers/BuildPreviewController.ts, src/client/render/types/Renderer.ts
targetingAlly is renamed to allyWarning. The warning includes only connected, non-traitor allies and flows into GhostPreviewData.rangeWarning.
Flashing warning circle
src/client/render/gl/passes/RangeCirclePass.ts
The warning color uses performance.now() to animate the circle between red and white.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant BuildPreviewController
  participant GhostPreviewData
  participant RangeCirclePass
  BuildPreviewController->>BuildPreviewController: Filter connected non-traitor allies
  BuildPreviewController->>GhostPreviewData: Set rangeWarning from allyWarning
  GhostPreviewData->>RangeCirclePass: Provide warning state
  RangeCirclePass->>RangeCirclePass: Animate warning color over time
Loading

Suggested reviewers: flopinguin

Merge Risk: ⚪ Minimal · up to 0bced

The preview now distinguishes traitor-marking strikes and animates the warning as intended; no actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely states the main change: the nuke warning circle flashes red only when the strike marks the player as a traitor.
Description check ✅ Passed The description directly explains the traitor-warning behavior, the exclusion of traitor and disconnected allies, the flashing indicator, and the test results.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 3…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A warning flag now tells the truth
Traitor marks guide its proof
Lost allies pass unseen
Red fades softly into white
The preview keeps its light

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

🤖 Claude Code Review

Verdict: ✅ No issues found. Findings: 0 critical, 0 major, 0 minor.

Reviewed the traitor-warning logic fix in BuildPreviewController.ts (excludes traitor/disconnected allies from triggering the nuke warning), the flashing red/white color math in RangeCirclePass.ts, and the JSDoc update in Renderer.ts.

  • Correctness: The !ally.isTraitor() && !ally.isDisconnected() condition mirrors GameImpl.breakAlliance's own guard exactly, and the break is evaluated at nuke launch (not detonation), so the client-side preview can't go stale. The targetingAllyallyWarning rename is applied consistently across all call sites with no stale references. The sinusoidal flash (t = 0.5 + 0.5*sin(performance.now()*0.01257), gb = 0.2 + 0.8*(1-t)) stays within valid [0.2, 1.0] uniform range, correctly sweeps between the original solid red and white, and yields the intended ~2 Hz flicker.
  • CLAUDE.md compliance: No i18n violations (no new user-visible strings). No src/core/ files touched, so determinism rules don't apply. One candidate issue was considered — the new flash constants (0.01257, 0.2, 0.8) are hardcoded in RangeCirclePass.ts rather than sourced from render-settings.json per src/client/render/CLAUDE.md's "single source of truth for tuning constants" rule — but this was rejected on verification: RangeCirclePass has never taken a RenderSettings slice and already hardcoded its base colors before this PR, so this is a pre-existing pattern the PR extends rather than a new violation.

No blocking issues. One non-blocking UX note for the author's awareness (not a defect, since it matches the PR's stated intent): nuking a traitor-marked ally still breaks the alliance and applies the relation penalty, but will now show no warning circle at all — the circle previously doubled as a general "this will break an alliance" signal and now only signals "this will mark you a traitor specifically." Worth a quick sanity check that this narrower scope is the desired UX.

🤖 Generated with Claude Code

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

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

1 participant