# 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
- Nine equipment slots, empty starter inventory, craftable item-level 1 gear,
  inventory comparison, and persistent equipping
- Aggregate item level, healing power, and resource bonuses that affect combat
- Four playable SQLite-authored content tiers at item levels 1, 10, 20, and 25
  with level gates, combat scaling, XP multipliers, and reward bands
- Gear progression through item levels 1, 5, 10, 15, 20, and 25 with
  boss-coin crafting and upgrade steps
- 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.
