When I had finished planning what I wanted my generator to do, I assumed I would be able to jump straight into building it. This was far from being the case – I quickly realised that I would have to define the scope of the generator more clearly if I were to have any hope of finishing it before the deadline, as understanding what I wanted the generator to do and how it would go about it were two very different propositions. I wasn’t prepared for quite how long this was going to take, or quite how many false starts I would end up making. Jacky’s work was continuing apace, and I felt like I was lagging behind.
Design Attempt 1 – structures and storylets
My first swing at designing involved using a storylet system (as mentioned in the previous devlog) which would check for levelCount, progress, and any other prerequisites set by previous storylets. However, I would need some consistency in how the levels worked in order to deliver a coherent narrative structure, akin to the one I had defined in my research. Through a discussion on campus, Jacky and I decided that each ‘level’ would be divided into three ‘versions’, each depicting a different phase of the development process: graybox, textured, and populated. For each version we landed on a three paragraph structure – one triggered on entering a level, one on entering the ‘killbox’ in the centre, and one on leaving the level. The idea was for an unnamed lead developer to reflect on the contributions of various ‘disappeared’ level designers on their lauded 90s FPS – by the time the player entered the second and third set of stages they would be assuming something about what had happened to the developer; in the fourth set they would question that assumption, and in the fifth they would be hit with the reality of what had happened.
I used Unity’s scriptable objects as a way to integrate my storylets. Jsons might have been appropriate, but I didn’t want the game to have to parse every single json in order to find out which ones were appropriate to show the player; better just to list all the ‘segment’ scriptable objects and have them point to individual jsons which could be imported and presented to the player. First, the script ‘stacked’ the deck by removing all inappropriate segments; then it would shuffle and return a random segment. Each segment contained three paragraphs, which would be assigned to three different colliders in the generated level, and displayed to the player OnTriggerEnter().

The problem was ultimately one of time, effort and coherence. Having designed this system, and then begun work on filling in the text, I realised just how interdependent each storylet would be on the others, and how – in order to avoid a sense of repetition or dissonance – I would be doing both high intensity curatorial work (to make it make sense) and high intensity procedural work (to make it feel different with each playthrough). They may have been the correct fit for a horror story generally, but storylets (seem to) function best when they’re used as events, and tied to specific player actions. With little in the way of player interaction in this piece, they ended up feeling neither particularly reactive or elegant.
In hindsight, I also think this decision constrained Jacky’s creativity somewhat; in order to accommodate what I perceived to be an easier approach to text generation, he directed his generator away from some of the more surprising levels it had been making.
Design Attempt 2 – setpieces
Frustrated with the vagueness of my storylet approach, I revisited one of my earlier devlogs (it’s the same one that’s linked above). Convinced that a lack of set-pieces was blocking me, I talked to Jacky about changing the game’s construction so that it reflected one of three possible set-pieces:
- the multiplication of features (more barrels or lights or stairs)
- the subtraction of features (fewer walls or floors or lights or textures)
- or a presence being felt in the levels (perhaps the previous developers spawning as ghosts)
Ultimately, though this provided Jacky with new ways to deepen his level generation (he ended up pushing the multiplication side of things), it rendered my text generation somewhat moot; the randomisation would’ve had little narrative effect, and I might as well have written each of these set-pieces myself.
Design Attempt 3 – just build a thing
I returned to probably the most fundamental question – not ‘what would be best to build?’ or ‘how should I build it?’ but ‘what am I currently able to build?’ and ‘what can I build in the time that I have?’ In some design tasks, responding to time pressures and working within one’s own limits are better actions than planning something ambitious. Maybe I would be able to alter or develop a simpler core generator into something more structurally responsive, but for now I just needed to make something that would consistently output the text.
I revisited the experimental procedural text generators I had written in Perchance, and set about jamming out a 5-beat structure similar to the 5-act one proposed in Design Attempt 1, but limiting each ‘beat’ to a ‘comment’.

It was during this design iteration that I reconsidered one of my earliest assumptions: that this story needed to be about somebody other than the narrator. It was far simpler to construct something in the first person, and have the player relate – through listening/reading – to that character rather than to another that they were talking about.
While talking about this potential new direction, Jacky suggested we define how both the level and the story would change over time. I thought this was a brilliant suggestion, and one that I’ve found myself positing to designers and writers when working on theatre shows, but never really in game design!
By leaning into this idea of change over time, I could circumvent the problem of procedurally generating narrative immediacy. Instead, the sense of horror could be tied directly to the number of playthroughs a player had completed – things would get stranger and more complex as the player continued. This, we figured, could be juxtaposed nicely with a gradual deterioration in level fidelity – blockier textures, posterized textures, more noise in the audio mixer – to create a sense of chaos, terror, gradual unwinding, and to erode trust and create sympathy for an obviously haunted narrator.
Conclusion
From this process I concluded that procedural text generators are naturally good at some things – atmosphere and tone, different versions of the same thing – but quite inflexible when it comes to others. Working procedurally with narrative structure, while obviously possible, takes a lot of design time – something that, when taken alongside learning how to create a text generator in the first place, I ended up lacking on this project. Ultimately, the product worked at a much simpler level than I had first imagined, but that was only appropriate for the timescale (and my relative level of skill!).