JSPM

open-dice-dnd

1.1.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 99
  • Score
    100M100P100Q73795F
  • License MIT

A 3D physics-based dice rolling engine built with Three.js and Cannon.js

Package Exports

  • open-dice-dnd

Readme

๐ŸŽฒ Open Dice DnD

A beautiful 3D physics-based dice rolling engine built with Three.js and Cannon.js. Perfect for adding realistic dice rolling to your web applications, games, or tabletop RPG tools!

โœจ Features

  • ๐ŸŽฏ Physics-based dice rolling with realistic behavior
  • ๐ŸŽจ Support for multiple dice types: d4, d6, d8, d10, d12, d20, d100
  • ๐ŸŽฌ Smooth animations and shadows
  • ๐Ÿ“ฑ Responsive and works on any container size
  • ๐Ÿ”ง Easy-to-use API
  • ๐Ÿ“ฆ Lightweight and modular
  • ๐ŸŽญ Customizable throw speed and spin
  • ๐ŸŒˆ Customizable dice colors (dice body, text, and background)
  • ๐Ÿ”’ Secret roll mode (hides numbers with "?")

๐Ÿ“ฆ Installation

Via npm

npm install open-dice-dnd

Local Development

git clone <repository-url>
cd open-dice-dnd
npm install

๐Ÿš€ Quick Start

Basic Usage

import { DiceRoller } from 'open-dice-dnd';

// Get your container element
const container = document.getElementById('dice-container');

// Create a new dice roller instance
const diceRoller = new DiceRoller({
    container: container,
    throwSpeed: 15,
    throwSpin: 20,
    onRollComplete: (total) => {
        console.log('Roll total:', total);
    }
});

// Roll some dice!
const diceConfig = [
    { dice: 'd20', rolled: 15 },
    { dice: 'd6', rolled: 4 }
];

diceRoller.roll(diceConfig).then(total => {
    console.log('Dice settled! Total:', total);
});

HTML Setup

<!DOCTYPE html>
<html>
<head>
    <style>
        #dice-container {
            width: 100vw;
            height: 100vh;
            position: relative;
        }
    </style>
</head>
<body>
    <div id="dice-container"></div>
    <script type="module" src="main.js"></script>
</body>
</html>

๐Ÿ“– API Reference

new DiceRoller(options)

Creates a new dice roller instance.

Options

Option Type Default Description
container HTMLElement Required The DOM element to render the canvas in
width number Container width Canvas width in pixels
height number Container height Canvas height in pixels
throwSpeed number 15 Initial throw speed (5-30)
throwSpin number 20 Initial throw spin (5-40)
onRollComplete function null Callback function when dice settle

Methods

roll(diceConfig)

Roll dice with the given configuration.

Parameters:

  • diceConfig (Array): Array of dice configurations
    • dice (string): Type of die - 'd4', 'd6', 'd8', 'd10', 'd12', 'd20', or 'd100'
    • rolled (number, optional): Target number for the roll
    • diceColor (number, optional): Dice body color as numeric hex (e.g., 0xf0f0f0)
    • textColor (string, optional): Text color as hex string (e.g., '#FFFFFF')
    • backgroundColor (string, optional): Background color as hex string (e.g., '#e74c3c')
    • isSecret (boolean, optional): Hide numbers with "?" for secret rolls (default: false)

Returns: Promise<number> - Promise that resolves with the total roll result

Example:

const result = await diceRoller.roll([
    { dice: 'd20', rolled: 18 },
    { dice: 'd6' },
    { dice: 'd8', rolled: 5 }
]);
console.log('Total:', result);

reset()

Reset and clear all dice from the scene with a fade animation.

Returns: Promise<void>

Example:

await diceRoller.reset();

setThrowSpeed(speed)

Update the throw speed.

Parameters:

  • speed (number): New throw speed (recommended: 5-30)

Example:

diceRoller.setThrowSpeed(20);

setThrowSpin(spin)

Update the throw spin.

Parameters:

  • spin (number): New throw spin (recommended: 5-40)

Example:

diceRoller.setThrowSpin(25);

destroy()

Destroy the dice roller instance and clean up all resources.

Example:

diceRoller.destroy();

๐ŸŽฎ Examples

Rolling Multiple Dice Types

const diceRoller = new DiceRoller({
    container: document.getElementById('dice-container')
});

// Roll a variety of dice
await diceRoller.roll([
    { dice: 'd20' },
    { dice: 'd12' },
    { dice: 'd10' },
    { dice: 'd8' },
    { dice: 'd6' },
    { dice: 'd4' }
]);

D100 (Percentile) Dice

// D100 automatically rolls two d10s
await diceRoller.roll([
    { dice: 'd100', rolled: 96 }
]);

Custom Dice Colors

// Customize dice appearance with custom colors
await diceRoller.roll([
    { 
        dice: 'd20', 
        diceColor: 0xff6b6b,        // Red dice body
        textColor: '#FFFFFF',        // White text
        backgroundColor: '#4ECDC4'   // Teal background
    },
    { 
        dice: 'd6', 
        diceColor: 0x95e1d3,        // Mint green dice body
        textColor: '#2C3E50',        // Dark blue text
        backgroundColor: '#F38BA8'   // Pink background
    }
]);

Secret Roll Mode

You can enable secret roll mode to hide all dice numbers with "?" characters. This is useful for GM rolls or surprise mechanics where you don't want players to see the actual result until revealed.

// Roll dice with secret mode enabled
await diceRoller.roll([
    { dice: 'd20', isSecret: true },
    { dice: 'd6', isSecret: true }
]);

// Mix secret and non-secret dice
await diceRoller.roll([
    { dice: 'd20', isSecret: true },  // Hidden
    { dice: 'd6', isSecret: false }   // Visible
]);

