Semantic timeline
Present a roll journal with explosions, rerolls, drops, classifications, and progress callbacks.
This article documents the published v2. For the current physics preview, see the v3 guide. V3 ↗ Licenses ↗
displayTimeline() receives an already resolved journal. Each entry in dice defines identity, sides, and theme; faces come from roll and reroll events. View validates the whole journal before clearing the scene.
const result = await viewer.displayTimeline({
id: 'explosion-1',
mode: 'physics',
dice: [
{ id: 'root', sides: 6 },
{ id: 'child', sides: 6 }
],
events: [
{ sequence: 1, type: 'roll', subject: 'die', dieId: 'root', parentDieId: null, rollIndex: 1, sourceNodeId: 'n1', value: 6 },
{ sequence: 2, type: 'roll', subject: 'die', dieId: 'child', parentDieId: 'root', rollIndex: 1, sourceNodeId: 'n1', value: 4 },
{ sequence: 3, type: 'explode', subject: 'die', dieId: 'root', parentDieId: null, rollIndex: 1, sourceNodeId: 'n1', childDieId: 'child', value: 4, reason: 'explode' }
]
})
console.log(result.eventCount, result.phaseCount, result.degraded)
Event types
All events have a strictly increasing positive sequence, dieId, parentDieId, rollIndex, and sourceNodeId; subject may be 'die'.
type |
Specific fields | Presentation |
|---|---|---|
roll |
value |
Reveals the first face |
reroll |
from, to, reason |
Changes the face; reason is reroll, reroll-once, unique, or unique-once |
explode |
childDieId, value, reason |
Introduces a child; reason is explode, compound, or penetrate |
transform |
from, to, reason |
Semantic adjustment; reason is minimum, maximum, penetrate, or compound |
include |
contribution |
Includes a contribution |
exclude |
reason |
Marks a drop; reason is drop, keep, or compound-absorbed |
classify |
outcome |
Highlights success, failure, neutral, critical-success, or critical-failure |
Validation covers IDs, references, initial rolls, lineage, cycles, and transitions. Do not invent a timeline from final values without rebuilding these relationships. Keep Core’s dice and matching events together.
compound and penetrate can yield values with no matching physical face. View keeps a valid face and shows the adjustment as a badge; it never invents a new face. minimum and maximum update state without their own choreography.
Configurable effects
await viewer.updateOptions({
timeline: {
maxDurationMs: 16_000,
effects: {
explode: { origin: 'source', burstHeight: 1.6, spread: 0.8 },
reroll: { style: 'hop', hopHeight: 2.2 },
criticalSuccess: { pulses: 2 },
compound: { showBadge: true }
}
}
})
Every effect accepts enabled, delayMs, durationMs, intensity (0..1), and color. Effects include explode, compound, penetrate, reroll, unique, keep, drop, success, failure, neutral, criticalSuccess, and criticalFailure. reroll/unique offer hop, edge, or spin; explode offers source or edge; critical effects offer pulses; compound/penetrate offer showBadge. updateOptions() merges each effect deeply.
timeline.enabled defaults to true; maxEvents to 500, maxDurationMs to 12000, and phaseGapMs to 180. If disabled or over budget, View presents the final flat state and returns degraded: true. Turning off an effect changes choreography only, never the face or outcome.
Synchronize UI and scene
const viewer = new DiceResultViewer({
container: '#dice-stage',
onTimelineProgress(progress) {
renderSubtotal(progress.dice)
console.log(progress.stage, progress.completedEventSequences)
}
})
The immutable snapshot reports stage (initial, phase, complete), phaseIndex, phaseCount, phaseId, effect, revealedDieIds, visible { id, value, discarded } dice, and completed event sequences. In physics, an explosion child may be released as soon as its parent settles, before other dice in that phase. Degraded flat playback emits only initial and complete. Callback errors are isolated.
displayTimeline() returns dice, durationMs, eventCount, phaseCount, and degraded. Unlike display(), it propagates graphical, asset, and physics failures so partial playback cannot count as success.