Claude Analysis

DeckCraft v4 (WIP)

Living documentation of the current codebase: what each page does, what works well, what's broken, and what's missing between the current state and the product goal.

Product goal

DeckCraft is an assistant that helps anyone design a printable, custom card-based board game end-to-end. The user answers guided questions, the assistant proposes structure & content (mechanics, resources, card types, decks, card copy, card art), and the output is a finished, physical, customised board-game that gets printed and shipped — not a digital-only game.

This context drives every decision below: anything that is virtual-only (animations, live state, online multiplayer) is not the goal. Anything print-facing (card layout, bleed, quantities, deck composition, art style) is core.

How DeckCraft thinks about a game

The whole app models the same mental picture: a game is a briefing that grows progressively into a concrete, printable artifact. Each wizard step takes the briefing a layer deeper without contradicting earlier layers.

  1. Briefing (Step 1). The user tells the assistant what kind of game they want: name, pitch, mechanic, world, vibe, scale. This is a creative brief, not a checklist — and everything that follows is the assistant working from it.
  2. Pieces (Step 2). The assistant proposes the building blocks: resources (mana, gold, energy), life/score tracks, card types (units, spells, events), families / factions, and the zones the cards will move between (hand, deck, discard, market).
  3. Decks (Step 3). The pieces are allocated across decks, with a frequency distribution (how many of each card type land in each deck). The total card count is constrained by the scale chosen in Step 1.
  4. Cards (Step 4). Each deck is filled with concrete cards: names, rules text, keywords, numeric stats, generated art.
  5. Print (goal, not yet built). The finished cards become a print-ready PDF — bleed, crop marks, card backs, manifest — and get physically produced.

Between steps, one fact is invariant: the AI always reads the briefing first. The briefing is the single source of truth about what game is being designed, which is why the capture quality of Step 1 disproportionately affects every later step. As of this pass, the opening framing the AI receives is actually derived from the briefing — "3-5 player cooperative set-collection card game" — instead of the old hardcoded deck-builder sentence.

Three pieces that interlock

It helps to keep three separate concerns in mind as you read the code:

  • The design. What the game is: briefing, resources, card types, zones, decks, cards. Lives in game_info, game_meta, game_parts, game_decks, game_cards.
  • The assistant. The AI conversation the user is collaborating with. Seeded at Step 1, extended by every subsequent suggestion call. Stored under message_history so the model retains context across pages.
  • The print target. Physical constraints the design has to respect: card size, card count, language. Currently mostly implicit — only the scale preset is captured. This is the biggest conceptual gap between where the code is and where the product wants to go.

High-level architecture

Stack

Backend
PHP 7/8, no framework
DB
MySQL via PDO (inc-db.php)
Frontend
Bootstrap 5 (DexignZone "DezNav" admin theme), jQuery, SmartWizard, noUiSlider, SweetAlert2, DataTables
AI layer
Custom PHP helpers (sendChatMessage, buildGameContextPrompt) — model/provider TBD
Session
PHP sessions; user_id hard-coded to 123 everywhere
Static config
JSON files under assets/data/ with .schema.json siblings

Wizard map

index-games.php (My Games) | v [ New Game ] | v index.php Step 1 Briefing | POST -> ajax-steps.php (method=init) v index-step2.php Step 2 Resources, card types, families | POST -> ajax-steps.php (method=full-form) v index-decks.php Step 3 Decks + frequency distribution | v index-cards.php Step 4 Cards (autogenerate + images) | v excel.php / print Export

Persistence model (at a glance)

Each game has a unique_id (MD5 of name + microtime). The "shape" of a game lives in a key/value meta table, accessed via getGameMeta() / getAllGameMeta() / updateGameMeta(). Known meta keys seen so far:

Meta keyWritten byShape
game_briefingajax-steps.php initFlat object (name, description, goal, world, volume preset, player count, etc.)
life_pointsStep 2{name, description}
card_typesStep 2Per-archetype overrides
custom_card_subtypesStep 2User-defined archetypes
card_familiesStep 2{enabled, families:{id:{name,description}}}
game_zonesStep 2Zone definitions
game_default_stylesindex-styles.phpGlobal + per-card-type style overrides
message_historyAI callsConversation transcript for context

Relational tables: game_info, game_decks, game_parts.

Global TODOs

Project-wide items that span multiple pages. Page-specific TODOs live on each page doc.

  • Replace deprecated FILTER_SANITIZE_STRING everywhere
    Removed in PHP 8.1. Present in 12 files. Use htmlspecialchars() on output or a whitelist regex on input.
  • Move DB credentials out of php-includes/inc-db.php
    Currently committed as plaintext. Move to an untracked .env or PHP config file excluded from git.
  • Decide fate of _old / _backup files
    index_old.php, index_old2.php, index-step2_old.php, index-decks_old.php, index-decks_backup_with_toggle.php, index-cards_old.php, partial-form-cardtypes_backup.php, ajax-cards-autogenerate_backup.php. Pick one: delete (git has them), or move to an _archive/ folder.
  • Real authentication (not hard-coded user 123)
    Every entry point starts with $_SESSION['user_id'] = 123;. Until there are real users, ownership/permission logic cannot be trusted.
  • Generalise the AI system prompt fixed
    New helper buildGameFramingFromBriefing() in inc-functions-final.php derives the opening framing from the briefing (mechanic + player_mode + player_count + subgenre). Applied to all 3 live prompt sites. Remaining: per-method prompts for zones / rules still assume 2-player symmetrical; flagged on the onboarding page for follow-up.
  • Add a print-output pipeline (end goal) review later
    The missing last mile: from a finished design to a print-ready PDF (bleed, crop marks, CMYK, card back, deck manifests, box insert). Today's export stops at excel.php / SimpleXLSXGen.php. Deferred — print specs (card size, run, language, box) will be captured when this pipeline is tackled.
  • Normalise naming: gameUniqueId vs uniqueGameId vs gameUniqueID
    ajax-ia-suggestions.php already has patch code handling all three spellings. Pick one, grep, normalise.
  • Stop committing logfile.log
    Gitignore it, rotate it, or move to /tmp.

Glossary

Briefing
The Step 1 summary of the game (name, pitch, mechanic, flavour). Stored under meta key game_briefing.
Mechanic
Top-level game type (Deck-Builder, TCG Duel, Draft, Set Collection, Trick-Taking). Subgenres live under each mechanic.
Card volume preset
One of small_game / medium_game / large_game / custom_game. Drives soft/hard caps on total card count.
Archetype / Card type
Character, Spell, Artifact, etc. Configured in Step 2.
Family
Guild / faction / race that spans multiple card types for flavour grouping.
Zone
A physical/conceptual space where cards live during play (hand, deck, discard, market, etc.).
Frequency distribution
Per-card-type share of the deck; sums to the total card cap.