Elemental Sandbox
The effects are the least valuable part. One rule came across — record dimensionless, resolve dimensions every frame.
Not one line of effect code came over, and one sentence decided the character of 43 places in my own code. The showy part of this repository is web-only and doesn’t reach my engine. What crossed is a single rule: “an instance remembers only a seed and ratios; metres, seconds and radians are recomputed from settings every frame.” Holding that up against my project — it was built exactly the opposite way.
What was built
A skillshot-effect playground that runs in a browser. A character stands on a floor; press a key and a ground reticle tracks the mouse; click and it fires. It isn’t a game — no enemies, no health. The single purpose is “look at the effect and turn the numbers.”
And the headline claim was true. “All generated in code” — cloning and checking exhaustively, there are ten binaries and not one of them is for an effect. No sprite sheets, no flipbooks, no effect textures.
| What | How it’s made |
|---|---|
| Ice crystals | procedural geometry |
| Lightning | one ribbon strip placed by a vertex shader |
| Meteor | a sphere carved into fracture faces on the CPU |
| Beam | a parametric tube drawn three times at three radii |
| Reticles, scorch marks, lava cracks | all distance-field + noise shaders |
| Smoke, embers, debris | GPU particles — silhouettes procedural too |
It has two runtime dependencies. And the repository was five days old, 18 commits, one contributor.
Why the sliders work while paused
Because the three things in the diagram hold at once, and the second is the heart of it. What a single ice spike remembers contains no metres, no radians, no seconds. Its position along the line is a ratio, its lateral offset is a ratio, and the rest is a handful of random numbers. The one real unit it stores is its time of birth — because that’s an event, not a dimension.
So every frame, update() multiplies those out against the settings object again. Pull the height slider and an ice field already standing grows.
The handling of values that can’t be expressed that way is good too. Four parameters — facet count, bend and the like — can’t be expressed as position and scale multiplication and have to be baked into geometry, which normally makes them “constants that need a restart.” The author hashes just those four into a string key, rebuilds wholesale only when it changes, and carries the instance’s seed and birth time across — new shape, same identity.
And the reasoning is in a comment. “A crystal is 108 triangles; rebuilding is cheaper than approximating.” A case of something that was “too expensive” being opened up by actually measuring the cost.
I ran it myself
Rather than trusting the docs I cloned it and ran it locally. Capture kept failing because the browser doesn’t paint when its window isn’t on screen — so I called the frame loop directly at a fixed step instead. The side effect was a deterministic timestep, which made the following check possible.
I fired the ice ability, advanced 54 frames, paused, and — without letting a single tick of time pass — changed three settings values and drew three more frames.
| elapsed | height | lean | |
|---|---|---|---|
| BEFORE | 13.95 | 3.1 | 0.42 |
| AFTER | 13.95 (identical) | 7.44 | 0.97 |
The claim held. With elapsed time exactly equal, crystals already standing grew taller and leaned further out. The smoke column, the snow particles and the character pose are pixel-identical — the simulation didn’t re-run; the same instant was re-interpreted at new dimensions. Draw calls matched too, 115 in both frames.
And measurement diverged from self-reporting. Idle draw calls matched at 32, but with the ice field standing mine ran 95–115 against a self-reported ~69. A difference in capture timing and resolution — the self-reported figure can’t be quoted as-is. The slider count came out at 918 against a claimed 938, off by 20.
Then I held it against my own code
The rule that transferred is this one.
An ability instance remembers only a seed and ratios. Metres, seconds and radians are recomputed from settings every frame.
My wuxia game project is built exactly the opposite way. When a boss produces a form, the telegraph duration freezes the moment the coroutine starts. Changing that duration mid-play never reaches a telegraph already running.
Counted across the project: 43 places freeze at start, 22 re-read every frame.
Not one line of effect code came over, and yet the character of 43 places in my code got decided. That’s the kind of return to expect from this bucket.
Read the licence in two places
Porting the code is rejected. Legally it’s free, but web shaders and a 3D-plane assumption mean there’s nothing to move into my 2D pipeline.
And taking it wholesale is risky. The same repository declares a permissive licence in its licence file and says something different in the README — “provided as-is for the purposes of this project.” The bundled character models and environment probe are only noted as retaining their original licences.
Treat it as a textbook, not a dependency. A five-day-old repository with one contributor. Game repos are short-lived, which makes that distinction matter more here than anywhere else.
One last thing this repository did well
It ships four reference stills in the repository root — a record of what it was tuned against. And the README lists seven “known rough edges” the author wrote about their own work: alignment artifacts, the flat-floor assumption, an empty pass.
The most portable techniques here are dimensionless recording, the zero-length frame, and that last one — because they’re design rules independent of engine and language. The rest is work you only have to do because the engine is manual, and its value collapses in an environment where the engine already does it for you.