Note: The demo application includes a "Secret Roll" checkbox in the UI for easy toggling.

With Custom UI Controls

const diceRoller = new DiceRoller({
    container: document.getElementById('dice-container'),
    onRollComplete: (total) => {
        document.getElementById('result').textContent = `Total: ${total}`;
    }
});

// Button click handler
document.getElementById('roll-btn').addEventListener('click', () => {
    diceRoller.roll([
        { dice: 'd20' },
        { dice: 'd6' }
    ]);
});

// Reset button handler
document.getElementById('reset-btn').addEventListener('click', () => {
    diceRoller.reset();
});

React Integration

import { useEffect, useRef, useState } from 'react';
import { DiceRoller } from 'open-dice-dnd';

function DiceComponent() {
    const containerRef = useRef(null);
    const diceRollerRef = useRef(null);
    const [result, setResult] = useState(null);

    useEffect(() => {
        if (containerRef.current && !diceRollerRef.current) {
            diceRollerRef.current = new DiceRoller({
                container: containerRef.current,
                onRollComplete: (total) => {
                    setResult(total);
                }
            });
        }

        return () => {
            if (diceRollerRef.current) {
                diceRollerRef.current.destroy();
            }
        };
    }, []);

    const handleRoll = () => {
        diceRollerRef.current?.roll([
            { dice: 'd20' },
            { dice: 'd6' }
        ]);
    };

    return (
        <div>
            <div ref={containerRef} style={{ width: '100%', height: '500px' }} />
            <button onClick={handleRoll}>Roll Dice</button>
            {result && <p>Total: {result}</p>}
        </div>
    );
}

Vue Integration

<template>
    <div>
        <div ref="containerRef" style="width: 100%; height: 500px;"></div>
        <button @click="handleRoll">Roll Dice</button>
        <p v-if="result">Total: {{ result }}</p>
    </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { DiceRoller } from 'open-dice-dnd';

const containerRef = ref(null);
const result = ref(null);
let diceRoller = null;

onMounted(() => {
    if (containerRef.value) {
        diceRoller = new DiceRoller({
            container: containerRef.value,
            onRollComplete: (total) => {
                result.value = total;
            }
        });
    }
});

onUnmounted(() => {
    if (diceRoller) {
        diceRoller.destroy();
    }
});

const handleRoll = () => {
    if (diceRoller) {
        diceRoller.roll([
            { dice: 'd20' },
            { dice: 'd6' }
        ]);
    }
};
</script>

๐Ÿ› ๏ธ Development

Running the Demo

npm run dev

Then open your browser to http://localhost:5173

Building the Library

npm run build:lib

This creates the distributable files in the dist/ directory:

  • open-dice-dnd.es.js - ES module format
  • open-dice-dnd.umd.js - UMD format (for browsers and Node.js)

Building the Demo

npm run build

๐Ÿ“ Dice Types

Type Description Range
d4 4-sided die 1-4
d6 6-sided die (standard cube) 1-6
d8 8-sided die 1-8
d10 10-sided die 0-9 or 1-10
d12 12-sided die 1-12
d20 20-sided die 1-20
d100 Percentile die (two d10s) 00-99 or 1-100

๐Ÿ“ Changelog

[1.1.0] - 2025-10-19

โœจ New Features

Customization:

  • ๐ŸŒˆ Added dice color customization support
    • diceColor: Customize dice body color (numeric hex format)
    • textColor: Customize text color (hex string format)
    • backgroundColor: Customize face background color (hex string format)
  • ๐Ÿ”’ Added secret roll mode
    • All dice numbers replaced with "?" characters
    • Perfect for GM rolls or surprise mechanics
    • Available via UI checkbox in demo

Demo UI Improvements:

  • ๐ŸŽจ Added color picker controls for easy color customization
  • ๐ŸŽฏ Quick apply colors to all dice in configuration
  • ๐Ÿ“ Multiple color preset examples
  • โœจ Real-time color synchronization between pickers and hex inputs

[1.0.0] - 2025-10-03

๐ŸŽ‰ Initial Release

Core Features:

  • โœจ 3D physics-based dice rolling engine
  • ๐ŸŽฒ Support for all standard RPG dice types (d4, d6, d8, d10, d12, d20, d100)
  • ๐ŸŽฏ Realistic physics simulation using Cannon.js
  • ๐ŸŽจ Beautiful 3D rendering with Three.js
  • ๐Ÿ“ฑ Responsive design that works on any container size

API:

  • ๐Ÿ”ง Class-based DiceRoller API for easy integration
  • โšก Promise-based roll method for async/await support
  • ๐ŸŽช Event callbacks for roll completion
  • ๐ŸŽ›๏ธ Customizable throw speed and spin
  • ๐Ÿงน Automatic resource cleanup and memory management

Developer Experience:

  • ๐Ÿ“ฆ Available as npm package: open-dice-dnd
  • ๐Ÿ“š Comprehensive documentation with examples
  • โš›๏ธ React integration example
  • ๐Ÿ’š Vue integration example
  • ๐ŸŽฎ Live demo included

Build & Distribution:

  • ๐Ÿ“ฆ ES module format (7.83 kB gzipped)
  • ๐ŸŒ UMD format for browser compatibility
  • ๐ŸŒฒ Tree-shakeable exports
  • ๐Ÿ”— Peer dependencies for optimal bundle size

License:

  • ๐Ÿ“„ MIT License

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

๐Ÿ“„ License

MIT License - see LICENSE file for details

๐Ÿ™ Credits

Built with:

๐Ÿ“ฎ Support

If you encounter any issues or have questions, please file an issue on the GitHub repository.


Made with โค๏ธ for tabletop gaming enthusiasts and web developers