Performance in an RPG application

Interpret benchmarks, reuse plans, choose result projections and measure your game's full path.

Throughput is one part of the experience

In the reproducible benchmark, Dice Core processed tens of thousands of simple expressions per second under Node.js. The three comparison packages were faster for those operations. That measurement can help size a server, but an actual roll may also include validation, rules, persistence, transport and sometimes 3D animation. Measure the path your game runs.

A full rollRpgDice call returns a total plus individual dice, groups, events and replay metadata. These fields help explain a roll in the UI and reproduce it later. Compare libraries by the data contract your application needs, too.

Reuse a plan for recurring expressions

When the same expression is rolled repeatedly, compile it once and pass the plan to subsequent rolls:

import { compileRpgDice, rollRpgDice } from '@erpg/dicecore/core'

const attack = compileRpgDice('2d20kh1+5')

function rollAttack() {
  return rollRpgDice(attack)
}

The benchmark harness measures this mode separately with 4d6kh3. It is a different workflow from the comparison table, which repeats an expression with Dice Core’s default cache enabled. When expressions change on every request, measure their compilation cost too.

Request the projection you need

Dice Core offers different levels of result detail. Select the one needed by your screen:

API When to use it
rollRpgDice Full result, including groups and events
rollRpgDiceDetails Dice data without groups, events or output text
rollRpgDiceSummary A summary without dice or events
import { rollRpgDiceSummary } from '@erpg/dicecore/core'

const summary = rollRpgDiceSummary('2d6+3')
console.log(summary.total)

These APIs have different contracts. Choosing the right projection reduces how much data the application consumes; we do not assume a throughput gain without measuring your case.

Validate public input before execution

For public notation fields, inspectRpgDiceNotation reports validity and estimated cost without rolling. Set cost limits appropriate for your product:

import { inspectRpgDiceNotation } from '@erpg/dicecore/core'

const inspection = inspectRpgDiceNotation('4d6kh3')
if (!inspection.isValid) {
  console.error(inspection.error.code)
} else {
  console.log(inspection.cost.totalStaticDice)
}

Inspecting and then rolling costs more than a single roll; use the extra step when the UI or a limits policy requires prior validation.

Seed, replay and random source

Without a seed, Dice Core obtains entropy from crypto.getRandomValues. A supplied seed makes results reproducible; a replay descriptor reproduces a roll and validates its expression. Those modes have different costs. The benchmark compares default APIs and measures a fixed seed in a separate experiment.

const result = rollRpgDice('2d20kh1', { seed: 'session-42' })
const again = rollRpgDice(result.input, { replay: result.replay })

For an application, the final test should include the target device or server, common expressions, result serialization and Dice View’s visual cost. Read the benchmark method before interpreting its numbers.