fix: collapse cmdr_dmg dict to int in _encode_global before division
Forge sends cmdr_dmg as a dict keyed by opponent seat (e.g. {"0": 14,
"2": 7}). _encode_global read it raw and crashed on `dict / 21.0`.
Fix: resolve cmdr_dmg to a scalar at the read site — sum dict values if
it's a dict, cast to int if it's already a number, default to 0.
This is defensive for all call paths (live Forge IPC, JSONL training,
_build_encoder_snapshot pre-collapsed int) so no upstream change needed.
This commit is contained in:
1 parent
4ca21e5e29
commit
018852c92d
1 file changed
+24
-1
@@ -167,6 +167,24 @@ class CardEmbeddingIndex:
|
||||
return self._loaded
|
||||
|
||||
|
||||
def _resolve_cmdr_dmg(raw) -> int:
|
||||
"""Collapse cmdr_dmg to a scalar integer regardless of source format.
|
||||
|
||||
Forge sends cmdr_dmg as a dict keyed by opponent seat string, e.g.
|
||||
{"0": 14, "2": 7}. _build_encoder_snapshot already sums this before
|
||||
passing to predict(), but the live Forge IPC path (and legacy JSONL)
|
||||
may send the raw dict. Summing all values is correct for Commander:
|
||||
the total commander damage received from all opponents is what matters
|
||||
for the life-loss threshold (21).
|
||||
"""
|
||||
if isinstance(raw, dict):
|
||||
return sum(int(v) for v in raw.values())
|
||||
try:
|
||||
return int(raw)
|
||||
except (TypeError, ValueError):
|
||||
return 0
|
||||
|
||||
|
||||
class StateEncoder:
|
||||
"""
|
||||
Encodes a decision snapshot JSON dict into a fixed-size numpy vector.
|
||||
@@ -241,6 +259,10 @@ class StateEncoder:
|
||||
Index 7 priority for total_power:
|
||||
1. p['total_power'] — real Forge value from Step 4 / _build_encoder_snapshot()
|
||||
2. p['creatures'] * 3 — legacy heuristic for old JSONL snapshots
|
||||
|
||||
cmdr_dmg is resolved via _resolve_cmdr_dmg() which handles both the
|
||||
live Forge format (dict keyed by opponent seat) and the pre-collapsed
|
||||
int from _build_encoder_snapshot / JSONL training snapshots.
|
||||
"""
|
||||
features = []
|
||||
|
||||
@@ -250,7 +272,8 @@ class StateEncoder:
|
||||
features.append(life / 40.0)
|
||||
|
||||
# idx 1: commander damage taken
|
||||
cmdr_dmg = p.get("cmdr_dmg", 0)
|
||||
# _resolve_cmdr_dmg handles dict (live Forge IPC) and int (JSONL/pre-collapsed)
|
||||
cmdr_dmg = _resolve_cmdr_dmg(p.get("cmdr_dmg", 0))
|
||||
features.append(cmdr_dmg / 21.0)
|
||||
|
||||
# idx 2: mana available
|
||||
|
||||
Reference in new issue
Block a user