scenario-godot-vfx
Installation
SKILL.md
Godot VFX
Target: Godot 4.7.2.stable, macOS Apple Silicon.
Expert level here means effects built as layers of small systems, every silent particle failure caught by a script before anyone looks, and every claim about look or cost backed by frames captured at exact times and by measured overdraw and GPU time per renderer. The agent builds effects in code, renders them windowed, and looks at contact sheets. If a sibling skill named here is missing from your available skills, ask the user to install it (npx skills add scenario-labs/skills --skill <name>); unattended, proceed from tool schemas and flag the gap.
REQUIRED BACKGROUND: scenario-godot-expert (gd_env, gd_run, gd_review, AgentKit, GD_MAX slots, windowed vs headless).
Stance (the expert delta)
- An effect is layers, and the head of a projectile is not particles. A projectile is head, tail and sparks; the head is a shader mesh with scrolling noise and HDR color above 1 (Le Lu 74XywaLGO5Q 00:00:34, 00:08:05). An explosion is flash, fire, smoke, sparks, debris, shockwave and light, each a small system made by duplicating a working one and changing a few values (Brackeys htRjt505sPg 00:02:30, 00:13:27). A one-particle system is fine for a shockwave ring (00:18:02).
- Particle settings fail silently, so audit them in code. Color and alpha curves do nothing without
vertex_color_use_as_albedo; scale curves do nothing on a particle billboard withoutbillboard_keep_scale; trails needtrail_enabled, a Ribbon or Tube trail mesh anduse_particle_trails(Godotneers cZ5Ang_Ji8E 00:09:44, 00:32:54; Brackeys 00:23:44). A sub-emitter's ownamountis a global cap (Godotneers yKoGuBGZatY 00:44:48) and its AABB is not inherited (cZ5Ang_Ji8E 01:06:19).vfx_audit.gdflags all of these. visibility_aabbis both culling and the collision area (Godotneers cZ5Ang_Ji8E 00:45:28). Measure it rather than guessing: on 4.7.2,capture_aabb()pads particle positions by the draw mesh's longest axis and ignores per-particle scale (measured: Flash quad 2 m gave a 4 m box; a ring scaled to 4.5 m still gave 2 m) [added].fit_aabbcorrects for scale and must run inside the level, because debris without its colliders falls 8 m through the world.- Tier by renderer, never by
amount_ratio.amount_ratiohides particles and saves nothing (GPUParticles3D docs; Bonkahe BUa-mKHEPUM 00:01:18). Loweramountper tier and drop the layers the renderer cannot draw. Compatibility drops decals with no warning, and logs warnings for trails and sub-emitters (measured) [added]. - Particles do not touch physics. Gameplay hits come from a ray swept every physics tick; particle collision needs GPUParticlesCollision nodes, and the step per tick is speed / fixed_fps, with fixed_fps 30 by default (Godotneers cZ5Ang_Ji8E 00:44:23, 00:47:17).
- Juice is code you can test. Hit-stop lowers
Engine.time_scaleand waits on a timer that ignores it, then restores 1.0 (Mostly Mad Jwv9t5zFlqI 00:00:32, 00:01:37). Shake comes from smooth noise with decay (Mostly Mad pG4KGyxQp40 00:00:39); trauma squared and a 3D camera offset are [added]. - Judge frames, not the inspector. Render windowed with
--fixed-fps 60, so frame k is t = k/60 s, at 0.03 to 2.2 s, and look at one contact sheet per renderer. Overdraw comes fromDEBUG_DRAW_OVERDRAWwith a measured per-layer calibration, and GPU time from the Vulkan driver (Metal reports 0 on macOS) [added]. - A trail that follows a node is a particle shader trick. Pin the particle to
EMISSION_TRANSFORM[3].xyzinstart()andprocess(), with no forces (Octodemy iPCzOe-S9EQ 00:05:42).