Wednesday, December 24, 2008

Game Engine configuration languages: Part 1: Introduction

ABSTRACT

Game engines include a framework for holding pieces and a configuration language for describing the details how to use those pieces to make a particular game. This blog covers those topics somewhat separately. The "Game Engine as Operating System" series describes the framework itself. This series entitled "Game Engine Configuration Languages" considers how to design a computer language to satisfy the requirements of a game engine. These topics are intricately related so this blog will alternate between the two topics.

INTRODUCTION

Game engines are a framework for creating interactive simulations with visualization. Visualization includes graphics rendering, audio playback and tactile feedback. Simulation includes physical and cognitive (i.e. "AI" or autonomous characters) aspects. Interaction primarily entails processing controller inputs to change game state. These elements are important but, taken in isolation, these are solved problems with ample attention. Not explicitly included in those elements, however is fun.

To fully answer questions about how to make a game engine which facilitates making something fun, we have to gather requirements from game designers to learn their process. This blog does not aim to discuss game design; I am not an expert in that area and have no great ambitions in that direction. But just has we do not have to become a artists to create tools in service of artists, we do not have to become game designers to create tools in service of designers. We do, however, have to understand their process and cater to their requests.

For the sake of making progress on the technical side, I will paraphrase relevant game design principles as I understand them, which is likely flawed and incomplete, but which will give us a starting point (from which we may later depart) in our attempt to provide superb tools for making great games.

The fun in games, one can argue, comes from structured game design paradigm and its successful application requires a focus on iteration of core gameplay mechanics (not just renderable assets).

Whereas the architecture of a game engine provides the components necessary to assemble a game, the configuration language of the engine describes how those pieces assemble.

Previous work

Existing professional game engines focus on rendering, physical simulation and run-time performance, not on usability or flexibility. Most game engines are best at making some characteristic game. We can consider separately complete game engines, game engines built upon middleware that provides many facilities, and scripting languages that provide the glue that binds middleware pieces into a coherent whole. I don't intend to evaluate game engines or middleware, only to review their properties and make the case that game engine technology needs to focus on a crucial missing element, which is a focus on rapid iterating on the gameplay mechanics themselves.

Complete game engines tend to have been extracted from some successful multi-level game which had a reasonable facility for changing game content, and therefore those engines tend to excel primarily at games that resemble the original game. Unreal does a good job at making character-based shooters and is famous for its great editor, but it is also infamous for being miserable to understand and extend. Warcraft does a good job at making top-down real-time strategy games. Likewise, Quake and Cry are well suited to making games that resemble the originals that made them famous. While it is probably possible to make (for example) a driving, role-playing or sports game using an FPS engine, it seems like the benefit gained would be marginal and much of the code that manifests the gameplay elements unique to the new game would exceed the code provided by the engine itself. Most of the overlap would come from rendering and physical simulation, not from gameplay or interaction.

Virtools seems like it might have the essential features I'm advocating. Check out this (somewhat dated) review of Virtools. It seems like Virtools has focused on building behaviors but they fall short in iterating on regular assets (like models, textures, etc.). And their support for character animation is limited. And Virtools lacks sufficient performance. But their model for building behaviors seems inspiring. Gregg Man summarizes by saying that Virtools (as of 2004 anyway) is good for prototyping but not for production. Although the focus of this blog is on the need for rapid prototyping, we need game engines that are good at both.

Middleware provides pieces of a game engine such as rendering (e.g. OGRE, Kaos, RenderWare, Kerkythea, Genesis3D, Irrlicht, Horde3D, Revolution3D, PhyreEngine, Avalon, Hilva), physical simulation (e.g. ODE, Bullet, Havok, PhysX, Newton, OPAL, SOFA, Tokamak), base components (e.g. RenderWare), sound (e.g. OpenAL, FMOD, Miles, PortAudio, SDL, DirectSound, ESD, Roar), AI (e.g. Kynogon, AI Implant, Brainiac, DirectAI, GALib, Spark, NightFall, Memetic, PathEngine). Let's consider these largely solved problems or at least problems with hordes of people addressing the remaining and emerging issues and leave those topics out of the present discussion.

This series focuses more on the glue that binds those pieces together, and in particular, the language used to express that glue. Scripting languages such as Lua and Python serve to create that glue and to some extent this series will review features of those languages. (Even if this series only elucidates how those languages work, at a fundamental level, then this text provides value in education which is, after all, my job.) But even scripting languages require sophisticated and specialized programming skills to use and we aim to open game configuration to non-technical (or, at least, less technical) developers such as artists and producers.

We might ultimately conclude that game engines need nothing more than Lua+OGRE+PhysX+whatever, and indeed obviously tons of successful, fantastic games have shipped using existing technologies. But I argue that the problem remaining is not to make great games, but to make making games better. The problem is one of optimization and (to some extent) commoditization. Innovation includes combining existing pieces in new ways. Let us aim to make the process of creating and tuning gameplay mechanics a primary goal and see whether we can derive a system that works for both prototyping and production.

GAME ENGINE CONFIGURATION LANGUAGE TOPICS

In this blog I have already touched on a few topics, seemingly at random, but those articles are bound by a cognitive structure and henceforth I plan to make that structure explicit. In the previous post, I already set the stage for viewing game engines through the analogy of an operating system (or reciprocally, one could imagine exploring operating system concepts through the construction of a game engine). Most of the remaining items on the list of potential future topics fall into the category of "programming language concepts" and indeed, game engines have many requirements which programming languages satisfy.

So henceforth I plan to maintain at least two threads of discussion: "Game engines as operating system" and "game engine configuration language".

All of these discussions have an undertone that the purpose of the particular game engine under focus is also by design written from scratch for the express purpose of teaching software engineering and computer science concepts, as well as exploring theoretical ideas for game engines proper. In other words, this is an academic discussion motivated by practical concerns. As with any other academic discussion, we will, for the sake of learning, sometimes deviate from conventional wisdom and common sense. With luck, sometimes that will lead to a real-world payoff, but usually it probably will not. But we may keep separate the hypothetical discussions and the choice of what to try by implementing in code; let's prefer practical solutions even if we sometimes allow ourselves to explore possibilities that seem like they're leading to something impractical.

In this series entitled "Game Engine Configuration Languages" I plan to discuss these topics:

  • Primitive elements: int, float, vector, matrix, table, procedure, reference, opaque pointer
  • Means of combination: hashed vector tables
  • Extensible parsing
  • Expression evaluation and virtual machine
  • Anonymous functions and closures
  • Declarative-procedural languages
  • Combining control flow and data flow into a single coherent system
    • Drag-and-drop / visual / dataflow programming
    • Visual language for automata / flow control
  • Futures
  • Continuations
  • Where do Lua and Python fit in?
A couple of topics span the gap between (what I have categorized as) operating system concepts and programming language concepts:

  • Cooperative multitasking -- while multitasking itself clearly falls under the category of an operating system concept, I intend to discuss aspects of how expressing concurrent tasks can (and perhaps should) be a fundamental aspect of a programming language (not only as a tacked-on library or via precompiler pragmas).
  • Threaded Code (not multi-threading) for expression evaluation -- this has more to do with how to implement a virtual machine, which ties into compiler construction, which is traditionally covered alongside programming language concepts. But the execution of code is related more to the underlying machine than to the high-level language used to create the code for that machine.

As these series progress, we should evolve a picture of what all game engines should include as facilities to access functionality. Assuming that a game engine already facilitates what a developer want to do, how do we provide access to that functionality to non-technical developers in such a way that facilitates both prototyping and production? And in particular, how can we facilitate creating and tuning gameplay mechanics?

No comments: