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.
- 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.
- 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).
- 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.
- Cards (Step 4). Each deck is filled with concrete cards: names, rules text, keywords, numeric stats, generated art.
- 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_historyso 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_idhard-coded to123everywhere - Static config
- JSON files under
assets/data/with.schema.jsonsiblings
Wizard map
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 key | Written by | Shape |
|---|---|---|
game_briefing | ajax-steps.php init | Flat object (name, description, goal, world, volume preset, player count, etc.) |
life_points | Step 2 | {name, description} |
card_types | Step 2 | Per-archetype overrides |
custom_card_subtypes | Step 2 | User-defined archetypes |
card_families | Step 2 | {enabled, families:{id:{name,description}}} |
game_zones | Step 2 | Zone definitions |
game_default_styles | index-styles.php | Global + per-card-type style overrides |
message_history | AI calls | Conversation 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_STRINGeverywhereRemoved in PHP 8.1. Present in 12 files. Usehtmlspecialchars()on output or a whitelist regex on input. -
Move DB credentials out of
php-includes/inc-db.phpCurrently committed as plaintext. Move to an untracked.envor PHP config file excluded from git. -
Decide fate of
_old/_backupfilesindex_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 fixedNew helper
buildGameFramingFromBriefing()ininc-functions-final.phpderives 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 laterThe 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:
gameUniqueIdvsuniqueGameIdvsgameUniqueIDajax-ia-suggestions.phpalready has patch code handling all three spellings. Pick one, grep, normalise. -
Stop committing
logfile.logGitignore 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.