Dojo Darelir, the School of Xenograg the Sorcerer

Category: Game Programming

Converted Map of Wizardry: Proving Grounds of the Mad Overlord, Level 1

December 20, 2025

At long last, I have achieved a milestone on this pet project.

The original maps of the Wizardry: Proving Grounds of the Mad Overlord computer roleplaying game (CRPG) utilized a wrap-around technique to create the illusion of a larger area than just a 20-by-20 grid. Here is the original grid of Level 1:

original map for Level 1

My pet project is converting these into maps rendered in HTML from a library of reusable images. These images are (with two exceptions) built as 4-by-4 grids. This allows for actual walls between adjacent areas. I am also “unrolling” all wrap-arounds.

The first milestone was completing Level 1 to my satisfaction. I have flipped and rotated it to place the entry stairs in the upper-left corner:

Programming d20 Combat: the Core Function

February 21, 2025

I defined the Combatant object in a previous post. Here is the core function that utilizes it:

function combatantAttacksCombatantOnce(
    Combatant $attacker, 
    Combatant $defender, 
    ProbabilitySet $probabilitySet
): SingleAttackResultIsSuccess|SingleAttackResultIsFailure|SingleAttackResultNotAttack
{
    ...
}

Although this function handles a single attack, all the input parameters contain the data for all attacks. I did this intentionally with an eye on how it will be invoked. The first time combatantAttacksCombatantOnce() is called, it will resolve the first attack. A second call will resolve the second attack, if it is defined.

The function returns one of three possible outcomes: success, failure, or not-attack. This last one is crucial as combatantAttacksCombatantOnce() could be inadvertently called again despite no more defined attacks. Rather than throw an Exception that must be caught, I utilize a defined third value that can simply be checked for or ignored.

Programming d20 Combat: What Has Come Before

February 18, 2025

I created the Game Programming category over two years ago. At the time, though, my actual game programming was at a nadir. Several prior attempts at building a d20 combat system had left me unsatisfied. I recently found an interest, again, so here we are.

Much of the prior work is good; I am not starting over. This post is to highlight the core elements that my new work is leveraging.

The original and still current goal of this project is to allow me to compare combat rules between any of the editions of D&D as well as my own homebrew versions. Wedded to this is a second goal of using this problem domain to experiment with and gain experience with programming concepts new to me. Lately, this has been functional programming—but only where applicable. As with any large project, some components are best composed functionally while others are best as objects. Supporting both/all in one project is a great real-world experience. Oh, and my preferred programming language is PHP—even on command line. Experimenting with new features recently added to the language is of huge practical value.

Controlling all variables except the edition rules means having the identical die rolls at all points. My first attempt was via a “Dice Tray” concept but that encountered serious problems around usage. So my second attempt was—and still is—via a Probability Set. That component is then utilized by a Dice component to produce random results within the desired ranges.

Lastly, the data structure that I am using as my starting point is named Combatant. This is a D&D character distilled down to the essential elements needed for combat. I just rewrote this using the readonly class feature added in PHP 8.2:

final readonly class Combatant
{
    public function __construct(
        public string $identity,
        public int $defenseValue,
        public AttackSeries $attacks,
    ) {}
}

Using Computers To Play Non-Computer Games Better

November 25, 2022

Many years ago, I was the Computer Statistician of my High School’s varsity football team. It was an unique position on the managerial squad. One of our coaches had purchased a software application for analyzing opposing teams’ offenses. Team scouts would collect the kind of data the application could analyze. My after-hours job was mostly data entry of any newly-arrived scouting reports but, more importantly, of running the analysis report of our next opposing team as soon as all relevant data was entered.

These reports were printed out on wide fan-fold paper because the bulk of each one was numerous ASCII grids that corresponded to lateral field positions. These simple graphics helped non-technical coaches interpret the results—statistical breakdowns of behavioral tendencies in an opponent’s play-calling. The breakdown categories were the traditional ones scouts and coaches use without computers: 1st-and-10, 2nd-and-long, et. al.

So I learned early that computers could be used for more than just playing games. They could be used as tools to help me play other games better. Even games that had nothing to do with computers.

I had found Dungeons & Dragons in Middle School, and already knew a few things about probability and statistics. I had been an user of computers, though mostly for playing games. I had even hacked game data once or twice. That only made the game easier to play; it did not make me a better player.

As the football seasons progressed, I watched those reports be used by the coaches to make our team play better through adaptation to our opponents’ patterns of play. Knowledge was power.

All that led to computer programming. My first original programs were various tools and toys for or related to D&D. I still write them in my leisure time, today. I intend to blog about them someday. See the Game Programming category for those posts.