本文へ移動
cccskills
無料GitHub で公開

scenario-godot-vfx

Use when making or fixing particle effects and game feel in Godot 4.7: GPUParticles3D or GPUParticles2D explosion, fireball projectile with trail, impact, sparks, smoke, shockwave, ribbon trails, sub-emitters, particle collision, color curve does nothing, particles pop out or vanish, effect too heavy on mobile, CPUParticles fallback for Compatibility or web, overdraw, hit-stop, freeze frame, screen shake, juice.

インストール方法を見る

含まれるファイル(24)

  • SKILL.md20.8 KB
  • references/critique.md5.2 KB
  • references/expert-notes.md9.9 KB
  • references/gui-paths.md4.2 KB
  • references/procedures.md24.4 KB
  • references/sources.md10.3 KB
  • scripts/agentkit/vfx/fx_looper.gd691 B
  • scripts/agentkit/vfx/runtime/fx_burst.gd2.6 KB
  • scripts/agentkit/vfx/runtime/fx_projectile.gd2.6 KB
  • scripts/agentkit/vfx/runtime/juice.gd2.1 KB
  • scripts/agentkit/vfx/shaders/fx_erode_add.gdshader285 B
  • scripts/agentkit/vfx/shaders/fx_erode_mix.gdshader262 B
  • scripts/agentkit/vfx/shaders/fx_erode.gdshaderinc1.7 KB
  • scripts/agentkit/vfx/shaders/fx_fire_head.gdshader1.3 KB
  • scripts/agentkit/vfx/shaders/fx_smoke_lod.gdshader1.5 KB
  • scripts/agentkit/vfx/shaders/fx_soft_core.gdshader571 B
  • scripts/agentkit/vfx/shaders/fx_trail_follow.gdshader755 B
  • scripts/agentkit/vfx/vfx_audit.gd14.7 KB
  • scripts/agentkit/vfx/vfx_build.gd17.6 KB
  • scripts/agentkit/vfx/vfx_capture.gd10.7 KB
  • scripts/agentkit/vfx/vfx_jobs.gd5.4 KB
  • scripts/agentkit/vfx/vfx_recipes.gd17.6 KB
  • scripts/agentkit/vfx/vfx_selftest.gd11.5 KB
  • scripts/gd_vfx.py12.3 KB

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)

  1. 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).
  2. 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 without billboard_keep_scale; trails need trail_enabled, a Ribbon or Tube trail mesh and use_particle_trails (Godotneers cZ5Ang_Ji8E 00:09:44, 00:32:54; Brackeys 00:23:44). A sub-emitter's own amount is a global cap (Godotneers yKoGuBGZatY 00:44:48) and its AABB is not inherited (cZ5Ang_Ji8E 01:06:19). vfx_audit.gd flags all of these.
  3. visibility_aabb is 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_aabb corrects for scale and must run inside the level, because debris without its colliders falls 8 m through the world.
  4. Tier by renderer, never by amount_ratio. amount_ratio hides particles and saves nothing (GPUParticles3D docs; Bonkahe BUa-mKHEPUM 00:01:18). Lower amount per 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].
  5. 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).
  6. Juice is code you can test. Hit-stop lowers Engine.time_scale and 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].
  7. 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 from DEBUG_DRAW_OVERDRAW with a measured per-layer calibration, and GPU time from the Vulkan driver (Metal reports 0 on macOS) [added].
  8. A trail that follows a node is a particle shader trick. Pin the particle to EMISSION_TRANSFORM[3].xyz in start() and process(), with no forces (Octodemy iPCzOe-S9EQ 00:05:42).

Establish first

InputChangesDefault
Target rendererswhich layers exist (trails, decals, sub-emitters)Forward+ desktop, Mobile phones, Compatibility web
2D or 3Dnode family, collision (LightOccluder2D vs GPUParticlesCollision3D)3D
Camera distance and screen sharequad sizes, overdraw budgetgameplay camera 4 to 10 m
Frame budget for VFXamounts per tierunder 2.5 ms GPU for six bursts at 720p on the dev Mac [added]
Lookunshaded additive vs lit smoke (Le Lu e_6ZA-xa_DQ 00:07:23)stylized, unshaded fire, alpha-blended smoke
Spawning modelfree-on-done vs pooledfx_burst frees itself; done signal for pools

