Last we left off I had established the foundation of my game. At this point in the development cycle, I was probably 4-5 months in. About 4 of those months were spent developing a game that only had one thing in common with this new iteration: It was also a text adventure.
So let's talk about text adventures. Once I got to this point, I was like, "This is where the fun begins! The writing!"
Here is the basic template for a scene. A scene is a single screen that typically resolves with a choice.
scene["sceneTemplate"] = {
initialize = function()
--PRE-VARIABLES:
local dialogue = {
"dialogue"
}
local prompts = {
"prompt"
}
local nextScenes = {
"TEMPEND"
}
--DIALOGUE: create dialogue scene of parts created above.
thisScene = Dialogue(dialogue, prompts, nextScenes)
--SAVE GAME: save ID and store it in a json
saveFile()
--POST-VARIABLES:
end,
running = function()
--UPDATE: do dialogue scene
thisScene:update()
--QUERY: for transition to next scene, game or prompt option
if sceneChange then
sceneTransition(selectedID)
end
end,
terminate = function()
--CLEAN UP: run cleanup function for dialogue
thisScene:cleanUp()
end
}
This Dialogue object has three lists. One array is the dialogue on screen. Each new line of dialogue ends with a button prompt. When the button is pressed, the next line of dialogue is printed. Once all of the lines of dialogue are printed then the prompt window is generated and the player can make their choice.

Realization #1. If I provide a choice in every scene, my scene quantity will grow exponentially. I will spend the next 3 years writing the intro, eventually lose my mind, and give up on the project after the Playdate 2.0 releases.
Realization #2. Even if I provide minimal branching, each branch could arguably create a fully unique ending. How do I communicate that the player character met this NPC? How will having met this NPC affect future scenes? Millions of possible endings: my head explodes.
Realization #3. I could solve both of the above realizations by doing what most video games with "choice" do. And that would be to create the illusion of choice. You select the answer to snarkily reply, "Actually, I don't want to take the toaster oven." but the NPC gives you the toaster oven anyway for some reason.
After a few days of staring at my screen, I came up with some solutions.
Resolution #1. To resolve the exponential growth of branches and scenes I decided to have the sort of act structure that would have each act ending in essentially the same scene, no matter your choices. For example, each player might do something totally different on the train platform... but they all eventually board the train. Additionally, within Acts, I would sometimes consolidate to a significant scene/sequence that most players would likely experience.
I have illustrated this in Microsoft Paint.
Resolution #2. To accommodate the feeling of player agency while also not losing myself in an ocean of unique scenes, I wrote in an info system and favor system. This allowed me to easily input whether or not the player had obtained certain info (names, knowledge, circumstances) and also whether or not they had met and befriended certain characters. This allowed the choices made between acts to affect the trajectory while still maintaining the same foundational narrative structure. Every player character boards the train but they may be friends with certain characters or know certain things that other player characters might not.
Resolution #3. This one is unavoidable to a certain extent. I have to utilize the illusion of choice because there are simply too many options that a player could choose. I must narrow that down. However, there are a few things I can do to make it seem like the players' choices matter more.
- Try to regularly print unique lines based on specific info/variables/favor.
- Try to regularly branch to unique scenes when having specific info/variables/favor.
- Try to regularly reference previous choices.
With these tactics in mind, I began to write. Of course, complexity grew exponentially with each passing act making it harder and harder to keep track of all of the moving parts. But it was now manageable. To illustrate the growth here is a scene in Act 1:
local dialogue = {
"A scene."
}
local prompts = {
nil
}
local nextScenes = {
"act1_scene_next"
}
--DIALOGUE: create dialogue scene of parts created above.
thisScene = Dialogue(dialogue, prompts, nextScenes)
--SAVE GAME: save ID and store it in a json
saveFile()
And this is an Act 5 scene.
local dialogue = {}
local prompts = {
nil
}
local nextScenes = {}
if chosenCharacter:hasSomething() then
--VARIABLES:
dialogue = {
"One scene."
}
nextScenes = {
"act5_one_possible_scene"
}
elseif chosenCharacter:hasSomethingElse() then
--VARIABLES:
dialogue = {
"Another scene."
}
nextScenes = {
"act5_death_for_someone_maybe?"
}
elseif chosenCharacter:hasFavor() then
dialogue = {
"Another, another scene."
}
prompts = {
"Save Someone! [SPEED, DC 10]",
"Don't risk it."
}
nextScenes = {
"act5_save_someone_roll",
"act5_death_for_someone_maybe"
}
if chosenCharacter:getHarm(1) == "dying!" then
dialogue = {
"You die here."
}
nextScenes = {
"act5_death"
}
end
--VARIABLES:
chosenCharacter:addHarm()
chosenCharacter:addPartyMember(someone)
chosenCharacter:killPartyMember(someone)
elseif chosenCharacter:hasFavor("someone else") then
if chosenCharacter:getWeapon() == "None" then
dialogue = {
"Whole different scene."
}
--VARIABLES:
chosenCharacter:addHarm()
else
dialogue = {
"Even more different scene."
}
end
prompts = {
"Save the SOMEONE ELSE! [SPEED, DC 10]",
"Don't risk it."
}
nextScenes = {
"act5_save_someone_else_roll",
"act5_death_for_someone_else_maybe"
}
if chosenCharacter:getHarm(1) == "dying!" then
dialogue = {
"You die... Unfortunately."
}
nextScenes = {
"act5_death"
}
end
elseif chosenCharacter:hasFavor("another group") then
--VARIABLES:
chosenCharacter:addPartyMember("someone")
chosenCharacter:killPartyMember("someone")
chosenCharacter:addPartyMember("someone else else")
chosenCharacter:killPartyMember("someone else else")
if chosenCharacter:getWeapon() == "None" then
dialogue = {
"More potential tragedy."
}
--VARIABLES:
chosenCharacter:addHarm()
else
dialogue = {
"At least in this scene you have a weapon."
}
end
nextScenes = {
"act5_a_slightly_better_scene?"
}
if chosenCharacter:getHarm(1) == "dying!" then
dialogue = {
"Oh but you can die this way too..."
}
nextScenes = {
"act5_death"
}
end
end
--DIALOGUE: create dialogue scene of parts created above.
thisScene = Dialogue(dialogue, prompts, nextScenes)
--NO SAVE ON THIS BUSY SCENE
Now... Listen. I know that this is likely not the most elegant execution. And I'll say again: I am not a programmer or a developer. And yes, Act 4 and beyond was a nightmare to write. But imagine... After you've written all of these scenes... Will they work?
So on the next Dev Blog... We are going to talk about playtesting and also release a public playtest. See you then.