2D VFX: fighting-game effects

An effect is a recipe: one name launches every layer of a hit or a blast together. Scripts, action_2d bursts and anim_2d frame events all use the same names.

self.fx('swing_heavy');                       // on this object: the arc follows the knight
game.fx('slam', [x, y], dir);                 // at a point; dir 1 / -1 or [x, y]
game.fx('hit_heavy', [x, y], dir, 1.5);       // strength scales shake, flash, hit-stop, counts and size
action_2d { burst "hit_slash" }               // every accepted hit; damage and killing blows scale it
anim_2d { events ["attack@1=fx:swing_heavy"] }

Layers a recipe can use

FieldWhat it draws
particlesup to 8 groups: spark, streak, ember, smoke, dust, debris, chip, orb, blood, ichor, oil. Colour ramp (color → colorEnd), sizeEnd, glow (HDR bloom), drag, stretch (velocity streak), image + pieces (one piece of a strip each: rocks, bones), emitters (rate, duration, the rate fades to zero), delay, radius, lift. Debris and fluids collide with solid tiles; debris settles, fluids leave stains.
flipbookspainted animations from Assets/2D/fx/*.png (one horizontal strip): frames, aspect, size, fps, offset [forward, up], rotate, jitter, growth, delay, fade, additive, glow. Mirrored with the facing.
swinga sword arc for any character (no rig needed): a glow band, a body ramping to a white-hot tip and a hot outer edge, tapering to the tail. radius, from/to degrees (0 forward, 90 up), time, width, trail, fade, core, color, glow, offset.
shockwavean expanding refraction ring that bends the picture, plus an optional visible ring (ring, color, glow); flat lays it on the floor.
decala mark under the event, snapped down to the ground (cracks, scorch, a slime puddle), fading over life.
hitStop, screenFlash (+flashColor, screenFlashTime), speedLines, chromatic, radialBlur, shake, lightthe camera and screen side of an impact.

Additive layers with glow feed the bloom target in HDR, so white-hot cores bloom past white while the art stays as painted. The refraction ring uses the 2D distortion target. Both work on Metal and OpenGL.

Built-in recipes

Swings swing_light, swing_heavy, swing_up, swing_spin; impacts hit_slash, hit_heavy, spark, hit_bone, hit_slime, hit_flesh, hit_magic, hit_fire, hit_ice, hit_lightning; deaths death_bones, death_slime, death_bat, death_boss; slam, barrel_explosion; movement dust, poof, dash_smear; and the older names (slash, heavy_slash, explosion, fire_hit, ice_hit, lightning, dust_land, dash_burst, coin_pickup, heal, level_up, magic_circle). spark, dust and poof replace the old pooled bursts of the same name.

Project effects

Every Assets/Effects/*.fx2d.json (one recipe or an array) loads when play starts and can override a built-in name; a file that fails to load is listed in the feel report's effect_problems. fx_2d {action:"preview"} renders a recipe on a stage with a floor, fx_2d {action:"save", recipe:{...}} writes one, fx_2d {action:"list"} lists all. Example: Assets/Effects/ironbell_bell_ring.fx2d.json.

The painted flipbooks

Assets/2D/fx/ is baked from the Nano Banana reference sheets in Assets/References/fx2d-1016/:

python3 Scripts/fx2d-bake.py <references> Projects/Sandbox/Assets [review.png]

Glow art (slashes, sparks, fire, magic) is keyed off the dark sheet background so it adds light; solid art (smoke, dust, slime, bones, cracks) gets a soft matte. Each strip has a .fx.json with its frame size and source boxes.

Arcwright Beta 2 (0.4.0) · generated from the engine source (25e375c86)Something wrong or missing? Tell us
Download Arcwright free