I wonder if you can help me.
I'm writing a game (2d) which allows players to take multiple routes, some of which branch/merge - perhaps even loop. Each section of开发者_Python百科 the game will decide which section is loaded next.
I'm calling each section an IStoryElement - And I'm wondering how best to link these elements up in a way that is easily changed/configured and at the same time, graphable
I'm going to have an engine/factory assembly which will load the appropriate StoryElement
(s) based on various config options.
I initially planned to give each StoryElement
a NextElement() As IStoryElement
property and a Completed()
event. When the vent fires, the engine reads the NextElement property to find the next StoryElement
.
The downside to this is that if I ever wanted to graph all the routes through the game, I would be unable to - I couldn't determine all possible targets for each StoryElement
.
I considered a couple of other solutions but they all feel a little clunky - eg Do I need an additional layer of abstraction? ie StoryElementPlayers or similar - Each one would be responsible for stringing together multiple StoryElement
perhaps a Series and a ChoicePlayer with each responsible for graphing its own StoryElement
- But this will just move the problem up a layer.
In short, I need some way of emulating a simple but dynamic workflow (but I'd rather not actually use WWF). Is there a pattern for something this simple? All the ones I've managed to find relate to more advanced control flow (parallel processing, etc.)
It might help to think about the StoryElement
objects as nodes in a directed graph. The edges of the graph could be represented by StoryElementTransition
objects (or some similar name). A StoryElementTransition
could contain references to the state you want to transition out of, the state you want to transition into, and maybe the event that triggers the transition.
By setting up your story as a graph, you open up the possibility of running a directed graph traversal algorithm to determine all the possible routes through the game. For example, you can run a Depth First Search algorithm on the Event graph, pushing each state and transition on a stack, and printing the entire stack once you reach an end state.
I know this question has an accepted answer and probably you've settled anyway, but I must say I've been thinking about that lately ("how should we model a storyline-centric game?") and the conclusions I've come to as of now are:
- Stories are data, they shouldn't be defined anywhere in code.
(The same applies for gameplay elements, for example you shouldn't have a Goblin
Class, instead you could load an Enemy.Creep
called "Goblin" from some database of enemies.)
- Most designs you can come up with will be limited or hard to extend.
This is a golden rule of design to me: make everything that may be extended, extensible. So make a good hierarchy of simple classes and interfaces that don't do more than they should and do it well. Because in some point you may want an event to be triggered by killing 50 goblins in the forest and if your design isn't good you'd have to adapt a story or re-factor a framework, both bad things.
- Most professional games rely on scripting and an engine.
There's a reason to this. First, the code that renders the game can be easily optimized if it's small, and all the story elements can be defined in either a common (like Lua) scripting language or even some custom notation. So you could have your characters defined in YAML or whatever you like.
- You shouldn't have to touch your engine after a point, and focus on the story.
This means that you'd be editing story files (databases? markups? scripts?) and seeing how they play together, while leaving your compiler alone.
精彩评论