Experimental Development Project: First Steps

Identifying a Project

In my experimental mini-devs I had mostly focused on procedural text generation, researching VR, and messing about with shaders. I enjoyed working on procedural text, so was keen to push that further, but didn’t have a clear starting point for what I wanted to create.

Luckily, Jacky shared the beginnings of his Experimental Development project – a procedurally generated maze that would make the player feel like a ghost – on the support group chat. I was struck with a lot of ideas for how a procedural text generator might interact with a procedural level generator (finding spooky notes in different rooms, ‘hearing’ a voice as you explore, an isometric dungeon generator with procedural encounter descriptions), and we soon agreed to collaborate.

We set up a meeting to talk through possible avenues, and settled on a direction partly inspired by the low-resolution shader techniques Zsan had shared with us: the levels would be from a 90s/early 2000s FPS, and the player’s progress would be accompanied by a procedurally generated commentary, displayed in text on a era-appropriate HUD.

We also put together a Miro for collecting design tutorials, aesthetic inspiration, useful tools and examples of developer commentary.

Our Miro after 1 week

From our research (and also a suspicion that this might be the best way to keep scope manageable) we concluded that deathmatch levels might be an appropriate constraint:

  • Deathmatch levels are self-contained and generally encourage players in a ‘looping’ direction. These loops are arranged around central ‘killboxes’ – open spaces that players are naturally directed towards. We suspect this design will make generating levels easier than ‘single-player’ levels; indeed, Jacky’s generator already functioned off a ‘figure-of-eight’ rule, which connected two ‘edge’ rooms to one ‘central’ room.
  • Levels each have a unique, vivid aesthetic, but their architectural and environmental design aren’t necessarily governed by a linear or progressive narrative, nor do they have to connect to each other. This means the level generation procedure doesn’t have to worry about building ‘towards’ a particular end, funnelling the player toward an exit, or having a logic to the order of aesthetics (textures going from light to dark or warm to cold, for example).
  • Deathmatch levels are arenas and play-spaces rather than puzzles or set-pieces. The logic of the former approach is much quicker to code than the latter, which requires a more rigorous set of conditions to be met in order to produce a ‘correct’ map (a room with a key cannot be spawned behind a locked door, for example; the lever to control a bridge must be on the side at which the player will first arrive, unless there is an alternate route – complicated!).

The first instance of FPS levels being designed and released specifically for multiplayer occurred in Quake, so on Friday we sat down to watch some walkthroughs of Quake Deathmatch levels for inspiration.

A video walkthrough of Quake’s DM5 – The Cistern

Identifying My Tool

In practising procedural text generation, I had already used two tools: Kate Compton’s Tracery and Perchance, a web-based platform for creating and sharing text generators (which is very popular with the indie TTRPG scene).

The first product was a simple NPC generator, which I initially built in Tracery and then exported to Perchance.

Code, output and html for Sad NPCs

It outputs three sentences:

  • A character (adjective and occupation) and something they are doing
  • A description of something they are carrying (item, adjective for item, location on character)
  • An action by another character that affects them, or an objective they pursue and how they pursue it

In building this I found that using grammatical prepositions (after, before, with etc) as the first generative step made for much more distinct sentences, and allowed me to be more granular in my list-making. I also noticed that adjectives often made lines overly unique, which had the odd affect of making them feel more similar to previous lines. [reference Procedural Storytelling for Games here] This problem was solved by decreasing the likelihood of the generator assigning adjectives.

The second product I wrote was a Contestant Generator for Love Island. I analysed examples from ITV’s own Islander introduction copy and created a generator capable of outputting five short paragraphs, defined at the top by two random choices – gender (for grammar) and occupation (for puns) and gender (for grammar).

This generator was slightly more complex in the sense that more dictionaries were required (for hometowns, hobbies, attitudes etc.).

In order to achieve even this level of logical sense within a reasonable timeframe I had to sacrifice variation in sentence structure, so in some ways this generator is much simpler than the previous.

Two options for paragraph structures

Unfortunately, my research failed to find an easy way to connect a powerful tool like Perchance to Unity, so I was left with the following options:

  • Tracery
    • Pros:
      • Easy to understand
      • Built for randomness
    • Cons
      • Can’t see a super easy way to get it to ‘remember’ previous states
      • Less variable-friendly
      • JSON syntax a bit tiresome (lots of quotations)
  • Ink
    • Pros:
      • I’m already familiar with the syntax
      • Easy to implement in Unity
      • Remembers states very well; variable-friendly
    • Cons
      • Not explicitly designed for ‘generation’
      • Lists & variables are locked to single words, so might be hard to integrate more phrase-centric grammars
  • C#
    • Pros:
      • Native to Unity, no need for ‘bridging’ scripts or functions
      • I’m already familiar with the syntax
      • Very flexible, editable Lists
      • Feels like the Perchance ‘method’ could be relatively easily translated to C#
    • Cons:
      • Would have to write own functions for shuffling, choosing, etc.
      • Probably a similar level of syntax ‘stickiness’ with quotation marks for strings etc.

I’m still mulling over which to use, but I’m leaning towards creating my own functions in C# – this would add another facet of technical experimentation to this project, which might help me grow my skills further.

Planning a Generator

Kate Compton’s ‘So you want to build a generator?’ provides a handy guide to ideating, defining and then building a procedural generator, summarised here:

  • Write down the thing that your generator will make
  • Write down everything you know that makes for a successful example of one of those thingsproperties to strive for
  • Write down everything you know that makes for an unsuccessful example of one of those thingsconstraints to work around/within
  • Consider how a human would build these things – consult an expert, research ‘frameworks’
  • Decide on a generative methods – options include Distributive (like picking options from a deck of cards), Parametric (altering individual elements of a handmade object), Tile-based (chop the problem into units, have pre-made objects fill those units in different orders), and Grammar-based (a series of rules and symbols that ‘unpack’ into sub-rules and sub-symbols, like language, for instance).
  • Build and test your generator!

Over the next week, I will endeavour to answer these questions about the artifact I would like the generator to create, as well as getting in contact with some horror writers that I know and researching frameworks for writing these kinds of stories. I will also start scoping the generator, deciding how much text, how many times per level the generator will need to run, and what kind of connectivity I would like the generator to have with each level.