Log inGet started
What it does

impact

What a round does where it lands. A flash goes off at the point of impact and a burst is thrown back along the surface normal — and what that burst is comes from the surface it hit, not from a colour parameter.

local hit = physics.raycast(muzzle.position, aim, 200)
if hit then
    effects.play("@builtin::systems.effects.combat.impact", {
        position = hit.point,
        params = { normal = hit.normal, surface = "metal" },
    })
end

normal takes exactly what a cast reports: every physics.raycast / raycastAll / raycastScreen / sphereCast hit carries { entityId, point, normal, distance, startedInside }, so the point goes to position and the normal goes to normal.

The surface it hit

surface is the parameter that makes this an impact rather than a burst. It is an enum, so it takes one of a closed list of names and a name outside that list raises and reports the ones that are in it.

surfaceWhat it throws
metal36 hot sparks at 9 m/s, no dust, a full-strength flash. Low drag and hard gravity, so they arc away and settle.
stone16 pale chips and a 26-particle grey dust cloud, at a little over half the spark speed, with a flash at 40%.
dirtNo sparks at all, a 46-particle brown cloud at a third the speed, and a flash at 8%.
wood12 tan splinters and 18 pale dust, with a flash at 15%.

Each row sets spark count, dust count, colour, speed, drag, gravity, particle size, how long the burst lasts and how bright the flash is. count, speed, spread and lifetime then scale the row the surface chose, so a big soft strike on dirt and a small hard strike on metal are the same asset.

Parameters

ParameterTypeDefaultRangeWhat it changes
normalvec3{0, 1, 0}world spaceThe surface normal at the point of impact — a cast's normal. The burst is thrown back along it.
surfaceenummetalmetal, stone, dirt, woodWhich profile above the burst comes out of.
countnumber1.00.0 – 4.0How much the surface throws, as a multiple of its profile. At 0 nothing is thrown and no emitter is leased.
spreadnumber0.450.0 – 1.0How wide the burst opens around the normal — 0 is a tight jet, 1 the whole hemisphere.
speednumber1.00.05 – 4.0How fast the burst is thrown, as a multiple of the profile.
lifetimenumber1.00.1 – 4.0How long the burst lasts, as a multiple of the profile. It is also the effect's own length.

Cost

<!-- cost: quoted verbatim from effect.yaml -->
gpuMsvramBytesmeasuredOn
0.0131524see effect.yaml

The size is what the effect's own backends report they hold at a representative instant — handle:stats().bytes — read identically on every engine, in every scene and on every repeat. The emitter vertex buffers an effect draws from come out of a pool shared across the process that grows in chunks, so a renderer.gpuMemory() delta taken around one play is that pool's growth as much as the effect's; what those buffers cost at the declared slot counts is below. The span is the median of five interleaved idle/loaded windows of the frame's measured GPU pass sum, which read 0.000 ms with a spread of about 0.008 ms: the effect costs less GPU time than that instrument resolves, and 0.01 is the bound the reading supports.

Measured on metal at the declared defaults: 31,524 bytes of emitter simulation state, plus 27,360 bytes of emitter vertex geometry — the spark emitter's 36 quantised slots at 760 bytes each. Slot counts are quantised in twelves so a spread of count values lands in a handful of pool buckets rather than one per value, and a surface that also throws dust leases a second emitter and spends its own slots on top.

What it draws with

AssetRole
combat/materials/combat_glowthe family's one additive material — the flash
combat/glowthe module that leases the flash card and writes its lanes

The sparks and the dust are particles rather than geometry, so the only thing the shared material draws here is the flash itself.

See also

  • @builtin::systems.effects.combat.tracer — the round that lands here.
  • @builtin::systems.effects.combat.shockwaveRing — the front a larger blast pushes out from the same point.
  • guides { path: "topics/physics" } — the casts that report a hit's normal.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

This asset doesn't declare a schema or structured payload.

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

0items
This part has no composite children. See the Files segment for its leaf payloads.
This part has no leaf payloads.

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported. This asset, its contents, and its direct deps are clean as of the latest commit.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.