OpenRoads Spell System
The OpenRoads spell system is a comprehensive, flexible magic system that allows content creators to design spells using YAML and JSON configuration files without writing Go code. The system supports everything from simple damage spells to complex multi-effect magical abilities.
๐ Quick Navigation
New to spells? Start with the Spell Creation Quick Start
Want to learn YAML? Follow the YAML Spell Tutorial
Need hardcoded spells? Check the JSON Spell Guide
Looking for examples? Browse the Custom Spells Directory
Need reference docs? See Spell Effects Reference and Configuration Reference
๐ฏ System Overview
The OpenRoads spell system is built around three core principles:
Accessibility - Content creators can add spells without programming knowledge
Flexibility - Support for simple and complex spell behaviors
Performance - Efficient loading and execution of spells
๐๏ธ Architecture Components
๐ Custom Spell Files (
spells/custom/*.yaml) - Individual spell files (recommended approach)๐ YAML Configuration (
world/spells.yaml) - Legacy bulk spell definitionsโ๏ธ JSON Configuration (
world/spells.json) - Hardcoded spells and overridesโก Effect System - Modular spell effects (damage, heal, summon, teleport, stat modification)
โฑ๏ธ Cooldown System - Per-player, per-spell cooldown tracking
๐ Cast Time System - Spells with casting delays and interruption support
โ Validation System - Element, level, resource, and target requirements
๐ฌ Message System - Customizable feedback for all spell interactions
๐ซ Restriction System - Combat, location, and instance limitations
File Structure
Custom Spell Files (spells/custom/*.yaml) - Recommended
spells/custom/*.yaml) - RecommendedEach spell in its own file:
# spells/custom/fireball.yaml
name: "Fireball"
description: "Hurls a ball of fire at target enemy"
element_required: "fire" # Optional: fire, water, air, earth
min_spell_level: 10
min_phys_level: 0
sp_cost: 15
cast_time: 0 # Seconds (0 = instant)
cooldown: 3 # Seconds
target_type: "enemy" # self, enemy, player, room, none
required_items: [] # List of required items
effects:
- type: "damage"
damage_min: 20
damage_max: 35
damage_type: "fire"
messages:
success: "Your fireball engulfs %s in flames!"
failure_element: "Only fire mages can cast fireball."
restrictions:
combat_only: false
non_combat_only: falseLegacy YAML Spells (world/spells.yaml)
world/spells.yaml)Bulk spell definitions (still supported):
spells:
spell_name:
name: "Display Name"
# ... same properties as aboveJSON Spells (world/spells.json)
world/spells.json){
"spells": {
"spell_name": {
"name": "Display Name",
"custom_handler": "function_name"
}
}
}File Loading Order
The spell system loads files in this order:
Main YAML file (
world/spells.yaml) - Legacy bulk definitionsCustom YAML files (
spells/custom/*.yaml) - Individual spell files (loaded alphabetically)JSON files (
world/spells.json) - Hardcoded spells and overrides
Later files can override earlier ones if they use the same spell name.
Creating Custom Spells
Recommended Approach: Individual Files
Create a new
.yamlfile inspells/custom/Use a descriptive filename:
meteor.yaml,heal.yaml, etc.Define your spell using the single-spell format
Test in-game with the
spellscommand
Example: Creating a New Spell
Create spells/custom/frost_bolt.yaml:
name: "Frost Bolt"
description: "Launches a bolt of freezing energy"
element_required: "water"
min_spell_level: 15
sp_cost: 20
cooldown: 4
target_type: "enemy"
effects:
- type: "damage"
damage_min: 30
damage_max: 45
damage_type: "ice"
messages:
success: "Your frost bolt freezes %s solid!"
failure_element: "Only water mages can cast frost bolt."Benefits of Individual Files
Easy Management: Each spell is self-contained
Version Control: Better Git diffs and merge conflict resolution
Collaboration: Multiple people can work on different spells
Organization: Easy to find and edit specific spells
Hot Reloading: Easier to reload individual spells (future feature)
Spell Properties
Basic Properties
name: Display name of the spelldescription: Detailed descriptionelement_required: Required element (fire, water, air, earth, or empty for any)min_spell_level: Minimum spell level requiredmin_phys_level: Minimum physical level requiredsp_cost: Spell point costcast_time: Casting time in seconds (0 for instant)cooldown: Cooldown time in secondstarget_type: Type of target required
Target Types
self: Targets the casterenemy: Requires an enemy targetplayer: Requires a player targetroom: Requires a room IDnone: No target required
Required Items
List of item names that must be in the caster's inventory:
required_items: ["teleport scroll", "mana crystal"]Effect Types
Damage Effects
effects:
- type: "damage"
damage_min: 20
damage_max: 35
damage_type: "fire" # fire, ice, lightning, earth, etc.Healing Effects
effects:
- type: "heal"
heal_min: 15
heal_max: 25Summoning Effects
effects:
- type: "summon_creature"
creature: "wolf"
duration: -1 # -1 for permanent
max_instances: 1Teleportation Effects
effects:
- type: "teleport"
teleport:
element_room: true # Teleport to element room
target_room: "123" # Specific room
random_room: true # Random room in range
room_range: [1, 100]Stat Modification Effects
effects:
- type: "stat_mod"
stat_mod:
str: 5 # Increase strength by 5
dex: -2 # Decrease dexterity by 2
duration: 300 # Duration in secondsMessages
Standard Messages
success: Successful cast messagemiss: Failed effect messagefailure_element: Wrong element messagefailure_level: Insufficient level messagefailure_sp: Insufficient spell points messagefailure_items: Missing required items messagefailure_cooldown: Spell on cooldown messagefailure_target: Invalid/missing target message
Cast Time Messages
cast_start: Message when casting beginscast_complete: Message when casting completescast_interrupt: Message when casting is interrupted
Broadcast Messages
broadcast_effect: Message sent to other players in room
Message Formatting
Messages support %s placeholders for targets and %d for numbers:
success: "Your fireball engulfs %s in flames!"
failure_level: "You need spell level %d or higher. (Current: %d)"Restrictions
Combat Restrictions
restrictions:
combat_only: true # Can only cast during combat
non_combat_only: true # Cannot cast during combatInstance Restrictions
restrictions:
max_instances: 1 # Maximum active instances of this spellLocation Restrictions
restrictions:
required_rooms: ["1", "2", "3"] # Can only cast in these rooms
forbidden_rooms: ["10", "11"] # Cannot cast in these roomsHardcoded Spells
For complex spells that require custom logic, use the JSON format with a custom_handler:
{
"spells": {
"servant": {
"name": "Aerial Servant",
"custom_handler": "cast_servant"
}
}
}The handler function must be implemented in spell_engine.go in the handleCustomSpell function.
Commands
Player Commands
cast- Show available spellscast <spell>- Cast a spell (if no target required)cast <spell> <target>- Cast a spell with targetspells- Show detailed spell information
Admin Commands
Debug spells are available in spells.json for testing:
debug_heal- Full healdebug_damage <enemy>- High damagedebug_teleport <room>- Instant teleportdebug_summon <room>- Summon debug creature
Examples
Simple Damage Spell
fireball:
name: "Fireball"
description: "Hurls a ball of fire at target enemy"
element_required: "fire"
min_spell_level: 10
sp_cost: 15
cooldown: 3
target_type: "enemy"
effects:
- type: "damage"
damage_min: 20
damage_max: 35
damage_type: "fire"
messages:
success: "Your fireball engulfs %s in flames!"
failure_element: "Only fire mages can cast fireball."Healing Spell with Cast Time
heal:
name: "Heal"
description: "Restores health to the caster"
min_spell_level: 5
sp_cost: 10
cast_time: 2
cooldown: 5
target_type: "self"
effects:
- type: "heal"
heal_min: 15
heal_max: 25
messages:
cast_start: "You begin channeling healing energy..."
success: "You feel your wounds close!"
restrictions:
non_combat_only: trueTeleport Spell with Requirements
teleport:
name: "Teleport"
description: "Teleports to a specified room"
min_spell_level: 20
sp_cost: 35
cast_time: 3
cooldown: 60
target_type: "room"
required_items: ["teleport scroll"]
effects:
- type: "teleport"
messages:
success: "You teleport to room %s!"
failure_items: "You need %s to cast this spell."
restrictions:
non_combat_only: true๐ Hot Reloading
Spells can be reloaded without restarting the server by calling ReloadSpells() from the admin interface or by restarting the spell loading process. This feature is planned for future implementation.
๐ System Integration
The spell system seamlessly integrates with all major game systems:
Core Game Systems
๐ค Player System: Level and element validation, stat modifications
๐ Inventory System: Required item checking and consumption
โ๏ธ Combat System: Damage dealing, healing effects, combat state tracking
๐ World System: Room targeting, teleportation, location restrictions
๐น Enemy System: Enemy targeting, health management, summoning
Advanced Integrations
๐ Routine Engine: Background spell processing, cooldown management
๐พ Save System: Persistent spell cooldowns and effects
๐ Statistics: Spell usage tracking and analytics
๐ Permission System: Admin spell access control
๐ Logging System: Comprehensive spell event logging
๐ Complete Documentation Suite
๐ฏ Getting Started
Spell Creation Quick Start - Create your first spell in 5 minutes
YAML Spell Tutorial - Comprehensive YAML spell creation guide
Custom Spells Directory - Examples and file management
๐ Reference Documentation
Spell Effects Reference - Complete effects documentation
Spell Configuration Reference - All properties and options
JSON Spell Guide - Advanced hardcoded spells
๐ฎ Content Creation
Spell Design Guidelines - Best practices for spell design
Spell Balance Guide - Balancing spells for gameplay
Spell Testing Guide - Testing procedures and tips
๐ Success Stories
The spell system has successfully enabled:
19+ Spells: Currently loaded and functional
8 Custom Files: Individual YAML spell files
Multiple Effect Types: Damage, healing, teleportation, summoning, stat modification
Zero Downtime: Hot-reloadable spell definitions
Easy Maintenance: Non-programmers can create and modify spells
Last updated
Was this helpful?