17 KiB
Echoes of the Ash 🌆
A dark fantasy post-apocalyptic survival RPG featuring exploration, combat, crafting, and scavenging in a ruined world.
🎮 Game Features
Core Gameplay
🗺️ Exploration & Movement
- Grid-based world navigation with coordinates (x, y)
- Stamina-based movement system - each move costs stamina based on distance
- Multiple biomes and locations with varying danger levels (0-4)
- Dynamic location discovery as you explore
- Compass-based directional movement (North, South, East, West)
⚔️ Combat System
- Turn-based combat with real-time intent preview
- NPC enemy encounters with weighted spawn tables per location
- Status effects system: Bleeding, Infected, Radiation
- Weapon effects: Bleeding, Stun, Armor Break
- Flee mechanics - escape combat with success/failure chance
- XP and leveling system - gain XP from defeating enemies
- PvP (Player vs Player) combat - challenge other players
- Death and respawn mechanics
🎒 Inventory & Equipment
- Weight and volume-based inventory system
- Equipment slots: Weapon, Backpack, Armor, Head, Tool
- Durability system - items degrade with use
- Item tiers (1-3) affecting quality and stats
- Encumbrance system - affects stamina costs
- Ground item drops - pick up and drop items
🔨 Crafting & Repair
- Crafting system with material requirements
- Tool requirements for certain recipes
- Repair mechanics - restore item durability
- Uncrafting/Disassembly - break down items for materials
- Workbench locations for advanced crafting
- Craft level requirements - unlocked through progression
🔍 Scavenging & Interactables
- Searchable objects in each location (dumpsters, cars, houses, etc.)
- Action-based interaction system with stamina costs
- Success/failure mechanics with critical outcomes
- Loot tables with item drop chances
- One-time and respawning interactables
- Status tracking per player (already looted, depleted, etc.)
📊 Character Progression
- Level system (1-50+) with XP requirements
- Stat points - allocate to Strength, Defense, Stamina
- Character customization on creation
- Skill progression tied to crafting levels
🌍 World Features
- Multi-location world (Downtown, Gas Station, Residential, Clinic, Plaza, Park, Warehouse, Office Buildings, Subway, etc.)
- Location tags - workbench, repair_station, safe_zone
- Danger zones with varying encounter rates
- Location-specific loot and enemy spawns
💬 Social & Multiplayer
- Online player tracking via WebSockets
- Real-time player position updates
- PvP combat system with challenge mechanics
- Character browsing - see other players' stats
🎨 PWA Features
- Progressive Web App - installable on mobile/desktop
- Multi-language support (English, Spanish)
- Responsive UI with mobile-first design
- Real-time updates via WebSockets
- Offline capabilities (service worker)
📁 Gamedata Structure
The game uses JSON files in the gamedata/ directory to define all game content. This modular approach makes it easy to add new content without code changes.
Directory Layout
gamedata/
├── npcs.json # Enemy NPCs and combat encounters
├── items.json # All items, weapons, consumables, and resources
├── locations.json # World map locations and interactables
└── interactables.json # Interactable object templates
📋 npcs.json Structure
Defines all enemy NPCs, their stats, loot tables, and spawn locations.
Top-Level Structure
{
"npcs": { ... }, // NPC definitions
"danger_levels": { ... }, // Danger settings per location
"spawn_tables": { ... } // Enemy spawn weights per location
}
NPC Definition
"npc_id": {
"npc_id": "unique_npc_identifier",
"name": {
"en": "English Name",
"es": "Spanish Name"
},
"description": {
"en": "English description",
"es": "Spanish description"
},
"emoji": "🐕",
"hp_min": 15, // Minimum HP when spawned
"hp_max": 25, // Maximum HP when spawned
"damage_min": 3, // Minimum attack damage
"damage_max": 7, // Maximum attack damage
"defense": 0, // Damage reduction
"xp_reward": 10, // XP given on defeat
"loot_table": [ // Items dropped on death (automatic)
{
"item_id": "raw_meat",
"quantity_min": 1,
"quantity_max": 2,
"drop_chance": 0.6 // 60% chance to drop
}
],
"corpse_loot": [ // Items harvestable from corpse
{
"item_id": "animal_hide",
"quantity_min": 1,
"quantity_max": 1,
"required_tool": "knife" // Tool needed to harvest (null = no requirement)
}
],
"flee_chance": 0.3, // Chance NPC flees from combat
"status_inflict_chance": 0.15, // Chance to inflict status effect on hit
"image_path": "images/npcs/feral_dog.webp",
"death_message": "The feral dog whimpers and collapses..."
}
Danger Levels
"location_id": {
"danger_level": 2, // 0-4 scale
"encounter_rate": 0.2, // 20% chance per movement
"wandering_chance": 0.35 // 35% chance for random encounter while idle
}
Spawn Tables
"location_id": [
{
"npc_id": "raider_scout",
"weight": 50 // Weighted random spawn (higher = more common)
},
{
"npc_id": "infected_human",
"weight": 30
}
]
Available NPCs:
feral_dog- Wild, hungry canine (Tier 1)mutant_rat- Radiation-mutated rodent (Tier 1)raider_scout- Hostile human raider (Tier 2)scavenger- Aggressive survivor (Tier 2)infected_human- Virus-infected zombie-like human (Tier 3)
🎒 items.json Structure
Defines all items, equipment, weapons, consumables, and crafting materials.
Item Categories (Types)
resource- Raw materials for craftingconsumable- Food, medicine, usable itemsweapon- Melee and ranged weaponsbackpack- Inventory capacity upgradesarmor- Protective equipmenttool- Utility items (flashlight, etc.)quest- Story/quest items
Basic Item Structure
"item_id": {
"name": {
"en": "Item Name",
"es": "Spanish Name"
},
"description": {
"en": "Description text",
"es": "Spanish description"
},
"type": "resource",
"weight": 0.5, // Kilograms
"volume": 0.2, // Liters
"emoji": "⚙️",
"image_path": "images/items/scrap_metal.webp"
}
Consumable Items
"item_id": {
...basic fields...,
"type": "consumable",
"hp_restore": 20, // Health restored
"stamina_restore": 10, // Stamina restored
"treats": "Bleeding" // Status effect cured (optional)
}
Weapon/Equipment Items
"item_id": {
...basic fields...,
"type": "weapon",
"equippable": true,
"slot": "weapon", // Equipment slot: weapon, backpack, armor, head, tool
"durability": 100, // Max durability
"tier": 2, // 1-3 quality tier
"encumbrance": 2, // Stamina penalty when equipped
"stats": {
"damage_min": 5,
"damage_max": 10,
"weight_capacity": 20, // For backpacks
"volume_capacity": 20,
"defense": 5 // For armor
},
"weapon_effects": { // Status effects inflicted (optional)
"bleeding": {
"chance": 0.15, // 15% chance on hit
"damage": 2, // Damage per turn
"duration": 3 // Turns
}
}
}
Craftable Items
"item_id": {
...other fields...,
"craftable": true,
"craft_level": 2, // Required crafting level
"craft_materials": [
{
"item_id": "scrap_metal",
"quantity": 3
}
],
"craft_tools": [ // Tools consumed during crafting
{
"item_id": "hammer",
"durability_cost": 3 // Durability consumed
}
]
}
Repairable Items
"item_id": {
...other fields...,
"repairable": true,
"repair_materials": [
{
"item_id": "scrap_metal",
"quantity": 2
}
],
"repair_tools": [
{
"item_id": "hammer",
"durability_cost": 2
}
],
"repair_percentage": 30 // % of max durability restored
}
Uncraftable Items (Disassembly)
"item_id": {
...other fields...,
"uncraftable": true,
"uncraft_yield": [ // Materials returned
{
"item_id": "scrap_metal",
"quantity": 2
}
],
"uncraft_loss_chance": 0.25, // 25% chance to lose materials
"uncraft_tools": [
{
"item_id": "hammer",
"durability_cost": 1
}
]
}
Item Examples:
- Resources:
scrap_metal,cloth_scraps,wood_planks,bone,raw_meat - Consumables:
canned_food,water_bottle,bandage,antibiotics,rad_pills - Weapons:
rusty_knife,knife,tire_iron,makeshift_spear,reinforced_bat - Backpacks:
tattered_rucksack,hiking_backpack - Tools:
flashlight,hammer
🗺️ locations.json Structure
Defines the game world, all locations, coordinates, and interactable objects.
Location Definition
{
"id": "location_id",
"name": {
"en": "🏚️ Location Name",
"es": "Spanish Name"
},
"description": {
"en": "Atmospheric description of the location...",
"es": "Spanish description"
},
"image_path": "images/locations/location.webp",
"x": 0, // Grid X coordinate
"y": 2, // Grid Y coordinate
"tags": [ // Optional tags
"workbench", // Has crafting bench
"repair_station", // Can repair items
"safe_zone" // No random encounters
],
"interactables": { ... } // Interactable objects at this location
}
Interactable Object Instance
"unique_interactable_id": {
"template_id": "dumpster", // References interactables.json
"outcomes": {
"action_id": {
"stamina_cost": 2,
"success_rate": 0.5, // 50% base success chance
"crit_success_chance": 0.1, // 10% chance for critical success
"crit_failure_chance": 0.1, // 10% chance for critical failure
"rewards": {
"damage": 0, // Damage on normal failure
"crit_damage": 8, // Damage on critical failure
"items": [ // Items on normal success
{
"item_id": "plastic_bottles",
"quantity": 3,
"chance": 1.0 // 100% drop rate
}
],
"crit_items": [ // Items on critical success
{
"item_id": "rare_item",
"quantity": 1,
"chance": 0.5
}
]
},
"text": { // Locale-specific text responses
"success": {
"en": "You find something useful!",
"es": "¡Encuentras algo útil!"
},
"failure": {
"en": "Nothing here.",
"es": "Nada aquí."
},
"crit_success": { ... },
"crit_failure": { ... }
}
}
}
}
Available Locations:
start_point- Ruined Downtown Core (0, 0) - Starting locationgas_station- Abandoned Gas Station (0, 2) - Has workbenchresidential- Residential Street (3, 0)clinic- Old Clinic (2, 3) - Medical suppliesplaza- Shopping Plaza (-2.5, 0)park- Suburban Park (-1, -2)overpass- Highway Overpass (1.0, 4.5)warehouse- Warehouse Districtoffice_building- Office Towersubway- Subway Station
🔍 interactables.json Structure
Defines templates for interactable objects that can be placed in locations.
Interactable Template
"template_id": {
"id": "template_id",
"name": {
"en": "🗑️ Object Name",
"es": "Spanish Name"
},
"description": {
"en": "Object description",
"es": "Spanish description"
},
"image_path": "images/interactables/object.webp",
"actions": { // Available actions for this object
"action_id": {
"id": "action_id",
"label": {
"en": "🔎 Action Label",
"es": "Spanish Label"
},
"stamina_cost": 2 // Base stamina cost (can be overridden in locations)
}
}
}
Available Interactable Templates:
rubble- Pile of debris (Action: search)dumpster- Trash container (Action: search_dumpster)sedan- Abandoned car (Actions: search_glovebox, pop_trunk)house- Abandoned house (Action: search_house)toolshed- Tool shed (Action: search_shed)medkit- Medical supply cabinet (Action: search_medkit)storage_box- Storage container (Action: search)vending_machine- Vending machine (Actions: break, search)
🛠️ Replicating Gamedata
Adding a New NPC
- Create NPC definition in
npcs.jsonunder"npcs":
"my_new_npc": {
"npc_id": "my_new_npc",
"name": { "en": "My NPC", "es": "Mi NPC" },
"description": { "en": "Description", "es": "Descripción" },
"emoji": "👹",
"hp_min": 20, "hp_max": 30,
"damage_min": 4, "damage_max": 8,
"defense": 1,
"xp_reward": 15,
"loot_table": [...],
"corpse_loot": [...],
"flee_chance": 0.2,
"status_inflict_chance": 0.1,
"image_path": "images/npcs/my_new_npc.webp",
"death_message": "The creature falls..."
}
- Add to spawn table in
npcs.jsonunder"spawn_tables":
"location_id": [
{ "npc_id": "my_new_npc", "weight": 40 }
]
- Add image at
images/npcs/my_new_npc.webp
Adding a New Item
- Create item definition in
items.json:
"my_new_item": {
"name": { "en": "My Item", "es": "Mi Objeto" },
"description": { "en": "Description", "es": "Descripción" },
"type": "resource",
"weight": 1.0,
"volume": 0.5,
"emoji": "🔮",
"image_path": "images/items/my_new_item.webp"
}
-
Add to loot tables (optional) in locations or NPCs
-
Add image at
images/items/my_new_item.webp
Adding a New Location
- Create location in
locations.json:
{
"id": "my_location",
"name": { "en": "🏭 My Location", "es": "Mi Ubicación" },
"description": { "en": "Description", "es": "Descripción" },
"image_path": "images/locations/my_location.webp",
"x": 5,
"y": 3,
"tags": ["workbench"],
"interactables": {
"my_location_box": {
"template_id": "storage_box",
"outcomes": {
"search": { ...outcome definition... }
}
}
}
}
- Add danger level in
npcs.json:
"my_location": {
"danger_level": 2,
"encounter_rate": 0.15,
"wandering_chance": 0.3
}
- Add spawn table in
npcs.json:
"my_location": [
{ "npc_id": "raider_scout", "weight": 60 },
{ "npc_id": "mutant_rat", "weight": 40 }
]
- Add image at
images/locations/my_location.webp
Adding a New Interactable Template
- Create template in
interactables.json:
"my_interactable": {
"id": "my_interactable",
"name": { "en": "🎰 My Object", "es": "Mi Objeto" },
"description": { "en": "Description", "es": "Descripción" },
"image_path": "images/interactables/my_object.webp",
"actions": {
"my_action": {
"id": "my_action",
"label": { "en": "🔨 Do Action", "es": "Hacer Acción" },
"stamina_cost": 3
}
}
}
-
Use in locations in
locations.jsoninteractables -
Add image at
images/interactables/my_object.webp
🎯 Key Game Mechanics
Stamina System
- Base stamina pool (increases with Stamina stat)
- Regenerates passively over time
- Consumed by: Movement, Combat Actions, Interactions, Crafting
- Encumbrance from equipment increases stamina costs
Combat Flow
- Player or NPC initiates combat
- Turn-based with initiative system
- NPCs show intent preview (next planned action)
- Player chooses: Attack, Defend, Use Item, Flee
- Status effects tick each turn
- Combat ends on death or successful flee
Loot System
- Immediate drops from loot_table (on death)
- Corpse harvesting from corpse_loot (requires tools)
- Interactable loot with success/failure mechanics
- Respawn timers for interactables
Crafting Requirements
- Sufficient materials in inventory
- Required tools with durability
- Crafting level unlocked
- Optional: Workbench location tag
📚 Additional Documentation
- CLAUDE.md - Project structure and development commands
- QUICK_REFERENCE.md - API endpoints and architecture
- docker-compose.yml - Infrastructure setup
🚀 Quick Start
# Start the game
docker compose up -d
# View API logs
docker compose logs -f echoes_of_the_ashes_api
# Rebuild after changes
docker compose build && docker compose up -d
Game runs at: http://localhost (PWA) and http://localhost/api (API)
📝 License
All rights reserved. Post-apocalyptic survival simulation for educational purposes.