Workflow

  1. Project and kit. Clone Base3D, gd_vfx.install(P) copies tooling to addons/agentkit/vfx/, and shaders and runtime scripts to res://vfx/ (they ship with the game). Read project.godot. GATE: 3d/physics_engine="Jolt Physics" and the intended renderer/rendering_method are present as text; vfx_selftest.gd:compile reports 0 errors over 10 scripts (check_all skips addons/agentkit/).
  2. Build per tier in code. gd_vfx.build(P, "high"|"mobile"|"low") saves explosion_, impact_, fireball_, shot_ and burst_stage_<tier>.tscn from vfx_recipes.gd. Specs are dictionaries (VB.emitter); curves and ramps become CurveTexture and GradientTexture1D (HDR when a channel exceeds 1); shared textures live in res://vfx/tex/*.tres (Brackeys 00:15:04: never embed). GATE: build ok, no captured errors. Kit layers: fireball (stretched SphereMesh head with fx_fire_head, noise minus gradient, HDR; inverted-Fresnel fx_soft_core; world-space eroded puffs driven by INSTANCE_CUSTOM.y, onetupthree N9ilhL8JFes 00:05:38; velocity sparks; ribbon via fx_trail_follow and an OmniLight3D, both off on low); explosion (flash, fire, depth-sorted smoke, colliding sparks, Face-Y ring, debris with a 30 Hz smoke sub-emitter on high, light, scorch Decal except low); fx_projectile (ray swept every tick, impact on the hit normal, frees itself after its trail dies).
  3. Static audit. gd_vfx.audit(P, scene, tier, level). GATE: 0 errors for the matching tier. Warnings are read and either fixed or written down. Prove the audit catches problems once on broken.tscn (21 findings, 4 errors).
  4. Fit AABBs in context. gd_vfx.fit_aabb(P, "res://vfx/burst_stage_high.tscn", node="Explosion", play_method="Explosion:play", write=True, out=effect_scene). GATE: old_encloses_live true for every emitter, and the timeline aabb_check reports nothing outside.
  5. Look at it, per renderer. gd_vfx.timeline(P, scene, times=[0.03,0.1,0.2,0.35,0.6,1.0,1.5,2.2], renderer=..., trigger="none", extra={"play_method": "Explosion:play", "aabb_check": True}); for the projectile, extra={"hold": "Fireball"}. Open the contact sheet. GATE: no all-black, all-white or uniform flags. By eye: the flash reads first, fire turns to smoke, nothing pops, the ring fades, sparks bounce on the floor, the scorch stays, and the head reads as fire with its tail behind it.
  6. Fallback. For Compatibility, use the low tier (no ribbon, decal, light or sub-emitter), or gd_vfx.to_cpu for a CPUParticles3D twin. GATE: read the lost list (collision, sub-emitters, trails, particle shaders, alpha_curve baked into the ramp, align mode) and render the twin in gl_compatibility.
  7. Budget. gd_vfx.overdraw(...) per tier, and gd_run.profile_scene(stress scene, size=(1280,720), driver="vulkan"). GATE: p99 layers and GPU p95 inside the numbers below, low tier lighter than high.
  8. Behavior. Run vfx_selftest.gd: lifecycle (node count back to baseline after 5 spawns), projectile (one hit, explosion spawned, everything freed) and juice (time_scale restored, shake bounded and back to 0). GATE: all ok.

Expert checklist (state these in the plan)

  • Complete code in the deliverable: paste the vfx_recipes.gd specs and fx_fire_head.gdshader, not prose; readers may lack the kit.
  • Replay with restart(), not emitting = true (docs).
  • Deterministic frames: use_fixed_seed, then speed_scale = 0, restart(), request_particles_process(t). Two seeks to 0.4 s were pixel-identical; without a fixed seed they differed by 0.50 (P13).
  • Fire into smoke in one system: premultiplied blend (BLEND_MODE_PREMULT_ALPHA, texture imported with Premultiply Alpha): low alpha adds, high alpha mixes; fade with black and alpha 0 (Brackeys 30:56 to 32:39). Measured over gray: alpha 0 brightened it, alpha 1 replaced it (P13).
  • Smoke LOD: fx_smoke_lod.gdshader maps a black-to-white color ramp to mip 0 to 8 of one noise texture, so the puff diffuses almost free; color moves to a uniform (Le Lu e_6ZA-xa_DQ 16:40 to 24:20). Detail spread fell from 0.10 to 0.0 over life on all three renderers (P13).
  • Duplicating a system: Brackeys' "Make Unique Recursive, but never the texture" is duplicate(true) in 4.7.2: embedded curves become unique, external .tres textures stay shared (P13). Keep the mesh shared and the material in material_override (Brackeys 13:59 to 15:04).
  • Billboard plus direction: Align Y conflicts with billboards; use transform_align Z Billboard + Y to Velocity (Brackeys 27:07).
  • Layered transparents flicker: offset the nodes first, then sorting_offset (Brackeys 29:57).
  • TAA ghosting: DRAW_ORDER_INDEX (the 3D default) is the only order with motion vectors; keep it for opaque particles (docs).
  • Preprocess runs the shader fixed_fps times per preprocessed second and can stall the GPU; never on one-shots (docs, audit preprocess_one_shot).
  • Near-camera quads: distance_fade_mode Pixel Alpha fades by distance without a depth read; proximity fade softens intersections.

