Static method was referencing bare gameState which is always null.
Now accepts gameState as parameter, and all 5 callers pass it through.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Was reading gameState.battlefield (doesn't exist) causing AI to
receive empty board state. Now reads gameState.battlefieldCards
and matches by ownerIndex.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add bright silver 3D smoky border around commander card zones
- Wrap all 4 life panels in a single bordered container
- Add drag-and-drop from hand zone to battlefield with ghost preview
- Update card placement to center of battlefield, avoiding overlaid zones
- Fix card dimensions in placement calc (110x150 -> 63x84)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move life/cmd-dmg/poison into 3-box life panels as a top-level
overlay (z-index 50) centered at quadrant intersections
- Remove center emblem
- Match battlefield card size to hand cards (63x84px)
- Overlay zone-row and commander-row on battlefield edges to
eliminate dead space and maximize battlefield area
- Restructure poison badges from per-player absolute positioning
into life-panel counters box
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Scale .hand-thumb from 32x45px to 63x84px so cards fill the
hand zone vertically while maintaining MTG card proportions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Mount lan-client/ as static files at /lan with html=True
- Mount precon-decks/ at /precon-decks/ for direct .dck access
- ai-bridge.js: use same-origin (empty URLs, auto-detect from window.location)
- engine.js: simplify deck fetch to use /api/lab/precons/deck endpoint + /precon-decks/ static fallback
- Eliminates cross-origin issues by serving everything from localhost:8080
Access the LAN battlefield at http://localhost:8080/lan/
Three fixes that prevented precon decks from loading into actual gameplay:
1. ui.js: window.startGame() now calls startGameWithDecks() when
setupDeckChoices has entries (the 3-tab selector stores choices there).
Previously it called initGame() which looked for old deck-sel-{i}
dropdowns that no longer exist.
2. engine.js: loadPreconForPlayer() now fetches .dck file content from
the backend (/api/lab/precons/deck?fileName=...) when precon.decklist
is empty. Falls back to fetching precon-decks/{file} directly.
PRECON_DATA entries only have metadata (name, commander, set) — the
actual card list lives in the .dck files.
3. engine.js: parseDeckList() now handles .dck bracket-style section
headers like [Commander], [Main], [metadata]. Previously only matched
bare text like 'COMMANDER:' without brackets. Also skips [metadata]
lines (e.g. 'Name=Elven Empire').
4. routes/precon.py: Added GET /api/lab/precons/deck?fileName=... endpoint
to serve raw .dck file content for the LAN client.
- Add max-height: 92vh and overflow-y: auto to .setup-card
- Widen .setup-card to 860px to fit 2-column deck grid
- Change .deck-assignment-grid from vertical stack to 2-column grid
so 4 player panels render in 2 rows instead of 4
- Tighten .deck-tab-content (170px) and .deck-precon-list (140px)
- Make top gradient bar sticky on scroll
- Responsive fallback to single column below 640px
- Generate lan-client/precons.js from precon-decks/precon-index.json so
PRECON_DATA is always available for local/offline mode (163 precons)
- Add scripts/generate-precons-js.js for regeneration when precons update
- Fix _loadBackendPrecons() to re-render the precon tab UI when backend
precons load successfully (was only updating status indicator text,
not populating the dropdown)
Without precons.js, PRECON_DATA was undefined and the dropdown showed
'No precon data loaded' even though 163 .dck files exist in the repo.
* feat: LAN Battlefield App integration with Commander-AI-Lab AI pipeline
Add the LAN Battlefield App as a browser client (lan-client/) that
connects to the Commander-AI-Lab backend for ML-powered AI opponents,
3-category deck selection, and enhanced player panels.
Phase 1 - Foundation:
- Remove floating mana pool display (keep internal tracking)
- Add energy, experience, rad, emblems fields to game state
- No-op renderManaPool(), showManaPool(), setupManaPoolDrag()
Phase 2 - Backend Connection (ai-bridge.js):
- BackendConnector: REST + WebSocket connectivity with retry/timeout
- GameStateBridge: Serializes engine.js state for /api/policy/decide
- MacroActionMapper: Translates 8 ML macro-actions to engine.js calls
- DeckSourceClient: Fetches precon/EDHREC decks from backend API
Phase 3 - Deck System:
- 3-tab deck selector (Precons / EDHREC / My Decks) replaces dropdown
- Precon grouping by set with collapsible sections and filtering
- EDHREC search integration (stub, ready for backend implementation)
- My Decks textarea import placeholder
Phase 4 - AI Integration:
- runAiTurn() priority chain: ML Pipeline > Forge > Local Heuristic
- _runMlAiTurn() async turn loop with multi-phase decision requests
- Backend session initialization on game start
- Automatic fallback to local AI on any ML pipeline error
Phase 5 - Enhanced Player Panels (player-panels.js):
- Collapsible panels with localStorage persistence
- Commander damage progress bars with warning/critical thresholds
- Poison, energy, experience, rad counter widgets
- Emblem tracking with add/remove
Phase 6 - Polish:
- Script loading order: precons > engine > ai-bridge > panels > ui
- Backend auto-detection on page load with status indicator
- Connection status display on setup screen
Closes#184, Closes#185, Closes#186, Closes#187, Closes#188, Closes#189
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: refine LAN battlefield integration with full JSDoc, proper phase IDs
- Add comprehensive JSDoc comments to all ai-bridge.js classes
- Use optional chaining for PHASES lookup in GameStateBridge
- Direct addLogEntry calls in player-panels.js (loaded after engine.js)
- Remove leftover mana pool CSS that was missed in initial pass
- Minor style.css cleanup for consistency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>