Browse Source
Add documentation and fix data persistence race condition
Add documentation and fix data persistence race condition
- Create SKILLS.md with base skill reference documentation - Update CLAUDE.md with comprehensive RPG system documentation - Update README.md with game features and mechanics overview - Fix race condition where auto-save could overwrite server data - Add statsLoadedFromServer flag to prevent premature saves - Move startAutoSave() to after server data loads - Add save error notifications to user 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>master
4 changed files with 1601 additions and 190 deletions
-
303CLAUDE.md
-
137README.md
-
288SKILLS.md
-
1063index.html
@ -1,68 +1,137 @@ |
|||
# HikeMap - KML Track Editor |
|||
# HikeMap - Location-Based RPG |
|||
|
|||
A single-page web application for viewing, editing, and navigating KML/GPS tracks on an interactive map. |
|||
A location-based RPG web application where you walk in the real world to explore trails, battle monsters, and level up your character. Also includes GPS track editing tools for trail mapping. |
|||
|
|||
## Features |
|||
|
|||
### RPG System |
|||
|
|||
**Character Creation** |
|||
- Choose from 4 races: Human, Elf, Dwarf, Halfling |
|||
- Select your class (Trail Runner with running-themed skills) |
|||
- Set your home base for respawning and skill management |
|||
|
|||
**Combat** |
|||
- Turn-based battles against MOOP (Matter Out Of Place) monsters |
|||
- Skill-based combat with damage, healing, buffs, and multi-hit attacks |
|||
- Hit/miss mechanics based on accuracy and dodge stats |
|||
- XP rewards and leveling system |
|||
|
|||
**Skills & Progression** |
|||
- Unlock new skills at levels 2, 3, 4, 5, 6, and 7 |
|||
- Choose between two skills at each milestone (both unlock, one activates) |
|||
- Swap your active skill loadout at your home base |
|||
- Class-specific skill names (e.g., "Gel Pack" instead of "Heal") |
|||
|
|||
**Home Base** |
|||
- Set anywhere on the map as your respawn point |
|||
- 3x HP regeneration when within 20 meters |
|||
- Required destination when defeated |
|||
- Skill loadout management location |
|||
|
|||
### Track Editing |
|||
- Draw new tracks directly on the map |
|||
|
|||
- Draw new GPS tracks directly on the map |
|||
- Reshape existing tracks with rope physics simulation |
|||
- Smooth tracks with a brush tool |
|||
- Smart track snapping at endpoints with auto-splitting |
|||
- Multi-track selection and merge operations |
|||
- 20-step undo/redo history |
|||
- Import/export KML files |
|||
|
|||
### Navigation Mode |
|||
|
|||
- Graph-based pathfinding using Dijkstra's algorithm |
|||
- Automatic trail intersection detection (within 5 meters) |
|||
- Real-time route recalculation when deviating >50m from path |
|||
- Automatic trail intersection detection |
|||
- Real-time route recalculation when deviating from path |
|||
- Map rotation to face direction of travel |
|||
- Auto-center on GPS position (toggleable) |
|||
- Persistent destination storage |
|||
|
|||
### GPS Integration |
|||
- Real-time location tracking using device GPS |
|||
- Automatic position updates every 3 seconds |
|||
- Requires HTTPS or localhost for geolocation API |
|||
- Auto-center on GPS position |
|||
|
|||
## Quick Start |
|||
|
|||
### Local Development |
|||
### Docker (Recommended) |
|||
```bash |
|||
# Serve via HTTP (required for GPS geolocation API) |
|||
python -m http.server 8000 |
|||
docker-compose up -d |
|||
``` |
|||
Then open http://localhost:8000 |
|||
Access at http://localhost:880 |
|||
|
|||
### Docker Deployment |
|||
### Local Development |
|||
```bash |
|||
# Build and run with Docker Compose |
|||
docker-compose up |
|||
npm install |
|||
node server.js |
|||
``` |
|||
Access at http://localhost:8080 |
|||
|
|||
## Game Mechanics |
|||
|
|||
### Stats |
|||
|
|||
| Stat | Description | |
|||
|------|-------------| |
|||
| HP | Health - reach 0 and you're defeated | |
|||
| MP | Mana - used for skills, regenerates while walking | |
|||
| ATK | Attack power | |
|||
| DEF | Reduces damage taken | |
|||
| Accuracy | Affects hit chance | |
|||
| Dodge | Chance to evade attacks | |
|||
|
|||
### Trail Runner Skills |
|||
|
|||
| Level | Skill Choice A | Skill Choice B | |
|||
|-------|---------------|----------------| |
|||
| 1 | Kick-ems! (basic) | - | |
|||
| 2 | Brand New Hokas (2x hit) | Gel Pack (heal) | |
|||
| 3 | Downhill Sprint (power) | Pace Yourself (defense) | |
|||
| 4 | Trail Blaze (AoE) | Quick Feet (accurate) | |
|||
| 5 | Second Wind (MP buff) | Trail Mix (quick heal) | |
|||
| 6 | Finish Line Sprint (3x hit) | Zone In (accuracy buff) | |
|||
| 7 | Ultra Marathon (full heal) | The Bonk (devastating) | |
|||
|
|||
See [SKILLS.md](SKILLS.md) for complete skill details. |
|||
|
|||
### Monsters |
|||
|
|||
| Monster | Level Range | Description | |
|||
|---------|-------------|-------------| |
|||
| Sub Par Moop | 1 | Tutorial enemy | |
|||
| Moop | 1-5 | Standard enemy | |
|||
| Fancy Moop | 1-5 | Higher attack | |
|||
| Fanciest Moop | 3-5 | Stronger variant | |
|||
|
|||
*MOOP = Matter Out Of Place (litter-themed enemies encouraging trail cleanup)* |
|||
|
|||
## Technical Details |
|||
|
|||
### Architecture |
|||
- **Single-file application**: Everything contained in `index.html` |
|||
- **No build process required**: Pure HTML/CSS/JavaScript |
|||
- **CDN dependencies**: Leaflet.js 1.9.4, leaflet-rotate 0.2.8 |
|||
- **Frontend**: Single-page app in `index.html` |
|||
- **Backend**: Node.js/Express server in `server.js` |
|||
- **Database**: SQLite via better-sqlite3 in `database.js` |
|||
- **Real-time**: WebSocket for live updates |
|||
|
|||
### File Structure |
|||
The entire application is in `index.html`: |
|||
- Lines 1-325: CSS styles |
|||
- Lines 326-420: HTML structure |
|||
- Lines 421-end: JavaScript application code |
|||
### Dependencies |
|||
- Leaflet.js 1.9.4 (maps) |
|||
- leaflet-rotate 0.2.8 (navigation rotation) |
|||
- Express (API server) |
|||
- better-sqlite3 (database) |
|||
- jsonwebtoken (authentication) |
|||
- ws (WebSocket) |
|||
|
|||
### Data Format |
|||
- Supports standard KML files with Placemark elements |
|||
- Automatically loads `default.kml` on startup if present |
|||
- Exports edited tracks back to KML format |
|||
### Data Storage |
|||
- User accounts with JWT authentication |
|||
- Server-authoritative game state |
|||
- LocalStorage as offline backup only |
|||
|
|||
## Browser Requirements |
|||
|
|||
- Modern browser with ES6 support |
|||
- HTTPS connection or localhost for GPS features |
|||
- Location services permission for navigation mode |
|||
- HTTPS or localhost for GPS features |
|||
- Location services permission |
|||
|
|||
## Documentation |
|||
|
|||
- [SKILLS.md](SKILLS.md) - Complete skill reference |
|||
- [CLAUDE.md](CLAUDE.md) - Development guide |
|||
|
|||
## License |
|||
[Add your license information here] |
|||
|
|||
[Add your license information here] |
|||
@ -0,0 +1,288 @@ |
|||
# HikeMap RPG - Skills Reference |
|||
|
|||
This document contains base skill definitions for the HikeMap RPG system. |
|||
|
|||
## Table of Contents |
|||
- [Skill Types](#skill-types) |
|||
- [Base Skills](#base-skills) |
|||
- [Skill Unlock Levels](#skill-unlock-levels) |
|||
- [Skill Loadout System](#skill-loadout-system) |
|||
- [Combat Formulas](#combat-formulas) |
|||
- [Database Schema](#database-schema) |
|||
|
|||
--- |
|||
|
|||
## Skill Types |
|||
|
|||
| Type | Description | |
|||
|------|-------------| |
|||
| `damage` | Deals damage to enemy/enemies | |
|||
| `heal` | Restores HP to self | |
|||
| `buff` | Applies a temporary stat boost | |
|||
| `status` | Applies a status effect (poison, etc.) | |
|||
| `utility` | Out-of-combat effects (MP regen, etc.) | |
|||
|
|||
--- |
|||
|
|||
## Base Skills |
|||
|
|||
### Basic Attack |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `basic_attack` | |
|||
| **Type** | Damage | |
|||
| **MP Cost** | 0 | |
|||
| **Base Power** | 100% ATK | |
|||
| **Accuracy** | 95% | |
|||
| **Target** | Single enemy | |
|||
| **Description** | A basic physical attack | |
|||
|
|||
### Double Attack |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `double_attack` | |
|||
| **Type** | Damage | |
|||
| **MP Cost** | 5 | |
|||
| **Base Power** | 60% ATK | |
|||
| **Hits** | 2 | |
|||
| **Accuracy** | 85% | |
|||
| **Target** | Single enemy | |
|||
| **Description** | Strike twice in quick succession | |
|||
|
|||
### Heal |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `heal` | |
|||
| **Type** | Heal | |
|||
| **MP Cost** | 8 | |
|||
| **Base Power** | 50% of max HP | |
|||
| **Accuracy** | 100% | |
|||
| **Target** | Self | |
|||
| **Description** | Restore HP | |
|||
|
|||
### Power Strike |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `power_strike` | |
|||
| **Type** | Damage | |
|||
| **MP Cost** | 10 | |
|||
| **Base Power** | 180% ATK | |
|||
| **Accuracy** | 80% | |
|||
| **Target** | Single enemy | |
|||
| **Description** | A powerful blow with extra force | |
|||
|
|||
### Defend |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `defend` | |
|||
| **Type** | Buff | |
|||
| **MP Cost** | 3 | |
|||
| **Effect** | DEF +50% for 2 turns | |
|||
| **Accuracy** | 100% | |
|||
| **Target** | Self | |
|||
| **Description** | Raise defense temporarily | |
|||
|
|||
### Whirlwind |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `whirlwind` | |
|||
| **Type** | Damage | |
|||
| **MP Cost** | 12 | |
|||
| **Base Power** | 75% ATK | |
|||
| **Accuracy** | 85% | |
|||
| **Target** | All enemies | |
|||
| **Description** | A spinning attack that hits all enemies | |
|||
|
|||
### Quick Strike |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `quick_strike` | |
|||
| **Type** | Damage | |
|||
| **MP Cost** | 4 | |
|||
| **Base Power** | 80% ATK | |
|||
| **Accuracy** | 98% | |
|||
| **Target** | Single enemy | |
|||
| **Description** | A fast attack with high accuracy | |
|||
|
|||
### Focus |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `focus` | |
|||
| **Type** | Buff | |
|||
| **MP Cost** | 6 | |
|||
| **Effect** | Accuracy +20% for 3 turns | |
|||
| **Accuracy** | 100% | |
|||
| **Target** | Self | |
|||
| **Description** | Concentrate to boost accuracy | |
|||
|
|||
### Second Wind |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `second_wind` | |
|||
| **Type** | Utility | |
|||
| **MP Cost** | 0 | |
|||
| **Effect** | 2x MP regen while walking for 1 hour | |
|||
| **Cooldown** | Once per day | |
|||
| **Target** | Self | |
|||
| **Description** | Double your MP regeneration while walking | |
|||
|
|||
### Heavy Blow |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `heavy_blow` | |
|||
| **Type** | Damage | |
|||
| **MP Cost** | 15 | |
|||
| **Base Power** | 250% ATK | |
|||
| **Accuracy** | 60% | |
|||
| **Target** | Single enemy | |
|||
| **Description** | A devastating attack that is hard to land | |
|||
|
|||
### Quick Heal |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `quick_heal` | |
|||
| **Type** | Heal | |
|||
| **MP Cost** | 4 | |
|||
| **Base Power** | 25% of max HP | |
|||
| **Accuracy** | 100% | |
|||
| **Target** | Self | |
|||
| **Description** | A small but efficient heal | |
|||
|
|||
### Triple Strike |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `triple_strike` | |
|||
| **Type** | Damage | |
|||
| **MP Cost** | 18 | |
|||
| **Base Power** | 50% ATK | |
|||
| **Hits** | 3 | |
|||
| **Accuracy** | 80% | |
|||
| **Target** | Single enemy | |
|||
| **Description** | Strike three times in rapid succession | |
|||
|
|||
### Full Restore |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `full_restore` | |
|||
| **Type** | Heal | |
|||
| **MP Cost** | 30 | |
|||
| **Base Power** | 100% of max HP | |
|||
| **Accuracy** | 100% | |
|||
| **Target** | Self | |
|||
| **Description** | Fully restore HP at great MP cost | |
|||
|
|||
### Poison (Monster Only) |
|||
| Property | Value | |
|||
|----------|-------| |
|||
| **ID** | `poison` | |
|||
| **Type** | Status | |
|||
| **MP Cost** | 0 | |
|||
| **Effect** | 5 damage per turn for 3 turns | |
|||
| **Accuracy** | 75% | |
|||
| **Target** | Single enemy | |
|||
| **Player Usable** | No | |
|||
| **Description** | Inflict poison that deals damage over time | |
|||
|
|||
--- |
|||
|
|||
## Skill Unlock Levels |
|||
|
|||
Skills are unlocked at level milestones. Each level offers a choice between two skills: |
|||
|
|||
| Player Level | Choice A | Choice B | |
|||
|--------------|----------|----------| |
|||
| 1 | Basic Attack | - | |
|||
| 2 | Double Attack | Heal | |
|||
| 3 | Power Strike | Defend | |
|||
| 4 | Whirlwind | Quick Strike | |
|||
| 5 | Second Wind | Quick Heal | |
|||
| 6 | Triple Strike | Focus | |
|||
| 7 | Full Restore | Heavy Blow | |
|||
|
|||
--- |
|||
|
|||
## Skill Loadout System |
|||
|
|||
### How It Works |
|||
|
|||
1. **On Level-Up**: When reaching a skill unlock level, the player chooses one skill to make **active**. However, **all skills offered at that level are unlocked**. |
|||
|
|||
2. **Active vs Unlocked**: |
|||
- `unlockedSkills`: All skills the player has learned |
|||
- `activeSkills`: Skills currently equipped for combat (one per tier) |
|||
|
|||
3. **Swapping Skills**: At home base, players can swap which skill is active for each tier. |
|||
|
|||
4. **Combat**: Only skills in `activeSkills` appear in the combat skill menu. |
|||
|
|||
### Skill Tiers |
|||
|
|||
| Tier | Level | Skills | |
|||
|------|-------|--------| |
|||
| 0 | 1 | Basic Attack (always active) | |
|||
| 1 | 2 | Double Attack, Heal | |
|||
| 2 | 3 | Power Strike, Defend | |
|||
| 3 | 4 | Whirlwind, Quick Strike | |
|||
| 4 | 5 | Second Wind, Quick Heal | |
|||
| 5 | 6 | Triple Strike, Focus | |
|||
| 6 | 7 | Full Restore, Heavy Blow | |
|||
|
|||
**Note**: Utility skills (like Second Wind) don't appear in combat loadout - they are activated from the character sheet. |
|||
|
|||
--- |
|||
|
|||
## Combat Formulas |
|||
|
|||
### Damage Calculation |
|||
``` |
|||
finalDamage = (skillPower * playerATK / 100) - enemyDEF |
|||
``` |
|||
|
|||
### Hit Chance |
|||
``` |
|||
hitChance = skillAccuracy + (attackerAccuracy - 90) - defenderDodge |
|||
``` |
|||
- Clamped between 5% and 99% |
|||
|
|||
### Defense Buff |
|||
When Defend is active: |
|||
``` |
|||
effectiveDEF = baseDEF * 1.5 |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## Database Schema |
|||
|
|||
### skills table |
|||
| Column | Type | Description | |
|||
|--------|------|-------------| |
|||
| id | TEXT | Skill identifier (primary key) | |
|||
| name | TEXT | Display name | |
|||
| description | TEXT | Skill description | |
|||
| type | TEXT | damage/heal/buff/status/utility | |
|||
| mp_cost | INTEGER | MP required to use | |
|||
| base_power | INTEGER | Base power percentage | |
|||
| accuracy | INTEGER | Base accuracy (default 100) | |
|||
| hit_count | INTEGER | Number of hits (default 1) | |
|||
| target | TEXT | enemy/self/all_enemies | |
|||
| status_effect | TEXT | JSON for status effects | |
|||
| player_usable | BOOLEAN | Can players use this? | |
|||
| monster_usable | BOOLEAN | Can monsters use this? | |
|||
| enabled | BOOLEAN | Is skill active in game? | |
|||
|
|||
### class_skills table |
|||
| Column | Type | Description | |
|||
|--------|------|-------------| |
|||
| class_id | TEXT | Class ID | |
|||
| skill_id | TEXT | Base skill ID | |
|||
| unlock_level | INTEGER | Level when skill becomes available | |
|||
| choice_group | INTEGER | Skills with same group are offered together | |
|||
|
|||
### class_skill_names table |
|||
| Column | Type | Description | |
|||
|--------|------|-------------| |
|||
| skill_id | TEXT | Base skill ID | |
|||
| class_id | TEXT | Class ID | |
|||
| custom_name | TEXT | Class-specific name | |
|||
| custom_description | TEXT | Class-specific description | |
|||
1063
index.html
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue