Created
November 2, 2011 04:47
-
-
Save cgranade/1332877 to your computer and use it in GitHub Desktop.
Proof of concept for story scripting in Python with coroutines.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
## | |
# storyyield.py: Proof of concept for story scripting in Python with coroutines. | |
## | |
# (c) 2011 Christopher E. Granade (cgranade@cgranade.com). | |
# Licensed under GPL v3. | |
## | |
from __future__ import print_function | |
## STORY ELEMENTS ## | |
class StoryElement(object): | |
pass | |
class DialogueLine(StoryElement): | |
def __init__(self, speaker, content): | |
self.speaker = speaker | |
self.content = content | |
class DialogueChoice(StoryElement): | |
def __init__(self, speaker, responses): | |
self.speaker = speaker | |
self.responses = responses | |
class Character(StoryElement): | |
def __init__(self, name): | |
self.name = name | |
def say(self, what): | |
return DialogueLine(self, what) | |
def offer_choice(self, responses): | |
return DialogueChoice(self, responses) | |
## MONKEY PATCHING FOR UI DISPLAY ## | |
# NOTE: This monkey patching would ideally be the glue between the story | |
# support and the rest of the game engine. | |
# By implementing via monkey patching, the glue can be replaced based | |
# on the current need, such as with a basic GUI for allowing authors to | |
# debug their stories without playing the full game. | |
# TODO: consider making a decorator to ease monkey-patching here. | |
def print_dialogue_line(self): | |
print("%s:\t%s" % (self.speaker.name, self.content)) | |
DialogueLine.handle = print_dialogue_line | |
def handle_dialogue_choice(self): | |
print("Dialogue choice for %s:" % self.speaker.name) | |
for idx in range(len(self.responses)): | |
print("\t%d: %s" % (idx, self.responses[idx])) | |
player_resp = raw_input(u"> ") | |
return int(player_resp) | |
DialogueChoice.handle = handle_dialogue_choice | |
## STORY SCENES ## | |
# NOTE: Authors need only be concerned with this part of the file. | |
def scene_test(): | |
alice = Character("Alice") | |
bob = Character("Bob") | |
yield alice.say("Hello, Bob.") | |
yield bob.say("That's supposed to be 'Hello, world', I think.") | |
resp = yield alice.offer_choice(["Oh, yeah.", "I'm more creative than that!"]) | |
if resp == 0: | |
yield bob.say("Keeping it traditional, K&R style. I love it.") | |
else: | |
yield bob.say("Next I know, you'll be telling me that you don't like pointers!") | |
## MAIN BLOCK ## | |
if __name__ == "__main__": | |
story_generator = scene_test() | |
try: | |
story_elem = story_generator.next() | |
while True: | |
retval = story_elem.handle() | |
story_elem = story_generator.send(retval) | |
except StopIteration: | |
print("\nEnd of story!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment