A self-contained LiveComponent that renders the pixel-art 3D dice roller.
Drop it into any LiveView (inline or as a modal) and it manages its own state:
the current expression, the quick dice tray, and the last roll result. The 3D
animation is driven by the DiceRoller JavaScript hook which lives in
priv/static/dic_ex.min.js.
Usage
# in your LiveView template (inline)
<.live_component module={DicExWeb.DiceRoller} id="dice-roller" />
# as a modal — wrap it however you like
<.modal :if={@show_roller}>
<.live_component module={DicExWeb.DiceRoller} id="dice-roller" />
</.modal>Options
default— initial expression (default"1d20").theme—"obsidian"(default),"arcane"or"dnd". Tunes the pixel palette.engine—"3d"(default; Three.js + Rapier physics) or"2d"(canvas, no physics: the die tumbles in 2D and lands on the authoritative value). Both engines share the exact same Elixir roll; this only swaps the hook.rng— RNG module for the rolls (defaultnil⇒DicEx.RNG.Default, reproducible via:seed). PassDicEx.RNG.Entropyfor cryptographic, non-replayable randomness. Applies to whichever engine is selected.on_roll— apid(or registered name) to notify of every roll viasend/2with{:dic_ex_rolled, %{result: result, component: id}}. The host uses this to feed the AI game master the structured outcome.
Receiving rolls
<.live_component module={DicExWeb.DiceRoller} id="roller"
on_roll={self()} />
def handle_info({:dic_ex_rolled, %{result: result}}, socket) do
# result is a %DicEx.Result{}; feed its JSON map to the LLM
{:noreply, socket}
end