| # 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! |