Skip to content

Releases

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 04 Oct 07:41

The first release of Polyhedral: polyhedral dice for Resolume Arena and Avenue, as two FFGL plugins, a source (SW Polyhedral, PY01) that throws a d4, d6, d8, d10, d12, d20 or d100 onto the table, and an effect (SW Dice Over, PY02) that throws them over your clip. Press Roll: the dice tumble, bounce off the edges of the frame and each other, and come to rest on a random result, or on the Fixed Total you set, at exactly Roll Time.

The one idea: a die's rotation group lets the result be chosen without touching the physics. Every die in a set is face-transitive. For any two faces there is a rotation of the solid onto itself that carries one to the other: 12 for the d4, 24 for the d6 and d8, 10 for the d10, 60 for the d12 and d20. So the plugin throws the dice honestly, ahead of time (rigid bodies, gravity, an impulse at every contact, friction, restitution), reads which face the physics left on top, and draws each die as R(t)·S, with S the symmetry that carries the wanted face onto that one. The outline, every bounce and every shadow are exactly what the physics produced; only the paint has turned. Random results come from an integer generator, uniform by construction; a Fixed result for several dice is a total, split uniformly over every combination that makes it. Up to six dice (six pairs for the d100, tens and units), a cocked die is rethrown, and a real set's numbering. Finishes: plastic, marble, pearl, metal, gem (refracting), stone, wood, galaxy, a picture of your own, wireframe, and in the effect the clip itself. The numbers come in any installed font or one from a file, painted or engraved, with 6 and 9 marked.

Downloads: universal macOS bundles (Apple silicon and Intel) as a .dmg or .zip, and a Windows x64 installer or .zip. The macOS build is signed and notarised; the Windows build is unsigned, so SmartScreen warns once. Every download carries both plugins: Polyhedral.bundle and Polyhedral Over.bundle (Polyhedral.dll and Polyhedral Over.dll on Windows). Drop both into Extra Effects.

What is measured (offline, tools/verify.sh, a harness that drives the real plugin classes in a headless GL context):

  • Outcome. Every value of every die thrown with Fixed, 220 throws: each came to rest showing the value asked for. 63 throws of 2, 4 and 6 dice got every total right.
  • Readback. The number on top is read out of the rendered pixels, in the built-in face and in Georgia, and the wanted number fits the ink best every time.
  • Silhouette. A die drawn at R and at R·S differs by at most one pixel of its outline, at 320×180 and 640×360.
  • Uniformity. Random passes a chi-square test at p = 0.001 for all seven dice.
  • At rest. Every die is flat to 0.0000°, still, inside the walls, and no two overlap.
  • Duration. The last die settles at Roll Time from 0.5 to 8 s, to 10⁻⁹ s, and is still moving one frame before.
  • Physics. Free flight is the exact parabola to 2.5×10⁻¹⁵ m, and no kept contact solve adds energy.
  • The effect. The clip is bit-exact more than five die radii from any die.
  • Determinism. The same seed and roll give byte-identical keyframes.
  • Controls. Ten deliberately wrong models are all detected, six one-character mutants of the shipped GLSL and C++ are all caught, and all 43 parameters change the picture.

Windows, in Resolume Arena 7.27.1 (win-lab, Mesa llvmpipe, no GPU, 2026-10-04): a CI build of this source loads from Extra Effects, SW Polyhedral registers as PY01, a source, and SW Dice Over as PY02, an effect; all 47 and 49 host controls match the declaration (the two names at Resolume's length limit complete); both render with a font and a picture loaded from file, and Arena's log stays clean: 19 passed, 0 failed of the fleet gate's checks. Every control that can change the picture without a throw was shown doing so, 33 on the source and 35 on the effect; Roll Time, Interval, Throw, Spin and Bounce act only during a throw, which the gate never presses. On llvmpipe the first instance after Arena starts holds Arena's REST API for about 50 s, most likely the shader compiling in software. Software rendering says nothing about a GPU or about speed.

Fixed before the tag: the d6's and d10's tables were sorted by an angle whose rounding differed between builds, so Apple Silicon, Intel and the browser printed some numbers a different way up (never a different result). tools/verify.sh now requires identical tables from three builds.

What is assumed, or unconfirmed. The contact model is the plugin's own (vertices against planes, edges against edges, sequential impulses), checked for energy, restitution, free flight and rest, not against a measured die; the rolling damping is chosen to look like felt. A real 20 mm die is still in 0.3–0.7 s, so a longer Roll Time is slow motion, not a longer throw. The rest is snapped flat over the last 0.15 s when the die is under 1° off. Edge rounding is shading only. The Gem is a single refraction. Arena restoring Font Name and Font in the same pause, which the font logic depends on, has never been seen.

Cost: one marble d20 at 1080p is 1.0–1.7 ms a frame on an Apple M-series GPU, and six gem d20s 3.5 ms. Planning a throw runs on a worker thread: 0.5 ms for one die, 12 ms for six.

Not done. Never loaded into Resolume on macOS; no presets and no OpenFX port. The browser demo runs the plugin's own C++ compiled to WebAssembly, with its shaders held to the plugin's character for character; on the page the Font list is Built-in only (a font file still loads), and throws are planned on the page's thread.