Category Archives: AI Design


On AI: Us Against the Machine

Imagining AI for a game usually conjures the image of simulated human players — robots designed to look and act like people that can stand in seamlessly for real human opponents. This expectation is natural and unsurprising; we humans have a strong innate tendency to anthropomorphize intelligent or semi-intelligent entities in any context, and the controlled environment of a game system provides an excellent framework for this projection. However, as an AI designer, you must sooner or later confront the realization that computers are not, and cannot be, effective simulated humans. To refer back to the quote from Dijkstra that opened this series, trying to squeeze a computer mind into the shape of a human mind is at best ineffective and at worst outright destructive to the success of your AI.

To illustrate this point, let us examine those ways in which the two kinds of minds encounter a game: a human player, and a computer player. Both should be equally capable of success and skillful play, but the avenues and mechanisms each will take to achieve that success are entirely different. Both will find greatest effectiveness under different circumstances, and will require different supports to make best use of their particular advantages. Acknowledging these areas where humans excel above computers, and vice versa, is the opening move in understanding how to architect an effective AI.

Continue reading


On AI and Appropriate Challenge

AI is a pretty broad concept. It seems silly to suggest that making any grand statements on what AI is or should be will be easy or simple. And yet, based on the AI systems I have seen and worked on, I often feel that it is. The range of approaches to architecting an AI are wide and varied, but the fundamental objective of game AI is not. Understanding why an AI is being made, and what it’s ultimate purpose as part of a game is, can and should be clear.

In my view, the ultimate objective of any AI in any game is: to provide appropriate challenge.

The AI is there to serve as an opponent for the player to endeavor to defeat. At first this probably seems blindingly obvious, but it’s not as straightforward as it appears. It’s easy to define “good AI” as one that is an expert — a fiendishly-clever master of the game that will demand the highest skill and commitment from a player. But is that really the case? Many games are, frankly, not that difficult to defeat. Does that mean they don’t have very good AI? Actually the opposite, most likely.

Continue reading


New Series on Designing AI

The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.
– Edsger Dijkstra

The design and architecture of game AI has long been one of my favorite subjects. AI is a peculiarly challenging and rewarding specialty of game design and programming, one that requires significant sophistication and inventiveness on the part of the designer. In addition to being critical to the success of any digital game, I believe a good understanding of AI patterns and methods makes one a better game designer across the board. Being able to think in the necessary abstractions to translate human analysis and decision-making into computer terms is hugely beneficial in crafting elegant, effective game systems. Particularly in complex games like strategy games, this ability is fundamental.

Learning to craft AI, however, can be difficult. Many AI resources I’ve encountered are difficult to really learn from. They tend to be esoteric, deal in theoretical situations or examples absent context, and can be hard to distill into their essential lessons such that you could readily make use of the learning in your own work. When I taught a course on programming AI at the University of Baltimore some years ago, I ran into a similar problem: to really learn AI, you have to be able to see it operating in a meaningful situation, and you have to be equipped to assess what you’re seeing and gauge its effectiveness. This is best done through practical demonstration, but that is even more difficult to find.

Therefore, I intend to undertake a series of articles and exercises focused on game AI from this practical perspective. My hope is that by working through the problems for my own edification, I can lend similar experience to readers and help illustrate how AI is actually, usefully achieved. My thought is to take a number of simple rulesets — some ordinary card games, for instance — and explore ways to craft AI to play them. Along the way we can see together how well some ideas work, when certain solutions are ideal and when they are not, and how to judge the suitability and effectiveness of game AI.

A word in preface: I will concern myself in this series with exploring AI design, meaning the techniques of representing appropriate player behavior in computer terms and the application of those techniques to real situations. While this process will be code-based, I am not going to focus overmuch on AI programming.

What is the difference? Primarily, it’s a question of optimization. Much of what consumes the work of game AI programming is keeping it smart while getting it to run cheap and fast. To do this is a difficult and time-consuming task, and in my experience always a custom-job to some extent: a particular AI’s optimization is mostly unique to its game and its circumstances.  There are very talented engineers out there (and on my team) that do this much better than I, and I will not pretend greater expertise than they have. The code I will be writing and showing will instead be written for algorithmic clarity — arranged so that the operation and movement of the mechanisms are clear and easy to replicate in whatever codebase you need them in. This can, and probably will, mean that the code makes sub-optimal use of data storage, contains unnecessary redundancy or churn, and other sins of optimized code. This is by intention. While I will certainly endeavor to keep the processes as efficient and elegant as I can, I will leave off from that effort if doing so makes the algorithm under demonstration too difficult to see or understand.

As I go, I welcome comments, identification of errors and suggestions for improvements! I may not always have the free time to go back and repair inefficient code, but I will always fix bugs or mistakes and note any improvements that I did not get to implement myself.