SwiftDice

0.1.0

A Swift package for tabletop RPG dice. Build dice expressions with Swift operators or parse standard notation like 4d6-L, then roll them. Supports drop and keep, exploding and reroll modifiers, Fudge dice, dice pools, and JSON round-tripping. Used by RolePlayingCore and DungeonCore.
mrlegowatch/SwiftDice

What's New

SwiftDice Swift

Code Coverage Swift Version Platform License: MIT

A Swift package for representing and rolling dice using standard tabletop RPG notation.

SwiftDice is built for developers implementing tabletop RPG mechanics who need more than a random number generator. Dice expressions are first-class Swift values that are composable with operators, parseable from notation strings, and serializable to JSON, so your game data layer and your dice logic speak the same language.

  • Operator-based expression building — write 4 * .d6, 2 * .d8 + 4, or (4 * .d6).dropping(.lowest) directly in Swift without formatting strings

  • Full notation parser — round-trips between Swift values and standard dice notation strings; DiceParser accepts everything from d6 to 4d6-L+d4

  • Drop and keep mechanics — dropping(.lowest), keeping(3, .highest), keeping(.highest) for ability rolls, advantage, and disadvantage

  • Exploding and reroll modifiers — per-die explosion chains and one-time reroll thresholds, combinable on a single die

  • Fudge/FATE dice — built-in dF support with the same operator and parser integration as standard dice

  • Pool mechanics — rollAll() returns per-die results before summing, enabling success-counting and per-die threshold logic

  • JSON round-trip — encode any Rollable as its notation string and decode it back

  • AnyRollable — a concrete, Equatable/Hashable/Codable value type wrapping any Rollable, so a struct gets dice-valued Codable for free:

    struct Treasure: Codable {
        let goldPerGoblin: AnyRollable   // decodes from `8` or `"2d6"` alike
    }

Installation

Add the package to your Package.swift:

dependencies: [
    .package(url: "https://github.com/mrlegowatch/SwiftDice.git", from: "0.1.0"),
],
targets: [
    .target(name: "YourTarget", dependencies: ["SwiftDice"]),
]

Quick Start

import SwiftDice

// Roll ability scores: 4d6, keep 3 highest
let abilityRoll = (4 * .d6).keeping(3, .highest)
let result = abilityRoll.roll()
print(result.result)       // e.g. 14
print(result.description)  // e.g. "((3 + 6 + 4 + 5) - 3)"

// Attack with advantage: 2d20, keep highest
let attack = (2 * .d20).keeping(.highest)

// Weapon damage: 2d8+4
let damage = 2 * .d8 + 4

// Parse from a notation string
if let gold = try? DiceParser().parse("5d4x10") {
    print(gold.roll().result)  // e.g. 80
}

For full API documentation — dice types, notation reference, drop/keep mechanics, exploding dice, JSON encoding, and error handling — build the documentation in Xcode via Product → Build Documentation.

Background

The dice implementation was originally developed as part of RolePlayingCore. Its early evolution is described in three posts on medium.com:

Description

  • Swift Tools 6.0.0
View More Packages from this Author

Dependencies

  • None
Last updated: Thu Oct 29 2026 21:08:11 GMT-0900 (Hawaii-Aleutian Daylight Time)