Technology TTRPGs

Motivation, History and a handful of Orcs

Hi potential readers!

My name is Luc, and this is my Blog. I started this blog to document my learnings in computational linguistics, share interesting facts and post about RPGs.

To start this blog off, I thought I’d write about one of my favorite open-source projects related to RPGs!

Orcpub, aka DungeonMastersVault Community Edition

Since inception of the first tabletop roleplaying games (TTRPGs), gameplay has revolved around the “Character Sheet”. Creation of these character sheets used to be a long, time-consuming process – having to write out your stats by hand after rolling for each of them, as well as making sure that what you were making was actually allowed within the system you were using. This all changed in the internet age, with the first online character builders popping up – at the time that Orcpub was created that was mainly D&D Beyond. Orcpub was created as a free alternative to D&D Beyond, to allow players to create their own characters using the parts of D&D that are under an open licence, as well as create their own content to add to the site as they wish. The original Orcpub is no longer available, as the creator made the code open-source after shutting down the website due to continued legal threats from Wizards of The Coast (The company that owns the rights to D&D). The project lives on as DungeonMastersVault Community Edition, which can still be found today at https://www.dungeonmastersvault.com/.

The Design behind Orcpub

Disclaimer: This part of the post was partially taken from Larry Christensens original writeup on Orcpub

Orcpub was written entirely in Clojure, a dialect of the lisp programming language based on the Java Platform. Like other Dialects of Lisp, Clojure treats code as data and has a lisp-like macro system.

The design is based around the concept of hierarchical option selections applying modifiers to a entity.

Consider D&D 5e as an example. In D&D 5e you build and maintain characters, which are entities, by selecting from a set of character options, such as race and class. When you select a race you will be afforded other option selections, such as subrace or subclass.

Option selections also apply modifiers to your character, such as ‘Darkvision 60’. Option selections are defined in templates. An entity is really just a record of hierarchical choices made.

A built entity is a collection of derived attributes and functions derived from applying all of the modifiers of all the choices made. Here is some pseudocode to this more concrete:

user> (def character-entity {:options {:race
                                       {:key :elf,
                                        :options {:subrace {:key :high-elf}}}}})
                                          
user> (def template {:selections [{:key :race
                                   :min 1
                                   :max 1
                                   :options [{:name "Elf"
                                              :key :elf
                                              :modifiers [(modifier ?dex-bonus (+ ?dex-bonus 2))
                                                          (modifier ?race "Elf")]
                                              :selections [{:key :subrace
                                                            :min 1
                                                            :max 1
                                                            :options [{:name "High Elf"
                                                                       :key :high-elf
                                                                       :modifiers [(modifier ?subrace "High Elf")
                                                                                   (modifier ?int-bonus (+ ?int-bonus 1))]}]}]}]}]}
                                                                 
user> (def built-character (build-entity charater-entity template))

user> built-character
{:race "Elf"
 :subrace "High Elf"
 :dex-bonus 2
 :int-bonus 1}