3D dice in the browser: how TerrainTale's roller works
A lot of "3D dice" on the web are an animation played over a number the server already picked. TerrainTale's dice roller isn't that: the six solids are built as real geometry, thrown with a rigid-body physics engine, and the result is read off whichever face ends up on top once they actually stop moving.
· 5 min read · TerrainTale

The dice are solids, not sprites
Each die is a true polyhedron: a tetrahedron (d4), a cube (d6), an octahedron (d8), a pentagonal trapezohedron (d10), a dodecahedron (d12) and an icosahedron (d20). They're built from vertices and a convex-hull routine that recovers the faces, so every face is planar and numbered the way real dice are — opposite faces sum to one more than the die's number of sides.
A physics engine, not a random-number generator wearing a costume
Press Roll and each die gets a random starting speed, spin and orientation, then a rigid-body physics engine bounces it off the tray floor, the rim and the other dice in the pool until everything settles. Nothing about the outcome exists before that simulation runs — it isn't a die rolled to match a number chosen ahead of time, the way some "3D dice" widgets fake it.
Only once a die is still is the result read: the face whose normal points straight up is the number, and on the d4 — which has no face pointing straight up — it's the corner that does. A die that ends up cocked, leaning on the rim or on another die, gets flicked and lands again, the same way you'd nudge a die that landed crooked on a real table.
What you can throw
The full D&D set — d4, d6, d8, d10, d12, d20 — up to 24 dice in a single roll, with a plus-or-minus modifier and, for the d20s specifically, a normal / advantage / disadvantage mode. Five dice sets (Amber, Obsidian, Ivory, Sapphire, Emerald) change the body and ink color of the whole tray. The last 12 rolls stay listed underneath so you can see what came before without scrolling back through a chat log.
When there's no WebGL
Some browsers or devices can't start 3D. The page detects that and falls back to a plain, fair random roll instead of failing — you still get a number, just without the tray. The tray itself lives in its own JavaScript chunk that only loads after the page mounts, so a crawler or a low-powered browser gets the full page and its FAQ without ever needing to run three.js.
It's a free stand-alone tool
The roller at /dice-roller isn't gated behind sign-in and doesn't try to be a character sheet or a rules engine — it just throws dice and reads the faces. Keep it open in a tab next to whatever you're running the table in, virtual or in person.
Why it's built this way
A page that just prints a random number is simpler to build than one that simulates physics on real polyhedra, so it's worth being clear about the trade being made: a bit more code and a moment's animation, in exchange for a roll you can actually watch happen instead of one you're asked to take on faith. For a game where the dice deciding a fight's outcome matters, that trade is the whole point of the tool.