Particles: a source wears a scene icon, and what isSymbolType really gates (#89)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rootandClaude Opus 5 committed 2026-09-14 08:26:01 +02:00
1 parent 198483b155
commit d52f1c1ef9
3 files changed
+19 -5

No files matched your search

+7
@@ -109,6 +109,13 @@ rebased to the second it was stopped at, or it resumes a minute further on. The
that changes *when* rather than *what* costs nothing but a term on that one argument — a particle
source's `Time scale` is a factor on it and `Prewarm` a summand, so neither needs a frame of
simulation nor a line in the drawing code.
**A predicate named after what a thing looks like will be asked what a thing *is*.** `isSymbolType`
reads as "draws an icon", but four callers use it for "is editor decoration": the running world, the
Game tab, the draw order and the upright placement all key off it. Giving a particle source an icon
by adding it there would have taken its particles out of the game. The two questions are now two
functions — `hasSceneIcon` for the drawing, `isSymbolType` for the decoration — and the icon itself
is a decoration of `SceneViewport`, which is editor-only for free because `GameViewport` never syncs
any.
Comments state contracts
and reasons, not what the code does: a `/** */` on every export whose name does not say it all,
`//` only for a decision or gotcha.
+2 -2
@@ -12,7 +12,7 @@ npm run check # typecheck + lint + format:check + tests, the gate CI runs
# code is lost (tail's is reported), so a red run reads as green
npm run build # writes dist/ and regenerates index.html
./build.sh # the same under `set -o pipefail`, for callers that pipe the output
node tools/seed-e2e.mjs && node tools/e2e.mjs # 821 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 824 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result
@@ -156,4 +156,4 @@ widths to find click points. The **render device is not in this repo** — `/dev
and a 1 GB `/dev/shm` come from `container.options` in the runner's own `config.yaml`, which
applies to every job on that runner. Without them chromium falls back to llvmpipe, which gets
WebGL 1.0 only. Measured in the job container: `ANGLE (Intel, Vulkan 1.3.230, HD Graphics 630)`,
WebGL 2.0, and the same 821 checks as here.
WebGL 2.0, and the same 824 checks as here.
+10 -3
@@ -94,6 +94,14 @@ can. Overriding one of them on a placed object is an ordinary override, with res
A **behavior** can start a source over with the `Emit` node (its `source` input names which one): in *Burst*
mode that is another burst, in *Continuous* mode the stream begins again at particle 0.
**Its icon in the Scene tab.** Like a behavior or a container, a source is marked by an icon of its
own — an orange ring with sparks, upright and unscaled at its position, with the object's name
beside it and a dashed line to its owner when it is parented. The ring is hollow because, unlike
those two, a source *does* draw something: the effect shows through the middle of its own mark. The
icon is editor decoration and never reaches the running game, but the source is **not** an editor
symbol: its particles are scene content, and what is grabbed and framed is the ring-sized square
around its position rather than anything that grows with the source's scale.
## Recipes
**Rain.** `Age in seconds → Multiply(b: 400) → Output.y`, and a `Random(-300, 300)` into
@@ -117,6 +125,5 @@ to a cold one over `Age`.
- **Particle time is the editor's clock, not the game's.** Pausing the game does not freeze a spray.
- **The preview shows the asset, not an instance**: the rows the asset carries, never the ones a
particular placed source was given — every one of them may be overridden where it is placed.
- **A source with `Emitting` off draws nothing at all** once the last particle has died, so it
disappears from the scene view; it is still in the hierarchy panel, and selecting it there shows
its handle.
- **A source with `Emitting` off draws nothing at all** once the last particle has died. In the
Scene tab its icon still marks the spot; in the running game there is nothing to see.