The Post About the Dialog System


The dialog system in Lepidoptera is one that feels a little too good to be true, using it as a programmer. It's been super easy to build content in it, and its flexibility isn't really limited in any way, as dialog's content resides in code alongside everything else you'd ever need. There's nothing groundbreaking about the system, it's just built in the way I'd want it, from the perspective of the person writing & implementing the dialog content.

The core feature set revolves around two 'modes': just displaying text, and being able to select a dialog option. Here's a quick example:

'just text':

Dialog options:


It's simple enough, giving a list of choices, and letting you choose any that aren't greyed out. The top option here has a field set to mask the actual text until its requirements are met. That's the gist of how it looks in game, so let's walk through all the code that got us there.


public static Dialog kitchenServer(GameObject requester)
{
    AlwaysAvailableResponse dontWant = new AlwaysAvailableResponse("No", dw1);
    WorldStateConditionalResponse want = new WorldStateConditionalResponse("Yes", w1, WorldData.WorldState.ON_KITCHEN_LIST, true);
    want.hidden = true;
    KnowledgeConditionalResponse rosiePickup = new KnowledgeConditionalResponse("Rosie's pickup.", rp1, PlayerData.Knowledge.ROSIE_NEEDS_MEAL_PICKUP);
    rosiePickup.masked = true;
    List<DialogResponse> kBasket = new List<DialogResponse>();
    kBasket.Add(rosiePickup);
    kBasket.Add(dontWant);
    kBasket.Add(want);
    kBasket.Add(wantCantHave);
    DialogSegment ds2 = new DialogSegment("You'd like some, I'd assume?", kBasket);
    DialogSegment ds1 = new DialogSegment("Today we're serving grilled vegetables.", ds2);
    return new Dialog(ds1);
}

Here's a very pared down version of this same dialog's actual code.  It's best read from the bottom up, as that's the way it gets displayed in game. So, a 'Dialog' object is basically just a container for a linked list, along with some helper methods to let the UI system know what it needs to do for whatever's coming down the pipe. The other objects are the real stuff we care about - DialogSegments and DialogResponses.  Dialog segments are the 'just text' modes, and Responses are the options you can choose. 'DialogResponse' is an abstract class that needs all child classes to define what its requirements are, as well as flags for being 'hidden', or 'masked'. This explains how there are actually four responses being added to the list, but only 3 visible in the screenshot - note how 'want' is set as a hidden response. Every element points directly to the next in the dialog sequence, giving the code its bottom-up structure. It's a little more awkward to write this way, but allows for compile-time assurance that the dialog we're writing isn't too broken.

The real fun comes in when looking at the elements of code stripped out of that block. DialogSegments can also hold Actions! That means we can execute any code we want mid-dialog. The other neat trick extends from the fact that methods to Dialog objects are constructed just before they're about to be displayed in game. That means we can do stuff like this:

DialogSegment w1;
if (GameManager.getWorldState().getStateVar(WorldData.WorldState.SERVED_KITCHEN_MEAL_DAY_ONE))
{
    w1 = new DialogSegment("You've already been served today. Don't be gettin' greedy, now.");
}
else
{
    w1 = new DialogSegment("Perfect, here you go!", w2, getFood, false);
}

We can mess with the construction of the dialog object based on game state! This technically means we don't need different response types, but that'd be much less convenient. Being able to mess with dialog object construction at this fine a level helps minimize any potential combinatoric explosion-type problems that would come from requiring a different dialog response chain for every variation we want. Plus it lets us display runtime values in the dialog text just by referencing them normally, no having to swap out and parse 'I want a variable here' type strings.

I'm sure this system has a bunch of downsides that I've not considered, because having a system that makes content with such flexibility and power that's this easy to use feels like cheating.

Thanks for reading!

Get Lepidoptera

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.