Skip to main content
vfx-muzzle-flash is a skill from the Summer skill library: a guide your AI agent reads when the task matches, so it builds the good version on the first try. Muzzle-flash effect: a one-shot ~80 ms burst at a gun barrel, from particles or a star-burst quad.

When your agent uses it

  • Authoring a muzzle-flash effect — gun fire, weapon flash, barrel flash, spell-cast burst at a hand
  • A gun or spell-casting hand shoots with no visible flash at the barrel or palm

Install

summer setup installs every skill for your agent. To add only this one:
Swap claude-code for your agent, such as codex or cursor. See Skills for every option.

The skill

A muzzle flash is on screen for 60–100 ms. Long enough to read, too short to animate. The recipe: a single billboarded quad with a star-burst gradient shader, fired by restart() on a weapon’s fired signal, plus an OmniLight3D snapping on for 60 ms to light the room. Optional: a tiny GPUParticles3D one-shot for sparks. Most shooters use this pattern.

When to use

  • “Add a muzzle flash to the rifle / pistol / shotgun.”
  • “When I fire, the gun should flash.”
  • “Spell-cast burst at the wizard’s palm.” (one-shot at hand position)
  • “Cannon fires, big flash at the barrel.”
  • The user just hooked up a weapon and the firing reads as silent / weightless.

When NOT to use

  • The user wants a continuous flame (flamethrower) — use vfx-fire, not muzzle-flash.
  • The user wants the impact spark on the wall the bullet hit — that’s vfx-hit-spark.
  • The user wants a tracer line from barrel to target — use an ImmediateMesh recipe, not this. The current Summer build has no Line3D (ClassDB.class_exists("Line3D") is false).
  • The user wants a slow-glowing spell charge-up — use vfx-magic-glow for the buildup, then this for the release frame.

Recipe

1. Files to create

2. Shader code

addons/vfx/muzzle-flash/muzzle_flash.gdshader:

3. GDScript controller

addons/vfx/muzzle-flash/muzzle_flash.gd:

4. Node tree

5. Wire it in (MCP calls)

Place the node at the barrel tip of the weapon. If your gun model has a BarrelTip Marker3D, parent there directly. Write the two files, then mount the flash with ONE summer_run_script call with an explicit scenePath — one transactional run, and mounting a flash on every weapon in the scene is a loop instead of a chain of calls per gun:
Then in your weapon script, on fire():
The script above already connects the weapon’s fired signal to the flash; the one-call form is summer_connect_signal(scenePath="res://main.tscn", emitter="./Player/Weapon", signal="fired", receiver="./Player/Weapon/BarrelTip/MuzzleFlash", method="fire").

5a. Verify

muzzle_flash.gd preloads its own shader, so a shader that failed to write takes the script down at parse time. Check before firing a shot.

6. Parameters to tune

Cookbook — named variants

pistol-flash (default)

rifle-flash

Slightly longer flash, narrower star.

shotgun-blast

Wide, short, lots of spokes.

plasma-cast (sci-fi / spell)

Cool color, slightly longer hold, no random rotation.

Anti-patterns

  • Looping the flash. It’s a one-shot. set_process(false) after the timer; do NOT call fire() from _process.
  • Forgetting to randomize random_seed per shot. Otherwise every flash is the identical orientation and the player notices it as a rendered sprite, not a flash.
  • Using blend_mix instead of blend_add. A flash mixes light, it doesn’t occlude. Always blend_add.
  • OmniLight3D with shadows enabled. A 60 ms shadow pass costs more than the flash itself. shadow_enabled = false.
  • Flash duration > 150 ms. Reads as a flamethrower or a stuck animation. Stay under 100 ms unless intentional.
  • Spawning a new MuzzleFlash each shot and freeing it. Rapid-fire weapons leak. Reuse one anchored to the barrel and call fire().
  • preloading the optional hit-spark scene. preload() resolves at parse time, so wrapping it in a runtime ResourceLoader.exists() check does nothing — the script fails to load entirely when hit-spark isn’t installed. Use load() behind the check.
  • Generating an animated flash sprite. That’s the misroute this skill exists to prevent. The procedural shader rotates per shot for free, and you can recolor without regenerating.

