# FX — the effect library Gameplay code fires a **named** effect; the **scene** decides how it looks. That split is the whole point: a programmer writes `Fx.spawn(&"blood_burst", hit_transform)` once, and from then on every change to how a hit *feels* is a `.tscn` Siim edits in the inspector — no code, no recompile. ```gdscript # anywhere in gameplay code Fx.spawn(&"blood_burst", global_transform) # at a node Fx.spawn(&"slam_dust", Transform3D(Basis(), point)) # at a world point ``` ## Siim's workflow 1. **Open the gallery.** Run `fx/effect_gallery.tscn`. It loops through every effect on a sand-lit stage with the effect's name on screen, so you see each one the way it reads in play. 2. **Pick an effect** `.tscn` in `fx/` (`blood_burst`, `slam_dust`, `spark`, `hit_flash`) and open it. 3. **Tune it in the inspector.** Everything lives on the `CPUParticles3D` node and its material: - **Colour** → the node's *Color Ramp* (start colour → faded/transparent end). - **Shape of the burst over time** → *Scale Amount Curve*. - **Amount / Lifetime / Explosiveness / Spread / Velocity / Gravity** → the node's emission group. - The viewport previews particles live as you drag — no play needed. 4. **Save.** That's the whole edit. Re-run the gallery to compare. New effect? Add a `fx/.tscn` (root = `CPUParticles3D` with `one_shot_effect.gd` attached — copy an existing one), then register its name → path in `fx/fx.gd`. ## House style (keep effects reading as one game) **Palette** — pull from these, don't invent per-effect colours: | Role | Start | End (fades to alpha 0) | |-------|---------------------------|-----------------------------| | Blood | `#FF0505` | `#400000` | | Dust | `#B89966` (tan) | `#8C7326` | | Ember | `#FFF299` → `#FF8C1A` | transparent | | Flash | `#FFFFFF` | transparent | **Timing budgets** — hits read best short: strike/flash effects ≤ **0.4 s**, dust/settle ≤ **1.1 s**. A one-shot effect frees itself `lifetime + 0.5 s` after spawn (`one_shot_effect.gd`), so keep `lifetime` honest. **PS1 look** — materials are **unshaded**, **alpha-blended**, **vertex-colour** (colour comes from the ramp), cull disabled. Prefer few, chunky, low-poly billboarded quads over dense fine particles; the game runs the PS1 filter over everything, so subtlety is lost anyway. **Mobile** — effects are **`CPUParticles3D`, never `GPUParticles3D`**. The web/GLES3/ANGLE target compiles particle shaders badly (see the notes in `player.gd`); CPU particles are just as tunable in the inspector and safe on-device. Keep this constraint when adding effects. ## Files | File | What it is | |---|---| | `fx.gd` | The `Fx` autoload — `spawn(name, xform, parent=null)`; name→path registry | | `one_shot_effect.gd` | Root helper: fires the emitter(s) once, frees the scene when done | | `blood_burst.tscn` etc. | The effects themselves — **edit these** | | `effect_gallery.tscn` | Preview stage (run it to review) | | `_seed_placeholders.gd` | One-off generator that wrote the first-draft defaults; not used at runtime |