# The Ashen Halls A UI-focused 2D healer game prototype. The player selects party frames and uses healing, shielding, and cleansing spells while an AI party fights through a dungeon encounter. ## Why this stack - **React + TypeScript:** The game is mostly interactive UI, timers, bars, and state. A full game engine is not necessary for the first version. - **CSS pixel-art presentation:** Fast to iterate now; sprite sheets and richer animation can be layered in later. - **SQLite:** Stores authored content and durable player data. Live combat state remains in memory because health and cooldowns change many times per second. - **Electron later:** The web build can be wrapped as a Windows/macOS/Linux desktop game once the core loop is fun. Phaser or Godot becomes worthwhile if the design grows into animated battlefield positions, projectile-heavy combat, physics, or map exploration. ## Run it ```powershell npm install npm run db:init npm run dev ``` Use the mouse to select a party member and click spells, or use keys `1` through `6`. For an online production build, see [DEPLOYMENT.md](DEPLOYMENT.md). ## Current vertical slice - Five party members with tank, healer, and damage roles - Mana management, cooldowns, direct healing, healing over time, group healing, shields, and cleansing - Reduced starter ability costs tuned to sustain an efficient full dungeon run - High-contrast selected-target raid frames and a persistent active-target card - Per-difficulty dungeon efficiency leaderboards ranked by resource spent, with class, level, item-level, and run-duration snapshots - Account registration, secure password hashing, cookie sessions, logout, and fully isolated character progression for each account - One-account-per-public-IP registration with local administrator exceptions - Live-safe SQLite backups for self-hosted account and save data - Explicit offline characters with local progression, gear, talents, and loot - A shared repository boundary for online HTTP, browser-local, and future desktop SQLite persistence - Two trash encounters followed by Warden Vhal - Boss-wide damage and a dispellable damage-over-time mechanic - Victory, defeat, loot, and restart states - Main menu with Dungeons, Raids, PvP, Customize Character, and Talents - SQLite-backed class selection and persistent six-slot ability loadouts - Three healer class foundations with level-gated abilities - SQLite-driven experience progression from level 1 to 25 - Dungeon XP rewards, level-up handling, talent-point awards, and ability unlocks - SQLite-backed class talent trees with ranks, tiers, prerequisites, refunds, and immediate persistence - Seven equipment slots, starter item-level 1 gear, inventory comparison, and persistent equipping - Aggregate item level, healing power, and resource bonuses that affect combat - Five SQLite-authored dungeon difficulty tiers with level gates, combat scaling, XP multipliers, and item-level reward bands - Encounter-specific weighted loot tables for every difficulty, with authored drop chances, slot pools, and item-level 5 through 25 reward variants - One live loot roll per defeated encounter, shown in the combat log and dungeon-complete summary - Atomic inventory awards with retry-safe roll records and stacked duplicate quantities - Safe duplicate cleanup that can discard spare copies without removing the character's final copy - SQLite schema and seed data for progression, talents, item-level difficulties, boss loot, characters, inventory, and runs ## Architecture direction The combat simulator should stay framework-independent as it grows. React renders the current state and handles player input. A content repository will load classes, spells, dungeons, encounters, mechanics, and loot from SQLite. This makes it possible to add content through an editor later without rewriting combat code. The Vite development and preview servers expose a local SQLite API used by the character screens. The API validates class ownership, unlock levels, duplicate abilities, and the six-slot limit. When the project is wrapped in Electron, this same repository boundary can move into the Electron main process. Offline characters use a separate browser-local save and do not require an account. Production web builds cache the application shell after one successful visit so they can reopen without a connection. Offline characters are excluded from online leaderboards. Run `npm run offline:export` after changing SQLite-authored classes, abilities, dungeons, difficulties, items, or loot tables so new offline characters receive the updated starter content. ## Suggested milestones 1. Move combat updates into a deterministic simulation module and add tests. 2. Apply authored talent effects to combat calculations. 3. Add currency or crafting materials for selling and salvaging spare gear. 4. Add two more bosses to complete the first three-boss dungeon. 5. Add cast times, global cooldowns, threat, overhealing, and a combat summary. 6. Replace placeholder glyphs with original pixel-art portraits, spell icons, enemies, and effects. ## Creative boundary Genre conventions such as party frames, mana, cooldowns, dispels, and healing styles are fair inspiration. Keep class names, spell names, lore, icons, sounds, characters, encounter text, and artwork original rather than copying World of Warcraft assets or terminology. # I want to Heal ## Android and AYN Thor The Android build uses Capacitor and includes a native `DualScreen` plugin. The plugin enumerates Android displays, launches the full interactive game on the largest display, and changes the smaller display to a compact dungeon, resource, targeting, skill, and cooldown panel. Android controller key events are forwarded into the web input system so menus and combat can both be navigated without touch. On devices that do not permit an activity to launch on a secondary display, the plugin falls back to a fullscreen `Presentation` WebView. Build prerequisites: - Android Studio with Android SDK 36 - JDK 17 or the Java runtime bundled with Android Studio Useful commands: ```bash npm run android:sync npm run android:open npm run android:apk ``` The debug APK is written to: ```text android/app/build/outputs/apk/debug/app-debug.apk ``` On the Thor, open Settings and inspect the display diagnostics under **AYN Thor Dual-Screen Mode**. The expected displays are approximately: - `1920×1080` at `120 Hz` - `1240×1080` at `60 Hz` If Android starts the main activity on the upper panel, the next native fallback is a second activity launched onto the lower display with `ActivityOptions.setLaunchDisplayId()`. The diagnostics identify whether that fallback is needed on the installed Thor firmware.