Performance notes

  • One quad + one light + ~8 sparks is negligible — safe at any rate of fire. That is an order-of-magnitude expectation, not a measurement.
  • The OmniLight3D snapping on/off per shot will trigger a shadow re-bake on lights with shadow_enabled = true — keep it off, always.
  • For full-auto weapons (10+ shots/sec), consider raising flash_duration to 0.10 and dropping intensity to 0.6 so consecutive flashes blend instead of strobe.

Edge cases

  • First-person view, gun fills half the screen. Your flash_size of 0.35 will look tiny because the camera is 0.3 m from the barrel. Bump to 0.6+ for FPS, scale down for third-person.
  • Weapon visible in a mirror / scope. The additive quad will appear in reflections only if the reflection probe captures it; for scope ADS, render the flash into the scope’s separate viewport.
  • Underwater shooting. Tint the flash blue-green via flash_color, drop light_range to 30%.
  • Silenced weapon. flash_size = 0.10, light_energy = 0.5, flash_duration = 0.04. Just a wink at the barrel.
  • Suppressed flash with a tracer. Pair this with an ImmediateMesh tracer from barrel to hit point, fired in the same call.

Fallback (no MCP)

Section 5 is fully automatable — summer_write_file writes the shader and the controller, summer_add_node + summer_set_prop place it, and summer_connect_signal wires fired → fire. Do not hand these steps to the user when the MCP tools are available. Without the MCP connection there is no engine to drive, so the user does it manually in Summer Engine:
  1. Create addons/vfx/muzzle-flash/ and write the three files above.
  2. Add a Node3D child to your weapon’s barrel tip Marker3D.
  3. Attach muzzle_flash.gd as the script. The runtime builds the quad + light.
  4. In your weapon’s fire code: $BarrelTip/MuzzleFlash.fire().
  5. Check the Errors dock — muzzle_flash.gd preloads the shader, so a broken shader path fails the script too.

Handoff

After firing this recipe, suggest:
  • vfx-hit-spark — pair on the bullet impact end.
  • vfx-smoke — for a small puff at the barrel after the flash for high-caliber weapons.
  • game-feel — recoil camera kick + screen shake (CameraShake.add_trauma(0.15)) on every shot makes the flash land much harder.
  • sound-effect — generate 9mm pistol shot, sharp crack, indoor, short tail, 400ms and play in the same fire().

See also

  • _building-blocks/additive-billboard-particles.md — canonical additive material reference
  • _building-blocks/trauma-shake-snippet.md — CameraShake.add_trauma() for the recoil punch
  • vfx-hit-spark — companion impact effect
  • vfx-lightning — for energy weapons (replace the flash with a beam)
  • game-feel — recoil + hit-stop wiring

From a shell

No Summer MCP tools in this session? Run each one as a command; when summer --version is missing or below 4.0, use npx -y summer-engine@latest in place of summer. Fields are flags in kebab-case (--scene-path res://main.tscn) or one --input '<json>', and summer ops describe <op> prints the exact input. The summer-cli skill has the rest.

Files in this skill

  • scene-scripting: Build scenes, levels, HUDs and wiring with one editor GDScript (summer_run_script) instead of call chains.
  • sound-effect: Make sound effects (swings, hits, whooshes, reloads, UI): three versions to pick from, then wire them.
  • game-feel: Add juice: hit-flash, trauma camera shake and audio ducking, one hit fires all three.
  • vfx-fire: Fire effect: animated flames from GPUParticles3D, a particle shader and a noise color ramp.
  • vfx-hit-spark: Hit-spark effect: a one-shot burst of additive particles oriented to the surface, fired on impact.
  • vfx-lightning: Lightning bolt effect: a jagged procedural path with a glow shader, end sparks and screen shake.
  • vfx-magic-glow: Magic-glow effect: a pulsing OmniLight3D, drifting additive motes and an optional emission shader.
  • vfx-smoke: Smoke effect: a rising column or puff of soft particles with a noise and density falloff shader.

Source: library/skills/vfx-muzzle-flash/SKILL.md, rendered from summer-engine@4.3.0 on npm.