Card Games: Enhancing poker to a commercially viable engine.
Every wondered what would be involved in taking that basic game you might have in your archive of personal projects and create a commercial project out of it? Well, depending on how you feel about the information in this article, you'll either soon be looking for a publisher or content with having your own small pet project with no commercial stresses.
The game here is poker, a game I've covered a bit in the past, and a game that I think is an extremely different beast when you start to talk about producing a commercial product out of an existing pet project. There are plenty of parts to look at, but I've broken the diagram to the right down into three different categorizations.
On the left side you see an abstract. These are the basic commands that are occurring and would be the start of a design process. You'd think of each of these abstract concepts and design them with story boards, state diagrams, or out loud while you are in the shower (hopefully with some steam so you can jot down notes on the glass).
The middle shows you a kind of code-path that you might follow. These are never as complete as I'd like them to be, but this does a good job of defining the final section, or Discipline. These are the types of coding or design that are going to take place in order for the project to come together.
Why?
Why am I taking this path? Well, first it is nice to value and note the amount of work that existing games have gone through to achieve their final product. Second, I want to point out that just because you might be able to program a fixed card engine for a specific game, there are an astounding number of gotchas waiting in the wings when you start to take it to the next level. We'll primarily look at the complexity of customization and how it plays a major role in every aspect of the game engine.
Initialize
Every game starts with some sort of setup menu where you get to decide your options. This is literally the bane of existence for a game like cards because it amounts to the majority of the complexity of the programming. In larger games this complexity is minimized, but check your local options menu and see how few things you actually get to play with. You'll find most options are limited to basic boolean flags that don't have a large impact on how the game is played, but rather turn some basic feature on/off.
Initializing any game starts with some set of rules that can be changed along with some defaults. From the diagram, you'll see I've defined three different game types, and each game type would in turn allow you to set various options. These game types are going to be extremely important as the remainder of the game engine is defined. In order to define a series of game types you need a game designer. For poker, go out and buy a few books on popular rules for games. Even after you do that, let someone knowledgeable with the game tell you which games are similar and define your game types with respect to how similar each game is in terms of graphical arrangement, rules that affect play and winning conditions, turns and rounds, etc... Dissimilar games should be separate game types, but similar games could be sub-games of a single game type. A common name for this setup pattern is called a profile, especially if you give fixed sets of options names, but still allow a custom game where all of the options can be manipulated.
Once the rules are defined you need some container for holding all of the values to be passed on to the game engine. The various settings for different games can be very different and you'll find it very hard to come up with a generic setup object. Now matter how you cut this, when you are talking about a large number of rules, you'll either end up with specialized configuration objects on a per game type, or a single, very complex class with the ability to not only set values, but also have some way to turn them off. Bool gated values (a bool paired with a field) or Nullable types are a wise investment.
The same level of complexity is going to exist at the UI level, but you do have some options. Remember, that no matter how ugly the configuration object, you can give your user a much prettier picture. The use of a wizard can allow setting variables based on previous selections in a directed manner, while the use of game profiles can automatically set most of the values the player needs and only supply them with the UI to set optional values. Do you really need a separate UI programmer for this step? It would certainly help prevent the creation of an overly complex or unintuitive UI. Not to mention, this complexity cascades for the remainder of the game engine and results screens as each game parameter and setting needs to be obeyed when showing users their cards.
Play
With the settings object in place you are ready to roll. Is your game engine prepared to handle all of the incoming settings? Probably not. For instance, the winning conditions of the various games are going to have to be re-prioritized and manipulated based on the game being played. The number of various turns and how the turns advance is going to be drastically different between games. Something simple like turning on betting may add generic rounds in between the actual playing of the game.
To start the process, you are going to need a programmer to set up the basic game loop. Poker really isn't a game loop, but more a turn based type engine or finite state machine. The turn manager is going to be initialized based on whatever the game rules might be. This is yet another step where the game designer would be essential in making this entire process as elegant as possible by defining the various turns for you. As various turns are encountered the engine will be able to process user input. Depending on which players need to process that user input, you may be grabbing information from the network or an AI component.
While poker is simple enough that a network programmer might not be needed, you'll want someone fairly knowledgeable in network protocols to make you aware of all the various cheating scenarios and denial of service style attacks. Network IO should always be managed by some time-out period and creating a voting system to remove existing players can be quite a burden on top of the rest of the code that needs to be written. If money is on the line this process is even more important. An AI programmer might not be necessary either, especially if you are a great poker player, right? Wrong! The better you are at a given game the more likely an AI programmer will be extremely useful. Remember these guys are specialized in creating personality, erratic behavior, and managing statistics. This last quality is very important when working on a Poker game and it is nice to have an applied mathematician around when you have questions about how fair your game might be.
Notice how the game types affect not only the rules and turn manager, but also the graphical display. Think of the hundreds of different ways that cards can be displayed based on what type of game is being played. New games means new layout logic, and even worse, new user input routines. Each game has a specific UI that will maximize the play experience and creating that specific UI for say 10 games is a daunting task, let alone a few hundred of them. At some point you are going to have to put a script kiddy to work or have the UI designer work on a data-driven layout approach. Remember testing? Every single UI, especially data-driven UI needs to be thoroughly tested to make sure all of the hooks are in place. The last thing you need are input elements that don't do anything. If you planned for a data-driven UI from the very beginning, then you may have also applied it to the configuration UI and the following results UI.
Results
When working with the final product results are going to be insanely important or a bunch of filler. If you have separate games that don't maintain any state in between then you are talking about a basic results screen and the users won't even bother looking at it. If every hand is going to result in some passing of money then you better darn well get the results screen perfect because everyone is going to want to check the hands, make sure the game engine did the right thing, and make sure money was properly credited to each user's account.
The UI designer and game designer are both important at this stage so the results make sense. Results are just as dependent on rules as the rest of the application and you can imagine there are a number of things you need to show and a number of others you don't. The game designer will know exactly what should be in this final screen and your UI guy is going to make it happen.
Wrap-Up
There is so much stuff to think about to take a basic poker engine and make it a professional engine. To do it right, with all of the associated testing, UI, and graphics you'd want at least a 6 month cycle on this project. I think an 8 to 12 month cycle is more appropriate if you are going to have lots of rules, true network play, and some decent AI opponents. Removing any of the components will help drop some time off the schedule. Network play is an easy component to add, but a hard component to do right making it a key location for short-cuts. The AI is the same, with a basic AI being purposed in only a few hundred lines of code including all rules variations. Don't expect that AI to kick any decent player's butt, because it is likely to make some definite betting errors.
If you have any particular areas you are interested in seeing blown up with some actual code, drop a comment or two. Keep the areas you are interested in small enough that they might fit in a single posting. I'll also expand the design diagram to contain the additional levels of detail for those interested. You can head back through some of the older postings and see the network design diagrams to get an idea of how much detail the above diagram is leaving out.