diff --git a/docs/ARTIST_GUIDE.md b/docs/ARTIST_GUIDE.md index 3b72aeb..aa1eb79 100644 --- a/docs/ARTIST_GUIDE.md +++ b/docs/ARTIST_GUIDE.md @@ -16,7 +16,7 @@ 7. [Animations](#animations) — item poses, fallback chain, variants, context animations 8. [Animation Templates](#animation-templates) 9. [Exporting from Blender](#exporting-from-blender) -10. [The JSON Definition](#the-json-definition) +10. [The JSON Definition](#the-json-definition) — field reference, components, pose priority, movement styles 11. [Packaging as a Resource Pack](#packaging-as-a-resource-pack) 12. [Common Mistakes](#common-mistakes) 13. [Examples](#examples) @@ -764,6 +764,7 @@ The `movement_style` changes how the player physically moves — slower speed, d | `movement_modifier` | object | No | Override speed/jump for the movement style (requires `movement_style`) | | `creator` | string | No | Author/creator name, shown in the item tooltip | | `animation_bones` | object | Yes | Per-animation bone whitelist (see below) | +| `components` | object | No | Gameplay behavior components (see [Components](#components-gameplay-behaviors) below) | ### animation_bones (required) @@ -785,6 +786,87 @@ At runtime, the effective bones for a given animation clip are computed as the * This field is **required**. Items without `animation_bones` will be rejected by the parser. +### Components (Gameplay Behaviors) + +Components add gameplay behaviors to your item without requiring Java code. Each component is a self-contained module you declare in the `"components"` block of your JSON definition. + +**Format:** A JSON object where each key is a component name and each value is the component's configuration (an object, or `true` for defaults). + +```json +"components": { + "lockable": { "lock_resistance": 200 }, + "resistance": { "base": 150 }, + "gagging": { "comprehension": 0.2, "range": 10.0 } +} +``` + +Items without the `"components"` field work normally — components are entirely optional. + +#### Available Components + +| Component | Description | Config Fields | +|-----------|-------------|---------------| +| `lockable` | Item can be locked with a padlock. Locked items cannot be unequipped. | `lock_resistance` (int, default: 250) — resistance added by the lock for struggle mechanics | +| `resistance` | Struggle resistance. Higher = harder to escape. | `base` (int, default: 100) — base resistance value | +| `gagging` | Muffles the wearer's speech. | `comprehension` (0.0–1.0, default: 0.2) — how much speech is understandable. `range` (float, default: 10.0) — max hearing distance in blocks | +| `blinding` | Applies a blindfold overlay to the wearer's screen. | `overlay` (string, optional) — custom overlay texture path. Omit for default | +| `shock` | Item can shock the wearer (manually or automatically). | `damage` (float, default: 2.0) — damage per shock. `auto_interval` (int, default: 0) — ticks between auto-shocks (0 = manual only) | +| `gps` | GPS tracking and safe zone enforcement. | `safe_zone_radius` (int, default: 50) — safe zone in blocks (0 = tracking only). `public_tracking` (bool, default: false) — anyone can track, not just owner | +| `choking` | Drains air, applies darkness/slowness, deals damage when activated. | `air_drain_per_tick` (int, default: 8) — air drained per tick. `non_lethal_for_master` (bool, default: true) — won't kill if worn by a master's pet | +| `adjustable` | Allows Y-offset adjustment via GUI slider. | `default` (float, default: 0.0), `min` (float, default: -4.0), `max` (float, default: 4.0), `step` (float, default: 0.25) — all in pixels (1px = 1/16 block) | + +#### Example: Shock Collar with GPS + +```json +{ + "type": "tiedup:bondage_item", + "display_name": "GPS Shock Collar", + "model": "mycreator:models/gltf/gps_shock_collar.glb", + "regions": ["NECK"], + "animation_bones": { + "idle": [] + }, + "pose_priority": 10, + "escape_difficulty": 5, + "components": { + "lockable": { "lock_resistance": 300 }, + "resistance": { "base": 150 }, + "shock": { "damage": 3.0, "auto_interval": 200 }, + "gps": { "safe_zone_radius": 50 } + } +} +``` + +This collar can be locked (300 resistance to break the lock), has 150 base struggle resistance, shocks every 200 ticks (10 seconds) automatically, and enforces a 50-block safe zone. + +#### Example: Adjustable Blindfold + +```json +{ + "type": "tiedup:bondage_item", + "display_name": "Leather Blindfold", + "model": "mycreator:models/gltf/blindfold.glb", + "regions": ["EYES"], + "animation_bones": { + "idle": ["head"] + }, + "pose_priority": 10, + "escape_difficulty": 2, + "components": { + "blinding": {}, + "resistance": { "base": 80 }, + "adjustable": { "min": -2.0, "max": 2.0, "step": 0.5 } + } +} +``` + +#### Component Tips + +- **You can combine any components.** A gag with `gagging` + `lockable` + `resistance` + `adjustable` is perfectly valid. +- **Omit components you don't need.** A decorative collar with no shock/GPS just omits those components entirely. +- **Default values are sensible.** `"lockable": {}` gives you standard lock behavior with default resistance. You only need to specify fields you want to customize. +- **Components don't affect rendering.** They are purely gameplay — your GLB model and animations are independent of which components you use. + ### Pose Priority When multiple items affect the same bones, the highest `pose_priority` wins.