Mechanic #058 - PGC Cards #2|
Part 2 in a series of articles describing a system for procedurally generating a game.
Continuing on the premise laid out by the previous entry, I now turn my attention to defining the basic structure of the procedural process. Some of this stuff is obvious. Some, not so much.
A Game Object is the closest thing you get to a "physical" object. It is something which has a code equivalent, usually mirroring the code layout of the game simulation. A Game Object is something which can be modified and instanced by the procedural algorithm, but new types of Game Objects cannot be invented by it.
For example, Game Objects may appear in the typical hierarchy that most RPGs seem to follow. A sub-tree of that might be "item" -> "equipment" -> "weapon" -> "sword" or something like that. Anything that is a Game Object can be instanced by the process, which basically means that each Game Object is a class of cards (I'll get to that in a moment). Because of this, and because Game Objects need to be implemented in code and then linked into the process, it is probably best if there are as few base types as possible. For instance, one might forgo making "sword" a specific class of weapon and instead make sword an instance of weapon and use composition to give it special features.
An algorithm is the basic building block of the process. It is basically a procedure that takes a number of inputs, processes them, and produces a single Game Object (which could potentially contain other Game Objects within it). For instance, a dungeon generation algorithm might take inputs for the average size of the rooms and it will return a Map Game Object.
Example 1: Simple Level Algorithm
Output: GameObject Level
Number of rooms: [ 1 - infinite ]
Room width: [ 5 - 20 ]
Room height: [ 5 - 20 ]
Borrowing from [#037 - PGC Templates], here is the types of inputs an Algorithm may take. Notice that it can take a range of possible options. An Algorithm doesn't dictate the values of the input, but may need to check the validity of the input against some measure. For instance, you don't want to pass -4,370 for room width.
The inputs are passed to an algorithm using a simple dictionary / hash table of input name = value pairs. This is checked against the Algorithm validity concerns and them to the Algorithm itself. The validity of the input could be checked within the code itself, but given the nature of random generation, it seemed necessary to publish the acceptable inputs so that the process creating input can revise input as needed.
A Template is simply a standardized format for declaring input values. For instance, a Template for a broad sword may declare the damage value to be a static 13. But you could also have a Template for a magic sword that has a damage value randomly chosen between 10 and 20.
Example 2: Swamp Temple Template
Algorithm: Simple Level Algorithm
Tileset: (static) swamp set
Number of rooms: (random)[ 8 - 12 ]
Room width: (bell curve)[ 5 - 15 ]
Room height: (static) 7
In other words, a template is a sort of mini-scripting language for declaring a random input set. There is a group of commands that exist to randomly select values in a range or do simple arithmetic to create values based on other values. A template has no input. It is called and it will create a dictionary of specific input values for an Algorithm to accept. It's little more than a scripted procedure for filling out a form.
Cards are where it gets interesting. At their most simple, a Card is simple a Template and Algorithm paired together. When the Card is instantiated, it will call the Template to create input values, then pass those values to the Algorithm, and produce a Game Object. A Card can be instantiated as many times as you want, and it will continue to produce new Game Objects based on the template.
Essentially, the Card is little more than a metaphor to couple an algorithm and template together. Because it comes with a picture and name, it is more easily recognized by a player, and because it is a card, it is something that can be collected, selected, and shuffled.
Cards also have one important difference: they can input in the form of other cards. Cards can have a certain number of slots in which you can install other cards (themselves potentially representing a tree of cards). These composite cards are treated as basically a single entity by the other cards, so whether a card actually a tree of cards or just a single card, it's all the same to the process that uses it.
Cards are passed to the algorithm directly. Since they represent a sort of function that can be called to produce a Game Object, they are best used to represent decisions about objects that will be needed by an algorithm. For instance, an algorithm might design a floor plan of a dungeon and could use a card tree to generate each entity that is placed in the dungeon (since they are passed as cards, they can be instantiated by the Algorithm as many times as needed - as long as the cards produce the expected Game Object).
Because of this, a Composite Card may be used to do some of the random decision making itself. For instance, a Randomizer Card may have a slot for five cards - when instantiated, it will randomly instantiate one of its children. As far as the Algorithm is concerned, it is simple asking for a new Game Object - it doesn't matter that it could potentially be receiving completely different ones. I'll be talking more about Control Cards later.
Basically, each Card is a function, and that means that functions can be passed to functions. Ultimately, the entire tree of Cards all leading up to a Game World object is something of a functional programming language. The Control Cards are cards that exist to make specific decisions, like ifs or while loops in a regular programming language. The advantage of it being cards instead of leaving all this stuff up to a scripting language is that the structural design of everything is already taken care of. For the most part, all the decisions the player and/or computer need to worry about is putting these blocks together logically.
To ensure that only the right cards are put in the appropriate slots, each slot requires a specific Game Object to be produced. In the case of Control Cards, it inherits the production type of the objects linked to it. However, because Game Objects are hierarchal, this means that a slot that accepts an ITEM will also accept a WEAPON and a PORTABLE_CONTAINER (itself perhaps containing multiple objects).
In addition to that, slots can be made smart, not unlike smart playlists in iTunes. Each Cards can have multiple different keywords attached to it, and a smart slot will have specific rules dictating which keywords are allowed. For instance, you might have an ITEM slot which only allows objects with the ELVEN keyword and not items with the SHODDY keyword. Thus, when the set of all possible cards that can be in that slot is compiled, it will selectively ignore cards that don't meet that criteria.
Without actually attempting to implement this system, I can't say for certain, but I think the smart keywords should be enough to dictate an appropriate structure for a game. I think that for the most part, less confinement will produce better procedural designs, but when it comes to genre decks, such things may be required.
A Modifier Card is a special case that is not actually a Game Object producer. Instead, it is applied to Card to modify it. For instance, a Card might instantiate to create a sword. The modifier card may turn that into a Sword of the Leech and adds the ability to absorb the health of those slain. A modifier card can either modify the Card itself (as in, change the values on the Template) or the Game Object the Card instantiates (by changing values on the Game Object).
How Modifier Cards are applied or work with the system, I'm still working out.
Ultimately, the entire design can be considered one giant tree with the root node producing a Game World object. This tree can be comprised of theoretically thousands of cards representing a game - and even then, each time the tree is instantiated, it will produce a similar, but different game. This tree should be considered a sort of outline for a bunch of different games in the same theme rather than a specific game itself. In fact, most Roguelikes could be considered variations on a single design tree in the first place.
But to take it to the next level, the computer needs to be able to design that tree, not just the stuff as that tree is being instantiated. This can be handled through a healthy use of smart keywords and which cards are used. For instance, say there are three cards for producing that Game World: a small continent, a group of islands, and valley surrounded by mountains. Any one of those worlds would produce very different maps. Those cards collective say what possible world layouts there are - removing even one of them could greatly affect the type of games produced.
So a Genre Deck is a specific set of cards selected as potential candidates to be used in the tree building process. Just like the tree itself is an outline for dozens of different games, the card selection is an outline for a dozen different trees. In other words, the deck defines the "genre" of the game. I don't mean genre, like scifi or fantasy - though deck design would largely be responsible for making that decision possible - but I mean that a single Genre Deck could produce a whole host of games with a specific set of building blocks. A different deck would produce a whole host of games with a different set of blocks.
In this way, you could certainly create a deck for scifi and a deck for fantasy, but more likely, you could create a deck for Swords and Sorcery fantasy and Tolkien-esque fantasy and Space Opera scifi versus Hard Science Fiction scifi. These are literally the rules which make up the game, and they don't just have to be what objects are in it, but how those rules themselves interact.
So, I forsee a situation where people create themed decks, not unlike Magic: the Gathering, where people can instantiate hundreds of themed games from them. These decks would be built more like one goes about building a world than a specific game. It's like saying that my world doesn't have Goblins, so there's no reason why it would have a Goblin Cave or a Goblin Settlement... but I like Elves, so the Eleven City is in, but not the Elven Monster Ranch, because that's a stupid zone and I don't like it. A genre deck has no limit to the number of cards in it (though I guess there could be benefits to such a thing).
Long story short, the genre deck is that main customization of the game. Though players may have the ability to affect the process of instantiation itself, by an large, the major decisions will be made in the process of designing a genre deck.
A genre deck, so far, just depends on selecting cards you like and not the ones you don't like. While that is great and all, with the ability for cards to be built around other cards, it should be possible for inclined designers to create their own cards. For instance, you could create a specific type of pink Lizardman who runs around with a spear and drops gum drops when killed. You could wrap that up into a Pink Lizardman card and just distribute that. Or if one wanted to, creating many different types of lizardmen and even lizardmen locations and releasing an small expansion pack. The next entry will focus on creating cards themselves through composition.