Give me Monsters! (Part 9)

After a long period of silence, time to get back to our series on modelling D&D using F#! In our last installment, we plugged our code into Fable Elmish, to create a crude application simulating and visualizing combat.

The main reason I didn’t write for so long was that, as I put things together, I realized there were flaws in the design. I made heavy changes during the December holidays to address some of them, but found it hard to break it down in smaller steps that would fit a blog post after the fact. I don’t see a reason why things would magically get easier if I wait longer, so I’ll bite the bullet and try to explain these changes today.

Design issues

What were the issues I ran into?

Our initial version was a direct implementation of a naive interpretation of the rules, which state that

On your turn, you can move a distance up to your speed and take one action.

This roughly translated to a model where each creature, on their turn, could issue one or more commands, updating the state (World), one command at a time:

type Command = 
    | Move of Direction
    | Action of Action
    | Done

So what was the problem with that?

More...

Give me Monsters! (Part 8)

In the previous installment of this series, we ended up with a primitive model for turn-based battles in Dungeons & Dragons, covering some of the rules related to movement. The model we came up with represents actions taken by creatures as commands, which we use to update the state of the world. One nice thing about this model is how easy it is to test it out, in the scripting environment or otherwise. However, it would be nice to observe what is going on visually. This will be our goal for today: take our existing domain model, and plug that into Fable Elmish to visualize our rules in action.

Warning: I claim zero expertise in Fable, Elmish or not. For that matter, I would rate my skills in web stuff as “inexistent”. All this to say that the Fable related code is likely going to have some flaws - would love to hear from people who actually know what they are doing, how I could do better ;)

More...

Lorentz Attactor visualization with Fable Elmish

Yesterday, I needed a bit of a break after a long day, and decided to try and visualize the Lorentz attractor in Fable. As it turns out, it wasn’t complicated, and I was pretty proud of the result, so I shared a gif on Twitter:

People of The Internet expressed interest in knowing more about this, so here we go: let’s talk about the Lorentz Attractor, F# and Fable.

More...

Give me Monsters! (Part 7)

Welcome back to our ever-expanding series attempting to model D&D 5e rules in F#! In our previous episode, we began to dive in the representation of turn-based combat. We left off with a sketch of a design, where we keep track of the state of affairs in a World entity, updating the position of each creatures by applying a Move command to it.

We also left a few open issues that need to be addressed. The most glaring issue at that point is that, in our current model, every creature can move in any direction, at any moment. This isn’t right: according to the rules,

On your turn, you can move a distance up to your speed. You can use as much or as little of your speed as you like on your turn. […] You can break up your movement on your turn, using some of your speed before and after your action.

To make that happen, we need to incorporate turns (which creature can currently make decisions), and movement (how many feet a creature is allowed to move).

More...

Give me Monsters! (Part 6)

It’s been a while since I posted any update in this series, but we are back! Besides life and work getting in the way, I also needed to give some thought on where I wanted to take this next. We have a reasonable draft model to represent Monsters at that point, but I feel it’s time to take a slightly different direction.

The driving question behind this whole project was, how can we check if an encounter between Adventurers and Monsters is balanced? To do this, I think the easiest approach is to simulate encounters. Put together some Monsters and Adventurers, let them fight it out, repeatedly, and see what happens.

This requires two distinct pieces:

  • an engine responsible for enforcing the rules, to determine what actions a creatures can take, and resolve what the results are,
  • some form of AI, to make reasonable decisions for the creatures, so we can simulate how an encounter might unfold.

The engine modeling the game itself is a prerequisite to build the AI system, so that is what we will start with. Once we have that piece in place, we should be able to deal with the AI part, and hopefully refactor the code we wrote so far to plug it in.

More...