Numbers

ValueRelative toSource
Head HDR color (2, 1.3, 0.6); sparks (2, 1.3, 0.5); spark lifetime 0.3 sglow threshold 1.0Le Lu 00:08:05, 00:28:15
Head render priority 2 over the core's 1; inverted Fresnel power 4 to 5nested transparent meshesLe Lu 00:18:25
Shockwave: 1 particle, 0.4 to 0.5 sone-shot burstBrackeys 00:18:34
Tunnel step = v_max / fixed_fps; fixed_fps 30 by defaultthinnest colliderGodotneers 00:47:17, docs
collision_base_size default 0.01 mvisible particle sizeGodotneers 00:57:27
Child amount at least parent amount x per-event count (AT_END, AT_COLLISION, AT_START); CONSTANT mode: parent amount x Hz x child lifetimesub-emitter capGodotneers 00:44:48 (per event); CONSTANT derived [added], both in link_sub_emitter
sub_emitter_frequency is in Hz: dots 1/f m apart at 1 m/smeasured 4 and 10 Hzlive V10
Overdraw per layer: 0.070 linear luma (Forward+, Mobile); 36.6/255 raw (Compatibility, saturates past 6)DEBUG_DRAW_OVERDRAW PNGlive V11 [added]
Explosion p99 layers at the 0.6 s peak: high 4.9 to 5.9, low 2.3 to 3.3 (seeds vary)640x360 view at about 5 mlive V11, 3 runs
GPU p95, 1280x720, M5 Max via Vulkan, machine shared with other Godot jobs: stage alone 1.0 to 2.3 ms; six looping explosions: high 3.4 to 4.0, mobile tier 2.1 to 2.7, low 1.2 msthe framelive V12, 3 runs
Particle counts, explosion / fireball: high 208 / 57, mobile 48 / 35, low 34 / 22tier scale 1.0 / 0.6 / 0.4kit [added]
Hit-stop 0.05 time scale for 0.08 s; shake 0.30 x 0.22 m at trauma 1, decay 1.8/sthe camera[added], typical range in Mostly Mad note
Smoke ramp about 0.06 linear for mid gray on Forward+; x3.6 on Compatibilitythe same framelive V5 [added]

Quality gates

Measurable:

  • Audit: 0 errors for the tier. Kit compile: 0 parse errors. Project file has Jolt and the chosen renderer.
  • AABB: every emitter's live box inside visibility_aabb at every captured time.
  • Lifecycle: node count equals the baseline after N spawns, and done fires N times with no safety timeouts.
  • Projectile: one hit at the expected time (12 m at 14 m/s gives 0.867 s, frame 52) and nothing left in the tree.
  • Juice: Engine.time_scale is 1.0 after single and overlapping stops, with no early restore; shake offset at most the maximum and exactly 0 at the end.
  • Overdraw p99 and GPU p95 per tier against the table. Compatibility logs show the expected warnings and no unexpected ones.

Visual (contact sheets of at most 1600 px; rubric in references/critique.md): flash then fire then smoke, no popping, readable silhouette at gameplay distance, ring fades, sparks bounce, the trail follows the head, the explosion is oriented to the surface normal, and each tier holds up on its renderer.

Common mistakes

