Flexible race system with slot-based equipment and dragon race

- Expand race TOML schema: 7 stats, body shape (size/weight/custom slots),
  natural armor and attacks with damage types, resistances, traits/disadvantages,
  regen multipliers, vision types, XP rate, guild compatibility
- Replace equipped_weapon/equipped_armor with slot-based HashMap<String, Object>
- Each race defines available equipment slots; default humanoid slots as fallback
- Combat uses natural weapons/armor from race when no gear equipped
- DB migration from old weapon/armor columns to equipped_json
- Add Dragon race: huge body, custom slots (forelegs/wings/tail), fire breath,
  natural armor 8, fire immune, slow XP rate for balance
- Update all existing races with expanded fields (traits, resistances, vision, regen)
- Objects gain optional slot field; kind=weapon/armor still works as fallback
- Update chargen to display race traits, size, natural attacks, vision
- Update stats display to show equipment and natural bonuses separately
- Update TESTING.md and AGENTS.md with race/slot system documentation

Made-with: Cursor
This commit is contained in:
AI Agent
2026-03-14 15:37:20 -06:00
parent 3f164e4697
commit 005c4faf08
18 changed files with 586 additions and 139 deletions

65
world/races/dragon.toml Normal file
View File

@@ -0,0 +1,65 @@
name = "Dragon"
description = "Ancient and mighty, dragons are creatures of immense power and terrifying intellect. Their scaled bodies house furnace-hot hearts and minds sharp enough to match any scholar."
metarace = "draconic"
[stats]
strength = 4
dexterity = -2
constitution = 3
intelligence = 1
wisdom = 1
perception = 2
charisma = -1
[body]
size = "huge"
weight = 2000
slots = ["head", "neck", "torso", "forelegs", "hindlegs", "tail", "wings", "main_hand", "off_hand"]
[natural]
armor = 8
[natural.attacks]
[natural.attacks.bite]
damage = 12
type = "physical"
[natural.attacks.claw]
damage = 8
type = "physical"
[natural.attacks.tail_sweep]
damage = 6
type = "physical"
[natural.attacks.fire_breath]
damage = 15
type = "fire"
cooldown_ticks = 5
traits = ["flight", "fire_breath", "darkvision", "frightful_presence", "ancient_knowledge", "treasure_sense"]
disadvantages = ["conspicuous", "slow_leveling", "large_target", "cannot_enter_small_spaces"]
[resistances]
fire = 0.0
cold = 1.5
physical = 0.7
poison = 0.3
[regen]
hp = 1.5
mana = 1.2
endurance = 0.8
[guild_compatibility]
good = ["sorcerer", "elementalist"]
average = ["warrior", "berserker"]
poor = ["thief", "bard"]
restricted = ["monk"]
[misc]
lifespan = 5000
diet = "carnivore"
xp_rate = 0.7
natural_terrain = ["mountains", "caves", "volcanic"]
vision = ["normal", "darkvision", "infravision", "thermal"]

View File

@@ -7,3 +7,26 @@ dexterity = -1
constitution = 2
intelligence = 0
wisdom = 0
perception = 0
charisma = -1
[body]
size = "small"
weight = 150
traits = ["darkvision", "poison_resistance", "stonecunning"]
[resistances]
poison = 0.5
earth = 0.7
[regen]
hp = 1.2
mana = 0.8
endurance = 1.1
[misc]
lifespan = 350
diet = "omnivore"
xp_rate = 1.0
vision = ["normal", "darkvision"]

View File

@@ -7,3 +7,26 @@ dexterity = 2
constitution = -1
intelligence = 2
wisdom = 0
perception = 1
charisma = 0
[body]
size = "medium"
weight = 130
traits = ["infravision", "magic_affinity"]
disadvantages = ["iron_sensitivity"]
[resistances]
charm = 0.5
[regen]
hp = 0.8
mana = 1.3
endurance = 0.9
[misc]
lifespan = 800
diet = "omnivore"
xp_rate = 0.95
vision = ["normal", "infravision"]

View File

@@ -7,3 +7,25 @@ dexterity = 3
constitution = 0
intelligence = 0
wisdom = 1
perception = 1
charisma = 1
[body]
size = "tiny"
weight = 60
traits = ["lucky", "stealthy", "brave"]
[resistances]
fear = 0.3
[regen]
hp = 1.0
mana = 1.0
endurance = 1.1
[misc]
lifespan = 150
diet = "omnivore"
xp_rate = 0.95
vision = ["normal"]

View File

@@ -7,3 +7,20 @@ dexterity = 0
constitution = 0
intelligence = 0
wisdom = 0
perception = 0
charisma = 1
[body]
size = "medium"
weight = 170
[regen]
hp = 1.0
mana = 1.0
endurance = 1.0
[misc]
lifespan = 80
diet = "omnivore"
xp_rate = 1.0
vision = ["normal"]

View File

@@ -7,3 +7,29 @@ dexterity = 0
constitution = 1
intelligence = -2
wisdom = -1
perception = 0
charisma = -1
[body]
size = "large"
weight = 250
[natural]
armor = 1
traits = ["berserker_rage", "intimidating"]
disadvantages = ["light_sensitivity"]
[resistances]
physical = 0.9
[regen]
hp = 1.3
mana = 0.6
endurance = 1.2
[misc]
lifespan = 60
diet = "carnivore"
xp_rate = 1.05
vision = ["normal", "low_light"]

View File

@@ -2,6 +2,7 @@ name = "Iron Shield"
description = "A dented but serviceable round shield bearing the blacksmith's mark."
room = "town:forge"
kind = "armor"
slot = "off_hand"
takeable = true
[stats]

View File

@@ -2,6 +2,7 @@ name = "Rusty Sword"
description = "A battered iron blade with a cracked leather grip. It's seen better days."
room = "town:cellar"
kind = "weapon"
slot = "main_hand"
takeable = true
[stats]