piclets / battle_system_design.md
Fraser's picture
closer
946e7bf
# Pictuary Battle System Design Document
## Overview
This document defines a new programmatic battle system for Pictuary that replaces the current description-based approach with executable building blocks. The design is inspired by Pokemon Emerald's sophisticated battle mechanics while being simplified for our use case.
## Core Philosophy
The battle system is built on **composable building blocks** that can be combined to create unique and dynamic effects. Each action and ability is defined using simple, atomic operations that can be chained together to create complex behaviors.
## JSON Schema for `generateStats`
### Monster Definition
```json
{
"name": "Zephyr Sprite",
"description": "A mysterious floating creature that manipulates wind currents",
"tier": "medium",
"primaryType": "space",
"secondaryType": null,
"baseStats": {
"hp": 65,
"attack": 85,
"defense": 40,
"speed": 90
},
"nature": "hasty",
"specialAbility": {
"name": "Wind Currents",
"description": "Gains +25% speed when opponent uses a contact move",
"trigger": "onOpponentContactMove",
"effects": [
{
"type": "modifyStats",
"target": "self",
"stats": { "speed": "increase" }
}
]
},
"movepool": [
{
"name": "Gust Strike",
"type": "space",
"power": 65,
"accuracy": 95,
"pp": 20,
"priority": 0,
"flags": ["contact"],
"effects": [
{
"type": "damage",
"target": "opponent",
"amount": "normal"
}
]
},
{
"name": "Piercing Gale",
"type": "space",
"power": 80,
"accuracy": 85,
"pp": 15,
"priority": 0,
"flags": [],
"effects": [
{
"type": "damage",
"target": "opponent",
"amount": "normal"
},
{
"type": "modifyStats",
"target": "self",
"stats": { "accuracy": "decrease" },
"condition": "afterUse"
}
]
},
{
"name": "Tailwind Boost",
"type": "space",
"power": 0,
"accuracy": 100,
"pp": 10,
"priority": 1,
"flags": [],
"effects": [
{
"type": "modifyStats",
"target": "self",
"stats": { "speed": "greatly_increase" }
}
]
},
{
"name": "Reckless Dive",
"type": "space",
"power": 120,
"accuracy": 80,
"pp": 5,
"priority": 0,
"flags": ["contact", "reckless"],
"effects": [
{
"type": "damage",
"target": "opponent",
"amount": "normal"
},
{
"type": "damage",
"target": "self",
"formula": "recoil",
"value": 0.25
}
]
}
]
}
```
## Building Blocks System
### Effect Types
All battle effects are built from these atomic operations:
#### 1. **damage**
```json
{
"type": "damage",
"target": "opponent" | "self" | "all" | "allies",
"amount": "weak" | "normal" | "strong" | "extreme"
}
```
#### 2. **modifyStats**
```json
{
"type": "modifyStats",
"target": "self" | "opponent" | "all",
"stats": {
"attack": "increase", // "increase" | "decrease" | "greatly_increase" | "greatly_decrease"
"defense": "decrease",
"speed": "greatly_increase",
"accuracy": "decrease"
},
"condition": "always" | "onHit" | "afterUse" | "ifCritical"
}
```
**Standard Stat Modification Levels:**
- **increase**: +25% (1.25x multiplier)
- **decrease**: -25% (0.75x multiplier)
- **greatly_increase**: +50% (1.5x multiplier)
- **greatly_decrease**: -50% (0.5x multiplier)
#### 3. **applyStatus**
```json
{
"type": "applyStatus",
"target": "opponent" | "self",
"status": "burn" | "freeze" | "paralyze" | "poison" | "sleep" | "confuse"
}
```
#### 4. **heal**
```json
{
"type": "heal",
"target": "self" | "ally",
"amount": "small" | "medium" | "large" | "full"
}
```
#### 5. **manipulatePP**
```json
{
"type": "manipulatePP",
"target": "opponent",
"action": "drain" | "restore" | "disable",
"amount": "small" | "medium" | "large"
}
```
#### 6. **fieldEffect**
```json
{
"type": "fieldEffect",
"effect": "reflect" | "lightScreen" | "spikes" | "healingMist" | "toxicSpikes",
"target": "playerSide" | "opponentSide" | "field",
"stackable": false
}
```
#### 7. **counter**
```json
{
"type": "counter",
"counterType": "physical" | "special" | "any",
"strength": "weak" | "normal" | "strong"
}
```
#### 8. **priority**
```json
{
"type": "priority",
"target": "self",
"value": 1, // Priority bracket (-5 to +5)
"condition": "ifLowHp" | "always"
}
```
#### 9. **removeStatus**
```json
{
"type": "removeStatus",
"target": "self" | "opponent" | "allies",
"status": "burn" | "freeze" | "paralyze" | "poison" | "sleep" | "confuse"
}
```
### Move Flags
Moves can have flags that affect how they interact with abilities and other mechanics:
#### **Combat Flags**
- **contact**: Move makes physical contact (triggers contact abilities like Rough Skin)
- **bite**: Biting move (affected by Strong Jaw ability, blocked by certain defenses)
- **punch**: Punching move (affected by Iron Fist ability)
- **sound**: Sound-based move (bypasses Substitute, blocked by Soundproof)
- **explosive**: Explosive move (affected by Damp ability)
- **draining**: Move that drains HP (affected by Liquid Ooze ability)
- **ground**: Ground-based attack (blocked by Sky Dancer, Levitate abilities)
#### **Priority Flags**
- **priority**: Move has natural priority (+1 to +5)
- **lowPriority**: Move has negative priority (-1 to -5)
#### **Special Mechanics**
- **charging**: Move requires charging turn (Sky Attack, Solar Beam)
- **recharge**: User must recharge next turn (Hyper Beam)
- **multiHit**: Hits multiple times (2-5 hits)
- **twoTurn**: Takes two turns to execute
- **sacrifice**: Move involves self-sacrifice or major cost
- **gambling**: Move has random outcomes
- **reckless**: Move gains power but has drawbacks (affected by Reckless ability)
#### **Interaction Flags**
- **reflectable**: Can be reflected by Magic Coat
- **snatchable**: Can be stolen by Snatch
- **copyable**: Can be copied by Mirror Move
- **protectable**: Blocked by Protect/Detect
- **bypassProtect**: Ignores Protect/Detect
### Triggers and Conditions
Effects can be triggered by various battle events:
- **always**: Effect always applies when move is used
- **onHit**: Effect applies only if the move hits
- **afterUse**: Effect applies after move execution regardless of hit/miss
- **onCritical**: Effect applies only on critical hits
- **ifLowHp**: Effect applies if user's HP < 25%
- **ifHighHp**: Effect applies if user's HP > 75%
- **onOpponentContactMove**: Trigger when opponent uses a contact move
- **endOfTurn**: Effect applies at the end of each turn
- **onSwitchIn**: Effect applies when Piclet enters battle
- **afterKO**: Effect applies after knocking out an opponent
### Target Specification
- **self**: The move user
- **opponent**: The target opponent
- **all**: All Piclets in battle
- **allies**: All allied Piclets (in team battles)
- **playerSide**: Player's side of the field
- **opponentSide**: Opponent's side of the field
- **field**: Entire battlefield
## Special Abilities
Special abilities are passive traits that can fundamentally alter battle mechanics. They can use standard effect building blocks OR modify core game mechanics directly.
### Mechanic Modifications
Special abilities can override or alter fundamental battle mechanics:
#### 9. **mechanicOverride**
```json
{
"type": "mechanicOverride",
"mechanic": "criticalHits" | "statusImmunity" | "damageReflection" | "healingInversion" | "priorityOverride" | "accuracyBypass" | "typeImmunity" | "contactDamage" | "drainInversion" | "weatherImmunity",
"condition": "always" | "ifLowHp" | "whenStatusAfflicted" | "vsPhysical" | "vsSpecial",
"value": true | false | "invert" | "double" | "absorb" | "reflect"
}
```
**Mechanic Types:**
- **criticalHits**: `false` = cannot be crit, `true` = always crit, `"double"` = 2x crit rate
- **statusImmunity**: Array of status types to be immune to
- **damageReflection**: Reflects % of damage back to attacker
- **healingInversion**: Healing effects cause damage instead
- **priorityOverride**: Always goes first/last regardless of speed
- **accuracyBypass**: Moves cannot miss this Piclet
- **typeImmunity**: Immune to specific damage types
- **contactDamage**: Attackers take damage when using contact moves
- **drainInversion**: HP draining moves heal the target instead
- **weatherImmunity**: Unaffected by weather damage/effects
- **flagImmunity**: Immune to moves with specific flags
- **flagWeakness**: Takes extra damage from moves with specific flags
- **flagResistance**: Takes reduced damage from moves with specific flags
### Advanced Ability Examples
#### 1. **Shell Armor** - Cannot be critically hit
```json
{
"name": "Shell Armor",
"description": "Hard shell prevents critical hits",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "criticalHits",
"condition": "always",
"value": false
}
]
}
```
#### 2. **Rough Skin** - Contact moves damage attacker
```json
{
"name": "Rough Skin",
"description": "Rough skin damages attackers on contact",
"triggers": [
{
"event": "onContactDamage",
"effects": [
{
"type": "damage",
"target": "attacker",
"formula": "fixed",
"value": 12
}
]
}
]
}
```
#### 3. **Photosynthesis** - Healed by flora-type moves
```json
{
"name": "Photosynthesis",
"description": "Absorbs flora-type moves to restore HP",
"triggers": [
{
"event": "onDamageTaken",
"condition": "ifMoveType:flora",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "damageAbsorption",
"value": "absorb"
},
{
"type": "heal",
"target": "self",
"amount": "percentage",
"value": 25
}
]
}
]
}
```
#### 4. **Poison Heal** - Healed by poison instead of damaged
```json
{
"name": "Poison Heal",
"description": "Poison heals instead of damages",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "statusEffect:poison",
"value": "invert"
}
]
}
```
#### 5. **Wonder Guard** - Only super-effective moves can hit
```json
{
"name": "Wonder Guard",
"description": "Only super-effective moves deal damage",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "damageCalculation",
"condition": "ifNotSuperEffective",
"value": false
}
]
}
```
#### 6. **Levitate** - Immune to ground-type moves
```json
{
"name": "Levitate",
"description": "Floating ability makes ground moves miss",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "typeImmunity",
"value": ["ground"]
}
]
}
```
#### 7. **Vampiric** - Drain moves damage the drainer
```json
{
"name": "Vampiric",
"description": "Cursed blood damages those who try to drain it",
"triggers": [
{
"event": "onHPDrained",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "drainInversion",
"value": true
},
{
"type": "damage",
"target": "attacker",
"formula": "fixed",
"value": 20
}
]
}
]
}
```
#### 8. **Insomnia** - Cannot be put to sleep
```json
{
"name": "Insomnia",
"description": "Prevents sleep status",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "statusImmunity",
"value": ["sleep"]
}
]
}
```
#### 9. **Prankster** - Status moves have +1 priority
```json
{
"name": "Prankster",
"description": "Status moves gain priority",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "priorityOverride",
"condition": "ifStatusMove",
"value": 1
}
]
}
```
#### 10. **Magic Bounce** - Reflects status moves
```json
{
"name": "Magic Bounce",
"description": "Reflects status moves back at the user",
"triggers": [
{
"event": "onStatusMoveTargeted",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "targetRedirection",
"value": "reflect"
}
]
}
]
}
```
### Complex Multi-Mechanic Abilities
#### **Protean** - Changes type to match moves used
```json
{
"name": "Protean",
"description": "Changes type to match the move being used",
"triggers": [
{
"event": "beforeMoveUse",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "typeChange",
"value": "matchMoveType"
}
]
}
]
}
```
#### **Contrary** - Stat changes are reversed
```json
{
"name": "Contrary",
"description": "Stat changes have the opposite effect",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "statModification",
"value": "invert"
}
]
}
```
### Status-Specific Abilities
#### **Frost Walker** - Alternative effect when frozen
```json
{
"name": "Frost Walker",
"description": "Instead of being frozen, gains +50% attack",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "statusReplacement:freeze",
"value": {
"type": "modifyStats",
"target": "self",
"stats": { "attack": "greatly_increase" }
}
}
]
}
```
#### **Glacial Birth** - Starts battle frozen
```json
{
"name": "Glacial Birth",
"description": "Enters battle in a frozen state but gains defensive bonuses",
"triggers": [
{
"event": "onSwitchIn",
"effects": [
{
"type": "applyStatus",
"target": "self",
"status": "freeze",
"chance": 100
},
{
"type": "modifyStats",
"target": "self",
"stats": { "defense": "greatly_increase" },
"condition": "whileFrozen"
}
]
}
]
}
```
#### **Cryogenic Touch** - Freezes enemy on contact
```json
{
"name": "Cryogenic Touch",
"description": "Contact moves have a chance to freeze the attacker",
"triggers": [
{
"event": "onContactDamage",
"effects": [
{
"type": "applyStatus",
"target": "attacker",
"status": "freeze",
"chance": 30
}
]
}
]
}
```
#### **Slumber Heal** - Heal when asleep
```json
{
"name": "Slumber Heal",
"description": "Restores HP while sleeping instead of being unable to act",
"triggers": [
{
"event": "endOfTurn",
"condition": "ifStatus:sleep",
"effects": [
{
"type": "heal",
"target": "self",
"amount": "percentage",
"value": 15
}
]
}
]
}
```
#### **Toxic Skin** - Poisons on contact
```json
{
"name": "Toxic Skin",
"description": "Physical contact poisons the attacker",
"triggers": [
{
"event": "onContactDamage",
"effects": [
{
"type": "applyStatus",
"target": "attacker",
"status": "poison",
"chance": 50
}
]
}
]
}
```
#### **Paralytic Aura** - Starts battle with paralyzed enemy
```json
{
"name": "Paralytic Aura",
"description": "Intimidating presence paralyzes the opponent upon entry",
"triggers": [
{
"event": "onSwitchIn",
"effects": [
{
"type": "applyStatus",
"target": "opponent",
"status": "paralyze",
"chance": 75
}
]
}
]
}
```
#### **Burn Boost** - Powered up when burned
```json
{
"name": "Burn Boost",
"description": "Fire damage energizes this Piclet, increasing attack power",
"triggers": [
{
"event": "onStatusInflicted",
"condition": "ifStatus:burn",
"effects": [
{
"type": "modifyStats",
"target": "self",
"stats": { "attack": "greatly_increase" }
}
]
}
]
}
```
#### **Confusion Clarity** - Cannot be confused, clears team confusion
```json
{
"name": "Confusion Clarity",
"description": "Clear mind prevents confusion and helps allies focus",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "statusImmunity",
"value": ["confuse"]
}
],
"triggers": [
{
"event": "onSwitchIn",
"effects": [
{
"type": "removeStatus",
"target": "allies",
"status": "confuse"
}
]
}
]
}
```
### Flag-Based Immunities and Weaknesses
#### **Sky Dancer** - Immune to ground-flagged attacks
```json
{
"name": "Sky Dancer",
"description": "Floating in air, immune to ground-based attacks",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "flagImmunity",
"value": ["ground"]
}
]
}
```
#### **Sound Barrier** - Immune to sound attacks
```json
{
"name": "Sound Barrier",
"description": "Natural sound dampening prevents sound-based moves",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "flagImmunity",
"value": ["sound"]
}
]
}
```
#### **Soft Body** - Weak to punch moves, immune to explosive
```json
{
"name": "Soft Body",
"description": "Gelatinous form absorbs explosions but vulnerable to direct hits",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "flagImmunity",
"value": ["explosive"]
},
{
"type": "mechanicOverride",
"mechanic": "flagWeakness",
"value": ["punch"]
}
]
}
```
#### **Ethereal Form** - Immune to contact moves
```json
{
"name": "Ethereal Form",
"description": "Ghostly body cannot be touched by physical contact",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "flagImmunity",
"value": ["contact"]
}
]
}
```
#### **Fragile Shell** - Takes double damage from explosive moves
```json
{
"name": "Fragile Shell",
"description": "Hard shell provides defense but shatters from explosions",
"effects": [
{
"type": "modifyStats",
"target": "self",
"stats": { "defense": "increase" }
},
{
"type": "mechanicOverride",
"mechanic": "flagWeakness",
"value": ["explosive"]
}
]
}
```
#### **Liquid Body** - Immune to punch/bite, weak to sound
```json
{
"name": "Liquid Body",
"description": "Fluid form flows around physical attacks but resonates with sound",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "flagImmunity",
"value": ["punch", "bite"]
},
{
"type": "mechanicOverride",
"mechanic": "flagWeakness",
"value": ["sound"]
}
]
}
```
#### **Thick Hide** - Reduced damage from contact moves
```json
{
"name": "Thick Hide",
"description": "Tough skin reduces impact from physical contact",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "flagResistance",
"value": ["contact"]
}
]
}
```
### Event Triggers for Abilities
Extended list of trigger events:
- **onDamageTaken**: When this Piclet takes damage
- **onDamageDealt**: When this Piclet deals damage
- **onContactDamage**: When hit by a contact move
- **onStatusInflicted**: When a status is applied to this Piclet
- **onStatusMove**: When targeted by a status move
- **onCriticalHit**: When this Piclet lands/receives a critical hit
- **onHPDrained**: When HP is drained from this Piclet
- **onKO**: When this Piclet knocks out an opponent
- **onSwitchIn**: When this Piclet enters battle
- **onSwitchOut**: When this Piclet leaves battle
- **onWeatherChange**: When battlefield weather changes
- **beforeMoveUse**: Just before this Piclet uses a move
- **afterMoveUse**: Just after this Piclet uses a move
- **onLowHP**: When HP drops below 25%
- **onFullHP**: When HP is at 100%
## Move Categories and Interactions
### Physical vs Special Attacks
- **Physical**: Direct combat using attack vs defense stats, affected by contact abilities
- **Special**: Ranged/magical attacks using attack vs defense stats, no contact interactions
- **Status**: No damage, focus on effects and stat manipulation
### Move Flags
Moves can have flags that affect interactions:
- **contact**: Triggers contact-based abilities (like Rough Skin)
- **sound**: Affects sound-based interactions
- **bite**: Triggers bite-specific abilities
- **punch**: Triggers punch-specific abilities
- **reckless**: Increased power but with drawbacks
- **priority**: Natural priority moves
- **multiHit**: Hits multiple times
- **charging**: Requires charging turn
## Dynamic Combinations
### Power vs Risk Tradeoffs
1. **High Power, Self-Debuff**
```json
{
"name": "Berserker Strike",
"power": 130,
"effects": [
{
"type": "damage",
"target": "opponent",
"formula": "standard"
},
{
"type": "modifyStats",
"target": "self",
"stats": { "defense": "greatly_decrease" },
"condition": "afterUse"
}
]
}
```
2. **Accuracy Trade for Power**
```json
{
"name": "Wild Swing",
"power": 100,
"accuracy": 70,
"effects": [
{
"type": "damage",
"target": "opponent",
"formula": "standard"
},
{
"type": "modifyStats",
"target": "self",
"stats": { "accuracy": "decrease" },
"condition": "afterUse"
}
]
}
```
3. **Conditional Power Scaling**
```json
{
"name": "Revenge Strike",
"power": 60,
"effects": [
{
"type": "damage",
"target": "opponent",
"amount": "normal"
},
{
"type": "damage",
"target": "opponent",
"amount": "strong",
"condition": "ifDamagedThisTurn"
}
]
}
```
### Extreme Risk-Reward Moves
Powerful moves with dramatic sacrifices create high-stakes decision making:
#### **Self Destruct** - Ultimate sacrifice for massive damage
```json
{
"name": "Self Destruct",
"power": 200,
"accuracy": 100,
"pp": 1,
"priority": 0,
"flags": ["explosive", "contact"],
"effects": [
{
"type": "damage",
"target": "all",
"formula": "standard",
"multiplier": 1.5
},
{
"type": "damage",
"target": "self",
"formula": "fixed",
"value": 9999,
"condition": "afterUse"
}
]
}
```
#### **Life Drain Overload** - Heal massively but lose stats permanently
```json
{
"name": "Life Drain Overload",
"power": 0,
"accuracy": 100,
"pp": 3,
"priority": 0,
"flags": ["draining"],
"effects": [
{
"type": "heal",
"target": "self",
"amount": "percentage",
"value": 75
},
{
"type": "modifyStats",
"target": "self",
"stats": { "attack": "greatly_decrease" },
"condition": "afterUse"
}
]
}
```
#### **Berserker's End** - More damage as HP gets lower, but can't heal
```json
{
"name": "Berserker's End",
"power": 80,
"accuracy": 95,
"pp": 10,
"priority": 0,
"flags": ["contact", "reckless"],
"effects": [
{
"type": "damage",
"target": "opponent",
"amount": "normal"
},
{
"type": "damage",
"target": "opponent",
"amount": "strong",
"condition": "ifLowHp"
},
{
"type": "mechanicOverride",
"target": "self",
"mechanic": "healingBlocked",
"value": true
}
]
}
```
#### **Mirror Shatter** - Reflect all damage taken this turn back doubled
```json
{
"name": "Mirror Shatter",
"power": 0,
"accuracy": 100,
"pp": 5,
"priority": 4,
"flags": ["priority"],
"effects": [
{
"type": "mechanicOverride",
"target": "self",
"mechanic": "damageReflection",
"value": "double",
"condition": "thisTurn"
},
{
"type": "modifyStats",
"target": "self",
"stats": { "defense": "greatly_decrease", "fieldDefense": "greatly_decrease" },
"condition": "afterUse"
}
]
}
```
#### **Temporal Overload** - Act twice next turn, skip following turn
```json
{
"name": "Temporal Overload",
"power": 0,
"accuracy": 100,
"pp": 2,
"priority": 0,
"flags": ["temporal"],
"effects": [
{
"type": "mechanicOverride",
"target": "self",
"mechanic": "extraTurn",
"value": true,
"condition": "nextTurn"
},
{
"type": "applyStatus",
"target": "self",
"status": "paralyzed",
"chance": 100,
"condition": "turnAfterNext"
}
]
}
```
#### **Blood Pact** - Sacrifice HP to double all damage dealt
```json
{
"name": "Blood Pact",
"power": 0,
"accuracy": 100,
"pp": 3,
"priority": 0,
"flags": ["sacrifice"],
"effects": [
{
"type": "damage",
"target": "self",
"formula": "percentage",
"value": 50
},
{
"type": "mechanicOverride",
"target": "self",
"mechanic": "damageMultiplier",
"value": 2.0,
"condition": "restOfBattle"
}
]
}
```
#### **Soul Burn** - Massive special attack that burns user's PP
```json
{
"name": "Soul Burn",
"power": 150,
"accuracy": 90,
"pp": 5,
"priority": 0,
"flags": ["burning"],
"effects": [
{
"type": "damage",
"target": "opponent",
"formula": "standard"
},
{
"type": "manipulatePP",
"target": "self",
"action": "drain",
"amount": 3,
"targetMove": "random",
"condition": "afterUse"
}
]
}
```
#### **Cursed Gambit** - Random effect: heal fully OR faint instantly
```json
{
"name": "Cursed Gambit",
"power": 0,
"accuracy": 100,
"pp": 1,
"priority": 0,
"flags": ["gambling", "cursed"],
"effects": [
{
"type": "heal",
"target": "self",
"amount": "percentage",
"value": 100,
"condition": "ifLucky50"
},
{
"type": "damage",
"target": "self",
"formula": "fixed",
"value": 9999,
"condition": "ifUnlucky50"
}
]
}
```
#### **Apocalypse Strike** - Massive damage to all, but user becomes vulnerable
```json
{
"name": "Apocalypse Strike",
"power": 120,
"accuracy": 85,
"pp": 1,
"priority": 0,
"flags": ["apocalyptic"],
"effects": [
{
"type": "damage",
"target": "all",
"formula": "standard",
"multiplier": 1.3
},
{
"type": "mechanicOverride",
"target": "self",
"mechanic": "criticalHits",
"value": "alwaysReceive",
"condition": "restOfBattle"
},
{
"type": "modifyStats",
"target": "self",
"stats": { "defense": "greatly_decrease", "fieldDefense": "greatly_decrease" }
}
]
}
```
### Multi-Stage Effects
Complex moves can have multiple phases:
```json
{
"name": "Charging Blast",
"power": 120,
"accuracy": 90,
"pp": 5,
"flags": ["charging"],
"effects": [
{
"type": "modifyStats",
"target": "self",
"stats": { "defense": "increase" },
"condition": "onCharging"
},
{
"type": "damage",
"target": "opponent",
"formula": "standard",
"condition": "afterCharging"
},
{
"type": "applyStatus",
"target": "self",
"status": "vulnerable",
"condition": "afterCharging"
}
]
}
```
## Implementation Benefits
### 1. **Programmatic Execution**
- All effects are defined as data structures
- Battle engine can execute any combination of effects
- No hardcoded move implementations needed
### 2. **Infinite Variety**
- Mix and match building blocks for unique moves
- Same building blocks create vastly different strategies
- Easy to balance by adjusting values
### 3. **Clear Tradeoffs**
- Every powerful effect has a drawback
- Players must weigh risk vs reward
- Multiple viable strategies emerge
### 4. **Emergent Complexity**
- Simple rules create complex interactions
- Abilities interact with moves in unexpected ways
- Meta-game develops naturally
### 5. **Easy Extension**
- New effect types can be added seamlessly
- New conditions and triggers expand possibilities
- Backward compatible with existing definitions
## Battle Flow Integration
The battle system processes effects in this order:
1. **Pre-Move Phase**: Priority calculation, ability triggers
2. **Move Execution**: Damage calculation, hit/miss determination
3. **Effect Application**: Apply all move effects based on conditions
4. **Post-Move Phase**: End-of-turn abilities, status effects
5. **Turn Cleanup**: Duration decrements, expired effect removal
This ensures predictable interaction resolution while allowing for complex chains of effects.
## Balancing Philosophy
The system encourages diverse strategies through:
- **No "strictly better" moves**: Every powerful move has meaningful drawbacks
- **Type diversity matters**: Different types offer different utility patterns
- **Timing is crucial**: When to use high-risk moves becomes strategic
- **Adaptation required**: Static strategies are punishable by counter-play
This creates a dynamic battle system where player skill and strategic thinking matter more than raw stat advantages.
## Complete System Reference
### Available Conditions
- **always**: Effect always applies when triggered
- **onHit**: Effect applies only if the move hits successfully
- **afterUse**: Effect applies after move execution regardless of hit/miss
- **onCritical**: Effect applies only on critical hits
- **ifLowHp**: Effect applies if user's HP < 25%
- **ifHighHp**: Effect applies if user's HP > 75%
- **thisTurn**: Effect lasts only for the current turn
- **nextTurn**: Effect applies on the next turn
- **turnAfterNext**: Effect applies two turns from now
- **restOfBattle**: Effect persists for the remainder of the battle
- **onCharging**: Effect applies during charging phase of two-turn moves
- **afterCharging**: Effect applies after charging phase completes
- **ifDamagedThisTurn**: Effect applies if user took damage this turn
- **ifNotSuperEffective**: Effect applies if move would not be super effective
- **ifMoveType:[type]**: Effect applies if move is of specified type
- **ifStatus:[status]**: Effect applies if user has specified status
- **whileFrozen**: Effect applies while user is frozen
- **ifWeather:[weather]**: Effect applies if weather condition is active
- **ifStatusMove**: Effect applies if move is a status move
- **ifLucky50**: Effect applies on 50% random chance (good outcome)
- **ifUnlucky50**: Effect applies on 50% random chance (bad outcome)
### Available Mechanic Overrides
- **criticalHits**: Modify critical hit behavior
- **statusImmunity**: Immunity to specific status effects
- **statusReplacement:[status]**: Replace status effect with different effect
- **damageReflection**: Reflect damage back to attacker
- **damageAbsorption**: Absorb damage of specific types
- **damageCalculation**: Modify damage calculation rules
- **damageMultiplier**: Multiply all damage dealt
- **healingInversion**: Healing effects cause damage instead
- **healingBlocked**: Prevent all healing
- **priorityOverride**: Override move priority
- **accuracyBypass**: Moves cannot miss
- **typeImmunity**: Immunity to specific damage types
- **typeChange**: Change Piclet's type
- **contactDamage**: Deal damage to contact move users
- **drainInversion**: HP drain heals target instead
- **weatherImmunity**: Immunity to weather effects
- **flagImmunity**: Immunity to moves with specific flags
- **flagWeakness**: Extra damage from moves with specific flags
- **flagResistance**: Reduced damage from moves with specific flags
- **statModification**: Modify how stat changes work
- **targetRedirection**: Change move targets
- **extraTurn**: Grant additional turns
### Available Event Triggers
- **onDamageTaken**: When this Piclet takes damage
- **onDamageDealt**: When this Piclet deals damage
- **onContactDamage**: When hit by a contact move
- **onStatusInflicted**: When a status is applied to this Piclet
- **onStatusMove**: When targeted by a status move
- **onStatusMoveTargeted**: When targeted by opponent's status move
- **onCriticalHit**: When this Piclet lands/receives a critical hit
- **onHPDrained**: When HP is drained from this Piclet
- **onKO**: When this Piclet knocks out an opponent
- **onSwitchIn**: When this Piclet enters battle
- **onSwitchOut**: When this Piclet leaves battle
- **onWeatherChange**: When battlefield weather changes
- **beforeMoveUse**: Just before this Piclet uses a move
- **afterMoveUse**: Just after this Piclet uses a move
- **onLowHP**: When HP drops below 25%
- **onFullHP**: When HP is at 100%
- **endOfTurn**: At the end of each turn
- **onOpponentContactMove**: When opponent uses contact move
### Available Status Effects
- **burn**: Ongoing fire damage
- **freeze**: Cannot act (unless replaced by ability)
- **paralyze**: Speed reduction and chance to be unable to move
- **poison**: Ongoing poison damage
- **sleep**: Cannot act for several turns
- **confuse**: Chance to hit self instead of target
### Available Move Flags
- **contact**: Makes physical contact
- **bite**: Biting attack
- **punch**: Punching attack
- **sound**: Sound-based attack
- **explosive**: Explosive attack
- **draining**: Drains HP from target
- **ground**: Ground-based attack
- **priority**: Has natural priority
- **lowPriority**: Has negative priority
- **charging**: Requires charging turn
- **recharge**: User must recharge after
- **multiHit**: Hits multiple times
- **twoTurn**: Takes two turns to execute
- **sacrifice**: Involves self-sacrifice
- **gambling**: Has random outcomes
- **reckless**: High power with drawbacks
- **reflectable**: Can be reflected
- **snatchable**: Can be stolen
- **copyable**: Can be copied
- **protectable**: Blocked by Protect
- **bypassProtect**: Ignores Protect
### Available Types
Types correspond to photographed objects in the real world:
- **beast** 🐾: Vertebrate wildlife — mammals, birds, reptiles. Raw physicality, instincts, and region-based variants
- **bug** 🐛: Arthropods great and small: butterflies, beetles, mantises. Agile swarms, precision strikes, metamorphosis
- **aquatic** 🌊: Life that swims, dives, sloshes: fish, octopus, ink-creatures, sentient puddles. Masters of tides and pressure
- **flora** 🌿: Plants and fungi captured in bloom or decay. Growth, spores, vines, seasonal shifts
- **mineral** 🪨: Stones, crystals, metals shaped by earth's depths. High durability, reflective armor, seismic shocks
- **space** ✨: Stars, moon, cosmic objects not of this world. Stellar energy, gravitational effects, void manipulation
- **machina** ⚙️: Engineered devices from gadgets to heavy machinery. Gears, circuits, drones, power surges
- **structure** 🏛️: Buildings, bridges, monuments, ruins as titans. Fortification, terrain shaping, zone denial
- **culture** 🎨: Art, fashion, toys, written symbols. Buffs, debuffs, illusion, story-driven interactions
- **cuisine** 🍣: Dishes, drinks, culinary artistry. Flavors, aromas, temperature shifts for support or offense
- **normal** 👤: Attack type only (no Piclets are Normal type). Represents mundane, non-specialized attacks
### Type Effectiveness Chart
| ATK \ DEF | 🐾 Beast | 🐛 Bug | 🌊 Aquatic | 🌿 Flora | 🪨 Mineral | ✨Space | ⚙️ Machina | 🏛️ Structure | 🎨 Culture | 🍣 Cuisine |
| ----------------- | :------: | :----: | :--------: | :------: | :--------: | :------: | :--------: | :-----------: | :--------: | :--------: |
| **🐾 Beast** | 1 | **×2** | 1 | 1 | ×½ | **0** | ×½ | ×½ | **×2** | **×2** |
| **🐛 Bug** | **×2** | 1 | 1 | **×2** | ×½ | ×½ | 1 | **0** | ×½ | ×½ |
| **🌊 Aquatic** | 1 | 1 | 1 | ×½ | **×2** | **×2** | **×2** | 1 | ×½ | ×½ |
| **🌿 Flora** | 1 | **×2** | **×2** | 1 | **×2** | ×½ | **0** | **×2** | 1 | ×½ |
| **🪨 Mineral** | **×2** | **×2** | ×½ | ×½ | 1 | ×½ | **×2** | 1 | 1 | **0** |
| **✨ Space** | **0** | **×2** | ×½ | **×2** | **×2** | 1 | ×½ | **×2** | ×½ | ×½ |
| **⚙️ Machina** | **×2** | ×½ | ×½ | **×2** | ×½ | ×½ | 1 | **×2** | 1 | 1 |
| **🏛️ Structure** | ×½ | ×½ | 1 | 1 | 1 | ×½ | **×2** | 1 | **×2** | **×2** |
| **🎨 Culture** | ×½ | ×½ | 1 | 1 | **0** | **×2** | **×2** | **×2** | 1 | ×½ |
| **🍣 Cuisine** | **×2** | ×½ | ×½ | 1 | **0** | **×2** | 1 | ×½ | **×2** | 1 |
| **👤 Normal** | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 |
**Legend:**
- **×2** = Super effective (2x damage)
- **×½** = Not very effective (0.5x damage)
- **0** = No effect (0x damage)
- **1** = Normal effectiveness (1x damage)
## JSON Schema
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Piclet Definition",
"required": ["name", "description", "tier", "primaryType", "baseStats", "nature", "specialAbility", "movepool"],
"properties": {
"name": {
"type": "string",
"description": "The name of the Piclet"
},
"description": {
"type": "string",
"description": "Flavor text describing the Piclet"
},
"tier": {
"type": "string",
"enum": ["low", "medium", "high", "legendary"],
"description": "Power tier of the Piclet"
},
"primaryType": {
"type": "string",
"enum": ["beast", "bug", "aquatic", "flora", "mineral", "space", "machina", "structure", "culture", "cuisine"],
"description": "Primary type of the Piclet"
},
"secondaryType": {
"type": ["string", "null"],
"enum": ["beast", "bug", "aquatic", "flora", "mineral", "space", "machina", "structure", "culture", "cuisine", null],
"description": "Optional secondary type"
},
"baseStats": {
"type": "object",
"required": ["hp", "attack", "defense", "speed"],
"properties": {
"hp": {"type": "integer", "minimum": 1, "maximum": 255},
"attack": {"type": "integer", "minimum": 1, "maximum": 255},
"defense": {"type": "integer", "minimum": 1, "maximum": 255},
"speed": {"type": "integer", "minimum": 1, "maximum": 255}
},
"additionalProperties": false
},
"nature": {
"type": "string",
"description": "Personality trait affecting stats or behavior"
},
"specialAbility": {
"$ref": "#/definitions/SpecialAbility"
},
"movepool": {
"type": "array",
"items": {"$ref": "#/definitions/Move"},
"minItems": 1,
"maxItems": 8
}
},
"additionalProperties": false,
"definitions": {
"SpecialAbility": {
"type": "object",
"required": ["name", "description"],
"properties": {
"name": {"type": "string"},
"description": {"type": "string"},
"effects": {
"type": "array",
"items": {"$ref": "#/definitions/Effect"}
},
"triggers": {
"type": "array",
"items": {"$ref": "#/definitions/Trigger"}
}
},
"additionalProperties": false
},
"Move": {
"type": "object",
"required": ["name", "type", "power", "accuracy", "pp", "priority", "flags", "effects"],
"properties": {
"name": {"type": "string"},
"type": {
"type": "string",
"enum": ["beast", "bug", "aquatic", "flora", "mineral", "space", "machina", "structure", "culture", "cuisine", "normal"]
},
"power": {"type": "integer", "minimum": 0, "maximum": 250},
"accuracy": {"type": "integer", "minimum": 0, "maximum": 100},
"pp": {"type": "integer", "minimum": 1, "maximum": 50},
"priority": {"type": "integer", "minimum": -5, "maximum": 5},
"flags": {
"type": "array",
"items": {
"type": "string",
"enum": ["contact", "bite", "punch", "sound", "explosive", "draining", "ground", "priority", "lowPriority", "charging", "recharge", "multiHit", "twoTurn", "sacrifice", "gambling", "reckless", "reflectable", "snatchable", "copyable", "protectable", "bypassProtect"]
},
"uniqueItems": true
},
"effects": {
"type": "array",
"items": {"$ref": "#/definitions/Effect"},
"minItems": 1
}
},
"additionalProperties": false
},
"Effect": {
"type": "object",
"required": ["type"],
"properties": {
"type": {
"type": "string",
"enum": ["damage", "modifyStats", "applyStatus", "heal", "manipulatePP", "fieldEffect", "counter", "priority", "removeStatus", "mechanicOverride"]
},
"target": {
"type": "string",
"enum": ["self", "opponent", "allies", "all", "attacker", "field", "playerSide", "opponentSide"]
},
"condition": {
"type": "string",
"enum": ["always", "onHit", "afterUse", "onCritical", "ifLowHp", "ifHighHp", "thisTurn", "nextTurn", "turnAfterNext", "restOfBattle", "onCharging", "afterCharging", "ifDamagedThisTurn", "ifNotSuperEffective", "ifStatusMove", "ifLucky50", "ifUnlucky50", "whileFrozen"]
}
},
"allOf": [
{
"if": {"properties": {"type": {"const": "damage"}}},
"then": {
"required": ["amount"],
"properties": {
"amount": {
"type": "string",
"enum": ["weak", "normal", "strong", "extreme"]
}
}
}
},
{
"if": {"properties": {"type": {"const": "modifyStats"}}},
"then": {
"required": ["stats"],
"properties": {
"stats": {
"type": "object",
"properties": {
"hp": {"type": "string", "enum": ["increase", "decrease", "greatly_increase", "greatly_decrease"]},
"attack": {"type": "string", "enum": ["increase", "decrease", "greatly_increase", "greatly_decrease"]},
"defense": {"type": "string", "enum": ["increase", "decrease", "greatly_increase", "greatly_decrease"]},
"speed": {"type": "string", "enum": ["increase", "decrease", "greatly_increase", "greatly_decrease"]},
"accuracy": {"type": "string", "enum": ["increase", "decrease", "greatly_increase", "greatly_decrease"]}
},
"additionalProperties": false,
"minProperties": 1
}
}
}
},
{
"if": {"properties": {"type": {"const": "applyStatus"}}},
"then": {
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["burn", "freeze", "paralyze", "poison", "sleep", "confuse"]
}
}
}
},
{
"if": {"properties": {"type": {"const": "heal"}}},
"then": {
"required": ["amount"],
"properties": {
"amount": {"type": "string", "enum": ["small", "medium", "large", "full"]}
}
}
},
{
"if": {"properties": {"type": {"const": "manipulatePP"}}},
"then": {
"required": ["action", "amount"],
"properties": {
"action": {"type": "string", "enum": ["drain", "restore", "disable"]},
"amount": {"type": "string", "enum": ["small", "medium", "large"]}
}
}
},
{
"if": {"properties": {"type": {"const": "fieldEffect"}}},
"then": {
"required": ["effect"],
"properties": {
"effect": {"type": "string"},
"stackable": {"type": "boolean"}
}
}
},
{
"if": {"properties": {"type": {"const": "counter"}}},
"then": {
"required": ["counterType", "strength"],
"properties": {
"counterType": {"type": "string", "enum": ["physical", "special", "any"]},
"strength": {"type": "string", "enum": ["weak", "normal", "strong"]}
}
}
},
{
"if": {"properties": {"type": {"const": "priority"}}},
"then": {
"required": ["value"],
"properties": {
"value": {"type": "integer", "minimum": -5, "maximum": 5}
}
}
},
{
"if": {"properties": {"type": {"const": "removeStatus"}}},
"then": {
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["burn", "freeze", "paralyze", "poison", "sleep", "confuse"]
}
}
}
},
{
"if": {"properties": {"type": {"const": "mechanicOverride"}}},
"then": {
"required": ["mechanic", "value"],
"properties": {
"mechanic": {
"type": "string",
"enum": ["criticalHits", "statusImmunity", "damageReflection", "damageAbsorption", "damageCalculation", "damageMultiplier", "healingInversion", "healingBlocked", "priorityOverride", "accuracyBypass", "typeImmunity", "typeChange", "contactDamage", "drainInversion", "weatherImmunity", "flagImmunity", "flagWeakness", "flagResistance", "statModification", "targetRedirection", "extraTurn"]
},
"value": {}
}
}
}
],
"additionalProperties": false
},
"Trigger": {
"type": "object",
"required": ["event", "effects"],
"properties": {
"event": {
"type": "string",
"enum": ["onDamageTaken", "onDamageDealt", "onContactDamage", "onStatusInflicted", "onStatusMove", "onStatusMoveTargeted", "onCriticalHit", "onHPDrained", "onKO", "onSwitchIn", "onSwitchOut", "onWeatherChange", "beforeMoveUse", "afterMoveUse", "onLowHP", "onFullHP", "endOfTurn", "onOpponentContactMove"]
},
"condition": {
"type": "string",
"enum": ["always", "onHit", "afterUse", "onCritical", "ifLowHp", "ifHighHp", "thisTurn", "nextTurn", "turnAfterNext", "restOfBattle", "onCharging", "afterCharging", "ifDamagedThisTurn", "ifNotSuperEffective", "ifStatusMove", "ifLucky50", "ifUnlucky50", "whileFrozen"]
},
"effects": {
"type": "array",
"items": {"$ref": "#/definitions/Effect"},
"minItems": 1
}
},
"additionalProperties": false
}
}
}
```
## Complete Example: Tempest Wraith
Here's a full example of a Piclet using the complete schema with advanced abilities and dramatic moves:
```json
{
"name": "Tempest Wraith",
"description": "A ghostly creature born from violent storms, wielding cosmic energy and shadowy illusions",
"tier": "high",
"primaryType": "space",
"secondaryType": "culture",
"baseStats": {
"hp": 75,
"attack": 95,
"defense": 45,
"speed": 85
},
"nature": "timid",
"specialAbility": {
"name": "Storm Caller",
"description": "When HP drops below 25%, gains immunity to status effects and +50% speed",
"triggers": [
{
"event": "onLowHP",
"effects": [
{
"type": "mechanicOverride",
"mechanic": "statusImmunity",
"value": ["burn", "freeze", "paralyze", "poison", "sleep", "confuse"]
},
{
"type": "modifyStats",
"target": "self",
"stats": { "speed": "greatly_increase" }
}
]
},
{
"event": "onSwitchIn",
"condition": "ifWeather:storm",
"effects": [
{
"type": "modifyStats",
"target": "self",
"stats": { "attack": "increase" }
}
]
}
]
},
"movepool": [
{
"name": "Shadow Pulse",
"type": "culture",
"power": 70,
"accuracy": 100,
"pp": 15,
"priority": 0,
"flags": [],
"effects": [
{
"type": "damage",
"target": "opponent",
"amount": "normal"
},
{
"type": "applyStatus",
"target": "opponent",
"status": "confuse"
}
]
},
{
"name": "Cosmic Strike",
"type": "space",
"power": 85,
"accuracy": 90,
"pp": 10,
"priority": 0,
"flags": [],
"effects": [
{
"type": "damage",
"target": "opponent",
"amount": "normal"
},
{
"type": "applyStatus",
"target": "opponent",
"status": "paralyze"
}
]
},
{
"name": "Spectral Drain",
"type": "culture",
"power": 60,
"accuracy": 95,
"pp": 12,
"priority": 0,
"flags": ["draining"],
"effects": [
{
"type": "damage",
"target": "opponent",
"formula": "drain",
"value": 0.5
},
{
"type": "heal",
"target": "self",
"amount": "medium"
}
]
},
{
"name": "Void Sacrifice",
"type": "space",
"power": 130,
"accuracy": 85,
"pp": 1,
"priority": 0,
"flags": ["sacrifice", "explosive"],
"effects": [
{
"type": "damage",
"target": "all",
"formula": "standard",
"multiplier": 1.2
},
{
"type": "damage",
"target": "self",
"formula": "percentage",
"value": 75
},
{
"type": "fieldEffect",
"effect": "voidStorm",
"target": "field",
"stackable": false
}
]
}
]
}
```
This example demonstrates:
### **Advanced Special Ability**
- **Conditional Triggers**: Different effects based on HP and weather
- **Multiple Mechanics**: Status immunity + stat boosts + weather interactions
- **Strategic Depth**: Becomes more dangerous when near defeat
### **Diverse Movepool**
- **Standard Attack**: Shadow Pulse with minor status chance
- **Type Coverage**: Storm and Shadow moves for different matchups
- **Utility Move**: Spectral Drain for sustainability
- **Ultimate Move**: Storm's Sacrifice - massive AoE damage with severe self-harm
### **Meaningful Tradeoffs**
- **Spectral Drain**: Healing requires hitting the opponent
- **Storm's Sacrifice**: Incredible power (130 base + 20% bonus to all) but costs 75% of user's HP
- **Low defenses**: High speed/special attack but vulnerable to physical moves
### **Emergent Strategy**
- Use standard moves early while healthy
- Spectral Drain for sustain in mid-game
- When low on HP, ability kicks in for immunity and speed boost
- Storm's Sacrifice as desperate finisher or when opponent is also low
This creates a Piclet that plays differently throughout the battle, rewards risk-taking, and offers multiple viable strategies depending on the situation!