MistakeWhat it looks likeFix
Vertex color offwhite quads, curves ignoredvertex_color_use_as_albedo
Keep scale off on a particle billboardscale curve ignoredbillboard_keep_scale
Trail without use_particle_trailschopped flat piecesset it on the trail mesh material
Child amount under the capsub-emitter trails thin outlink_sub_emitter computes the cap
Default 8 m AABBeffect pops out, collisions stopfit_aabb in the level
collision_base_size larger than the spawn heightdebris stuck at the origin (measured: 0.5 m of travel instead of 10 to 12 m)spawn above the collider
amount_ratio used as the mobile tierno savinglower amount
emitting = true to replayone-shot sometimes skippedrestart() (docs)
Freeing the projectile on hitworld-space trail vanishes at oncestop emitters, wait for the trail to die, then free
convert_from_particles on view-depth sorting"Index p_order = 3 is out of bounds", sorting lostVB.to_cpu maps draw order
Same colors on every renderersmoke near black on Compatibilityretune the low tier on Compatibility
Profiling on Metalgpu_ms 0driver="vulkan"

Handoffs

  • Receives hit events (point, normal, pooling) from scenario-godot-gameplay, budgets from scenario-godot-performance-export, glow and environment from scenario-godot-rendering-lighting.
  • Delivers res://vfx/*.tscn per tier, res://vfx/shaders and runtime (fx_burst, fx_projectile, Juice), audit JSON, sheets, overdraw and GPU tables.
  • Asks scenario-godot-shaders for new surface shaders (dissolve, water, distortion), scenario-godot-audio for impact sounds, and scenario-godot-2d for 2D effect integration.

Godot 4.7 notes

  • capture_aabb() pads by the draw mesh's longest axis and ignores particle scale (4.7.2, measured).
  • CPUParticles3D.convert_from_particles copies draw_order as a raw integer, but the enums differ: GPU view depth is 3, CPU view depth is 2. CPUParticles3D has no alpha_curve (4.7.2, measured).
  • Compatibility logs "Particle trails are only available when using the Forward+ or Mobile renderer" and "does not support particle sub-emitters"; decals disappear with no warning.
  • Headless draws nothing, so captures need a windowed run. On macOS, Metal reports GPU time as 0; use --rendering-driver vulkan.
  • Curve enforces min_value and max_value since 4.4, so widen the range for scale curves above 1. AgX arrived in 4.4. Glow defaults changed in 4.6 (intensity 0.8 to 0.3): retune older effects.
  • Particle shaders use start() and process(); a Godot 3 vertex() writing VELOCITY fails.
  • The trail sections refresh bug (Octodemy, 4.7 era) and Godotneers' 4.2 trail and SDF bugs: not yet run on 4.7.2.

References

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Handle review comments received on GitHub for the current branch's PR or a given PR number or URL, by triaging each unresolved thread, fixing what is warranted, pushing, and replying in each thread, when asked to address, fix or answer PR comments. Works in any Scenario repository.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

Generate one short Conventional Commits squash message describing only the net diff between the PR's base and head, set its header as the PR title, validate it with the repository's commitlint and both copy its description to the clipboard and display it, when asked for a squash message. Works in any Scenario repository, whatever its default branch.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

Refresh the current pull request description from its net changes, following the repository's PR template, when asked to update or write the PR summary. Works in any Scenario repository, whatever its default branch.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

scenario

無料

Use when connecting an AI agent to Scenario (scenario.com) through MCP, or when a task involves generating images, video, 3D, audio, sprites, textures, or game assets. Also when picking a Scenario model, running a LoRA, refining a generation prompt, uploading reference images, waiting on generation jobs, checking credits or quota, hitting Scenario auth, scope, or Forbidden errors, or setting up mcp.scenario.com in Claude Code, Cursor, VSCode, or another agent.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

Use when generating or handling 3D assets through the Scenario MCP server, including text-to-3D or image-to-3D meshes, GPT-6 Astra 3D or Claude Opus 5.5 3D, GLB, FBX, OBJ, STL, or VOX files, PBR-textured or game-ready models, voxel models, multi-view reconstruction, retexture, remesh, UV unwrap, auto-rigging a biped or quadruped, or retargeting an animation, previewing a mesh in the inline 3D viewer, or downloading a model for import into Unity, Unreal, Godot, or Blender.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

Use when generating navigable 3D worlds or Gaussian splat scenes on Scenario via MCP: text-to-world, image-to-world, a 360 panorama or skybox turned into a walkable splat, multi-view photos or a video walkthrough reconstructed as a splat, or one object photo to splat. Keywords: World Labs Marble 1.1, 1.1 Plus, 1.0 Draft, Hunyuan World, HY World, image-to-skybox, skybox-to-splat, multiview-to-splat, TripoSplat, gaussian splatting, 3DGS, spz, world generation, explorable scene, VR.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9922026年10月13日 更新

scenario-labs のスキルをすべて見る

このスキルの問題を報告する