For the ship system, think of it as three layers: data model, DM tooling, and player views, all wrapped around a “battle map canvas” that understands ships, decks, and tokens. 1. Core Data Model for Ships, Decks, and Tokens In Laravel terms, I’d model it roughly like this: - Ship “types” (templates) - Concrete ship instances (this campaign’s Salt Wraith; this specific enemy frigate) - Per-ship decks/layers - Tokens placed on decks (cannons, crates, NPCs, markers) - Visibility rules: global (party/enemy) and per-player overrides Conceptually:// Ship template, reusable across campaigns class ShipBlueprint extends Model { // name, size_class, default_image, etc. } // Actual ship in a campaign class ShipInstance extends Model { // campaign_id, ship_blueprint_id, name_override, is_player_ship, is_active, etc. } // Each deck/layer of a ship class ShipDeck extends Model { // ship_instance_id, name (Main Deck, Below Decks), order, base_image_path, is_visible_to_players } // Placeable token (PNG, JPEG, SVG) on a deck class ShipToken extends Model { // ship_deck_id // type (cannon, prop, marker, NPC, effect) // image_path // x, y, rotation, scale // z_index // audience: 'dm', 'party', 'player' // visible_to_player_id (nullable if audience === 'player') // is_revealed (so DM can stage tokens) } Tie this into your existing campaign/roles/knowledge_unlocks: - ‎⁠ShipInstance⁠ belongs to ‎⁠campaign⁠. - One ‎⁠ShipInstance⁠ is flagged as ‎⁠is_player_flagship⁠ per campaign. - Others can be tagged as “enemy”, “neutral”, “hazard”, etc. - Visibility of whole ships is either: ▫ DM-only ▫ Party-visible ▫ Player-specific (for special “Only You Recognize This” situations) ▫ That’s just a thin wrapper over a ‎⁠visibility⁠ column similar to your tier badges. 2. DM Ship Picker & Session Control On the DM dashboard, add a “Naval Scene” card using your Stacked Log layout: - Left column: list of ‎⁠ShipInstance⁠s in the current campaign. - Right column: current “active scene” with ship thumbnails and a “Live Player View” preview. For each ship row: - Toggle “in scene” / “not in scene” - Toggle “player-flagship” (only one) - Toggle “visible to players” - Optional: select “visible to which player only?” Internally: - Add a ‎⁠naval_scenes⁠ table if you want multiple saved scenes per campaign (e.g. “Ambush at Sargasso”, “Port Veridian Dock”). - Or keep it simple at first: one “current scene” per campaign and a JSON blob with ‎⁠ship_instance_id⁠ and positions. You can then use Livewire to: - React to DM actions (add/remove ship from scene, change visibility). - Push “state changed” events to the player view via Livewire events (live-ish updates without heavy JS). 3. Decks & Player Deck Switching Each ‎⁠ShipInstance⁠ has one or more ‎⁠ShipDeck⁠s. Player ship usage: - Party site shows only the player flagship. - UI: a simple tab/segmented control for decks: ▫ “Main Deck”, “Gun Deck”, “Cargo Hold”, etc. - Each tab loads that deck’s base image + all tokens visible to the player. DM view of the same ship: - Dropdown or tabs with all decks, including ones not yet revealed. - DM can toggle ‎⁠is_visible_to_players⁠ on a per-deck basis: ▫ For example, players only see Main Deck until they go below. This fits beautifully with your Map Table metaphor: the deck is the “chart,” tokens are little markers the DM pushes around. 4. Token Placement System (Images & Future Animations) For the “drag props (cannons, barrels, etc.) around on the boat image” piece, I’d treat each deck as a canvas. Implementation sketch: - Use something like Konva.js or Fabric.js in a Livewire component: ▫ Base image = ‎⁠ShipDeck.base_image_path⁠ drawn as the bottom layer. ▫ Each ‎⁠ShipToken⁠ is a draggable image node on top. - Editing mode (DM only): ▫ DM drags/rotates/resizes token images. ▫ On drop, JS sends x/y/rotation/scale/z_index back to Livewire via an action. - View mode (players): ▫ Canvas is read-only and only renders tokens with: ⁃ ‎⁠audience = 'party'⁠ ⁃ or ‎⁠audience = 'player'⁠ and ‎⁠visible_to_player_id = auth()->id()⁠ ▫ Optionally: animate specific tokens (e.g. a flickering lantern, cannon recoil later). Token visibility controls in DM UI for each token: - Audience dropdown: DM / Party / Player. - If Player: a select2 of characters/players. - “Reveal/Hide” button mirrors your knowledge_unlocks pattern: DM can prep tokens ahead of time and reveal them with a click mid-session. Later, animations: - Add ‎⁠animation_type⁠ and ‎⁠animation_settings⁠ JSON on ‎⁠ShipToken⁠ (e.g. “bob”, “pulse”, “flash”). - Your JS layer reads these settings and applies CSS or canvas animations; DM toggles them from the dashboard. 5. Player Experience From the players’ perspective, keep it as simple as a map viewer: - On the player site: ▫ A “Current Ship” page with: ⁃ Short ship summary (name, HP, mood, crew count). ⁃ Deck switcher. ⁃ Read-only view of the canvas for the current deck. - Optional later: show player tokens (where PCs are on the deck) as a separate token type. You keep the “no phones during table time” rule by: - Treating this as optional, between-session or projection-on-TV material. - When at the table, you can project the player view in a browser window on a big screen while controlling everything from the DM dashboard. 6. Access & Knowledge Integration This system should respect your access tiers: - DM-only: ▫ Hidden tokens (enemy below decks, traps, secret hatches). ▫ Hidden decks. ▫ DM notes tied to tokens (e.g. right-click a cannon → “has 3 loaded shots”). - Party-shared: ▫ Player ship, revealed enemy ship silhouettes, visible tokens. - Player-private: ▫ Very rare: e.g. a Signal Flare token only visible to one PC, using the “player-private” tier logic. Knowledge unlocks can hook into this: - When a ‎⁠knowledge_unlock⁠ is created (“The enemy flagship is a war galley with reinforced hull”), you can: ▫ Mark the enemy ship’s blueprint and tokens as visible. ▫ Or change the ship thumbnail from “shadowed silhouette” to full art. 7. Suggested Build Path for the Ship Tool To avoid disappearing into a giant canvas rabbit hole, I’d do: 1. Phase A: DM Ship Picker (No Canvas Yet) ▫ Implement ‎⁠ShipBlueprint⁠, ‎⁠ShipInstance⁠, ‎⁠ShipDeck⁠. ▫ Let DM pick “current player ship” and mark enemy ships + their visibility. ▫ Players see only a textual “Your ship / enemy ships” section. 2. Phase B: Static Deck Viewer ▫ Add a single deck image per player ship. ▫ No tokens, just show the image and deck tabs. ▫ DM can toggle which decks are visible. 3. Phase C: Token System ▫ Implement ‎⁠ShipToken⁠ and add a simple Fabric.js/Konva.js editor for DM. ▫ Store token positions and render read-only on player side. 4. Phase D: Per-Player Visibility & Fancy Stuff ▫ Add per-player tokens and visibility. ▫ Add basic animation options. ▫ Tie into knowledge_unlocks and “Only You Recognize This” cards. 8. Markdown Files per Phase of the Website Below are suggested ‎⁠.md⁠ files based on your docs and build orders. You can copy-paste these straight into your repo. ‎⁠01-concept-and-principles.md⁠# The Black Reach — Concept & Core Principles > **Core Principle:** Screens are for prep. The table is for play. A pirate-themed D&D 5e campaign tool that bridges the DM's Obsidian vault and the game table. The app replaces mid-session vault-scrolling with a fast DM dashboard, and gives players a minimal in-character website between sessions — without pulling anyone into their phones at the table. --- ## Campaign Premise Every player character comes from a different timeline — high fantasy, magitech, post-apocalyptic, whatever fits 5e. During a shared event (a flash of light, a sound like tearing silk), they were ripped from their worlds and dropped into a vast archipelago they do not recognize. They start with nothing: no armor, no spellbook, no savings, no reputation. They do not even speak the local language. The only thing they have is each other. --- ## The Convergence and the Black Reach Something is tearing holes between realities. Things slip through — people, monsters, entire ships. The locals call it "the Convergence" the way others speak of weather or plague. It is not a one-time event; it is still happening. The Black Reach is the wound left by the Convergence — a stretch of ocean that drinks light, a beach of black sand that exists in every timeline and no timeline at all. At its heart stands the Convergence Spire. The campaign begins with the players shipwrecked and lost. By the end, they discover that the name they heard in their first tavern was always the final destination. --- ## Arcs, Factions, and Key Locations ### Campaign Arcs 1. Stranded — survive arrival; meet each other; escape initial danger. 2. The Crew — establish roles; first heists; build reputation. 3. The Convergence Mystery — discover others from timelines; find who knows the truth. 4. Masters of the Sea — legendary pirates; final confrontation with the force behind the Convergence. ### Major Factions - **The Reef Lords** — local power brokers of the archipelago. - **The Silver Navy** — an imperial fleet hunting pirates (and quietly also refugees). - **The Displaced** — refugees from other timelines who lost their minds to the Reach. - **The Harrowed** — a cult worshipping the Convergence as divine will. ### Key Locations - Port Veridian — main hub port. - The Sargasso Maze — ship graveyard and Merrow hunting ground. - The Flotilla — floating settlement of the Displaced. - The Convergence Spire — at the heart of the Black Reach. --- ## App Roles and Access Tiers Three conceptual roles: - **DM (Game Master)** — full control, secrets, prep, real-time toggles. - **Player** — their own character, shared ship/crew info, logs, no DM secrets. - **Observer (later)** — read-only view. Every piece of content respects three visibility tiers: | Tier | Who sees it | Examples | | ------------- | ------------------ | --------------------------------------------------- | | DM-only | DM | hidden stats, monster HP, faction secrets, loyalties | | Party-shared | all authenticated | recaps, known locations, public rumors, ship status | | Player-private| one specific player| "Only You Recognize This" cards, personal hooks | The app is the digital layer on top of the Obsidian vault — not a replacement. The vault stays the source of truth; the app is what DM and players interact with at the table. ‎⁠02-mvp-dm-dashboard.md⁠# Phase 1 — DM Prep Dashboard (MVP) > Goal: reduce DM friction during sessions. Tap a button, get the info, read it aloud. The DM dashboard is a local, DM-only web interface that replaces digging through Obsidian mid-session. --- ## Modules ### Adventure Index - Quick links to all adventures by level. - Pulls high-level metadata from the vault's `Adventures/_Index` note. - Optimized for: "What can I run at level 5 tonight?" ### Monster Quick Cards - Stat summaries for campaign monsters. - References 5e.tools for full stat blocks when needed. - Pulls data from `Monsters/_Index` and monster notes. ### Items & Spells Reference - Fast lookup for items and spells actually used in the campaign. - Pulls from `Items/_Index` and `Spells/_Index`. - Links out to the self-hosted 5e.tools instance for details. ### Ship Reference - All ship tiers, current ship, and quick naval combat rules. - Pulls from `Ships/Current-Ship` and `Naval Combat Quick Rules`. - Designed to be readable out loud at the table. ### Crew & Morale Tracker - Editable tracker for crew mood, roles, and deaths. - Pulls initial data from `Crew-and-Morale`. - Updates become the system of record for the campaign. ### Ship Log - Editable daily ship log. - Pulls starting content from `Daily-Ship-Log`, then becomes app-native. - Ties into recaps and random daily events. --- ## UX & Visuals - Uses the **Stacked Log** layout pattern (captain's desk metaphor). - Calm DM palette: same fonts and colors as the player site, but flatter and less textured. - No torn edges or heavy grain on this surface; legibility over vibes. --- ## Technical Notes - Backend: Laravel 11 (PHP 8.3+), MySQL 8. - Auth and roles via `spatie/laravel-permission`. - Livewire components for each module: - `AdventureIndex`, `MonsterCards`, `ShipReference`, `CrewTracker`, `ShipLog`. - Obsidian integration: - First pass: manual import or file path configuration. - Later: change detection and incremental sync. ‎⁠03-mvp-player-site.md⁠# Phase 2 — Player-Facing Campaign Website (MVP) > A minimal, in-character site the players can check between sessions. The player site is deliberately small and diegetic. It is written as if someone aboard the ship is keeping a log. --- ## Pages ### The Crew - Party member names, roles, and short in-character bios. - Player-written where possible. - Lives in the app but can sync to/from an Obsidian note. ### The Ship - Current vessel name, stats, and general condition. - High-level traits only (HP summary, mood, supply status). - Pulls from the DM's ship and crew systems. ### Known World - Locations the party has visited. - Each entry: short description, who controls it, last visit date. - Pulls from `Locations/_Index` plus app-side tracking. ### Factions Met - Factions the players have actually encountered. - Each entry: name, what they want, how they treat the crew. - Pulls from `Factions/_Index` and the faction reputation system. ### Rumors & Bounties - A short, rotating list of hooks. - Updated after each session by the DM. - Can originate from the Tavern Rumor Board or DM notes. ### Session Recaps - One-page summaries of what happened, written in character when possible. - Backed by a DM-only recap editor that can also output printable letters. --- ## Rules for Player Site Content - No DM secrets. - No full worldbuilding; only what characters reasonably know. - Update only between sessions, not live during play. --- ## Tone and Voice - Written "by someone aboard": quartermaster, bosun, etc. - No out-of-character language, no modern metaphors, no "account/settings" UI copy. - Recaps, rumors, and notices may use the lantern, spyglass, and anchor icons as small inline motifs. --- ## Access & Tiers - All player site content is either party-shared or player-private. - DM-only information is never rendered here, even if present in the same database row. - Private notes (e.g. "Only You Recognize This" cards) appear under a player's logged-in view only. ‎⁠04-random-generators-and-world-tools.md⁠# Phase 3 — Random Generators & World Tools > One-button web versions of existing generators. DM-only, behind the screen. These tools wrap existing markdown/HTML generators into focused DM utilities. --- ## Generators ### Port & Island Generator - Pulls tables from `Port-Island-Generator` note. - Outputs: name, port type, key features, one strange detail. - Can export results into locations and adventure seeds. ### Daily Event Roller - Pulls tables from `Daily-Event-Roller`. - Integrated with the Daily Ship Log: - Roll, accept, and log in one flow. - Emphasizes "ship life" even between big set pieces. ### Sea Encounter Generator - Rebuild or embed `Ships/sea-encounter-generator.html` to match the Black Reach style. - Rolls: - Weather - Sea monsters - Other ships - Timeline weirdness --- ## Worldbuilding Support Tools ### Shanty & Prophecy Archive - Archive of in-world shanties and prophecies. - Can output printable song sheets (ties into the handout pipeline). - Optional link to a simple audio player if recordings exist. ### World Ideas Index - A filtered view of worldbuilding hooks (from "World Ideas — Pirate Campaign"). - Tag by: - Threat type (monster, faction, storm). - Level band. - Timeline relevance. --- ## Usage - All generators are DM-only. - Players never directly interact with these tools. - Results can be: - Instantly used in play, or - Saved as hooks and adventures for later sessions. ‎⁠05-printable-handout-pipeline.md⁠# Phase 4 — Printable Handout Pipeline > Goal: turn digital notes into physical props that hit the table. Printables are one of the highest-impact features for in-person play. --- ## Handout Types ### Session Recap Letters - One-page letters in-world voice, dropped on the table at session start. - Layout: - IM Fell English for headings, EB Garamond for body, Caveat for signature. - Can be generated from session logs plus DM notes. ### NPC Portrait Cards - 3×5 cards with: - Generated portrait. - Name and faction. - One-line motive. - Printed and physically handed over when NPCs become important. ### Faction Reference Cards - Playing-card-sized: - Who they are. - What they want. - How they treat the crew. - Helps players track the political web without checking a screen. ### Ship Condition Cards - Hull/sail/oar HP trackers the DM can mark with dry-erase. - Tied to the ship-tracking system in the app, but usable on their own. ### Map Fragments - Printable sections of the archipelago as players discover them. - Delivered as torn fragments or scrolls, not full maps at once. ### Rumor Scrolls & Letters - Torn-paper or wax-sealed notes. - Generated from Rumor Board entries or DM-written hooks. ### QR Handouts - Cards with QR codes linking to specific player-facing pages. - Examples: - Sailor superstitions. - Wanted posters. - Shanty lyrics. --- ## Visual Treatments Each handout type has a distinct look so players know what they are holding at a glance: - Recap letters: narrow margins, letter format, signature. - Bounty posters: large "WANTED" heading, double border. - Rumor slips: small, dashed border, slightly skewed. All designs follow the style guide's print specs and keep legibility in grayscale. --- ## Pipeline Flow 1. DM selects a content source (session log, NPC, faction, rumor). 2. App renders it into a specific handout template. 3. DM preview and minor edits. 4. Export to PDF/print. 5. Optional: log that this handout has been "issued" so lore discovery can be tracked. ‎⁠06-ship-and-naval-tools.md⁠# Phase 5 — Ship & Naval Tools > Ship selection, deck views, and naval scenes that respect visibility tiers. This phase introduces interactive ship tools that stay aligned with the "screens for prep" principle. --- ## Ship Library - **Ship Blueprints**: - Reusable templates: sloop, brig, frigate, war galley, dragon-turtle base. - Hold metadata: size class, speed, default crew, upgrade slots. - **Ship Instances**: - Concrete ships in a campaign: named vessels with history. - Tracks upgrades, damage, and reputation. --- ## DM Ship Picker From the DM dashboard, a "Naval Scene" module allows: - Choosing which ships appear in the current scene. - Marking which ship is the party flagship. - Tagging ships as enemy, ally, neutral, hazard. - Controlling visibility: - DM-only (unseen threats). - Party-shared (visible enemy ships). - Player-private (rare special cases). --- ## Decks and Layers Each ship instance can have multiple decks (layers): - Main deck, gun deck, cargo hold, captain's cabin, etc. - Each deck has: - A base image. - An order (top to bottom). - A visibility flag (revealed to players or not). Players can switch between visible decks of their own ship on the player site. The DM can see and edit all decks. --- ## Tokens and Props Tokens are placeable images (PNG, JPEG, SVG) on a deck: - Types: - Cannons, barrels, crates, furniture. - NPCs, monsters, crew markers. - Effects (fire, fog, spell areas). - Stored properties: - Position (x, y), rotation, scale, z-index. - Image path. - Audience (DM, party, specific player). - Optional animation settings. The DM can drag and drop tokens on an interactive canvas in the dashboard. Players see a read-only version with only the tokens they are allowed to see. --- ## Player Experience On the player site: - "Current Ship" page: - High-level status (HP, mood, supplies). - Deck switcher. - Visual deck view for the party flagship. This view is optional during table time and ideal for projection or between-session browsing. --- ## Future Enhancements - Per-player-only tokens for "Only You Recognize This" moments. - Animated tokens for environmental effects. - Integration with knowledge unlocks: - Reveal ships, decks, or tokens when lore is discovered. You can continue this pattern for more advanced phases (faction tools, storm mapper, auto-notetaker), but these six files will already give you a neat “phase by phase” structure in your repo. If you’d like, I can next sketch