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