Recently, I was asked to develop a way to easily create a branched narrative, where the user can select options to progress the story in their own path. After a couple hours of fiddling around with different options I managed to produce this simple code.
### STORY BRANCH MANAGEMENT
class Branch:
def __init__(self, dialogue, options={}):
self.dialogue = dialogue
self.options = options
self.keys = list(options.keys())
self.canbranch = options != {}
def __iter__(self):
for x in self.keys:
yield x
def __str__(self):
return self.dialogue
def choose(self, choice):
return self.options[self.keys[choice]]
story_main = Branch("You find yourself in a room with three doors, which one do you choose?", {
"Left door":
Branch("You fell in a hole and died"),
"Middle door":
Branch("Oh hey, you win a free Parker pen"),
"Right door":
Branch("You tripped over the door frame", {
"Get up and walk away":
Branch("Oh well, at least you lived"),
"Die on the spot":
Branch("Nevermind...") } ),
"All of the above":
Branch("Well I guess that works") } )
### PLAY THE STORY
def play():
br = story_main
while br.canbranch:
# Output the current branch's dialogue
print(br)
# Create blank line, then displays the sub-branch choices as an enumerated list
print("")
for i,x in enumerate(br):
print("\t{}) {}".format(i + 1, x))
# Have the user to select an option
print("")
c = -1
while c not in range(len(br.keys)):
c = int(input("Select --> ")) - 1
# Update the current branch to the sub-branch that the user just chose
br = br.choose(c)
print("---")
# If the user reaches a 'final' branch (i.e, no choices), output it's dialogue and close the program after enter is hit.
input(str(br) + "\n---")
play()
The code itself makes sense I hope, but the main concern I have is with the part in the middle where we can create a story: story_main = Branch( ... )
. It seems a bit... strange. I've been told that it is readable, but it doesn't seem very 'pythonic'. I assume this is because of the way I've used dictionaries to store a choice and its corresponding sub-branch as the key and value respectively.
If you can't understand how the story is written, I'll brief over what it does so that it may be easier to grasp. When the program is opened, you're told "You find yourself in a room ... "
Then, you are given a list of options, "Left door"
, "Right door"
, and so on. If you chose to enter the right door, the program would output "You tripped over the doorframe"
and give you some more options, "Get up and walk away"
and "Die on the spot"
. If you chose to die on the spot, it would output "Nevermind..."
and the story would end.
This is what the program looks like when run:
So as you can see it works, but is it acceptable to use this method?
EDIT: The answers so far have both recommended to save the story as an external file in some way, and then access it from within the code. I imagine this is for organisation, and it was actually what I originally had in mind. The program from which the code I provided is from did do something like this (although likely less convenient than suggested methods in most respects). If anyone has more suggestions on how storing the narrative could be optimised, that would also be appreciated.