Skip to content

Forward setUsedToPay highlights to network clients#10272

Merged
tool4ever merged 3 commits intoCard-Forge:masterfrom
MostCromulent:fix-blocker-selection-overlay
Apr 4, 2026
Merged

Forward setUsedToPay highlights to network clients#10272
tool4ever merged 3 commits intoCard-Forge:masterfrom
MostCromulent:fix-blocker-selection-overlay

Conversation

@MostCromulent
Copy link
Copy Markdown
Contributor

@MostCromulent MostCromulent commented Apr 4, 2026

Remote network clients currently don't get the blocker assignment highlight during declare blockers phase.

InputBlock.setCurrentAttacker() calls setUsedToPay() to highlight the selected attacker, but this only reaches the host's local GUI. InputBlock runs on the host as part of the game engine, so the host's PlayerControllerHuman.getGui() returns its local CMatchUI. For the remote client player, getGui() returns NetGuiGame — but setUsedToPay was missing from the network protocol, so the call was silently absorbed without forwarding to the client.

Screenshot 2026-04-04 133227

Solution

  • Add setUsedToPay to ProtocolMethod and override in NetGuiGame to forward to clients.

  • Simplify InputBlock.setCurrentAttacker to track previous/new selection instead of looping all attackers — The old setCurrentAttacker looped over all attackers, calling setUsedToPay once per attacker to clear all highlights then set the new one. Since setUsedToPay is now a protocol message, that loop would send N messages when only 2 matter (unhighlight old, highlight new). Replaced the loop with explicit previous/new tracking to avoid the redundant sends. This is safe because InputBlock only ever has one selected attacker at a time, stored in the currentAttacker field.

  • Side benefit: also enables other highlights in network play that were previously host-only (attacker/defender selection, target highlighting, London mulligan selection)

Alternatives considered

The core challenge is that setUsedToPay is driven by InputBlock on the host, which has access to the game engine - it knows which attackers exist, which can be legally blocked, and which is currently selected. The remote client has none of this context.

So there are fundamentally two approaches: transmit across the network boundary, or attempt to recreate it client-side with a heuristic that can't access engine state. The latter approach requires significantly more code and can never be fully accurate (e.g. it can't check blocking legality). Transmitting is simpler and correct by construction.

The following alternative options were considered:

  • Client-side heuristic + selectCard sync (~65 lines, 3 files) — CMatchUI auto-selects an attacker visually and sends selectCard to sync with host. No protocol change needed, but the heuristic can't check blocking legality (e.g. flying) and may highlight an unblockable attacker.
  • Client-side only, no sync (~65 lines, 2 files) — CMatchUI auto-selects visually with no host communication. Visual hint can desync from host's actual blocker assignment so when client declares a blocker it is assigned against an attacker they did not intend.
  • New highlightAttacker protocol method (~15 lines, 7 files) — Purpose-built method across IGuiGame, ProtocolMethod, NetGuiGame, and implementations. Adds a new interface method for a narrow use case.
  • Piggyback on showCombat parameter (~20 lines, 7 files) — Pass the selected attacker as a parameter to showCombat(). Changes an existing interface signature across all implementations and callers.
  • Forward setUsedToPay via protocol (chosen, 10 lines, 3 files) — Reuses existing IGuiGame method. Host remains authoritative with no engine changes. Smallest diff by far.

Network cost

Network cost is trivial — each message is a CardView reference + boolean. setCurrentAttacker sends at most 2 messages (unhighlight previous, highlight new) rather than iterating all attackers. On the receiving end, AbstractGuiGame.setUsedToPay short-circuits redundant calls. setUsedToPay is transient UI state, not persistent game model state. The protocol message is fire-and-forget, same as setPanelSelection or setSelectables.


🤖 Generated with Claude Code

MostCromulent and others added 3 commits April 4, 2026 13:40
Network clients never received setUsedToPay highlights because the
method was missing from the protocol. This meant blocker assignment,
attacker selection, target highlighting, and London mulligan selection
were all invisible to remote players. Add setUsedToPay to
ProtocolMethod and override in NetGuiGame to forward to clients.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tool4ever
Copy link
Copy Markdown
Contributor

good idea: I have taken this one step further and also included player highlighting by merging both - this allowed cleaner code too :)

@tool4ever tool4ever merged commit 2bb888e into Card-Forge:master Apr 4, 2026
2 checks passed
@MostCromulent MostCromulent deleted the fix-blocker-selection-overlay branch April 8, 2026 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants