Friday, December 31, 2010

Musings on text-based game design

Man has it been awhile since I last did anything on this blog. For a while, I was handling a personal website through webs.com, but that ended up being really silly and dumb for something I wanted to keep personal. When I discovered Google Docs, though, I moved everything over there, where it was easier to keep track of my individual ideas. BUT! While I wait for my new computer to live again, I can't access GDocs - at least, not on my PS3 (which is where I'm typing this from).

Anyways. Lately, I've been musing about game design, and I've come to a conclusion - without an artist or musician, my games won't feel "good and polished". Instead of exposing my amateurish pixel art to the world (and my horrid attempts at composing chiptunes), why not just make a game that does everything entirely through text? Everything is described to the player instead of shown, which involves more imagination on the player's end. It's totally not me being lazy, no sir.

There seem to be three major approaches I can use:
(1) The Rogue-like Approach - this is where I use ASCII symbols to represent things in the game world, and I describe the character's interactions through short sentences dumped onto the screen. The final project would come out looking like ZZT, Megazeux, or pretty much any Rogue-like in exsistance. On the up-side, this would allow a greater sense of the player exsisting in the game-world, but the "graphics" may distract from the notion that this is primarily a text game, and not a fast-paced action sort of thing.
(2) The Interactive Fiction Approach - this is where I describe what happens to the character in response to s/he describing what the character does. This sort of storytelling mimics my experiences with role-playing games (the pen and paper kind), and is based strongly off of Interactive Fiction ("text adventures", as they were formerly called). The biggest downside to this is that I'd have to take into consideration *everything* a player would try to do in a given situation, as well as all possible synonyms and antinyms for their actions. Writing a parser would be a pain, too, though I guess I could just use Inform 7... Still, this would allow for a good degree of creativity on the player's end. Still, probably not this one.
(3) The CYOA Approach - this is where I describe the situation and then present a list of choices for the player to choose from. CYOA stands for "Choose Your Own Adventure", and it is in the style of these sorts of books that I think I'd make my game. So why this style? Well, it allows for multiple choices on the player's end (which is always a good thing in games), it allows me to keep tabs on what is possible (which is always a good thing for designers), and it's simple enough to implement.

So, now to flex my programmer muscle. I'm going with the CYOA approach, by the way. To start, we need a singleton class that keeps track of the game's state, a singleton class that keeps track of the player character's state, and a map that holds the game's possible states. Each game state (I'll refer to them as Events) has three main functions - an OnInit function for initializing the event, an OnEntry function for adjusting events based on the character's state on entering the event, and an OnExit function for adjucsting events when the character leaves the event. So, an event can be pre-filled with general content (such as a shopkeeper's saludatory spiel), and then fitted with more customized content based on the character. Actually, do I even need an "OnExit" function? Probably not. Anyhoo, when the player enters an event, the OnEntry function is called. Then, the event's text is posted to the screen, and then the player is given his/her choices. The choices are actually just links to other events! So, we need a string to hold text, and a list of choices (with each choice being another event) for each event.

Alright, so the class would look something like this:

class GameEvent{
def OnInit(text, choices){ self.txt = text, self.choices = choices}
def OnEntry(){ nop }
}

Problem - each GameEvent is going to need different code in its OnEntry function. How do I do that? I guess via inheiritance - I'll write up a generic class that does all the default stuff, make OnEntry a virtual function, and then have each event inheirit the GenericEvent class, and have it overload the OnEntry function. But then, why am I even using classes if each needs to be written differently? I need to reconsider things...

No comments: