Quantcast
Channel: Casual Effects
Viewing all 48 articles
Browse latest View live

The Skylanders SWAP Force Depth-of-Field Shader

$
0
0
Our depth of field effect in the game.
Mike Bukowski, Padraic Hennessy, Brian Osman, and Morgan McGuire (that's me) published in GPU Pro4 an early version of a depth of field shader that we developed while working together on Skylanders: SWAP Forceat Vicarious Visions, and Activision studio.  This post describes the shader a bit more and includes links to updated sample code.



A lens camera can only focus perfectly at one depth.  Everything in front of that depth in the near field is out of focus, with each point blurred to a circle of confusion (a.k.a. point spread function) radius that increases towards the camera.  Everything past that depth in the far field is also out of focus, with radius increasing towards infinity.  When the circle of confusion radius is less than about half of a pixel, it is hard to notice points are out of focus, so the depth region around the plane of focus is called the focus (a.k.a. mid) field. Technically, "depth of field" is a distance specifying the extent of the focus field.  However, in the industry, a "depth of field" effect is one that limits this from the common computer graphics pinhole camera effect of having an infinite depth of field to one that resembles a real camera with a small, finite depth of field.

The method that we describe is a simple modification to a previous post-processing technique by David Gilham from ShaderX5.  Our technique is simple to implement and fast across a range of hardware, from modern discrete GPUs to mobile and integrated GPUs to Xbox360 generation consoles. As you can see from the screenshot above, the depth of field effect is key to both framing the action and presenting the soft, cinematic look of this game. Scaling across different hardware while providing this feel for the visuals was essential for the game. "Simple to integrate" means that it requires only a regular pinhole image and depth buffer as input, and that it executes in three 2D passes, two of which are at substantially reduced resolution. The primary improvement over Gilham's original is better handling of occlusion, especially where an in focus object is seen behind an out of focus one.

The diagram below shows how the algorithm works.  The implementation in our sample code computes the Signed CoC radius from depth. One can also directly write those values during shading. See the book chapter and our sample code below for full details.
The code linked below contains some changes from the original. It performs 4x downsampling in each direction during blurring to speed the gather operations. We disabled one of the occlusion tests within the far field to reduce artifacts from this downsampling (at the expense of introducing some glowy halos in the far field--use 2x downsampling and uncomment that test to avoid this.) We added support for guard bands to reduce artifacts at borders and work with other techniques (such as our Alchemy AO '11 and SAO '12 algorithms) General small performance improvements appear throughout. It has also been updated to compile under version 10 of the open source G3D Innovation Engine, although you need not compile it since we include a binary.

Here's a video result showing how the effect looks in motion:



Here are some high resolution shots that help to understand what the effect is doing. These are taken in Crytek's Sponza model with the far field blur disabled and relatively strong near field blur to show the algorithm's strength. There is FXAA antialiasing but no bloom in these images.

Pinhole camera input buffer.
The output of our implementation of Gilham's method. Note the sharp edges on the foreground pillar.
The output of our method. Note the soft edges on the foreground pillar
and smooth near-to-focus transition on the side walls.
The "Blurry Near Field" buffer with premultiplied alpha.
The "blurry far field" buffer described in the diagram
above.  This has 1/16 the number of pixels of the input and output.
Download the source code, shaders, and Windows 32 and 64-bit binaries from:

http://graphics.cs.williams.edu/papers/DepthOfFieldGPUPro2013/VVDoFDemo.zip (130 MB)

Anyone interested in our technique may also be interested in some alternatives that include:
I patched the code on Sept. 22, 2013 to fix normalization of the far field radius - Morgan



Morgan McGuire is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

JavaScript Desiderata

$
0
0

Why JavaScript?

I teach the the programming portion of Williams CS107:Creating Games using codeheart.js, which is a minimal game framework for JavaScript. I use JavaScript because it has several practical advantages over other currently available languages for beginning students (as well as for my own jam games and prototypes):


  1. Requires no software IDE, compiler, etc. to be installed. Anyone with a web browser and a text editor can immediately begin programming, regardless of what user privileges they have on a machine
  2. Allows creation of web games, including mobile games
  3. Allows easily sharing your creations with others
  4. Minimal boilerplate in the syntax
  5. Supports first-class functions, which enable important and elegant CS concepts (e.g., lexical scope, iterators, anonymous functions, abstraction, functional programming)
  6. Easy access to 2D graphics and GUI features
  7. Supports network, threading, audio, gamepad, and OpenGL for the sufficiently motivated student (albeit awkwardly)
  8. C-like syntax transitions students quickly to Python, Java, and C++ for upper-level courses
  9. Surprisingly fast for numerically-dense code (memory allocation and garbage collection remain slow in all implementations I've used.)
  10. Interpreted, so that code can be interacted with from the console ("REPL")
  11. Debuggers and profilers are readily available (if somewhat flakey)
  12. Is also supported by non-browser environments, e.g., node.js and rhino

A Near-Minimal Subset

To reduce both the students' and my own confusion, I use a near-minimal subset of the language:
  1. IF and WHILE (many students will quickly pick up FOR on their own)
  2. Function declaration
  3. Variable declaration
  4. Essential standard operators (omitting ++, ===, etc.)
  5. Arrays
  6. Objects as structures (not classes)
codeheart.js provides the structure that allows students to use this minimal subset:
  1. Function-based wrapper for essential data structure functionality
  2. INCLUDE
  3. Canvas-based graphics setup with a standardized resolution
  4. A more useful and intuitive Array iterator
  5. Argument checking for its own built-in functions
  6. A unified event model for mouse, touch, and keyboard
  7. Abstraction of some browser peculiarities and differences
  8. A generic math library suitable for scalars or vectors
Part of the point of using small framework and a common language is that students are welcome to go beyond the minimal subset that I teach (and use myself), since any JavaScript that they learn can be applied. 

Why Not JavaScript?

JavaScript is limited by some really poor design choices and certain missing features, a few of which
are intentionally missing in the name of browser security but really provide little additional security. Limitations that are impossible to work around within the language include:


  1. No built-in module or scoped variable ("let") support. One has to use (function() { ... })() to perform the equivalent of a LET statement. A strangely non-functional LET is in JavaScript 1.7, which Apple does not support in Safari since they are using the 13-year old JavaScript 1.5 specification.
  2. No built-in INCLUDE statement. There are various workarounds for this (and codeheart.js has one), but they all lead to serious confusion in the presence of program errors.
  3. The threading API precludes efficient data transfer between threads, forcing all data to be marshalled through strings.
  4. Due to ambiguity in the syntax, whitespace is significant within a RETURN statement and anonymous function calls require an extra set of surrounding parentheses.
  5. The FileSystem and Clipboard APIs are near useless since they don't really provide access to those features.
  6. The gamepad API is only supported on Chrome
  7. "Cross-site" scripting limitations make simple actions like looking at the pixels of an image or other data loaded from a different host impossible to perform in a generic way
  8. No peer-to-peer network API (for browsers); one has to relay everything through a server. No actual security is gained by this because the same communication is possible, but all networking becomes slower and substantially more awkward.
  9. The serialization API (JSON) is missing:
    1. Support for comments and whitespace
    2. A way to serialize and deserialize floating point specials such as Infinity and NaN
    3. A way to serialize the undefined value (which itself weirdly has no literal syntax)
    4. A way to specify the deserializer for an object without parsing it. E.g., one can't parse "Foo {a: 1, b: 2}", one has to make up a special convention such as "{type: 'Foo'; a: 1, b:2}", which is obviously not generic or suitably abstract and extensible
  10. No support for multiline strings (like Python's """)
  11. No support for synchronous loading of large data files (WebGL demos embed giant 3D models as code literals!)
  12. No support for #file and #line pragmas (see the next section for why these are important)
  13. No support for operator overloading (nearly essential when writing graphics and game code)
  14. No (universal) support for constant declarations; some limited object freezing
  15. No support for static argument checking (e.g., types, number of arguments)

The last point makes it almost impossible to write large JavaScript programs because refactoring requires manual checking of all potentially affected code and explicit test coverage. Dynamically-typed variables are a great feature; they elegantly enable polymorphism, avoid clutter, and ease new programmers into a language. However, type inference and/or compile-time argument checking are essential for checking contracts and static error detection in software engineering. After about 1000 lines, I find it impossible to maintain a JavaScript program. Some of my larger web games are about this size because they've saturated.

Three Dangerous Roads Forward

For those morally insulted by the limitations listed above or seeking to use JavaScript more seriously in a CS curriculum or development environment, I see three ways to address JavaScript's limitations while keeping most of its benefits:

  1. Just wait. The JavaScript (ECMAScript) specification is evolving quickly. However, waiting is not particularly attractive because: 
    1. to capture the "runs everywhere" benefit, one must use the version supported by the least functional major browser (iOS Safari seems to be this), and
    2. the specification is evolving crazy new syntax and OOP features rather than addressing the fundamental limitations of the language...just like Python, C++, Java, and other languages are going off the rails by chasing features instead of ensuring good design.
  2. Use a language that compiles to JavaScript. This allows a more advanced, and often better-thought-out language while retaining the JavaScript runtime. ASM.js also provides an assembly-language JavaScript compilation target that JIT compiles to native code on many browsers. There are many languages implemented this way. The primary new drawbacks of this are:
    1. adding a compilation step destroys the "work without installing software" and "interactive debugging" features
    2. none of these languages are sufficiently popular that I'd want to depend on their implementations for long-term courseware
    3. the languages that I've investigated all introduce new syntax, which might be superior but is a new learning (and remembering) hurdle
    4. it is really hard to debug programs when errors occur in generated code
  3. Extend JavaScript with a self-interpreter. This is the classic Scheme-like approach to language development, and JavaScript is sufficiently Scheme-like that it seems viable. The idea is to write a JavaScript interpreter in JavaScript so that everything still runs dynamically and in the browser, and try to keep the generated code sufficiently close to the base language that one can still interact usefully at the console with it. Some features of HTML and JavaScript that make this approach plausible are:
    1. JavaScript has an EVAL statement
    2. JavaScript has first-class functions, so one can compile code to functions
    3. HTML allows embedding arbitrary code in <script> tags with custom MIME-types. These will be ignored by the browser but are accessible to JavaScript itself as source
    4. JavaScript can insert more JavaScript into HTML as additional <script> tags (I use this to implement INCLUDE())
    5. Critically, Ariya Hidayat and others have already written an open source JavaScript parser in JavaScript: Esprima. This is the hardest part of writing an interpreter and it is already done.
For example, LET support can be added to a legacy JavaScript implementation by rewriting code, as in this example:

Before:
...
if (x > 3) {
   let y = 2;
   ...
}


After:
...
if (x > 3) {
   (function(y) {
      ...
   })(2);
}

provided that one is very careful about RETURN, CONTINUE, and BREAK statements, which trigger non-local control flow that is altered by a function. More aggressively, one could directly interpret JavaScript and EVAL functions into the native interpreter as needed.

I'm not aware of any JavaScript + features implementations in JavaScript, although I suspect that a few exist (and I welcome hearing about them in the comment thread below!). The basic idea was already proven by Flapjax and ASM.js. The features that I'd most want in such a language in order of decreasing importance are full JavaScript compatibility, optional type declarations, optional argument count checking, CONST declarations, functional LET and modules, and operator overloading. I can work around most of the other limitations given these to abstract the solutions.

The first two approaches that I suggested above are "dangerous roads" because they lose features and move one towards an increasingly arcane language. The third approach is dangerous because writing an interpreter is often how a computer scientist (e.g., Knuth) manages to spend a lifetime building infrastructure to write a very nice 100-line program.




Morgan McGuire is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Some Interesting New Game Art Styles

$
0
0

Little Big Planet 2
Expressive, also known as "non-photorealistic," computer graphics seek conscious stylization over mimesis. The world of animated films has long embraced non-mimetic styles, however relatively few games exhibited bold style after display resolutions and processor throughput became high enough to escape the (pleasant) confines of pixel art and flat-shaded polygons. Some noteworthy big-budget exceptions are Oni, Okami, Another World, Wind Waker, Prince of Persia, Jet Grind Radio, Ni No KuniLittle Big Planet, Borderlands, and Mirror's Edge.

Our SIGGRAPH course notes on stylized rendering describe the art history of expressive games, some basic stylized rendering algorithm examples, and case studies of important recent expressive games.

Maintaining a bold style is challenging for games, especially for 3D games, in part because the player can alter the composition and lighting. This creates situations that are visually ambiguous, incongruous, or require a simulated version of lighting. It is also challenging because many natural media styles have no obvious animated or 3D analogue, and because the computational demands of well-done expressive rendering are often paradoxically higher than those of photorealistic rendering when under currently-known algorithms. On the business side, I've experienced first-hand the reluctance of large publishers to adopt expressive graphic styles that have not been as proven as (attempted) mimesis in the market. That is a natural but regrettable risk aversion for the company funding development.

Kentucky Route Zero
Many small ("indie") developers adopt expressive styles. They already have such astronomical risk that market shrinking is not a consideration (in fact, defining a niche may be advantageous). They have limited art budgets that are often best-stretched to hand-drawn art, and generally weaker rendering systems whose limitations can be disguised by stylization. Braid, Kentucky Route Zero, Limbo, Minecraft, Incredipede, Monaco, Spelunky, PixelJunk Eden, and Antichamber are a few recent popular expressive indie games.

Games are Art

LIMBO
Games are artworks. Most are not intended as fine art but as popular art, like genre novels, comicbooksfilms, television, and music. The $100M and higher budgets of large-scale games require that games be popular art; if they were not, then we could not afford to make them without heavy patronage. Visuals are only one element of the art of video games; audio, controls, narrative, and gameplay (at multiple reward-cycle scales) are others. As with most art, a majority of games are not very good. Many are good, and a few are great. (Most oil paintings were terrible, too. We only see the good ones because the others were destroyed a long ago or are still hidden in painters' closets.)

There have been a number of games that elevate the art of games in various elements. The Last of Us, Ico, Shadow of the Colossus, Age of Empires, LIMBO, Braid, Shenmue, Tearaway, Portal 2, God of War, Tetris, The Stanley Parable, JourneyThe Sims, and Gone Home are among these, as are pretty much all games created by Tim Schafer and Shigero Miyamoto. These are also all likely to stand the test of time and are examples I proudly offer to academic colleagues of why I'm excited to work and live in this field.

Visual Art

Some very recent and upcoming (hopefully--even big-budget games often don't ever see the light of day or live up to their potential) indie releases are pushing in new directions with game art visuals. Many of these adopt well-known styles from fine art and explore their extension to interaction. Others innovate with novel styles.

As a survey of these games, below are some screenshots with links to the game developers' web sites.

Tengami

Cloudbuilt

The Long Dark
Monument Valley
Biome
White Night
TRAUMA
Apotheon
That Dragon, Cancer


Dream

Miegakure (this game has four spatial dimensions)


Child of Light
Cuphead

The Witness
The Banner Saga
Beyond Eyes
Lumino City
The Swapper
No Man's Sky

Voodoo
Atelier Sento
See also Tom Kail's new Tumblr image blog on art styles.


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

An Introduction to JavaScript for Sophisticated Programmers

$
0
0

Introduction

JavaScript (which is defined by the ECMAScript specification) is a just-in-time-compiled, memory-managed (garbage collected), dynamically-typed, functional programming language. Its greatest practical strength is its use on the web as the primary client-side programming language. This means that nearly every computing device with a display serves as both a target platform and a potential development environment. That is powerful and convenient.

The language is relatively elegant, but has an undeserved reputation for being confusing or awkward. This is perhaps due to large amounts of poorly-designed code available on the web and general misunderstandings about how the language works. As with every language that I know, the specification has some poor design decisions of its own, but these are mostly avoidable and are patched over by many implementations already (e.g., see strict mode, constlet).

Learning any programming language means learning:
  1. the syntax and semantics
  2. the style of effective programs, with emphasis on idioms
  3. specific implementations (particularly, performance characteristics)
  4. the standard library
  5. common third-party libraries
A wealth of both good factual information and diverse opinions for the final three topics on JavaScript is currently available on the Internet (e.g., & N.B.: MDN, caniuse.com, ecmascript, jquery.com, stackexchange.com). So, in this document I focus on the first two topics because I have found existing resources address them less well.

Anyone who already knows how to program well in some other language (i.e., a "sophisticated" programmer) should be able to program in JavaScript immediately after reading this document, and should be writing effective and elegant programs after about a week of experience. Also, those programmers accustomed to Python's list comprehensions or with experience in functional languages such as Scheme, ML, and Haskell may find JavaScript immediately familiar. To address the non-programmer audience, I am writing a short book on JavaScript as a first language, but unlike that book, this document is intentionally not for first-time programmers.

In addition to this article, I recommend Yotam Gingold's example-based overview (which I use as a quick reference guide), the fantastic resource of stackoverflow.com, the reasonable resource of JavaScript: The Good Parts, verbose-but-correct MDN, and the somewhat-questionable but conveniently terse resource of w3schools.com.

I provide two additional resources for both the novice and experience JavaScript programmer. The codeheart.js framework is a small library that provides function access to core data structure routines, argument checking, and smooths over implementation differences between browsers. I use it when teaching introductory programming and in my own work, even for commercial video games. The codeheart.js website includes many examples of both simple JavaScript programs and those that do some tricky things, such as access gamepads and the camera or perform complex algorithms. The Graphics Codex is a web and iOS reference app for graphics programming. It contains JavaScript, HTML, CSS, Unicode, and OpenGL information relevant to the JavaScript (graphics) programmer.

The most popular JavaScript interpreters are presumably those in web browsers. Be aware that there are other implementations available. The two I'm familiar with are node.js, which was designed for server-side programming of client-server applications, and Rhino, which was designed for embedding JavaScript within applications written in other languages.

Some common reasons for learning JavaScript are:
  • Abstracting repetitive structure in web pages
  • Adding interactive features (such as form error checking) to web pages
  • Implementing full applications that run within a web browser, including real-time games
  • Implementing WebGL programs, which are largely written in a language called GLSL but require JavaScript to launch the GLSL threads
To accomplish the tasks implied by those reasons, one obviously has to learn about the library conventions for accessing the HTML document tree data structure (called the "DOM") or the WebGL library. For the DOM, I recommend reading the formal specification and the more colloquial quirksmode and w3schools descriptions. The WebGL specification is understandable (although not particularly pleasant reading) for those already familiar with OpenGL. For those new to GL, I recommend Mozilla's documentation.

Three Simple Examples

JavaScript begins executing at top level and declarations can be mixed with execution; there is no "main" function. The HTML script tag embeds JavaScript in a web page for evaluation by a browser:

<script src="file.js"></script>

<script>
// Inline javascript here
</script>


Browser Output

To run this example in a web browser, create two files. The first is index.html with contents:

<html>
<body>
<div id="output"> Some output: <br/> </output>
<script src="example.js"></script>
</body>
</html>

The second file is example.js, with contents:

alert("hi"); // Pop up a modal dialog
var i;
for (i = 0; i < 10; i += 2) {
console.log(i); // Print to the developer console
}

// Emit marked-up into the HTML document
document.write("<b>Hello world</b>");

// Assume that a tag of the form <div id="output"></div> already appeared
// in the HTML
document.getElementById("output").innerHTML += "<i>More</i> information";

Now, load index.html in your web browser and open the JavaScript Console (a.k.a. Developer Console, Error Console, and so on in different browsers) to see the result of the console.log statements. This console (a.k.a. "interaction window", "read-eval-print-loop", REPL) is useful for debugging and experimentation. You can enter code at it for immediate execution. That code can reference any global variables, as well as declare new variables. This allows inspection of any exposed state (console.dir even prints values in an interactive tree view!) as well as experimentation with functionality before committing it to the main program. Many browsers also have built-in debuggers and profilers, but this immediate interaction with your code is often the best place to start investigations. Browser consoles that have command completion also allow discovery of new features during experimentation.

Insertion Sort

function insertionSort(a) {
var i, j, temp;
for (j = 0; j < a.length; ++j) {
for (i = j + 1; i < a.length; ++i) {
if (a[i - 1] > a[i) {
// Swap
temp = a[i - 1]; a[i - 1] = a[i]; a[i] = temp;
}
}
}
}

Derivatives

function derivative(f) {
var h = 0.001;
return function(x) { return (f(x + h) - f(x - h)) / (2 * h); };
}

console.log(" cos(2) = " + Math.cos(2));
console.log("-sin(2) = " + Math.sin(2));
console.log("(d cos/dx)(2) = " + derivative(Math.cos)(2));

function f(x) { return Math.pow(x, 3) + 2 * x + 1; };
var x = 12.5;

console.log("[6x | x = 12.5] = " + (6 * x);
console.log("(d^2 (x^3 + 2x + 1)/dx^2)(12.5) = " +
derivative(derivative(f))(x));

Types

JavaScript is a dynamically-typed language, so values have types but variables may be bound to any type of value. The value domain of JavaScript is:
  • Immutable unicode-capable string (uint8 characters with escape sequences; string length may not be what you expect)
  • Boolean
  • 64-bit floating point (a.k.a. "double precision") number
  • First-class, anonymous function
  • Apparently expected, amortized O(1)-time access table (a.k.a. "dictionary", "map", "hash map", "hash table") mapping strings to values, called object. Non-string keys are coerced silently.
  • A null value
  • An undefined value, which is returned from an object when fetching an unmapped key
Those seven types define the semantics of JavaScript values. Several other types are provided for efficiency within implementations. Except for some possibly-accidental exposure of limitations on those, they act as optimized instances of the above types. These optimized types are:
  • Array of values. This is semantically just an object that happens to have keys that are strings containing integers, however when allocated as an array and used with exclusively integer keys the performance is what one would expect from a true dynamic array (a.k.a. "vector", "buffer").
  • Native functions, provided by the interpreter.
  • Typed numeric arrays: Uint8Array, Int8Array, Uint8ClampedArray, Uint16Array, Int16Array, Uint32Array, Int32Array, Float32Array, and Float64Array. These are objects that use efficient storage for numeric types and necessarily support only limited get and set functionality. Functions that operate on normal arrays do not work with these types.
As implied by its name, the "object" type is frequently employed as a structure holding fields that are accessed by name. JavaScript has some constructs that support object-oriented programming based around these structures. There are no classes or inheritance in the Java or C++ style, however functions and objects can be used to emulate much of that style of programming, if desired. I discuss some of the idioms for this later in this document.

Syntax

JavaScript syntax is largely similar to that of C. It is case-sensitive, whitespace is insignificant, except in return statements, and braces are used for grouping. Semicolons are technically statement separators instead of statement terminators and are optional in many cases. Like many people, I happen to use them as if they were terminators to avoid certain kinds of errors and out of C-like language habits.

I find it easier to learn syntax from concrete examples than formal grammars. A slightly-idiomatic set of examples (e.g., braces aren't required around single-expressions except in function declaration) of core JavaScript syntax follows. I recommend reading the actual grammar from the specification after becoming familiar with the syntax.

Expressions

3 // number
3.14 // number
"hello" // string
'hello' // Single and double-quoted strings are equivalent
true // boolean
function(...) { ... } // Anonymous function literal
{"x": 1, "name": "sam"} // Object literal
{x: 1, name: "sam"} // Object literal with implicit quotation of keys
[1, 2, "hi"] // Array object literal
null // Null literal

These can be nested:

{material:
{color: [0.1, 1, 0.5],
tile : true},
values: ["hello", function(x) { return x * 2; }, true, ['a', 'b']]
}

Technically, the following are protected global variables and not literals:

Infinity
NaN
undefined

That technicality matters because the serialization API, JSON, provides no way to serialize undefined or floating-point special values (it also provides no way to serialize function values, although that is less surprising).

JavaScript provides common C-like operators:

a + 3
a + "hello" // String concatenation
a - b
a * b
a / b // Always real-number division, never integer division. Use Math.floor if you want an integer...
a++
++a
a % b // Floating-point modulo. Use Math.floor first if you want integer modulo
a -= b
a += 3
a += "hello" // Shorthand for a = a + "hello"; does not mutate the original string
// etc.

a >> 1 // Bit shift left; forces rounding to 32-bit int first
a << 1 // Bit shift right; forces rounding to 32-bit int first
a > b
a >= b
! a
a != b
a == b
a !== b
a == b
a || b
a && b
// etc.

a ? b : c // Functional conditional

As is the case in most languages, the logical "and" (&&) and "or" (||) operators only evaluate the left operand, if it determines the value of the expression. Undefined, null, false, zero, NaN, and the empty string all act as false values in logical expressions. The empty object (or empty array, which is an object) acts a true value in logical expressions. Logical "and" and "or" return one of the operands, as is common in dynamically-typed languages. For example, the expression 32 || false evaluates to 32.

There are two versions of the equality operator. Triple-equals (===) compares values in a similar way to the C language, and is almost always the operator desired for an equality comparison. Double-equals (==) is equality comparison with coercion, so the expression 3 == "3" evaluates to true. The not-equals operator has the same variant.

Exponentiation and other common math functions are mapped by the global object named Math:

Math.pow(b, x) // b raised to the power of x
Math.sqrt(3)
Math.floor(11 / 2)
// etc.

Parentheses invoke functions:

y(...) // Invoke a function

(function(...) {...})(...) // Invoke an anonymous function at creation time

Note that extra parentheses are required around an anonymous function that is immediately invoked, due to an ambiguity in the syntax of the combined function declaration and assignment. As Jeremy Starcher points out in the comments below (thanks!), any operator is sufficient to force invocation of the function, but parentheses probably the most convenient and clear.

Function invocation syntax leaves another apparent ambiguity: is the above expr expr or a function applied to its arguments? The language is defined to have the above invoke the function and there is no way to express two adjacent expressions, one of which is a function literal and both of which have ignored values.

Extracting a key from an object is accomplished with:

a[b] // Get a reference to the value mapped to key b from a
a.hello // Shorthand for a["hello"]

Those are legal right-hand values for assignment operators:
student["fred"] = { name: "fred", height: 2.1};

body.leftarm.hand = true;

sphere.render = function(screen) { drawCircle(screen, 100, 100, 3); }

Statements

// Single line comment
/* multi-line comment */
var x; // Declare a variable in the current scope
var x = 3; // Declare and assign
if (...) { ... } // Conditional
if (...) { ... } else { ... } // Conditional
switch (...) { case "a": ... break; ...} // Conditional
while (...) { ... } // Loop
for (...; ...; ...) { ... } // Loop
return 3; // Return from a function
x = true; // Assignment (an operator--any expression can be made into a statement by a semicolon)
throw ...; // Throw an exception
try { ... } catch (e) { ... } // Catch an exception
function foo(...) {...} // Shorthand for var foo = function(...) {...};

Within a loop, continue and break skip to the next iteration and terminate the loop, respectively. As previously mentioned, the return statement is sensitive to whitespace. A newline after a return ends the statement, so the returned expression must begin on the same line as the return itself to be included.

Functions are the only mechanism for creating scope in JavaScript. Specifically, braces {} do not create a new scope line the way that they do in C++. This means that the variable defined by a var statement exists within the entire scope of the containing function. I declare all variables at the top of a function (like a C programmer) to avoid accidentally creating the same variable inside two different sets of braces. Furthermore, writing to a variable that has not been defined automatically declares it in global scope, which can turn an accidental missing declaration into a serious program error. Fortunately, most browsers support an opt-in "strict mode", in which this is an error.

JavaScript identifiers are a superset of those from the C language because they allow dollar sign ($) and unicode characters to be treated as letter characters. Beware that the popular jQuery and Underscore.js libraries by default bind $ and _ as the most frequently used variable. So, you may encounter code like $("p").hide(), in which one might expect that the dollar sign is an operator but it is in fact simply a function that happens to act as half of a particular kind of tree iterator useful for document manipulation.

Beware that, while there are few reserved words, some variables (and accessors that use variable syntax) are immutably bound in the global namespace (the "window" object) by the web browser. The one that often catches game programmers off guard is "location". The following code causes the browser to redirect to a page ("spawn point") that does not exist, rather than reporting an error that the variable has been declared twice or doing what the programmer probably expected of simply storing a string:


var location = "spawn point";

Function calls eagerly evaluate all arguments, which are then passed by value. To return values, one must either use the return statement or pass an object (or array object) whose fields can be mutated. All arguments are optional and those lacking actual parameters are bound to undefined. To support arbitrary numbers of arguments, an array-like collection of all arguments called arguments is bound within a function call. To return multiple values from a function either return an object (e.g., an array), or pass in an object or array whose contents can be mutated.

OOP with this and new

JavaScript has two special expressions that provide a limited form of object-oriented behavior: this and new. You can write an awful lot of useful JavaScript without reading this section, and are more likely to write understandable and debuggable code if you don't use the features described here. JavaScript's design is really that of a functional programming language, not an object-oriented language, and thinking in terms of functions instead of objects will usually lead to more elegant code. ("Objects are a poor man's closure.")

The expression this evaluates to an object and cannot itself be explicitly assigned--it is not an identifier for a variable. In a function invoked by the syntax fcn(...), and at top level, this evaluates to the object representing the browser window. It has keys for all global variables, including the library built-ins (most of which can be reassigned). 

In a function invoked by the syntax obj.fcn(...), that is, where the function expression was returned as a value within an object, this evaluates to the object within the scope of the function. Thus, one can use it to create method-like behavior with the idiom:


var person = {height: 1.5, name: "donna"};
person.grow = function(amount) { this.height += amount; }

person.grow(0.1);

In this example, the "grow" key in the "person" object maps to a function that increments the value bound to the "height" key in the "person" object. One could create multiple objects that share a the same function value.

JavaScript also binds this during the somewhat bizarre syntax and idiom:

function Farm(c) {
this.corn = 7;
this.wheat = 0;
this.cows = c;
}

var f = new Farm(3);

When the new keyword precedes the function expression in function invocation, this is bound to a new object and the value of the expression is that object, not the return value of the function. This is typically employed as a combination class declaration and constructor. Note that the Farm function could bind other functions to keys of this,  creating an object that acted much like a Java or C++ class with respect to the object.method(...) syntax.

Furthermore, an object can be chained to another object, so that keys that are not mapped by the first object are resolved by the second. In fact, in the above example, the object bound to f is chained to an implicitly-created object Farm.prototype. Any keys bound on that prototype act as if they were bound on f, so it acts very much like the "class" of f. The prototypes themselves can be chained, creating something that feels a bit like the classical inheritance model (or...lexically scoped environments).

I find that object-oriented programming in any language is a tool that frequently clarifies code at first by grouping related state and computation. As a program grows, the boundaries between clusters grow complex and ambiguous, and object-oriented programming often seems less attractive. The fundamental problem is that the most powerful computation mutates state from multiple objects and has no natural class to own it. I observe the same properties in this prototypal inheritance, but magnified. I use it, but sparingly, and almost always rely on first-class functions for dynamic dispatch instead of explicit objects. In C++ and Java one doesn't have that alternative, so OOP is often the right, if imperfect model in those languages.

If you prefer the object-oriented style of programming for JavaScript, I highly recommend Douglas Crockford's articles on the topic.

Idioms

The key to effective JavaScript programming is appropriate use of functions and objects, often through functional programming idioms. Here are two heavily-commented examples demonstrating some of these idioms.

Graph


use strict;

// The common (function() {...})() idiom below works around ambiguous
// syntax for immediately invoking an anonymous function,
// as previously described.
var makeNode = (function() {
// This state is private to makeNode because it is a local
// variable of the function within which the actual makeNode
// function was defined. This is one way to make "private"
// state.
var lastID = 0;

return function makeNode(v) {
++lastID;

// Each node has three properties, a unique ID, an array of
// neighbors, and a value. We choose to make the node's fields
// immutable.
return Object.freeze({id: lastID, neighbors: [], value: v});
};
})();


/* Can the target node be reached from this starting node? */
function reachable(node, target) {

// A third argument was secretly passed during recursion.
// This avoids the need to declare a helper procedure with
// different arguments. Note the use of the OR operator
// to return the first non-undefined value in this expression.
var visited = arguments[3] || {};

if (visited[node.id]) {
// Base case
return false;
} else {
// Note how we're using the object as a hash table
visited[node.id] = true;

// Think functionally instead of imperatively, which often
// means recursively. The target is reachable if we are at
// it, or if it can be reached from one of our neighbors. Use
// the built-in iterator (a reduction) to traverse the
// neighbors. Note that we use a first-class, anonymous function
// to specify what operation to apply within the iteration.
return (node.id == target.id) ||

node.neighbors.some(function(neighbor) {
// Pass the third argument to the recursive call.
return reachable(neighbor, target, visited);
});
}
}

Note the use of the Array.some function above. Although JavaScript provides some of the usual functional programming utility routines (e.g., map, fold), you'll often either have to write them yourself or using a library such as Underscore.js to bring them in. Underscore is very nicely designed, but I can never remember the conventions of all of the variants, so I simply use the big hammer of codeheart.js's forEach, which has just enough functionality to emulate most forms of iteration.

My A* (shortest path) example demonstrates one way to define the graph itself using first-class functions, in order to generalize a graph algorithm without either fixing the underlying representation or forcing an OOP style on the program.

Module

There are several ways of using functions to group state and implement module-like functionality. The simplest is to have modules be objects that contain functions (and constants, and variables...).

use strict;

var module = (function() {
// This cannot be seen outside of the module, so it will not create namespace
function aPrivateFunction(z) { return Math.sqrt(z); }

// Freezing and sealing are two ways to prevent accidental mutation of the
// module after creation.
return Object.freeze({
// These are accessible as module.anExportedFunction after the definition
anExportedFunction: function(x, y) { return x + aPrivateFunction(y); },
anotherExportedFunction: function(x) { return 2 * x; }
});
})();


Another variation mutates the global namespace object:

use strict;

// Use function to create a local scope and persistent environment
(function() {
function aPrivateFunction(z) { return Math.sqrt(z); }

// Mutate the global environment
this.anExportedFunction = function(x, y) { return x + aPrivateFunction(y); };
this.anotherExportedFunction = function(x) { return 2 * x; };
})();



Performance

No-one chooses JavaScript for its performance. The language is inherently slow relative to C because it is dynamically typed, can be interrupted for memory management at any time, performs a hash table fetch for nearly every variable access, and forces the use of 64-bit floating point. However, the latest JIT compilers produce remarkably fast code given those constraints if one structures a program in a way that is amenable to certain optimizations. Numerically-dense code and string manipulation can perform comparably to Java, and when using WebGL, graphics programs may run nearly as fast as those written in C.

As is the case in most high-level languages, the primary performance consideration is memory allocation. Avoid allocating memory or allowing it to be collected within loops. This may mean mutating values instead of returning new ones, or ping-ponging between two buffers. My simple fast ray tracer is an example of minimizing heap allocation in the main loop. In that case, the program ran 25x faster than the nearly-equivalent slower version that allocated memory for each 3D vector operation instead of mutating a previous vector in place. (The fast version also replaces some generic codeheart.js utility methods with specialized ones.)

Wherever possible, rely on standard library functions that are backed by native code instead of re-implementing them in JavaScript. For example, the string, regular expression, and array manipulation functions may be an order of magnitude faster than what can be implemented within the language.

It is common practice for developers of large JavaScript libraries to "minify" their source code before distributing it. This process renames most variables to a single letter, eliminates whitespace and comments, and makes other reductions to the size of the source code. In some cases, this is effective obfuscation of the source code. I do not recommend this practice as a performance optimization for small scripts. It is unlikely to have a significant impact on execution time because parsing is rarely a performance bottleneck and most web servers today send content across the network using gzip compression. Furthermore, renaming variables can break JavaScript programs that take advantage of the fact that there are two syntaxes for key lookup within objects, or ones that share variables with other scripts.

For canvas (vs. WebGL) graphics, drawing images is very fast compared to drawing other primitives such as lines and circles. Consider pre-rendering images of circles and then drawing the image, rather than forcing software circle rasterization at run time. When WebGL is practical to employ, use that instead of software canvas graphics for a tremendous performance boost.

Arithmetic on numbers entered as integer literals is performed at integer precision in many implementations, which is substantially faster than full 64-bit floating point precision specified by the language. Very recent (as of 2014) JavaScript implementations also support Math.fround, which notifies the compiler that floating-point arithmetic can be performed at 32-bit precision.

The typed arrays (e.g., Float32Array) provide significantly better cache coherence and lower bandwidth than general arrays. My Show me Colors sample program performs the main image processing operations on typed arrays and is able to run in real time on a live video feed because of this optimization. If operating on large arrays of numbers, use them. If operating on an array of structures that use numeric fields, invert the structure of the program:


// Before:
var objArray = [{x: 1, y: 1, z: 2}, ..., {x: 4, y: 0, z: 3}];

// After:
var x = new Float32Array(1, ..., 4);
var y = new Float32Array(1, ..., 0);
var z = new Float32Array(1, ..., 3);

JavaScript provides limited multithreading support through the web workers API. This is ideal for applications that perform significant independent computations where the end result is small, for example, computing the average value of a large array that is downloaded from a server. The input and output must be small to realize this advantage because the web workers API marshalls all data through strings for inter-thread communication.

Finally, clear and simple code is often fast code. JavaScript code isn't going to be terrifically fast anyway, so don't exchange code clarity for a modest performance gain. Only complicate code when the performance gain is disproportional to the added complexity and in a truly critical location.

I thank John Hughes and the commenters below for their edits.







Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. His most recent games are Rocket Golfing and work on the Skylanders series. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Weighted, Blended Order-Independent Transparency

$
0
0
I'm leaving this up for historical reasons, but I recommend my more recent post on blended order-independent transparency for implementors.

Glass, smoke, water, and alpha-cutouts like foliage are important visual elements in games that are all challenging to render because they transmit light from the background. This post explains a new method called Weighted, Blended OIT for rendering all of these effects quickly and with pretty good quality on a wide set of target platforms. (As is common game developer jargon, I refer to all of these as "transparency" effects. The appendix of my earlier transparent shadow paper with Eric Enderton explains the subtle differences between them.)

The traditional approach is to sort the transparent polygons, and then render them in order from farthest from the camera to nearest to the camera. That sorting is itself slow, and causes further performance problems because it triggers more draw calls and state changes than otherwise needed and prevents common performance optimizations such as rendering amorphous surfaces like smoke at low resolution.

Most games have ad-hoc and scene-dependent ways of working around transparent surface rendering limitations. These include limited sorting, additive-only blending, and hard-coded render and composite ordering. Most of these methods also break at some point during gameplay and create visual artifacts. One not-viable alternative is depth peeling, which produces good images but is too slow for scenes with many layers both in theory and practice. There are many asymptotically fast solutions for transparency rendering, such as bounded A-buffer approximations using programmable blending (e.g., Marco Salvi's recent work), ray tracing (e.g., using OptiX), and stochastic transparency (as explained by Eric Enderton and others). One or more of these will probably dominate in five years, but all are impractical today on the game platforms that I develop for, including PC DX11/GL4 GPUs, mobile devices with OpenGL ES 3.0 GPUs, and next-generation consoles such as PlayStation 4.


A transparent CAD view of a car engine rendered by our technique.

Weighted, Blended Order-Independent Transparency is a new technique that Louis Bavoil and I invented at NVIDIA and published in the Journal of Computer Graphics Techniques to address the transparency problem on a broad class of current gaming platforms. Our technique renders non-refractive, monochrome transmission through surfaces that themselves have color, without requiring sorting or new hardware features. In fact, it can be implemented with a simple shader for any GPU that supports blending to render targets with more than 8 bits per channel. It works best on GPUs with multiple render targets and floating-point texture, where it is faster than sorted transparency and avoids sorting artifacts and popping for particle systems. It also consumes less bandwidth than even a 4-deep RGBA8 k-buffer and allows mixing low-resolution particles with full-resolution surfaces such as glass. For the mixed resolution case, the peak memory cost remains that of the higher resolution render target but bandwidth cost falls based on the proportional of low-resolution surfaces.

The basic idea of our OIT method is to compute the coverage of the background by transparent surfaces exactly, but to only approximate the light scattered towards the camera by the transparent surfaces themselves. The algorithm imposes a heuristic on inter-occlusion factor among transparent surfaces that increases with distance from the camera. After all transparent surfaces have been rendered, it then performs a full-screen normalization and compositing pass to reduce errors where the heuristic was a poor approximation of the true inter-occlusion.

The CAD-style visualization of the engine above shows that our method can handle many overlapping transparent surfaces with different colors. Below we show a scene with many overlapping glass layers using a glass chess set. Note that the post-processed depth of field even works reasonably well because we fill in the depth buffer values after compositing transparent surfaces. The reflections are rendered with an environment map and there is no refraction.


A glass chess set rendered with our technique.


In the pond video below, we show many overlapping transparent primitives that have highly varying transmission (alpha) and color values. The water is both reflective and transmissive according to Fresnel's equations. The fog has a Perlin noise texture and is rendered with low-coverage billboards. All of the tree leaves and the grass are rendered with alpha-cutouts applied to simple quads. In fact, sorted transparency cannot even render this scene because the fog and tree leaves pass through each other, as do the water plants and pond surface. So, there is no valid triangle ordering for producing the correct image and a per-pixel method such as ours is required to produce a convincing image.


Pond scene showing different kinds of transparent surfaces simultaneously: water with transmission varying by Fresnel's equations, alpha-cutout foliage, and large fog billboards, rendered in real-time by our technique.

The primary limitation of the technique is that the weighting heuristic must be tuned for the anticipated depth range and opacity of transparent surfaces. We implemented it in OpenGL for the G3D Innovation Engine and DirectX for the Unreal Engine to produce the results here and in the paper. Dan Bagnell and Patrick Cozzi implemented it in WebGL for their open-source Cesium engine (see also their new blog post discussing it). From that experience we found a good set of weight functions, which we report in the journal paper. In the paper, we also discuss how to spot artifacts from a poorly-tuned weighting function and fix them.


Smoke scene. This example shows high opacity used for concealment during gameplay, and smooth transitions during simulation unlike the popping from traditional ordered billboard blendeding.

Implementing Weighted, Blended OIT

The shader modifications to implement the technique are very simple. During transparent surface rendering, shade surfaces as usual but output to two render targets. The first render target must have at least RGBA16F precision and the second must have at least R8 precision. Clear the first render target to vec4(0) and the second render target to 1 (using a pixel shader or glClearBuffer + glClear).

Then, render the surfaces in any order to these render targets, adding the following to the bottom of the pixel shader and using the specified blending modes:

// Output linear (not gamma encoded!), unmultiplied color from
// the rest of the shader.
vec4 color = ... // regular shading code



// Insert your favorite weighting function here. The color-based factor
// avoids color pollution from the edges of wispy clouds. The z-based
// factor gives precedence to nearer surfaces.
float weight =
max(min(1.0, max(max(color.r, color.g), color.b) * color.a)), color.a) *
clamp(0.03 / (1e-5 + pow(z / 200, 4.0)), 1e-2, 3e3);

// Blend Func: GL_ONE, GL_ONE
// Switch to premultiplied alpha and weight
gl_FragData[0] = vec4(color.rgb * color.a, color.a) * weight;

// Blend Func: GL_ZERO, GL_ONE_MINUS_SRC_ALPHA
gl_FragData[1].a = color.a;

If you are rendering some calls (such as particles or out of focus regions) at low resolution, then you can run the above code to different resolution textures independently and combine them during compositing. It will work even if the low- and high-resolution content are interleaved in depth.

Finally, after all surfaces have been rendered, composite the result onto the screen using a full-screen pass:

vec4 accum = texelFetch(RT0, int2(gl_FragCoord.xy), 0);
float reveal = texelFetch(RT1, int2(gl_FragCoord.xy), 0).r;

// Blend Func: GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA
gl_FragColor = vec4(accum.rgb / max(accum.a, 1e-5), reveal);

The compositing must occur before gamma-encoding (that is, I'm assuming that the renderer performs gamma-encoding (if needed by your target), color grading, etc. in a subsequent full-screen pass.)

See the paper for full details and fallback paths for GPUs or APIs that do not support multiple render targets or per-render target blending functions.

Keep the depth buffer that was rendered for opaque surfaces bound for depth testing when rendering transparent surfaces, but do not write to it. This preserves early-Z culling, which can significantly improve throughput. I recommend rendering surfaces that have alpha cutouts during both the transparent and opaque passes. During the opaque pass, use an alpha test of GL_EQUAL to 1.0. This makes the fully-opaque regions of the surfaces appear in the depth buffer and avoids any fading of that part of the surface with depth.

To help others with implementing this method, I rendered a simple scene using weight equation 9 from the paper. I recommend trying to reproduce this image before evaluating on more complex scenes:

Color values are given before pre-multiplication, e.g., the premultiplied blue value is actually (0,0,0.75,0.75).
Note that compositing is in "linear" RGB space, but the whole image is converted to sRGB for final display.

Note that weighted, blended OIT is a blending operation. If the results that you see are outside the range of the original surfaces, that must be a bug in your implementation. For example, regions darker than the original colors are likely underflow during blending. Regions that are brighter than the original surfaces correspond to overflow (saturation)...or due to forgetting to use premultiplied alpha.

The curves in the paper are tuned for avoiding precision problems with 1-100 surfaces using 16-bit float blending, assuming that the alpha values are roughly on the range [0.2-0.9] and that in scenes with very high transparent surface counts, those surfaces have lower alpha values (e.g., smoke clouds).

Louis and I thank the graphics team at Vicarious Visions for their support and feedback while developing this algorithm and Analytic Graphics for their WebGL expertise.




Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Fast Terrain Rendering with Continuous Detail on a Modern GPU

$
0
0
Terrain rendering is challenging. It requires both high detail close to the camera and a large extent. There must be less detail per square meter in the distance to render this efficiently (and ideally, the amount of detail per pixel would be about the same), but the transitions from high to low detail should be imperceptible.

There's been a lot of research and development on terrain rendering systems. The best systems today can render worlds in which the viewer can pull back continuously from individual stones and flowers to observing entire planets from space, and when looking at the flowers can still see mountains in the distance. The underlying perception, art, and geometric issues of course remain unchanged over time, but hardware architectures and available resources change dramatically. So, terrain rendering methods that were preferred even a few years ago (e.g., ROAMgeomipmapping, projective grid) may be obsolete today. (Today's methods will likely be obsolete in a few more years). Fortunately, the last few hardware generations have moved in a direction where the currently-preferred implementations are more simple to implement than the previously-preferred ones.



In this post I describe a terrain renderer that I built with some current best practices. It draws on a lot of other blog posts and research articles that I'll mention in passing. My implementation renders in 3.4 ms at 1680x1050 resolution on NVIDIA GeForce 650M under Windows 7 (i.e., on a MacBook 2012 Pro under boot camp), and supports both forward and deferred shading. It is written in OpenGL using the G3D Innovation Engine 10.0 beta (SVN revision 4283) and I provide the full source code. I don't expect anyone to compile and run that code directly, however. I'm releasing it without support (i.e., I'm always happy to discuss algorithms, but please don't ask me for help dealing with your compiler/library/installation) to help others with their own implementations and as a case study in GPU optimization of large mesh rendering.

Geometry

The underlying geometry is a static mesh submitted in a single draw call. This mesh is a version of a geo clipmap (thesis, SIGGRAPH paper, GPU Gems) that does not require explicit updates. It has high resolution near the camera, and then becomes coarser farther from the camera in the same way that textures are sampled from increasingly coarse MIP-maps farther from the camera. I generated the static mesh indices in order from the highest to the lowest resolution. This allows hierarchical and early depth culling to efficiently avoid overdraw when the camera is close to a large feature.

The vertex shader performs two major transformations on the static mesh:
  • translate the mesh, to always keep it centered around the camera
  • alter the elevations to conform the the terrain height (which is stored in a texture map)
If the terrain moved smoothly, then the individual vertices would ripple over the heightmap and not look like solid terrain (this might be acceptable for water, however). So, the vertex shader rounds off the translation along the horizontal axes to the nearest grid vertex position. This makes vertices appear to be static in world space, even though they are in fact holding still and then jumping between frames to their neighbors' previous positions.
Because the grid has varying resolution, the roundoff varies throughout the grid. I store the resolution of the mesh at each location in the vertical coordinate (which will be overwritten by the sampled elevation during vertex transformation). The vertex shader then uses the resolution to compute the appropriate rounding factor.

I tessellated the grid as regular squares that are themselves subdivided into a fan of eight triangles. While this does not give optimal conformance for a regular structure like an isometric heightfield, it is much better than slashed diagonals while also being easier than the isometric grid to stitch together where the mesh resolution drops.

Many terrain implementation divide the static mesh into quadrants or octants that are then frustum culled to avoid transforming geometry that is behind the camera. I performed some quick tests and determined that on my target GPU the performance gain for doing so was minimal (around 0.2ms). Frustum culling the terrain adds complexity to the code that I felt was unjustified for that performance gain, so I simply submit the entire mesh each time.

Distant terrain undersamples the heightfield texture. This aliasing would appear as vertical "noise" if a simple nearest-neighbor minification scheme were applied, so I compute a MIP chain for the heightfield. Default hardware MIP-mapping reduces four pixel blocks to a single pixel by averaging. This has several undesirable characteristics, including a large bias in filtering based on the location of a height texel within the image. I use a 3x3 downsampling filter and explicitly adjust texture coordinates during sampling to match the difference between this and the default MIP layout.

To eliminate discontinuities in elevation between grid resolutions, I use an explicit form of "trilinear" (MIP-map) interpolation. Vertices interpolate vertically towards the next lower-detail MIP level so that they exactly match the next resolution at the edge of a grid patch.

To conceal the vertical aliasing of the 8-bit input heightfield, at the highest detail mesh I apply quadratic interpolation instead of linear interpolation between heightfield vertices and add a small amount of value noise to break up large flat plateaus.

The mesh in this implementation is an explicit indexed triangle list using a full 32-bit precision vertex array. Reducing the mesh to 16-bit 2D horizontal vertices and 8-bit resolution flags (in a second attribute stream) would reduce the vertex bandwidth cost. It would be most elegant to generate it procedurally in the vertex shader, or using a tessellation shader. Procedural approaches would completely eliminate the input bandwidth cost. However, because attribute stream bandwidth to the vertex shader was not a significant bottleneck and the stitching logic would be much more complicated to implement under procedural mesh generation, I did not optimize this part of the process.

Lighting

The ambient occlusion term, ignoring the environment map
I precompute self-shadowing (of the sun) and ambient occlusion (of the sky) on the terrain and store this information in a texture map. The RGB channels of this texture are the irradiance from the sky and the A channel is 1 where the sun is visible and 0 where it is occluded by terrain. I blur this texture to minimize the appearance of tessellation artifacts.


White terrain with the precomputed lighting applied
I apply a simple Phong shading model in the images shown on this page. Obviously, the terrain could benefit from more sophisticated shading and normal or parallax-mapping near the camera, but that is not terrain-specific, so I didn't extend it further.

Materials

The implementation supports set of five elevation zones (specified in a data file). Within each zone, there is a one material for steep surfaces (e.g., dirt) and one for flat surfaces (e.g., grass). Steep vs. flat is determined by the shading surface normal, which is fetched from the elevation texture. The surface normal rarely matches the actual mesh geometry, so triplanar mapping doesn't work directly. Instead, I hardcoded the texture rate for sloped surfaces and then optimized down the code to a handful of operations. 

All materials are stored in a single GL_TEXTURE_2D_ARRAY, which acts like a 3D texture with no filtering between array elements. This allows a fetch without a hardcoded texture binding. One alternative is a set of branches to select the appropriate sampler, which is slow (I tried that first); another alternative is packing all of the textures into a large atlas, but then one can't use hardware texture tiling. After computing texture coordinates and weights, I branch over texture fetches corresponding to low weights to reduce bandwidth. Because texture coordinate derivatives (for selecting MIP levels) are computed by finite differences between adjacent pixels, this breaks automatic MIP-level selection. So, the code computes explicit gradients outside of the branches. I intended to use DXT1 texture compression to reduced bandwidth, but the OpenGL API doesn't support copying individually-compressed textures into a 2D array. The vestiges of the setup are left commented out in the code--the next step would be to explicitly read back the compressed texture pixel transfer buffers to the CPU, merge them, and then upload them into the 2D array at once.

I also intended to modify the blending around contiguous features, however that detail wasn't needed for my immediate application in a flight simulator so I left it a using typical (and slightly muddy) lerp.

Direct texture mapping only works well in the foreground. Medium-distant surfaces would reveal the texture tiling and far-distant surfaces would always hit the lowest-resolution MIP level and exhibit a solid color. To reduce bandwidth, I precomputed the blended materials for surfaces past the highest-resolution into a single lookup table indexed as (elevation, slope). This texture I did compress with DXT1, because it accounts for a majority of the texture fetches on screen.

To increase variation, I add noise at several scales in several ways. I vary the slope and elevation used for selecting textures according to a procedural and hand-painted noise map (I'm just re-using the rock texture as the noise map in the scene shown here). This creates the appearance of medium details such as individual rocks, patches of grass, and patches of snow, and breaks up material striations on large cliffs. I also modulate the intensity of the diffuse texture by a different combination of the noise texture and functions at a very low frequency. This hides texture tiling and creates visual detail.

Finishing Touches

Raw terrain solves a technical challenge but not an artistic one. It benefits from the addition of effects that increase the sense of scale:
I added fog and depth of field in some of these screenshots, and started prototyping water but did not implement the other effects. For a PC game, I think that weighted, blended transparency would work particularly well for blending the grass, trees, and clouds based on the video result below:



Finally, below is a video with the water prototype. It is not included with the source release, but is built on G3D's open source screen-space ray tracing, refraction, and Fresnel helper functions.


Thanks to Padraic Hennessy for introducing me to many resources on this topic.


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

A Computer Science Book Reading List

$
0
0
This is a list of good books on computer science.
Most are accessible to anyone with programming experience equivalent to an introduction to computer science course. Of course, everyone in the field has his or her own favorite books. There isn't a universally accepted list of "best", but I think all would agree that these are at least pretty good in both writing quality and technical content, and that you would not go wrong by reading them.


If you read one book from each category within CORE, SYSTEMS, and THEORY, then, congratulations: you've just completed the equivalent of an undergraduate major in computer science! Pick up a few from APPLICATIONS and you're at the Masters level. In my ideal CS department, this would be the main thread of the majors curriculum, to be augmented with mathematics and more computing application electives.

I made this list in the process of researching acquisitions for the Williams College library. I reviewed the curriculum (for topics) and syllabi (for book recommendations) of many of the top CS programs and liberal arts colleges, including: MIT, Cal Tech, University of Washington, Princeton, Stanford, Berkeley, Brown, Rice, Williams, Amherst, Swarthmore, Harvey Mudd, and Wellesley. I gave special emphasis for each topic to the schools and professors that specialize in it, e.g., Rice for compilers and programming languages. I also looked at various recommendation lists on the web and the Amazon best-sellers in each category. I was familiar with many of the books already. For the others, I reviewed the table of contents, read sections, looked at reviews, and particularly examined code samples. I then selected the book in each topic that I would want to use if teaching the course. For some topics, there were a few choices that had very high quality but very different approaches, so I listed all of those. If teaching that course, I would try one a year to see which worked best with the students. I generally didn't choose the best graduate textbooks or reference books, but instead the ones that would be appropriate for first encountering a topic, e.g., in an undergraduate course.

I'm also often asked for recommendations for professional programmers without CS degrees or undergraduates who want to learn more CS without necessarily taking courses or majoring. This is a nice list for those groups as well. Because of the way that CS books are categorized, it is hard to browse them in a library. Some are filed under "engineering," others under "math,""programming,""computer science," or the application area, such as artificial intelligence books appearing in psychology, cognitive science, and biology. So, think of this as the book shelf that I wish you could find in a library, with all of the short-lived "Learning Ruby in 21 Days" and "Visual Fortran 2012 for Dummies"-type books that normally clutter such a section removed.

For convenience, I've linked the books to Amazon for everyone and the Williams College library for my students (some are not yet at Williams, but are coming soon.) If you're reading through these book-club style, just choose one book from each category--whichever your library has or appeals to you will be fine. To keep the list approachable, I didn't include all of the well-respected books in each category but tried to choose one or two. Rather than making this a catch-all, I'll let others maintain their own lists of best computer science books---but I do appreciate recommendations, especially for application areas farther from my specialization in computational graphics.

Programming & Specific Languages
In the long run, it doesn't matter what language you begin with, and any book in this group is sufficient to get started. Skip on to the CORE section after reading one.

Introduction to Computer Science Using Python: A Computational Problem-Solving Focus
Dierbach
[Amazon] [Williams]
A Byte of Python
Swaroop
[Free!]
The Little Schemer
Friedman et al.
[Amazon]
The C++ Programming Language
Stroustrup
[Amazon] [Williams]
JavaScript: The Good Parts
Crockford
[Amazon] [Williams]
The C Programming Language
Kernighan and Ritchie
[Amazon] [Williams]
Java: An Eventful Approach
Bruce et al.
[Amazon] [Williams]


CORE

Computer Organization
Computer Organization and Design
Patterson and Hennessy
[Amazon] [Williams]

Data Structures
Data Structures and Algorithms
Aho et al.
[Amazon] [Williams]
Java Structures: Data Structures in Java for the Principled Programmer
Bailey
[Free!]
Data Structures and Algorithms
Wirth
[Free!]

Algorithms 
Algorithms
Dasgupta et al.
[Amazon]
Introduction to Algorithms
Cormen et al.
[Amazon] [Williams]
Algorithms
Sedgewick and Wayne
[Amazon] [Williams]

History of Computer Science
Alan Turing: The Enigma
Hodges
[Amazon] [Williams]
Hackers: Heroes of the Computer Revolution
Levy
[Amazon] [Williams]
The Universal History of Computing: From the Abacus to the Quantum Computer
Ifrah
[Amazon] [Williams]


THEORY

Theory of Computation
Introduction to the Theory of Computation
Sipser
[Amazon] [Williams]

Programming Language Theory
Programming Languages: Application and Interpretation
Krishnamurthi
[Free!]
Design Concepts in Programming Languages
Turbak and Gifford
[Amazon]

Advanced Algorithms & Data Structures
Advanced Data Structures
Brass
[Amazon] [Williams]
Probability and Computing: Randomized Algorithms and Probabilistic Analysis
Mitzenmacher and Upfal
[Amazon]
Randomized Algorithms
Motwani and Raghavan
[Amazon] [Williams]

Cryptography
Introduction to Modern Cryptography: Principles and Protocols
Katz and Lindell
[Amazon]

SYSTEMS

Architecture
Computer Architecture: A Quantitative Approach
Hennessy and Patterson
[Amazon] [Williams]

Operating Systems
Operating Systems: Principles and Practice
Anderson and Dahlin
[Amazon]

Networks
Computer Networks and Internets
Comer
[Amazon]

Compilers
Engineering a Compiler
Cooper and Torczon
[Amazon] [Williams]

Parallel Programming
Programming Massively Parallel Processors
Kirk and Hwu
[Amazon] [Williams]

Numerical Methods
Numerical Recipes: The Art of Scientific Computing
Press et al.
[Amazon] [Williams]

Databases
Database System Concepts
Silberschatz et al.
[Amazon] [Williams]
Fundamentals of Database Systems
Elmasri and Navathe
[Amazon]

Distributed Computing
Distributed Systems: Principles and Paradigms
Tanenbaum and Van Steen
[Amazon]

Software Engineering & Management
The Mythical Man-Month: Essays on Software Engineering
Brooks
[Amazon] [Williams]


APPLICATION AREAS

Machine Learning
Learning From Data
Abu-Mostafa et al.
[Amazon]
Understanding Machine Learning: From Theory to Algorithms
Shalev-Shwartz and Ben-David
[Amazon]

Artificial Intelligence
Artificial Intelligence: A Modern Approach
Russell and Norvig
[Amazon] [Williams]

Computational Graphics
Computer Graphics: Principles and Practice
Hughes et al.
[Amazon] [Williams]

Computer Vision
Computer Vision: Models, Learning, and Inference
Prince
[Amazon]

Human-Computer Interaction
Designing the User Interface: Strategies for Effective Human-Computer Interaction
Shneiderman et al.
[Amazon]

Computational Biology
Algorithms in Structural Molecular Biology
Donald
[Amazon] [Williams]
An Introduction to Bioinformatics Algorithms
Jones and Pevzner
[Amazon]

Game Engine Programming
Game Engine Architecture
Gregory
[Amazon]



Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. His most recent games are Rocket Golfing and work on the Skylanders series. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Favorite Short Films from Annecy 2014

$
0
0
The 2014 Annecy International Film Festival  screened 500 new films in the beautiful resort town of Annecy, France. Since 1960, the best animated films have been shown here, with emphasis on experimental short films. I've attended since 2004, and each year been amazed--and often overwhelmed--by the quality and diversity of ideas. Last year I began posting summaries of my favorite films.

My 2014 favorites films are here. I'm partial to representational; uplifting, humorous, or sexy; narrative shorts. From recalling the previous years' award winners, this is the festival audience's preference as well. That bias is perhaps partly because it is hard to present a new aspect of important but well-explored topics such as abuse, genocide, and aging; and also because it is very easy to make overwrought films on those topics.

Yet, this year many of my favorites were atypical. In those cases, they took on difficult subjects with maturity and grace. My favorites usually overlap heavily with the festival award winners, however this year only two appeared on that list and my (tied) top two choices won no awards in competition at all.

The Best Film of Annecy 2014

These two radically different films impressed me greatly. Both displayed mastery of the medium, expert pacing, and bent in unexpected directions. I consider them tied for "best short".

Hipopotamy () - A beautifully executed film for its animation, music, pacing, and maturity, with deeply disturbing content: human forms applied to animal (titually hippotamus, but most likely elephant seal) behaviors, which are deplorably not so implausible on human forms.  It is important and an intelligent combination of beauty and ugliness directed with enough space for the audience to draw their own conclusions and parallels. http://www.fumistudio.com/

Moulton og meg (Torill Kove) - Three girls raised by modernist architects. A killer concept with ready-made art humor, nice coming-of-age elements, and heartwarming comments on families. The clean modernist-meets-children's style of black lines and solid, marker color fits the material perfectly. The narration is top-notch, as is the script and timing. Trailer



Other Favorites

I recommend all of these films, which are refreshingly innovative and have some great moments. I'm a bit critical of the ones near the bottom because I think that they have flaws, whereas the others are solid all of the way through. All deserve viewing and discussion.

Hasta Santiago (Mauro Carraro) - A modern pilgrimage rendered in computer colored pencil. Told as a straight travel and character study with occasional surrealist flair and great pacing. 2014 award for first film, Sacem award for music. Trailer






Sandy (Joseph Mann/Blink Industries) - A boy at the beach, harmlessly aping adult sexual behavior. It is cute and giggly while remaining earnest and honest.

Laznia (Tomek Ducki- A short film about swimming and aging and friendship. The animation is what sets this apart, with two different graphic-design styles of clean lines and gradients. Trailer

Le Petite Casserole d'Anatole (Eric Montchaud/JPL Films- A touching claymation story of difference and acceptance delivered with a light touch and maturity. I look forward to sharing it with my children. 2014 audience award winner. Excerpt

Kaly Live Dub "Allaxis" (Thomas Fourniret) - A high energy music video with impeccable, anime-influenced animation. This is at the bare edge of narrative, but I didn't mind one bit. It is everything cool from heist movies and road movies at once. A Scanner Darkly should have been this good.




La Guillotine (Cédric Villain/Arte France Développement, Claire Doutriaux) - Rarely does a short documentary impress me, but this one is fantastic. It is a great example of the power of film as a visual medium for education. Even without any understanding of French, you'll understand the details and historical points. This was the right medium for the right subject.

Sneh (snow) (Ivana ŠEbestova/Feel Me Film S.R.O.) - An occasionally-surreal love story with just enough room for ambiguity at the end. It uses its longer running time well.

Salmon Deadly Sins (Steven Vander Meer) - I enjoyed the wordplay and wacky illustrations.

365 (The Brothers McLeod) - One second of animation drawn per day for an entire year. This could have been a bit shorter, but it is interesting to see their style evolve over the year, the recurrence of themes, and their impressive discovery of how to pull off single-beat stories. Trailer

FMX 2014 Rugbybugs (Carl Schröter, Martin Lapp, Emanuel Fuchs, Fabian Fricke and Matthias Bäuerle/Filmakademie Baden-Württemberg) - This trailer for FMX is an impressive piece of student work with great rendering.

Supermoine Holypop (Supamonks Studio) - A beverage commercial (with a NSFW heavy metal theme song) with terrific blockbuster-style movie rendering of medieval mayhem. I'd like to make a video game that looks like this.

Louis (Mathilde Parquet/École des Metiers du Cinema d'Animation) - An afternoon exploration turned horror movie reminiscent of David Lynch.

Marilyn Myller (Mikey Please- A well done styrofoam stop motion about a styrofoam stop motion artist. It has a typical but well-executed rendition of the modern artist's journey and uses a fun, different medium. Trailer, Behind the Scenes

Pickman's Model (Pablo Ángeles/Dei ar Guachin OS, SA de CV)- Beautifully rendered and voice acted, with a solid story from H. P. Lovecraft. I found the film complete after the first reveal and felt that the remainder overplayed the twist rather than trusting the audience. Trailer

Beauty(Rino Stefano Tagliafierro) - Oil paintings subtly animated. This is a good idea, although the execution doesn't quite work for me in this case. The animation and composition simply aren't up to the quality of the original images, so the film tars itself a bit as uneven and exploitative of its sources. Yet, I hope to see more of this. Some styles, like sand art, are becoming overused and this was a truly fresh direction.








Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

The Joy of Modern Board Games

$
0
0
Depiction of the ancient Egyptian game of Senet
Board games have been enjoyed for thousands of years. This category includes card and dice games, as well as table-top games with proper boards. In the 19th and 20th century, standardized commercial games began to appear, with Milton Bradley, Parker Brothers, and Hasbro dominating the themed "American board games" market into the late 20th century. This includes popular titles such as Monopoly, Risk, Trivial Pursuit, and Chutes & Ladders. These are the games that many current young parents grew up playing at home.

The Settlers of Catan
In the late 1990's, board games experienced a revolution. New games emerged in Europe (especially Germany) such as The Settlers of CatanThese games combined the accessibility of Monopoly with a level of strategy previously found only in hardcore wargames and role playing games. These quickly became popular around the world. They scaled from family board game sessions to college game nights. This accessibility was due to relatively short play times (compared to wargames and role playing games), strong themes attractive to a wide audience (compared to chess), and the crucial ability to accommodate many players who are not eliminated during play. Many entries in this new genre of "Eurogames" drew on advances in design from video games and from mathematical principles such as set theory.


Today, there are hundreds of well-designed games in this mold. The BoardGameGeek website is an excellent resource for discovering them. I play Eurogames with my students, peers, and family. In fact, my game design course begins with these games and only addresses video games at the end of the semester. I'm not alone in that--game design at most schools builds from board games in the same way that computer science builds from mathematics and digital art from natural media.

The classic introduction to these Eurogames is Settlers of Catan, which is sort of like Monopoly redesigned for fun, strategy, and intelligence. From there, Carcassonne, Dominion, Puerto Rico, Seven Wonders are natural next steps, although there are really so many good games that it is hard to go wrong with anything rated highly on BoardGameGeek. Some of my personal favorites are Space Alert, HiveEminent Domain, and Space Hulk: Death Angel, all of which tend towards hardcore.
Carcassonne

A key point for families: children who can perform addition and are just beginning to read are able to play Settlers of Catan and Carcassonne. My own children started with Abandon Ship at age four and then graduated to these other games within a year. Even such young children can quickly develop the critical thinking skills of strategic play through these, including minimax logic, basic probability, statistics (well, card counting), and negotiation.

Like many families, we have house rules for our favorite games. As a game developer, author of game textbooks, and game teacher, I try to understand our intuition and motivation for these changes and frame objective arguments for why these rules improve the games. I've written about those in many places previously and will start to collect some of those on this blog. But my first goal in a series of upcoming posts is to begin to publicly document some of our house rules to share them with a wider audience (...and to have a place to point or warn friends before they come to visit.) I'll begin with Carcassonne in the next post.



Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

McGuire House Rules for Carcassonne

$
0
0
Carcassonne is a family-friendly Eurogame (modern board game) that, with appropriate expansions and modifications, scales well from two to six players and admits serious competition at any age from five up. It allows players to chose a game length from about 20 minutes up to hours (with multiple sets). The game was designed by Klaus-Jürgen Wrede and was first published in 2000 by Rio Grande and others. This post describes our house rules for Carcassonne. For simplicity when learning the game, I give a nearly complete rulebook rather than differences from printed rules.

We've been playing Carcassonne for over a decade (most recently with small children). The McGuire house rules arose from that play experience, some in-depth game theory analysis, and analysis of rule differences in different regional editions and printings. We believe that compared to the American printed rules, these increase fairness and balance, extend the game to meaningful two-player play, manage game length, and increase strategy, while avoiding unnecessary complexity and staying true to the core mechanics that made Carcassonne great originally. I wrote an analysis of the original rules a few years ago for my game design course that explains the motivation for many of these changes.

For various reasons, including marketing and a desire to not reprint even when errors are discovered, the box that you buy of a game doesn't always have the best version of the rules. I encourage everyone to experiment with the rules of games that they play, and if you're playing Carcassonne, here are some to start with. Lots of folks will disagree with our rule set, and that's great too. The best part of playing a game is often changing the rules and finding where the lead you, and everyone has their own taste for what makes the game ideal.

Setup

We play a set that combines the base game with these expansions:
  • The River (ships with new editions of the base game)
  • Inns and Cathedrals
  • Traders and Builders
  • King & Scout
  • Six-player expansion
and a set of homemade 50-point markers, because games often run over 150 points per player and the scoring track only counts to 50. If you don't have all of these expansions, then you can just ignore some of our rules without affecting balance. We've tried and rejected The Countof Carcassonne, The Dragon, The Princess & The Dragon, and The Tower expansion, and some of the rules (but not the tiles) from the above expansions. The game has about 10 other recent expansions that we haven't tried yet.

If you lose some followers from your game set, you can purchase replacements ("meeple") and other shapes for your own new rules in compatible wood and colors from http://www.meeplesource.com/. I haven't found a good way to manufacture or replace tiles, however if you buy a second base game or some expansions you'll have an awful lot of tiles to work from and you don't need them all to play.

Decide how long of a game you wish to play. Choose a number of tiles equal to twice (or a bit fewer, if this is your first time) the number of minutes desired, rounded to an even multiple of the number of players.  Put all tiles in the draw bag. For a very long game, begin with the river tiles, otherwise, set them aside with the excess tiles. Even for a long game, always leave out a random set of a few tiles, and for all games ensure that no-one sees the tiles that are held back--this prevents "card counting" in the end game, which is slow, tedious, and an unfairly large advantage to experienced players.

Place the pigs on the zero square of the scoreboard  (if you don't have pigs from the base game, use colored counters).

Grant each player initial points based on his or her handicap. This should increase with the number of tiles in play. For example, my five-year old currently begins with points equal to 30 less than the number of tiles in the bag. After each game, adjust handicaps based on the final score so that each player begins the next game with a relatively fair chance of winning. We shift handicaps by about half the difference from the winner for children until stable, and more slowly for adults.

Put the first river tile or the start tile (it has a dark back) face up in the center of the table to begin the world. If you're using the river opening, follow the rules from the expansion for it--those are the only ones I don't repeat here.

Draw a three tiles and place these face up. These form the shared hand from which players will choose their tiles each turn. You may also wish to use a number of tiles equal to the number of player colors; that can slow the game down, but we've had equal success with it for balance and strategy.

Features

The cardboard squares are tiles. Each tile has one or more pieces of features on it. A feature is a contiguous shape that can span multiple tiles. A key concept is when a feature is complete and can be scored before the end of the game. The features are:
A Monastery 
  • Roads (white lines), which end at intersections with other roads and with cities. Bridges are not intersections. Inns and lakes are not intersections. Roads with inns on them have special scoring rules. Roads are complete when both ends are intersections with roads or cities.
  • Cities (brown areas containing buildings). Some cities contain blue-and-white checkered shields; each shield counts as an extra tile when scoring. City tiles entirely consumed by cathedrals have special scoring rules. Ignore the "trade good" icons. Cities are complete when their border walls have no gaps.
  • Monasteries (a.k.a. cloisters; centered large buildings surrounded by green) are single-tile features. They are complete when all spaces in the 3x3 grid centered on the monastery are filled.
  • Farms (green areas that may contain buildings) are bordered by roads and cities. Farms must be connected by a continuous green swath--where different cities pinch together at tile corners and no green passes through, a farm ends. Farms are never complete.
Four separate farms
There is a critical distinction in the game between separate features that are likely to merge in the future and continuous features. The primary strategic move in the game is claiming an unoccupied feature and then merging it into an occupied one.

Turn

A Builder
Players take turns in order around the table. On your turn, a take the following actions, in order:
  1. Draw a tile to fill the shared hand (on the very first turn of the entire game, the first player does not draw a tile) if there are any tiles left in the bag.
  2. Choose any one tile from the shared hand and place it in the world so that at least one edge is adjacent to another tile and all edges are consistent. (No corner-only touching, if there is a road or city, it must match up on all sides with any roads or cities present in the world.)
  3. Optionallydo one of the following:
    1. Place one follower (little or big person) on the tile on a feature that is not already owned by anyone. By convention, farmers lie down in fields to make them clearer.
    2. Place the builder (looks like a chef) on the tile on a road or city feature that is already owned by you.
  4. Score any cities, roads, and monasteries that placing that tile completed, even if they aren't yours, and return those followers to the players who own them (see below). Note that scoring and retrieving followers and builders occurs after placing--if you didn't have a follower before closing a feature, you cannot recycle the follower that just returned home. Farms are not scored until the end of the game--farmers never return home.
  5. If you added your tile to a feature that already contained your builder, then optionally repeat steps 1 through 4 once. (You can never place more than two tiles in a turn.)
Play continues until all tiles have been played. At that point, commence end-game scoring.

(It may be possible to draw a shared hand that contains only unplayable tiles...although I have never encountered this in practice. I propose that if it happens to you, then you immediately declare the game a tie and go out for ice cream.)

Note that farms are features and a follower cannot be placed onto an already-owned farm. Builders cannot be placed onto farms.

In a two-player game, each player plays two colors and these colors are played in alternating order. For example: player 1 plays black, then player 2 plays red, then player 1 plays gray, then player 2 plays yellow. Each color is separate, as under normal rules (e.g., on red's turn, player 2 can't place a yellow follower), but the player's score at the end of the game is the sum of the scores of his or her colors. This makes sharing features viable in a two-player game--you just want to share more with yourself than with your opponent.

Scoring

During play (before the end of the game), a road, city, or monastery feature that is completed immediately scores points for the player(s) who own it and all followers and builders on that feature "return home" to the players who placed them. Farms are never completed.

A feature is owned by the player who has the most followers on it, with the large follower counting as two and the builder not counting at all. If multiple players are tied for most followers on the feature (which is a common and desirable case), then those players each receive full points for that feature. The values of completed features are:
Cathedrals increase risk and reward
  • Monastery: 9 points
  • Road:
    • With an Inn: 3 points/tile
    • Two tiles: 2 points
    • Otherwise: 2 points/tile
  • City: (recall that each shield counts as an additional tile)
    • With a Cathedral: 3 points/tile
    • Two tikes: 2 points
    • Otherwise: 2 points/tile
Note that the number of tiles is critical--if a city or road winds through the same tile twice, that tile is still only counted once.

At the end of the game, farms and incomplete features are scored as follows (score features, not followers, and remove them as scored to avoid miscounting):
  • Monastery: 1 point for each tile in the 3x3 grid centered on the monastery
  • Road:
    • With an Inn: 0 points
    • Otherwise: 1 point/tile
  • City: (recall that each shield counts as an additional tile)
    • With a Cathedral: 0 points
    • Otherwise: 1 point/tile
  • Farm:
    • 3 points/completed city touching the farm 
Note that multiple followers on a feature affect who owns it, but do not affect how many points it is worth.


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

McGuire House Rules for Settlers of Catan

$
0
0
The Settlers of Catan is perhaps the most widely-played modern board game, easy to learn, deep
enough to be interesting for everyone, and playable by anyone old enough to add small numbers. The game was designed by Klaus Teuber and first published in 1995 by Kosmos and other companies. It has since been revised and expanded many times.

The basic gameplay is similar to Monopoly: players gain resources through random events, build small and large buildings to increase their income, and trade resources.  Unlike Monopoly, Settlers grants players significant control over the randomness, expands from a single resource to a five-commodity economy, separates points from resources, and keeps all players in the game until the end (which usually arrives after about 45 minutes). These elements are the hallmarks of Eurogames and were popularized by Settlers, which initiated the current board game Renaissance.

The base game has several drawbacks, which were oddly compounded instead of reduced by the published expansions (for example: Knights & Cities and Seafarers). Settlers is poorly balanced compared to more recent games for two reasons.

First, the setup round in which players choose their starting positions largely determines the game. This is because an experienced player will seize resources that allow him or her to more quickly enter the positive feedback loop of expansion ("building an engine").

Second, there is too much variance (colloquially, "randomness") in the resource model and equally-matched players will have very different scores. Part of the strategy is naturally to minimize the impact of variance by diversifying one's resource pool, but the underlying spread is too high to overcome through strategy. For these reasons, many players quickly graduate to Puerto Ricoand then Agricola, which have a similar feel but more strategic and focused play.

In the McGuire household, we've adopted several modifications of Settlers of Catan that keep it engaging and challenging for more sophisticated players while also making it more fun for young children.

We find that these rules work well for our diverse mix: a seven-year old and peers, some hardcore board gamers, and visiting college students and older adults who haven't played Eurogames before. I describe these rules relative to the American 4th edition printing.

An overview of our changes and motivation for them are:

  • Eliminate the imbalance of placing first or being very experienced during the setup round (see also Carian's game-theory inspired Last Diminisher opening)
  • Give weaker players a head start
  • Speed up the opening of the game, when no-one can do much in the base game because there are few resources in play
  • Eliminate the need for card counting, which is tedious and too hard for young players
  • Eliminate "attack" moves (robber, knight, and monopoly), which force an undesirable choice between group harmony/happy marriage/smiling children and effective moves
  • Ensure that everyone has an equal number of turns to build
  • Ensure that the current player receives a resource when rolling a 7; this is the most common number in the game and in the base version often results in no income, slowing down the game

Setup

1. Construct the frame for the island and set aside the desert hexagon. Shuffle the remaining resource hexagons and then stack them face down. Place the resources within the frame to fill the island, leaving one space along the border blank. The choice of space will affect the available ports and could be chosen randomly, but in practice this doesn't matter much.

2. Place the desert hexagon face down (so that the sea background is up) in the remaining space...it is now the harbor. Take the extra port tile corresponding to the port that was lost in making the harbor, and a 3:1 port tile, and place them on inner corners within the harbor.

3. Sort the round letter tiles alphabetically and place them in a tightening spiral from the outer hexagon adjacent to the harbor in towards the center, as in the game rules (the harbor is water and does not receive a letter tile).

4. One of the best players places two settlements (houses) and two roads for each player color, one adjacent to each house. Settlements are placed at corners where three hexagons meet (or on the outside of the island) and roads are placed along edges between hexagons. All settlements must be separated by two edges from each other. It is in this player's interest to make all colors equally good because this player is likely to be assigned the worst of these colors. It is generally a good idea to place settlements to obtain the highest sum of dots on adjacent hexagons, to be adjacent to every kind of resource, to cover as many different numbers as possible, and to leave room for expansion. 

5. Starting with the weakest player and proceeding in skill order up to the player who placed the initial settlements, each player chooses which color (settlement placement) that he or she would like. After all are chosen, players who care about the actual color (vs. the setup) may swap pieces to obtain their favorite color in the chosen position.

6. Each player receives the resource for each hex adjacent to his or her two settlements.

7. Give weaker players the additional resource cards of their choice. Our seven-year old currently receives eight resource cards.

8. Roll for who will play first.

Turn

Each player has a hand of resource cards that are maintained face up and organized so that others can easily see and count them, a set of (maybe zero) development cards that are face down, a set of played development cards that are face up, and a pile of settlements, cities, and roads that have not yet been deployed.

Players take turns in clockwise order around the table. Each player's turn has two phases: resource [distribution] and trading.

Resource Phase:
Roll 2d6. 

If you rolled a number other than seven, then all players receive resources according to their settlements (this is the same as the base game rule). For each settlement adjacent to a hexagon with the number rolled, a player receives one of that resource from the bank. For each city adjacent to a hexagon with the number rolled, a player receives two of that resource from the bank.

If you rolled a seven, then all players with more than seven resource cards in hand lose half of their cards (round down; if someone has nine cards, then he or she loses four). All players are immune to losing cards before their first build phase of the game. You receive a prize for rolling the seven: another player holds a shuffled hand of one of each resource from the bank and you blindly choose two resources from that. The remaining cards are returned to the bank.

If you like theme for your rules, then, on a seven: a tornado blows through the island, destroying some stockpiles but depositing a windfall for this player. Tornadoes are scary, so in my house we instead shout, "it's your birthday" when a player draws from the bank's hand, for reasons only clear to my children.

This phase must be resolved before any trading.

Trading Phase:
You may trade resources with the bank for other resources; for development cards; and for deployment of your cities, settlements, and roads. 

You may trade resources with other players for resources. The same kind of resources cannot be exchanged, and each player must receive at least one resource. You may not trade objects other than resources, including: development cards, buildings, and promises or "I Owe You"s.

Other players can only trade with the current player, although they may initiate multi-way trades using the current player as a middleman. Each trade must be completed before the next begins. For example, a player cannot use a port in the middle of a trade with another player.

During the trading phase, you may play one development card that was not purchased that turn. The development cards contain the rules on them, although we modify two of them. Victory Point cards are never played, but are revealed when the game ends. The modified rules are:

Knight: The knight card does not move the robber (since there is no robber in our game!) Instead, playing a knight allows you to draw two random cards from the bank, as if you had rolled a seven. This avoids having players attack one another. Knights still count towards largest army and in practice are typically deployed for the purpose of winning that award.

Monopoly: When declaring a monopoly, count the number of resource cards in all players' hands (including your own) of that resource type, and then receive that many of that resource from the bank. This avoids having players attack one another and accelerates the game instead of slowing it.

Victory Condition

A player must declare at the end of his or her turn if he or she has a total of 10 victory points (including development cards). The game then ends at the end of that round. That is, the game ends as soon as the original first player's turn begins, so that everyone has had an equal number of trade phases. All players who have at least 10 points at this point win.

This rule encourages ties and also ensures that everyone has had a fair number of turns. It slightly prefers earlier players who had a chance to trade before others knew that the game was ending, but it is unlikely that anyone would make a disadvantageous trade knowing that another player was likely about to end the game.

After the game ends, adjust starting bonuses for players for the next game. We find that if you want small children to play with you more than once, then it is a good idea to first overestimate their bonuses and then bring them back down until they win a proportional amount of the time.


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Screen Space Ray Tracing

$
0
0
Pretty good reflections computed by our
screen space ray tracer in ripply water
This post describes a screen space ray tracing implementation that I wrote with Mike Mara for use in our indie games and graphics research. A full paper is freely available at the Journal of Computer Graphics Techniques. The properties of this method match those sketched out by other developers for some of the latest game effects. We found it tricky to understand and get exactly right from their presentations, so we're sharing our full code and the derivation in the paper to help others implement it.

Games march 3D rays across the height field defined by a depth buffer to create very approximate screen-space reflections. You can see this technique in action in Crysis 3 and Just Cause 2. When the point where the 3D ray hits the 3D surface in camera space is discovered, the game projects that point back to 2D and uses the color of the pixel for the color of the reflection. This is obviously limited to reflections of objects that are on the screen, so most games fall back to an environment cube map when no hit point is found in the depth buffer because the ray went off screen or behind an object (see Bart Wronski's detailed explanation of failure cases).

Although it is primarily used for reflections today, this technique can do much more. Many computer graphics algorithms are based on casting rays. For example, we experimented with screen space rays for approximate reflection, refraction, glossy reflection, ambient occlusion, and even global illumination (much more efficient approximations are available for the last two).

Different effects computed by our screen-space ray tracer. The rightmost two are not real-time.

The Problem with 3D Marching

In current games, the ray march is usually limited to a small number of iterations to ensure real-time performance. Due to perspective, marching in regular steps along a 3D ray doesn't generally give 2D steps across the screen. This means that the limited number of samples are distributed poorly--especially in the case of water reflections like the ones shown in the dragon picture above. For that kind of camera and reflective surface, the ray will skip away from the surface too quickly, missing near-by objects. It will then bunch up the remainder of the samples on a few pixels, limiting how far away reflecting objects can be and wasting computation sampling the same pixels repeatedly.

The diagram below visualizes the problem. The over-sampled pixels are colored red for the 3D ray march. The under-sampled pixels are obvious gaps.



This limitation of the ray march technique is why the water reflections of distant mountains fade out in my terrain prototype video:


The 2D Marching Solution

Fast, exact thin-line and conservative 2D rasterization algorithms have been known for over 20 years. We built our ray caster by trivially extending the "Digital Differential Analyzer" (DDA) line algorithm with perspective-correct interpolation (i.e., how hardware rasterization handles interpolators) and then optimizing the implementation for the particular concerns of GPU programming, such as minimizing divergence, memory bandwidth, and peak register count. The optimized implementation is below. Our upcoming paper explains the optimizations in more detail includes extension to deep G-buffers. It also includes code for operating directly on a depth buffer instead of requiring a linear-z buffer, although we don't advise it for performance. This kind of approach has already proven reliable in production: Assassin's Creed 4 (see page 80) and Killzone 4 (page 90) presentations both describe it.

// By Morgan McGuire and Michael Mara at Williams College 2014
// Released as open source under the BSD 2-Clause License
// http://opensource.org/licenses/BSD-2-Clause
#define point2 vec2
#define point3 vec3

float distanceSquared(vec2 a, vec2 b) { a -= b; return dot(a, a); }

// Returns true if the ray hit something
bool traceScreenSpaceRay1(
// Camera-space ray origin, which must be within the view volume
point3 csOrig,

// Unit length camera-space ray direction
vec3 csDir,

// A projection matrix that maps to pixel coordinates (not [-1, +1]
// normalized device coordinates)
mat4x4 proj,

// The camera-space Z buffer (all negative values)
sampler2D csZBuffer,

// Dimensions of csZBuffer
vec2 csZBufferSize,

// Camera space thickness to ascribe to each pixel in the depth buffer
float zThickness,

// (Negative number)
float nearPlaneZ,

// Step in horizontal or vertical pixels between samples. This is a float
// because integer math is slow on GPUs, but should be set to an integer >= 1
float stride,

// Number between 0 and 1 for how far to bump the ray in stride units
// to conceal banding artifacts
float jitter,

// Maximum number of iterations. Higher gives better images but may be slow
const float maxSteps,

// Maximum camera-space distance to trace before returning a miss
float maxDistance,

// Pixel coordinates of the first intersection with the scene
out point2 hitPixel,

// Camera space location of the ray hit
out point3 hitPoint) {

// Clip to the near plane
float rayLength = ((csOrig.z + csDir.z * maxDistance) > nearPlaneZ) ?
(nearPlaneZ - csOrig.z) / csDir.z : maxDistance;
point3 csEndPoint = csOrig + csDir * rayLength;

// Project into homogeneous clip space
vec4 H0 = proj * vec4(csOrig, 1.0);
vec4 H1 = proj * vec4(csEndPoint, 1.0);
float k0 = 1.0 / H0.w, k1 = 1.0 / H1.w;

// The interpolated homogeneous version of the camera-space points
point3 Q0 = csOrig * k0, Q1 = csEndPoint * k1;

// Screen-space endpoints
point2 P0 = H0.xy * k0, P1 = H1.xy * k1;

// If the line is degenerate, make it cover at least one pixel
// to avoid handling zero-pixel extent as a special case later
P1 += vec2((distanceSquared(P0, P1) < 0.0001) ? 0.01 : 0.0);
vec2 delta = P1 - P0;

// Permute so that the primary iteration is in x to collapse
// all quadrant-specific DDA cases later
bool permute = false;
if (abs(delta.x) < abs(delta.y)) {
// This is a more-vertical line
permute = true; delta = delta.yx; P0 = P0.yx; P1 = P1.yx;
}

float stepDir = sign(delta.x);
float invdx = stepDir / delta.x;

// Track the derivatives of Q and k
vec3 dQ = (Q1 - Q0) * invdx;
float dk = (k1 - k0) * invdx;
vec2 dP = vec2(stepDir, delta.y * invdx);

// Scale derivatives by the desired pixel stride and then
// offset the starting values by the jitter fraction
dP *= stride; dQ *= stride; dk *= stride;
P0 += dP * jitter; Q0 += dQ * jitter; k0 += dk * jitter;

// Slide P from P0 to P1, (now-homogeneous) Q from Q0 to Q1, k from k0 to k1
point3 Q = Q0;

// Adjust end condition for iteration direction
float end = P1.x * stepDir;

float k = k0, stepCount = 0.0, prevZMaxEstimate = csOrig.z;
float rayZMin = prevZMaxEstimate, rayZMax = prevZMaxEstimate;
float sceneZMax = rayZMax + 100;
for (point2 P = P0;
((P.x * stepDir) <= end) && (stepCount < maxSteps) &&
((rayZMax < sceneZMax - zThickness) || (rayZMin > sceneZMax)) &&
(sceneZMax != 0);
P += dP, Q.z += dQ.z, k += dk, ++stepCount) {

rayZMin = prevZMaxEstimate;
rayZMax = (dQ.z * 0.5 + Q.z) / (dk * 0.5 + k);
prevZMaxEstimate = rayZMax;
if (rayZMin > rayZMax) {
float t = rayZMin; rayZMin = rayZMax; rayZMax = t;
}

hitPixel = permute ? P.yx : P;
// You may need hitPixel.y = csZBufferSize.y - hitPixel.y; here if your vertical axis
// is different than ours in screen space
sceneZMax = texelFetch(csZBuffer, int2(hitPixel), 0);
}

// Advance Q based on the number of steps
Q.xy += dQ.xy * stepCount;
hitPoint = Q * (1.0 / k);
return (rayZMax >= sceneZMax - zThickness) && (rayZMin < sceneZMax);
}

All of the images on this page used the new method, except for the terrain video that I used to demonstrate the old ray marching method.

Reflecting teapots in water
Our code can execute 25 iterations for every pixel on the screen at 1920x1080 in less than 1 ms on a high-end GPU like NVIDIA GeForce Titan and in about 5 ms on a low-end GPU like NVIDIA GeForce 650M (i.e., on my two-year old Macbook Pro). If you don't expect every single pixel on the screen to require a ray cast and use stride to stretch those samples over many pixels, this can provide large, high-quality reflection and refraction. The full variant of the code on this page will ship in the open source G3D Innovation Engine version 10, which we use for most of our research and indie game projects and was the framework for these experiments.

You can eliminate the division from the inner loop by performing the depth comparison in homogeneous clip space. The problem with doing so is that it is impractical to apply a depth interval to the depth buffer, since any constant interval in homogeneous clip space grows hyperbolically away from the near plane. We believe that developers who use this approach simply make the interval infinite, i.e., assume that the depth buffer is a continuous sheet. The drawback to that approach is that it makes objects that should have finite z extent appear infinite. An example is below.

The long streaks are artifacts caused by assigning infinite depth extent objects. This is much faster, but may be an unacceptable approximation for some scenes, like this one. Our recommended approach of finite depth gives the better quality result shown at the top of this article.
There are some natural extensions which can further improve quality and utility. MIP-mapping the color buffer is an inexpensive way to approximate cone-traced glossy reflections: just read from higher MIP levels when farther from the reflective object. Bilinear interpolation when sampling the color buffer smooths out jaggies (as does post-processed antialiasing, which we used for our results). For the ray cast itself, when using a large stride the final interval can be refined using binary search, as is done for linear 3D ray marching and parallax mapping. For really long ray casts a min-max MIPped depth buffer allows iterations in large steps across areas of the screen that are entirely far or near (like an oct-tree). Chris Oat and I implemented this min-max method in 2008 using Amanatides and Woo/Musgraves's heightfield algorithm for the conservative iteration. We found it too slow at the time, but I think that it should be revisited on a modern GPU.

A lot of game engines are moving to temporal filtering to reduce the cost of computing effects. This kind of filtering is hard to apply to reflection and refraction because they are view dependent. Mike and I briefly experimented with the filters in Unreal Engine 4 for screen-space reflections and did not like the quality, so we don't yet have a recommendation on how to do this well. However, we implemented some nice temporal filters for our deep G-buffer paper and include the source on that page to help others explore the problem.


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. His most recent games are Rocket Golfing and work on the Skylanders series. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Game Design as a Science for Public Policy

$
0
0
Screen shot of the action role-playing game Titan Quest
by Iron Lore Entertainment © (THQ Inc., 2006)
This is the first in a series of posts defining and motivating a game design research agenda.

What do a presidential election, a sporting event, government spending bills, and a video game have in common? They are all subject to analysis as games: scenarios where intelligent agents (players) seek to maximize their payoff (win) under a set of rules. Although some seem like fun and others like work, an understanding of each instance informs the others, and insights for any improve how we both work and play.

Games are about decisions, and decisions matter. Computer science, mathematics, psychology, economics, and political science have explored decisions in formal games for several decades. Their classic problem is to find the best strategy under a set of rules. A new, more important problem reverses this: design a rule system that drives players to desirable behaviors. In the real world, we want the rules in our tax code and laws to be fair and encourage strategies that benefit society as well as the individuals. In virtual worlds, choices must also entertain the agents. Sometimes the line between these is blurry: Ebay's auction rules intentionally trade market efficiency with the thrill of last-minute deals ("sniping"). The short-lived "entertainment shopping" introduced by the Swoopo company took this one step further, in a form that we're likely to see more in the future.

Rules are designed by lawyers, politicians, and game designers. Science and engineering can help improve their process. This is because rules are mathematical and mechanical. In fact, machines, mathematics, and rule systems are equivalent--computer programs demonstrate this1. Any design field benefits from rigorous analysis techniques and a solid theoretical base. Unfortunately, most rule systems are not designed or tested in any engineering sense. Instead, they are crafted by gurus using black-box intuition and defended with subjective arguments.

We see bad policies every day. I began to study the relationship between policy and games when I was a graduate student in New England and also working professionally on the Titan Quest video game. Back then, the city of Boston closed its public transportation 90 minutes before its bars. This led to drunk driving and street crime against students walking long distances late at night. The local Citizens Bank (long since acquired in the US bank mergers) required a customer to withdraw cash and then redeposit it as the only way to move money between accounts without a transaction fee or delay.
Rapes reported in Rhode Island. (NBER)
Local car rental agencies required customers to be 21, but moving agencies such as U-haul only required a driver's license--so undergraduates chose to rent moving trucks for road trips. During this same period the state of Rhode Island modified a simple statute, causing it to accidentally legalize prostitution. This in turn created a significant decrease in rape as measured by police reports, an unexpected consequence of an unintended consequence. These examples show that even simple, individually-innocuous rules can easily go awry where they interact.

Informal design of a complex and critical system, such as a tax code, can be disastrous. For example, a 2005 U.S. transportation law gives tax credits for combining alternative fuel with diesel. Paper mills are some of the agents subject to the U.S. tax code. The efficient, 80-year-old Kraft process for making paper uses no external fuel because it draws energy from pulp waste. But, after the tax rules changed, mills immediately started burning unnecessary fossil fuels to receive tax credits. Calling this "exploiting a loophole" sways emotions against the mills. However, the objective fact is that a rule design error is encouraging pollution and may cost taxpayers up to $8 billion dollars per year2. The mills are not moral beings and are thus not at fault for operating with economic efficiency instead of energy efficiency. The legislature should be the social advocate, not the firm, and is responsible for aligning both forms of efficiency. Finally, as recently as 2008 we saw massive failures in SEC regulations and bailout rule systems that cost the U.S. a decade of economic growth, with political scapegoats everywhere. Blame is missing the point, here. Architects and mechanical engineers don't blame wind or friction for exploiting their design errors. They fix their designs and the processes behind them. Rule makers should, too.

So, how can we improve rule design? And how can we become better players within the rules that others impose?

Classical research on game theory assumes clear choices and objective goals. The methods developed can motivate tactics like price discrimination, proscribe efficient auction strategies, and solve some board games perfectly. Unfortunately, these methods are limited; one of the largest successes was solving checkers (it is a draw if both players are perfect)3. That was a major contribution, but it won't get us to modern video games or real-world scenarios.

Perhaps solutions to design and play lie in more rigorous exploration of entertainment games. In the last ten years, board games have exploded in complexity and popularity. Modern board games like Eminent Domain and Agricola are orders of magnitude beyond the complexity Monopoly or chess, to the point where precise analysis is probably intractable. That is, they approach the complexity of real-world situations. Designing one is comparable to designing a car engine or a large set of company bylaws. Playing such a game trains you to recognize and exploit patterns in complex systems; you learn most when playing a game that you're bad at, and should perhaps focus on those to train for serious analysis tasks at work4.

Modern video games augment their rules with significant technology (i.e., more rules) for 3D graphics, physics, and networking. These are arguably the most complex systems engineered in any discipline, ever. As a coarse comparison of complexity, the entire U.S. federal tax code is about 14,000 printed pages. A contemporary video game contains about three times as much source code, plus extensive data. Both contain errors, yet most games seem to avoid serious loopholes. Furthermore, the best game designers seem able to create stable rule structures and balance them for fairness--properties that the SEC policies and tax code evidently lack.

Bringing rigorous analysis to how their designers create, we see some principles emerge. Game designers work with recursively nested systems, each balanced separately. There are tens of established patterns for these systems that provide a basic framework. Many of these ideas will resound with engineers across disciplines. Games also veer away from classic engineering in some ways. Designers consider a subjective notion of engagement and weigh it against the mechanical nature of their systems. They accept that players have a meta-choice of not to play the game at all, and adjust their systems to present actively attractive options rather than least-negative ones. Recall that these are products that ask a group of people to learn complex rules and solve hard problems in multi-hour sessions, and yet which the customers love and voluntarily seek. There are many places outside games that would benefit from this success, from education to product design.

Unlike most other synthesis disciplines, games lack a clearly articulated design theory. To leverage the insights of game development for solving real-world game-like problems and complex engineering tasks, much more research is needed. The first step is to cast the still largely undocumented and ad hoc methods of entertainment game designers into a rigorous theory. We can then reconcile this theory with that of other design fields, benefiting from the complementary pieces. This will reduce some of the design risk that plagues the games industry and export its abilities to stabilize massively complex systems and engage its players.

I invite you to explore these ideas and some specific design strategies with my coauthor Chad Jenkins and me in our book, Creating Games. The text explains the design, art, and technology of entertainment games. It relies heavily on computer science and economics for rule design but touches disciplines from management science to graphic arts for describing the other aspects of games. The centerpiece is a discussion of how rules interact with the broader problems discussed in this article. I recommend related texts The Game Design Reader, Rules of Play, and The Art of Game Design.

This post is based on my invited article: McGuire, "Apply Game Design as a Science for Public Policy to Rescue Economy, Planet", MIT Infinite Connection, April 2009. https://alum.mit.edu/news/WhatMatters/Archive/200904

Notes

1. The formal Church-Turing Thesis statement of this correspondence is the foundational idea of computer science.
2. Hayes, "Pulp Nonfiction", The Nation, April 2, 2009
3. Schaeffer et al., Checkers is Solved, Science, 14, September 2007. http://www.sciencemag.org/content/317/5844/1518.
4. Koster, A Theory of Fun for Game Design, Paraglyph Press, 2004


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Posts by Topic

$
0
0

McGuire House Rules for 2-Player Uno

$
0
0
Uno is a card game for "2 to 10" players that is currently owned by Mattel. Like other games that appeal to small children, the challenge is in learning to follow rules and recognize appropriate play and not in executing a strategy. The game appeals to its core audience because the rules are simple, play is fast, and a lack of strategy means that there really are no "good" or "bad" players. The first two properties are desirable in any game. The shallowness enforced by the third may limit the sting of losing for children, but also limits the audience.



The only way to play Uno truly well is to card-count a double deck. That doesn't match the target demographic, and isn't a style of play generally desirable for board games. Uno's mechanics also degenerate at the two player level, because the game becomes both zero-sum and concepts such as turn order no longer apply.

We've created two-player duel version of Uno to address these issues. I play it daily with a kindergartener and a second grader, and it engages each of us. The rule changes in our version simultaneously increase pace and strategic complexity, primarily by making all player information public. That also turns a game about learning to just follow rules into one in which players can also learn strategic thought and minimax search. This happens in two ways.

A five-year old's depiction of gameplay
The first way our game teaches is that a weaker player sees what choices a stronger player is making. In any game, a good move is indistinguishable from luck to the observer unless the observer knows what the alternatives were.

The second way is that a stronger player is able to advise a weaker player. However, I recommend giving children only advice when they solicit it. Let them learn on their own, and lose if necessary. Losing too often is unfair and upsetting, but handicaps address this better than lowering the opponent's level of play or artificially boosting the child's.

Under our rules, a typical game only consumes about half of the draw deck, so card counting is thankfully not a strong advantage.

Our rules do not scale to multiple players. The lack of hidden information in a multiplayer game can make it very slow, and the way that we've modified skipping and drawing rules causes a random walk in hand size rather than a consistently decreasing one.

The Rules

Like base Uno, this variant can be played with two standard decks of playing cards. I recommend purchasing Uno cards. They aren't much more expensive than generic cards, the bold art style matches gameplay, and they speed play because they are easier to recognize. Our deck reinterprets the 108 card Uno deck as:

  • Four color suits: red, green, yellow, and blue; each containing the following ranks:
    • One zero card
    • Two of each number card, 1 - 9
    • Two Skip cards, which skip the opponent's turn
    • Two Draw Two cards, which force the opponent to draw two cards immediately but do not skip the opponent's turn
    • Two Color Wild Cards labelled with two arrows ("R" = Reverse in older decks), which allow the player to name a new color suit (including the current one)
  • Four Wild cards, which can be played on any suit and allow the player to name a new color suit
  • Four Wild Draw Four cards, which can be played on any suit when the player does not have another card in that suit. These force allow the player to name a new color suit and then force the opponent to draw four cards immediately but do not skip the opponent's turn
You can always play a card with the same rank on another, for example, a red Skip on a green Skip or a blue Color Wild Card on a Yellow Color Wild Card.

Begin the game by shuffling the deck thoroughly and then dealing each player seven cards, face up. Stronger players can be handicapped by dealing them extra cards at the start of the game. The remaining cards become the draw deck. Flip the top card from the draw deck to form the face-up discard pile. The starting player, who lost the previous game, plays first. Players then take turns, except when a Skip card skips a player.

On a turn, a player may optionally discard from his or her hand a card that satisfies one of the following conditions:

  • Match the suit of the top of the discard pile
  • Match the rank of the top of the discard pile
  • A Wild or Wild Draw Four, if the conditions are satisfied

If the player does not discard, then he or she must draw one card from the top of the draw deck. If it is legal to play this card, then he or she may optionally play it immediately. Otherwise the card is placed face up in the player's hand.

The first player to discard his or her entire hand wins. Players are not required to shout "Uno!" when reaching a single-card hand.

Handicap a strong player by giving him or her extra cards at the start of the game and removing cards from the weaker player, Do not go below 6 cards or the game degenerates to luck for the weaker player's starting draw. When playing with my six-year old, I start with 8 cards and he starts with 6.

Observations

There is a slight first-player advantage. Because the game is short, we prefer to address this by playing multiple games rather than completing rounds. Rarely does one player win by a single turn; we observed over about 50 games that the losing player has on average five cards in hand.

Because players can see each other's cards, they plan ahead at least one move and typically an entire suit run of moves. This obviously creates more opportunities for strategy, and strategic play is often slower than random play. However, in this case it is much faster than blind play because players quickly execute the pre-planned moves. Pauses occur mainly when a player must evaluate the odds of drawing a particular new card, or consider the best tactic for a card that has just been drawn.

Players do not tend to race towards a minimal hand. Instead, a better strategy is to reduce hand size while building an unassailable run of cards that will trigger forced moves. This resembles the gameplay of Flash Duel, an excellent newer (and more complicated) dueling game by David Sirlin. It is typical to play a series of Skip and Wild cards, mixed numbers in a suit that the opponent cannot match, in the final run towards victory. We've identified several kinds of end run that allow forcing a win, which as ending on a string of Skip cards followed by a number card in the color suit, ending on a Wild card, and ending on a number pair that the opponent cannot interrupt. Rarely does good play end by luck--both players know about four turns from the end who is going to win and the player in the weaker position is desperately trying to draw a card to interrupt the run. I consider this an ideal ending for a game.

Players often will choose to not play cards in hand that would have been legally allowed on a given turn. That is because reducing hand size is often secondary to building a viable victory run, or to attempting to gain Draw or Skip cards to interrupt the opponent's victory run mid-execution. This creates a dueling feel of lunches, parries, and blocks. There is still enough randomness that one can't plan too far ahead and can enjoy the thrill of occasional unlikely upsets, however, strong players will consistently beat weak ones.

I do not recommend Mattel's new Uno Attack variant
Shuffling an Uno deck is hard. It is twice the size of a single standard card deck. Play naturally sorts cards into runs within a suit, so a perfect (Faro) shuffle will merely deal one player an ideal hand. Shuffles don't randomize a deck. They permute it in a predictable way. The semi-random offset caused by an imperfect shuffle and imperfect cut introduce some randomness, but anything close to a set of perfect shuffles is often close to a specific permutation. Depending on the number of shuffles, that can be a step in a sorting algorithm or a cyclic shift, which may actually maintain or increase ordering in the deck instead of decreasing it. We address this with two methods. One is to split the deck into four small decks and shuffle these together sequentially, and then repeat the process a few times. The second is to leverage a card shuffling machine to shuffle the deck many times. These (surprisingly) tend to shuffle so much worse than a good human shuffler that they generate more randomness over a large number of shuffles. They are really fast and can help poor shufflers (which both children and players with arthritis may be) to quickly shuffle the deck or sub-decks many times. A shuffling machine of course makes the game less portable, but also is fun to operate.

Mattel would prefer that, instead of playing our strategic variant, you take the already too-random version that they sell and add more randomness by purchasing Uno Attack for $24. This version replaces drawing with a machine that ejects pseudo-random numbers of cards at a button press. I prefer to teach young players strategy and planning instead of gambling, so I don't recommend Mattel's version.


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

You Can Play Video Games

$
0
0
Journey
There are video games that you'll enjoy and be good at playing. They address your gender, sexual, religious, and ethnic identity. They have worlds where you'll feel comfortable and engaged. You can find what you're looking for, whether it is non-violent play, strong narratives and characters, complex decisions, freedom, or emotional highs and lows. Most games are not very expensive and many run on computing platforms that you already own, such as your old PC, your Mac laptop, or your mobile phone.

Advertising for big-budget action games like Call of Duty and Halo, some outdated conventional wisdom, and some misguided editorials might have led you to think that video games aren't for you. If so, don't get stuck there. Consider an analogy: maybe today's top-selling pop song isn't your favorite (on November 19, 2014, that's a tie between Taylor Swift's "Blank Space" and Hozier's "Take Me to Church"). That doesn't mean that the entire medium of music is one that you can't enjoy. To find music that you like, you might have to range a little further than full-page advertisements in newspapers and prime-time commercials on television. You might instead discover the music that appeals to you through asking friends for recommendations, reading papers with smaller distributions (and blogs), patronizing small clubs, and browsing independently owned music stores.

Likewise, the games that you'll enjoy might not be the ones with the largest marketing budgets. Ask your friends what they're playing--you might be surprised by both who answers the question and what they answer it with. Investigate the indie game scene and search some online game stores (such as Steam and itch.io), which, unlike retail mall stores, aren't exclusively stocked by publisher-funded releases.

I list below some of the great games made in the last few years. These have a breadth of gameplay, themes, and visual styles. They're all intelligently crafted. Some, such as Monument Valley and Minecraft, are actually the best-selling games on their platforms despite a lack of coverage in mainstream media. Others, such as Papers, Please, have small sales and are niche finds. Not all games are about narrative, but the games on this list that tell stories present ones that are not in the generic Hollywood style. They have diverse protagonists and those protagonists do interesting things. Many of these games are suitable subjects for a thesis.

Monument Valley
Limbo
Papa & Yo
dys4ia
If you're seeking for games for children, apply the same judgement that you would for film and books. Research a game ahead of time and play at least part of it with the child.

Just because these games are great doesn't mean that there's anything wrong with also playing the games in the Halo series, just as there's nothing wrong with listening to Taylor Swift's music. Large, mass-market productions are of course enjoyed by many people, and a benefit of that economic scale is tremendous polish. I enjoy a lot of pop music and a lot of AAA games. I'm also proud to have contributed a very small amount to the large team that built Call of Duty to the premier gaming franchise. Such AAA games are among the most complex human endeavors, representing the latest engineering and person-centuries of effort towards a perfected play experience for their target audiences. Yet, I'm also proud of the indie games to which I've contributed--those present individual, uncompromising experiences. They push the boundaries of games as both an entertainment and art form, and welcome different audiences.

I chose the games mentioned in this article for diversity, accessibility as an entrance to the medium, and their appeal to me. There are hundreds of other great games like them, and new games are released daily. I hope that at least one of them opens games to you. Through these I became a war hero, a starship captain, a trans woman, an abused child in a favela, and a British adventurer. Those human experiences were otherwise inaccessible to me.

Just as I also enjoy many mass-market games, you may find that you like those too, and have been mislead by what you've heard about them. It would be silly to let someone else's opinion preclude your own evaluation. The only mistake in this space is assuming that any particular work in a medium defines all of the content within that medium, and that mistake seems to be made frequently with the particular medium of video games.

Please start looking at some of the games on my list, talking to friends about less-advertised games, and seeking reviews of "indie", "casual", and other games that aren't covered by national publications. The great promise of a game is that it is limited only by the imaginations of the developer and the player. Many of today's mass-marketed games tell the story of a particular demographic, but there's room for everyone's experience in games and many of those experiences are available today. So, start enjoying a medium that is open to everybody, including you.


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

9 Years Later

$
0
0
The minimalist 9 title card
At the time of its premiere in 2005, Shane Acker's 9 (11 min, USA. dir: Shane Acker) was one of the the greatest student animated films yet produced. Student films and other low-budget computer animations often do not age well. Yet, Acker's film remains in rare company in 2014. With a few others such as Miss Todd (13 min, UK, 2013. dir: Kristina Yee), today it stands at the acme of short-form representational animation, with no "student film" qualification needed. This article analyzes why.



Acker's film depicts the life of rag doll named "9" and its mentor, "5." These dolls inhabit a still world of rubble and junk with their nemesis, a cyborg cat beast. The film is full CGI with design in the style of stop motion, an original score, and no dialogue.

I first saw 9 at the SIGGRAPH 2005 Computer Animation Film / Electronic Theater. The audience of animation experts was ecstatic about the film. That night, it topped all submitted professional animations of the year to win Best in Show and a nomination for the Best Animated Short Academy Award. (It didn't win that 2005 Academy Award, but neither did the excellent One Man Band short, with the resources of Pixar behind it.) 9 won the 2005 Student Academy Award, the 2005 Student Emmy, and first place at eleven film festivals.

9 now streams on the web at Vimeo, a bit degraded by compression. It looks soft at the original 720x540 pixel DVD resolution when compared to current 1920x1080 television and 4096x2160 theater standards but otherwise holds up well.

The Journeyman

Shane Acker directed, produced, and worked in the primary animation roles on 9 over four years at the UCLA MFA program. The lighting and animation are professional but unexciting. The next quality level would be more tonal contrast, stronger key poses, and some fog or dust clouds to frame the shots in depth.

Character designs are thoughtful. For example, 9 is burlap with a zipper that also reads as a short tie. Mentor 5 is older, so it has button closures instead. The characters are their own pockets. Acker channels Lasseter to make this charming; Burton would have made it insipidly precious and Miyazaki, grotesque.

Texturing and materials are uneven. The textures occasionally stretch too far for real materials, distorting their appearance. A master CGI animator at the time might have carefully adjusted material mapping over the surface for each frame to avoid this. Today, cloth simulation technology economically solves this technical problem. So, the visual artifact is more a product of its time than an explicit lapse.

The Young Master

Introducing the beast.
The film's greatness arises from Acker's confidence as a writer and director. In that role, he honors animation traditions, eschews showmanship, and develops interesting moments and transitions in a way that feels fresh but natural. He conserves running time for character and narrative by adopting conventional relationships, setting, and structure--we drop right into a new twist on a formula that makes us feel at home. The script is tight. The cinematography is immaculate.

The character designs are specific through recognizable materials and differentiation. 9 and 5 are clearly similar but have distinct eyes, feet, and chests. The designs are suitably generic, with no fixed ethnicity, gender, body shape, or spoken language. That removes any barrier the viewer's personal identification. The abstraction of hand-drawn animation naturally achieves this. Acker is able to translate the property to a representational film. The setting is ambiguous early in the film to strengthen universality. Later elements suggest Europe or North America as the setting. These include brick architecture, an umbrella, and a white porcelain doll in the ruins.

All plot points and character relationships are clearly established. We knows the rules of this world and the major props from the outset. The foundations of plot twists are properly established so that the audience never feels blindsided. We see each trap being built, even though we don't realize it at the time. 9's number immediately indicates that there were at least eight others. We see the beast consume 5's soul, so we are prepared for the ending.

The film opens with brief vignettes of 9's daily life, linked by fading through black. Introducing a character though mundane experience is a technique for creating empathy. From this classic opening, Acker follows through with transparent mastery of other techniques:
  • Clear establishing shots establish the set for each scene
  • Cuts from POV shots to the characters' eyes
  • Triangular compositions and blocking
  • Dynamic color script, from muted browns to greens to warmer colors, and then a burst into pink and blue for the finale
  • Clean lines and relatively high value contrast
The final showdown.
Two potential melee scenes are resolved abruptly. I suspect Acker wanted combat choreography (since it is the high point of his follow-up film with Tim Burton), but knew that it wasn't essential and didn't have the resources to deliver it in the student film. So, he cut it. The beast immediately snatches 5 for its victory and then later falls into a pit and is impaled for its defeat. A production house would have distracted from the story with elaborate battles. Acker made the right call, regardless of his motivation.

Weaknesses

I quibble with only two of Acker's choices. The first is the walking cane (hook screw) falling at 4:30. This event distracts the beast and enables 9 to escape. One should use such coincidences to draw characters into trouble, but never to release them. This is Hitchcock's rule.

The back of the beast.
A second odd choice is at 5:28. The beast's back fills half the frame and we clearly see 5's skin (and the unknown 3's as well) taut over it. Presumably, the beast used their skins for repairs. Although we previously saw the beast manipulate the sensor, its quadruped articulation implied inability to reach its own back and its movements contraindicated self-repair. So, one can misread this shot as the beast being number 35, or 50-something (with the second digit concealed on the right flank). The development is inconsistent and the shot is confusing.

Moments of Brilliance

5 strolls into the frame.
Enter 5. 9 is painfully alone throughout most of the film. We enter the flashback at 2:00 and still see only 9 for the first ten seconds. Then, 5 casually walks into the frame. This is an understated moment for the film that provokes outside joy for the audience. It is powerful because we've been misled by the narrative to not expect another doll. Yet, it yields joy instead of confusion because the setting (again, especially those numbers) conveyed the possibility in a way that is immediately and retroactively clear.

Exiting the flashback. Acker uses traditional tools to signal the beginning of the flashback: change of music and pace, faux film scratches, and a younger version of a character. Exiting a flashback is tricky. Like the character, the audience will be disoriented as they seek to recall the conditions before it. One must re-establish the scene and thus risk tedium by, for example, recycling a wide shot and then closeups to recall the character relations.
Immediately after the flashback.

Acker deploys a bold technique for exiting the flashback. At 4:40, he crossfades between the flashback long shot of 9 running from the beast and the present-time, over-the shoulder shot of 9 in contemplation. The camera is in the same place but the lighting and color grading change. There is a necessary rack focus, but the depth of field is quite large at this point to obscure it. We never quite see flashback-9 and present-9 in the same frame, and the right-to-left running motion in the distance naturally leads directly to 9 entering the frame on the left due to a camera pan. This allows us to wake slowly from the flashback alongside 9 while avoiding repetition of the earlier establishing shot with the doll.

The reverse shot after the jump in time; Acker twice
advances time within scenes instead of between them.
The reverse jump cut. There's an aesthetic rule for making point-of-view (POV) shots read well: show what a character sees, and then a close-up of the character's eyes, or vice versa. This is called a reverse shot. This is workaday and is employed by Acker as it would be by any director, until 8:57. At that point, Acker cuts from the lit bonfire at night to 9's eyes at dawn. An abrupt jump between two otherwise (mostly) aligned shots is called a jump cut. Jump cuts are rare because, lacking any sort of spatial logic for the cut, they make the audience conscious of editing. The exception is that they are effective for quickly conveying the passage of time, but often bring comedy in doing so since actors appear to teleport between positions. More often one establishes the passage of time within a scene by a change of lighting or a series of ponderous cross-fades. Jump cuts are also hard to employ in anything other than a static shot; changing actor positions, time, and camera position simultaneously within a scene is confusing. Acker maintains momentum with a clean cut while advancing time. He pivots from the night POV to the sunrise reverse as if it were a jump cut, and this works. As when exiting the flashback, the audience then slowly senses the new day with 9 and turns to face the future.



Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

3ds Max for Graphics Programmers

$
0
0
This post is a draft of new content for The Graphics Codex app. Please e-mail suggestions and corrections to morgan@casual-effects.com. I'll update this article in response to that feedback.

Graphics programmers often need to use a 3D modeling tool. Just as in any other domain, data in 3D graphics often contain errors. Excel and Photoshop are a better tools than a text editor for editing spreadsheets and images. 3ds Max is a common tool that is faster and easier than a text editor for editing 3D models once one understands a bit of its complicated interface.

Key Elements of the 3DS Max GUI 


For students and indie programmers, there is little quality control on models downloaded from Internet repositories, even relatively high-quality ones like TurboSquid. For professional graphics programmers working with an art team, the assets are often better-suited to the rendering system at hand. However, like anyone else, artists make mistakes. It is often necessary for a programmer to fix them directly while debugging instead of waiting for the artist to correct the model and check in a new version to revision control. Some common model errors are:
  • Inverted faces leading to holes and surfaces that disappear when seen from behind.
  • Incorrectly assigned or missing materials. For Internet-sourced models, artists often use Vray and other plugins whose materials will be lost when loading without them.
  • Stray geometry. Visual effects flags, hitboxes, and corrupt vertices often create extra or broken faces that cut across usable geometry.
  • Missing geometry due to corruption or missing polygons.
  • Excessive geometric detail from amateur modelers working with subdivision surfaces.
  • Incorrect or missing texture parameterizations ("UVs")
Max is a fast and powerful alternative to ad-hoc scripts and manual data-file editing for correcting these.

3ds Max ("Max") is a 3D modeling tool by Autodesk that is frequently used in video game development. It is free for the educational community and costs about US$1500 per year for commercial use. Max is pretty good for polygon-based modeling. Alternatives include Autodesk's Maya and the free, open-source Blender. For volumetric modeling (like sculpting), Pixologic's Z-brush and Autodesk's Mudbox are two popular tools.

Max is a professional tool with a user interface that evolved over many versions. Even for experts in 3D graphics and modeling, it is confusing to learn. In this article, I explain some basic Max operations for graphics programmers with no previous Max experience, so that programmers can fix the kind of errors describe above--at least, well enough to continue their own work. There are plenty of tutorials for artists on how to use Max. I've found them not particularly useful for programmers. Programmers understand the concepts of 3D model representation, but not the concepts of Max or process of authoring a model, and need to perform modeling tasks that are executed less-frequently by artists. I describe and give screenshots from 3ds Max 2015, but the interface is fairly consistent across recent versions.

Camera Movement

Max requires a three button mouse (the mouse wheel may be the middle button on your mouse--try pushing it down).
The navigation cube
shown in the upper-right
corner of the viewport.

Hold the middle button and move the mouse to translate the camera perpendicular to the view axis. Scroll the mouse wheel to translate along the view axis. Left click and drag the center of a face on the navigation cube to orbit the camera around the currently-selected object's pivot. Click on a face, vertex, or edge of the navigation cube to snap to a canonical perspective.

For a perspective viewport, you can also use video-game style first-person controls. Select a perspective view and then press the up arrow key to switch to first-person movement. In first person view you can use the W, A, S, D keys or arrow keys to translate the camera in the horizontal plane, translate vertically using E and C, and rotate by pressing the left mouse button and moving the mouse. Pressing any other key or other mouse actions will exit first person movement. The default movement rate is slow. Use [ to slow further and ] to accelerate it.

View

The viewport configuration menus.
By default, Max opens with three wireframe plan views and one perspective view. The top-left of each viewport contains three drop-down menus for configuring it. The first is labeled "[+]". The second is labeled with the active projection and the third is labeled with the active rendering mode.

I spend most of my time when working on model corrections in a Perspective projection with the rendering mode set to Shaded. On the menu labeled "Shaded", I set the following Lighting and Shadows options, so that I can see all areas, regardless of the scene's lighting rig:

  • Illuminate with Default Lights
  • Shadows
  • Ambient Occlusion 

Backface culling is toggled through
the Display Properties rollout on the
display tool panel.
Unlike most video game renderers, Max shows not only polygons facing the camera but also backfaces. To see the model with backfaces removed, enabled Backface Cull. This option is not in the viewport menus. It is on the Display Properties roll-out panel of the display tab of the tool panel that is located on the right side of the default screen layout. Backface culling is a per-object property, so it must be enabled for each object. You can either select everything in the scene to enable it universally at the start of an editing session, or enable it per object as needed. 

Meshes, Selection, and Modifiers

Most meshes in Max are represented as Editable Poly or Editable Mesh objects. For a programmer, the only practical difference between these is that some tools are only available on one or the other type. Right-clicking on any object opens the context menu, which always contains options to convert to one of these forms.
The context menu.

Modifiers and selection tools.
Left click selects an object. A selected object can be translated, rotated, and scaled using the axis widget and the tools on the top toolbar. From the right-click context menu on an object, the small black boxes at the far-right of the Move, Rotate, and Scale options open the corresponding dialogs. These allow precise transformations based on quantitative input.

When selecting, CTRL adds to the current selection and ALT removes from the current selection.

Once an object is selected, the Modify tab of the tool panel presents context-specific rollouts. The Selection rollout allows selecting vertices, edges, border edges, faces, and whole sub-meshes ("objects"). Pressing one of these red Selection buttons freezes the current object-level selection, so that only parts of that object are eligible. To return to whole object selection in the viewport, either right-click in the viewport and select Unfreeze All or uncheck all of the Selection buttons.

In a crowded scene, it is often useful to use the right-click context menu to hide unselected objects (or sequentially select and then hide objects) to reduce clutter and expose embedded objects. Use the Unhide All option on the context menu to restore full visibility when done editing.

Selecting individual faces.
Modifiers are non-destructive modifiers applied to objects, like Photoshop Layers and Effects. Once a modifier has been added to the "stack" for an object, additional options appear in the context rollout panel for that object.

Flip Normals

Max doesn't expose winding directions for mesh faces. Instead it presents the face orientation through the face normal. To flip normals, add the Normal modifier to the mesh. Click on the down arrow for the Modifier List dropdown and select Normal. This adds it to the "stack". By default, it appears with normals flipped, so no further work is needed for this task. Scroll down to the new Normal rollout on that mesh to toggle the option.

Make Two-Sided

Meshes can be made two-sided by attaching a two-sided material to them, but this doesn't work with all renderers and will be lost if exporting to OBJ format. So, in practice it is often necessary to explicitly duplicate the geometry.

To make a mesh into a two-sided object with some thickness, apply the Shell modifier. This duplicates and inverts the mesh, and then stitches the edges together with new polygons.

To create a zero-volume two-sided object, clone the mesh (from the right-click context menu), and then apply a Normal modifier to flip the faces.

Adding and Deleting Faces

To delete faces, select the object, choose the face Selection option (with the red square icon), select the faces, and then press the delete key.

To add new faces, choose the face Selection option. Then, scroll the rollout panel down to the Edit Geometry rollout and select Create. Vertices of the currently-selected mesh will be shown as small blue squares in the viewport. Click on individual vertices to connect them into a polygon (the winding order is irrelevant) and press the Escape key to create the polygon. Be careful when selecting because clicking too far from a vertex will create a new vertex in empty space.

Apply, Edit, and Create Materials

To assign or modify materials, open the material editor. The toolbar icon for it looks like a checkered sphere with a small dialog box over it. The left side of the material editor lists materials that can be created, procedural maps, controllers, and Scene Materials. Scene materials are those already in the scene instead of a material library. You can double click them to have them appear in the center panel's node-based material editor.

The Material Editor
There are two ways to assign an existing material to an object in the scene. The first is to drag the material from the Scene Materials list onto the object in the viewport. The second is to select an object in the viewport and then right click on a material in the node editor panel of the Material Editor. The right-click menu offers "Assign to Selection" as an option. Materials with textures will not appear correctly on objects that lack texture coordinates (UVs). See the next section for how to assign texture coordinates if needed.

Max supports many kinds of materials. The Standard material is a Blinn-Phong one that exports correctly to most external formats. I use it exclusively because of that property. Materials from plugins, such as VRay, or materials other than Standard may not import into different versions of Max for others and will almost never export correctly.

To edit an existing material, double-click on it in the node editor or the Scene Materials list. The right panel of the editor will then show the fields for editing. To add a texture map, drag a file from your operating system into the node-based view and connect its output node to the desired field's input node.

To create an entirely new material, drag the Standard material from the left pane into the node based editor and then rename and modify it. Note that materials that are not assigned to objects in the scene will be lost during export.

Create Texture Coordinates ("UVs")

To add reasonable unique texture coordinates to a mesh, add the UnwrapUVW modifier to it. Press the Open UV Editor button on the new rollout.

UVW Editor in the foreground, the Unwrap UVW rollout in the background
Within the UVW Editor, the polygons are shown drawn on a texture map with their coordinates given by texture coordinates. Use the mouse middle button to translate the view and the scroll wheel to zoom. This 2D editor shares a selection and the selection concepts with the 3D viewport. 

The primary command in the UVW Editor is to select the Mapping menu and then the Flatten Mapping menu item. This creates an automatic parameterization. You can further adjust it by moving individual faces and vertices. As with other tools in Max, there are many sophisticated ways that you can adjust the result. See Waylon Brink's tutorial for a good walk through.

Reduce Detail Level

Max has a fairly powerful tool for reducing the tessellation level of a mesh while preserving overall shape. Like many Max tools, it is slow and sometimes locks up, so save your file before trying this.

Add the Pro Optimizer modifer to an object, and then select the "Preserve UVs" option within its rollout. Press the Calculate button, which causes it to compute some metrics (probably an ordering of edge collapses) and is the part that takes a while. When it finishes, change the Vertex% value to the fractional number of vertices that you would like to preserve. The mesh will immediately retessellate to the new vertex count. You can continue to adjust this value to find a good setting.


Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. His most recent games are Rocket Golfing and work on the Skylanders series. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Adapting a Camera Entity for Virtual Reality

$
0
0
Classic rendering systems have a virtual "camera" that is active in the scene during rendering. These systems produce the image seen from that camera.

But head-mounted displays like the Oculus Rift, Samsung Gear VR, and Microsoft HoloLens need to render two views every frame, one for each eye. They also incorporate tracking of the body in a way that traditional rendering systems don't model.

Some of the problems with tracking arise even on a single-view tracking display, and some of the problems with multiple views are increased for parallax-barrier and other passive 3D systems that might require four or eight projections.

Extending a rendering system to support these devices is more complex than just "adding a second camera" because of the way that the modeling system and post processing need to maintain state and the way that tracking information is integrated. This article describes how Michael Mara and I are extending the open source G3D Innovation Engine to support head-mounted and other multiview displays.

The Problem

A modern single-view graphics engine usually has Entity and Model classes (I'm linking to G3D's documentation for the most common subclasses of these, so that you can see the kind of API I have in mind as well as relate them to the classes in your engine). An Entity is an object in the scene, which may reference a Model that describes its geometric properties. Models are sometimes also called mesh, surface, or shape classes.

Camera and Light are usually special Entity subclasses that don't reference Models because they aren't visible. It is useful to represent cameras and lights as Entitys so that they can be manipulated in a scene editor, scripted, and attached to other Entitys.

The Camera Entity usually combines the following properties, which are often abstracted through other helper classes:

  • Body frame: center of projection of the view as a rotation and translation (often using a 3x4 matrix or vector and quaternion). This is bolted to an object in the scene for first person views, simulated via leashes and springs for third person views, scripted for cinematics, and directly manipulated for debugging. Regardless, this is controlled by the simulation/application.
  • Projection: a perspective projection, usually represented as a 4x4 matrix or field-of-view, near plane, far plane, and subpixel-offset parameters.
  • Post-processing configuration: Settings that affect depth of field, motion blur, antialiasing, tone mapping, vignetting, and other post-processed camera effects. These may be specific to the algorithms used for those visual effects or model a physical camera through models like sensor sensitivity, exposure time, and iris size.

That information relates what is on screen to what is in the virtual world. The challenge of extending a traditional renderer to virtual reality is that a natural head-mounted display abstraction of that mapping requires twice as many state abstractions in a system that is unprepared for them. A VR system needs:

  • Body frame: As above. This is controlled by the simulation.
  • Two eye frames: The eye position can move relative to the body frame when the player turns his or her head, bends over, or leans. There are also two eyes, each offset from the center slightly. The eye frame is controlled by the player, not the simulation.
  • Two projections: Each eye may have a separate projection. (Oculus does, because it uses view-space translation to model the fact that that each eye image's "center" should not be in the center of the physical display--eyes don't have symmetric fields of view.)
  • Post-processing configuration: There is a single set of post-processing options that should be used for both eyes.

Making this adjustment requires addressing several ideas. The thorniest one is separating the body frame from the eyeframe. When incorporating existing content, we want to still be able to move the "camera" using existing controls and simulation, yet we still want head tracking (which could also be done with Microsoft Kinect for a single view without a head mounted display). A lot of our high-level simulation code attaches controller objects to the Camera. These execute code like "void Controller::update() { m_target->setFrame(frame); }", where the target is the camera. We want these controller abstractions to continue to work without modification in VR. A lot of our low-level rendering code accepts a camera and asks it for its frame, meaning the center of projection. We want that code to continue to work as well, and we don't want those two "frames" to diverge, because for every other Entity, setting and followed getting the frame gives you back the original value.

We considered explicitly modeling a body Entity and attaching two Cameras to it, one for each eye. This has a few problems. First, it would require modifying all of our existing scenes and projects to support virtual reality. That's a problem because we want existing content to work with a new, slightly modified renderer.

Part of our productivity as researchers is being able to quickly construct experiments by combining pieces from our extensive library of code and assets. So, new tools need to integrate into that library instead of imposing new constraints on it. This is similar to the constraints on game engine programmers, who need to add new features without imposing high content creation costs. Second, the cameras need to move freely around the body Entity due to head tracking and need to incorporate the player's known real-world height.

So, we can't directly attach cameras to a body entity, but would need some kind of VR tracker-controller joint between them. Third, scenes modeled with an explicit body and two cameras won't work for anything other than two views, such as our existing single-view or new four-view displays. 

A Solution

Our current solution is to create two different implementations of Camera, one of which is not visible at the API level. Most code will still continue to use the existing G3D::Camera class and construct it using the existing Camera::create static factory method and the data-driven G3D::Any constructor that works with scene data files. The implementation of Camera::create will now construct what is effectively the body entity, and by default, will act like a single camera bolted to the body's root position. This means that the existing API will continue to function as it did in G3D 10.00 for traditional displays with no tracking.

Internally, however, the Camera will also have a VRCamera subclass that it can produce on demand. VR-aware applications can query the number of views available and request a Camera for each one. Camera synthesizes VRCameras as needed and returns them under these queries. The VRCameras are placed by taking the root position, computing a vertical root offset based on the difference between the height of the average target player current player's height, and then composing the VR tracker's coordinate frame with this new root. The VRCameras receive a copy or reference to all of the post-processing parameters of the original Camera. In this way, they act like a body-and-eye scene graph, but without that complexity visible outside of the API boundary.

G3D tracks scene changes to minimize state changes, light probe updates, and shadow map updates. This means that there is no need to modify the renderer to amortize the cost of most operations over multiple views--that happens automatically because they are amortized over multiple frames already.

In summary, the desirable properties of our design are:
  • The Renderer doesn't need to know about VRCamera. Any code that was written to work with Camera will still work, because VRCamera is a subclass.
  • Assets don't need to know about VRCamera. They still specifies the camera in the scene and the VR adjustment is made automatically.
  • There's no additional (public) scene graph complexity, so modeling and simulation code can assume that the "camera" is synonymous with the "player avatar" in the way that it historically had.
  • The design extends to more than two views.
  • Post-processing parameters will automatically be synchronized between views because the VRCameras copy all non-projection/orientation state from the master Camera.
  • The built-in 3D debugger and scene editor user interfaces will still work with a single camera and need no modification.
  • Full compatibility between VR-specific and previous assets.
Having a body avatar in VR is important for creating presence and reducing motion sickness. Without a body, the player feels like a floating head and has no solid reference. This API doesn't address that issue. A body avatar can be attached, but won't be by default. The Camera will have to export some tracking data so that VR-aware applications that attach a body automatically will be able to adjust it to the real-time tracked head position.

These changes, and likely a future evolution of the design from it, will be in the G3D source repository soon. That will show the details of how we integrated with the Oculus VR SDK, compensated for different coordinate system conventions, dealt with the notion of "field of view" needed for scene culling well before the VRCameras are instantiated each frame, and optimized the full implementation.

I'd like to check the Oculus Rift support into the G3D repository as well, but have to first carefully separate the parts of the Oculus VR SDK that are legally redistributable from those that are not. For developers to use G3D with the Oculus Rift, they will then have to install the Oculus VR SDK on their own, change some flags, and rebuild G3D. Since John Carmack, the CTO of Oculus, has a strong track record with open source and Oculus has little incentive to prohibit distribution of software that enables their hardware, I hope that they will someday allow unlimited redistribution of the SDK for open source projects.



Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, visiting professor at NVIDIA Research, and a professional game developer. He is the author of the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.

Learning to Create Games

$
0
0
Why should you learn about game development? How and where should you learn? Most important, what do you need to learn? This article captures my current thoughts for those hoping to enter the industry, new indie developers, and games students as I refine my Creating Games course for next semester at Williams College.

Hive
There are many ways to think about games and inspire learning. One that excites me is the theme of the course: how quantifiable design elements give rise to meaningful player experiences. I assume that everyone is going to primarily make video games, but should learn about game design through board games.



I emphasize in this article and my course a combination of elegant strategic games, such as Hive and Dominion, and those with emotional impact, such as Gone Home and This War of Mine. The combination showcases games as an artistic medium, which is why I teach in both the studio art and computer science departments. While we also must study visual art and computer programming as tools for creating games, I think people interested in games should begin with the computational art of game design. As game developers, we create machines from mechanics, and these machines then create experiences with the players.



The Contents of this Article

  • Why and How to Learn
    • Understanding Games
    • Creating Games
    • The Burden of Dreams
    • A Supportive Community
  • What to Learn
    • Areas of Experience
    • Design Theories
    • State, Computation, and Abstraction
    • Some Game Design Skills
    • Process
  • A Syllabus
    • Games to Make
    • Games to Play
    • Further Online Reading

Why and How To Learn

Understanding Games

Monaco
Everyone can benefit from understanding and playing games well. Those activities develop planning, logical thinking, a good grasp of probability, and analysis of relationship graphs. Those are empowering life skills on par with calculus, reading great novels, and cooking.

Games are emerging as a dominant medium of our time. Nearly everyone plays board games (whether Poker, Agricola, orGo) and about half the population plays video games (whether Words with Friends or Halo). They are the only successful interactive art form and can be lighthearted entertainment or complex fine art. If you're not convinced, consider some recent (US-specific) indicators of the significance of games as a topic worth learning:

Creating Games

The Longest Journey
Although I recommend that everyone seek to understand games, creating games is not something everyone should pursue. In fact, you should probably only undertake it if you're sufficiently obsessed with games that you're willing to sacrifice a lot to engage them more deeply.

In this article, I'm using "games" to refer to aspirations of commercial-quality efforts such as Ticket to Ride and Kerbal Space Program. Everyone should make little ad hoc games as a natural process of play and incentivizing actions, and a Tetris clone or Monopoly modification is a fine weekend project. But making even moderately sophisticated, polished games that other people want to play is a serious endeavor at the level of taking on a new sport, writing a novel, or pursuing a major. Perseverance, skill, and talent are all required. Here are some reasons that you shouldn't attempt it, at least if you have the wrong goal in mind or underestimate the task.

Waking Mars
Games are not a lucrative or easy career. Game development doesn't make much money even for most of the people who are critically successful at it, compared to alternatives that could be pursued with the same skills. The amount of work for the infrequent gain of creating something worthwhile is high compared to even other creative fields.

Video game programmers are paid below market rate for their technical skills, although they make a good salary compared to non-programmers outside the industry. A few well-known developers drive exotic cars, but so do the first employees at Google, Apple, Microsoft, and Facebook, and for the same reason: they were in the right place at the right time.

Game artists generally are paid significantly less than programmers. They probably make less than graphic designers and 3D modelers outside of the entertainment industry, but the market for art skills is always weak and capricious. Management, audio, and other roles vary.

The hours are quite long in the industry whether you're independent or at a major studio, the perks beyond freedom of expression are few, and sometimes the fans turn on you in ugly ways. So few people make a living designing board games that it isn't worth analysis.

Monument Valley
Games are not an externally-rewarded art medium. Games are art, although it is exceptionally hard to produce good art as a game. That's mostly because it is hard to produce any game to begin with, and then if you do make a game, you often have to make significant artistic compromises to bring it to market. It is even harder to receive non-commercial funding for games than for other artistic endeavors; there aren't many painting grants and fellowships, but there are more than there are game art opportunities.

If you succeed at producing an artistically interesting game, it is hard to get serious critical notice or recognition. Some people deservedly find financial success and critical acclaim with expressive games. Monument Valley, Gone HomeLimbo, JourneyandBraidare a few commonly-cited examples. Their developers deserve everything that they've received, but keep in mind that those are the fortunate exceptions. Most great art games are known in the community but not such big hits outside of it, for example, The Stanley Parable.

There's only one sure path for achievement in artistically expressive games: Pursue your art for your own satisfaction instead of external validation.

Creating a game is very different from playing one. My students are often surprised by the challenge of creation despite being experienced players. Maybe that shouldn't be so surprising, though: I can listen to hundreds of violin concertos, but couldn't play even a few notes of one myself. That's not just about skill.

The Stanley Parable
It is true that some good, releasable games can be created in a few weeks by a single person with a lot of experience. However, most commercial video games reflect thousands of person-years of development. They are an inherently ensemble art and a major commitment.

The challenge of creating games isn't the only pitfall of attempting to make them. Regardless of whether you succeed, there's no returning to your previous level of ignorance and taste. Beware that my students also find that after studying games that they often no longer enjoy playing many of them--they see the flaws and strategies to plainly, and now have the burden of critical taste.

Masterful games are the those where you see what is happening mechanically, yet value the experience even more because of that appreciation...and are sometimes pleasantly surprised by being led astray by what you thought the mechanic was (Naughty Dog's games excel at this). That is, you see the artistry of the design and appreciate it at that level as well.
XCOM: Enemy Unknown / Enemy Within

So, if you learn about how games are made, you're likely to both fail to make them yourself and become unable to enjoy playing games made by others. Now that I've argued that most people are not prepared to really try game creation, I'll admit:
If you want to creating meaningful experiences through interaction, creating games is the best job or hobby in the world.
Creating games is immensely satisfying even if you're really inexperienced and untalented at it when you begin, as long as you're sufficiently committed. If you read this far in this article and want to continue, then maybe you really are sufficiently interested to attempt game creation. Welcome to the club. I'll spend the rest of this article assuming that you're invested and sharing some advice and experience to help you succeed.

The Burden of Dreams

Quotation from Ira Glass
When you first begin to make games, they're mostly going to be terrible. That's normal, and common to all forms of creative work. It is a good sign if you see many flaws in your work (even though you're proud of having made something!). It means that you have good taste and a drive to make your ability at synthesis match the quality of your analysis. Ira Glass explained this perfectly in the context of the craft of storytelling. The image on the right is a quote from his famous interview.

Keep up the hard work when you reach the point of finishing the construction of a game that you then don't like. Completing even a bad game project is an achievement. Make another hundred and one might rise to mediocre. Some day, you're going to do something that you will think is barely acceptable, but someone else will start raving about. That's how you know that you're doing really well. You're likely in trouble only if you believe that everything that you make is good from the start.

When you begin making games, you will spend more time playing at making games than doing productive work. This is natural and necessary. Humans learn almost everything by first pretending to complete the task and mimicking experts. There are cargo cult cases of mistaking the symptom for the cause where you can go astray. If you're spending your time making websites for your game company and picking out the right game developer T-shirt, then you're not on the right path.

You're on the right path if you're mimicking the productive activities of a game developer such as debating mechanics, modifying code, and critiquing other games, even if you're ineffectual at first. One day you find that you're actually doing it. By analogy, think about babies pretending to talk, small children pretending to read, and high school students mimicking academic tasks...at some point, they transitioned seamlessly from appearing to have these skills to actually having them.

A Supportive Community

Games are a craft medium. The best way to learn how to create games is to create games. Don't study something else for years to build up your skills first. It is like any other craft. You need to dive in, make mistakes, study some good examples in light of your mistakes, and then try again. It helps to have a mentor and a cohort for this process. They will share their experience so that you can at least make new mistakes instead of common ones, and they will provide both feedback and support.

Portal grew out of a student final project 
I recommend that you take a game development course if you are already at a school that offers one. However, beyond that course, I don't think it is necessary or even advisable to attend a game school or major in a games program. I know some successful developers who got their starts in game programs at schools such as CMU, RPI, UC Santa Cruz, SMU, and Full Sail. But I know many more who first excelled as computer science, literature, and fine arts majors and then brought deep knowledge of those skills to game development.

What you need to find success are a community, a set of skills, and a portfolio, not a specific set of games courses on your transcript.

Grim Fandango
If you aren't in school, or a school with games courses, then you're still in the mainstream of the community learning to make games. Many people of all ages who are learning games outside of their primary activity are doing so without a formal program. Many professional developers entered games from careers in other fields. Combined with the academics and professional developers, they form a large online game creation community.

The game creation community is welcoming and supportive, and it has grown substantially in the last decade. Perhaps from the combination of social media for collaboration, widespread excitement about games as a medium, the rise of casual gaming as part of a lifestyle through web and mobile platforms, and the emergence of inexpensive hardware and software computing tools.

Similar to those in film and music but with broader participation, there's now a vibrant "indie" game scene through which many explore the medium and build their careers. It spans small professional developers, artists using games as a medium, hobbyist game creators, and students.

Some current social media hubs for the game-learning and indie game community are:
The community frequently organizes around "game jams," both in person and online. These are intense creative sessions that build skills, connections, and camaraderie. Three popular jams are:
...and the practice has become so popular that there at least one web-based game jam nearly every weekend.

    What to Learn

    Some fundamental, high-level skills of a game developer are listed below, with examples to help you decode the technical terms. In the following sections I explain the game design, computer science, and economics terms and how to acquire these skills more fully in the following sections.

    Recognizemechanics in an existing game, and separate them from the content.
      The "wolves" in Age of Empires have a similar role to the "pawns" in Chess for the opening game...they prevent a direct rush attack and reward a positional strategy. See Koster's discussion of recognizing mechanics.
      Abstract and form computational models of systems in the real world.
        Diet affects short-term energy, long-term health, social status, ethical status, future food demand, and mental satisfaction. Let's model each of those as scalars for a given meal or ingredient, and purchasing food as trading income for a vector of these properties, where not all possible vectors are available in each store.  
        Apply mechanics to those computational models to make them into games.
          Let's make fire trucks a cool-down ability that can be deployed instantly to cancel fires, but deploying them creates vulnerability for a fixed period of time and thus requires careful planning or adaptive tactics for handling the second fire.
          Map mechanics to algorithms and data structures (in video games).
            We'll use a pointer-based graph to implement the skill-learning chains and compute a minimum spanning tree to identify when a character has enough skills to unlock the boss battle.
            Analyze mechanics in the absence of experimentation, for coarse balance and to predict strategies
              This new card offers two unrestricted actions, two draws, and one attack. That corresponds to an expected two victory points per play, so we should probably assign it a price similar to that of the Vindicator card. 
              Perform qualitative and quantitative experimental evaluation.
                Many people complained during the playtest that arrows are too powerful, but analysis shows that these complaints correlated highly with players who bought new weapons instead of plate mail to defend against ranged attacks. 
                Add and tune mechanics to adjust the set of viable strategies.
                  Players are grinding and then hoarding treasure. That makes the game too repetitive early on. In the mid game it is too hard because players who don't buy equipment are underpowered. The game is then too easy for them at the end because they can go all-in on exactly the right gear for the final encounter. What if we continuously inflate prices throughout the game? That will encourage players to buy gear immediately and will discourage hoarding treasure.
                  Master role-specific tools and workflows (such as programming, asset creation, and team management)
                    The examples are numerous: using a C++ profiler, linking to new libraries, using non-destructive edits in Photoshop, working with asset management systems, handling human dependencies in a schedule, bringing a design team to consensus, etc.

                    Areas of Experience

                    Super Smash Brothers
                    There are three broad areas of experience specific to games: Technical elements (creating board game pieces, programming, mastering software), game rules, and content (visual art, music, stories, 3D models, layout, etc.) Each has its own "design" area that then blends into implementation through process. That is, there are three design fields to study for games, each providing theory for its own craft:
                    • softwaredesign (sometimes called architecture)
                    • game [rule] design (the "rule" is conventionally dropped)
                    • art [and music, story, character...] direction
                    I focus here mostly on the first two, software and rules. Other people are better at teaching content creation topics such as visual art and writing. There's less need for new and specific educational material in those fields as well. They have been developing for thousands of years instead of the mere decades of modern software and game design.

                    Toca House
                    The distinction between software design for games and computer game design is important. They require different techniques and on a large game are created by different people.

                    Computer games have "rules" at two different scales of rigor and abstraction. One is the set of rules for the player. These are structured by game design.  The other is the set of rules for the computer, which micro-manage the player's rules.

                    The second set of rules in a computer game is one structured by software design. It is always much larger than the set of rules for the player.

                    For example, I can fully explain Tetris in about 500 English words. Yet, I need about ten times as many words in a programming language to express the rules to a computer. That's largely because computer programming is more detailed. Computers lack common sense and high-level concepts like rotation and obstruction. We also expect a computer game's code to handle graphics and sound, which aren't in the rules of most games.

                    Design Theories

                    The Elder Scrolls V: Skyrim
                    Software design, game design, and art design each admit a formal design theory and have a technical jargon for it. The elements of these design theories are primarily data structuresandalgorithms in computer science, mechanics in game design, and art principles for content.

                    Some design elements are readily quantified, for example hash tables for software, bidding mechanics for game design, and local contrast for visual art. Some are more abstract relationships for which formalizing a definition of the idea is tricky, and everyone seems to evolve their own intuition for them through experience.

                    Eminent Domain
                    There have been several efforts to categorize the more abstract elements of design theories, to support education and critical analysis. For software and game design, some well-regarded books on this topic are Design PatternsPatterns in Game Design, and Game Programming Patterns (A Book of Lenses is in this vein, but doesn't go so far.)

                    I'm not in the educational mainstream on classifying design principles--I think that these categorization schemes are useful to the authors and might be useful to some experienced designers, but are largely misguided attempt to reduce creative and experience-born elements of design to a metagame and jargon. I find case studies and masterwork exemplars more valuable. I recommend a starter games canon at the end of this article, along with a syllabus of exercises for moving through important previous works.

                    State, Computation, and Abstraction

                    SimCity
                    Among the game development skills in my initial short list, I believe that computational modeling is the key skill. It is not something that many people learn in high school or even college unless they pursue a science or economics degree, and it is absolutely essential for game design (and programming; pure artists can probably get by).

                    Computational modeling happens to be a skill that is taught really well in computer science courses, which is why everyone should probably take a computer science course even if they don't plan to program. Chris Granger's "Coding is not the new literacy" blog post unpacks that wisdom very clearly. My introductory games course is offered by the computer science department. That's because computer science methodology is essential to design, not because we sometimes make computer games using programming in class.

                    Specifically, the three core elements of computer science are also those of game design. They are categories of mental and mathematical tools for modeling systems of the real world in a way that is objective, subject to analysis, and has manageable complexity:
                    • State represents nouns/objects/things. Variables, constants, meta-state (types), properties for restricting and extending state, and a host of data structures are the tools that computer science provides for state.
                    • Computation represents verbs/actions/rules can be applied to the nouns. Algorithms are the computer science tools of computation. Functions, events, callbacks, threads, and other features implement computation as well as abstract them...
                    • Abstraction provides definitions/groups for related state or computation, for building large structures out of smaller ones. Functions, names, classes, references, modules, macros, languages, and code generators are some of the tools of abstraction. 
                    One application of these computer science ideas to game design is obvious. A game models nouns that have access to verbs, and these features need to be named and grouped into a rule hierarchy to be manageable. The process of writing any program is that of computationally modeling some system, whether truly from the real world or one that is mathematically possible but may not have a physical analog. "Games" are just the computational models that happen to be interesting to humans.

                    Rush Hour
                    The core skill of game design is the same modeling process learned in computer science, although it is a hard skill to study explicitly. Most of us learn the modeling process in computer science from trying to design programs many times, not from reading any particular text or hearing a lecture.

                    Interestingly, the power of computer science for game design runs even deeper than computational modeling. Some of the deep ideas are also accessible from a more theoretical side instead of requiring direct experience. I'm going to hint at this for the remainder of this section. This is an advanced topic and shouldn't be at the top of your list for first learning to create games. But it should pique your curiosity and hint why more than a single computer science course might be valuable to the non-programmer.

                    Most of the italicized terms in the examples from my list of computer science techniques sound like tools from pure mathematics...because they are. What computer science adds to mathematics is a notion of the cost of computation. In the concrete real world, actions take time, consume energy, require storage for the input and output, produce waste (e.g., heat), or incur some other form of expense. This is true for players trying to decide what move to make, economic agents making decisions, and computers evaluating mathematics. Once we have these real and measurable costs, we have an objective way of argument that one mathematical model is better than another.

                    San Juan
                    For example, I might try to arrange a deck of cards in order by repeatedly finding the smallest remaining card from a draw deck and putting it on top of my discard deck. On average, that process takes me a number of card comparisons proportional the square of the number of cards. We can measure how long it takes me to look at an individual card and use that to estimate how long the whole process takes.

                    You might achieve the same card-arranging goal by repeatedly splitting your deck in half until you have many single-card "decks," and then repeatedly reconstructing sorted ones. If we started with 256 cards, then after the first reconstruction step you'd have 128 two-card decks, each in the right order. Within eight steps you'd have the whole deck in order. That process is much faster (it takes a number of card moves proportional to the product of the size of the deck and its logarithm, which is smaller than the product of the size of the deck with itself). So you can make a really good argument that your method of repeated splitting and combining is better than exhaustive comparison for large, randomly arranged decks.

                    DayZ
                    While putting cards in order does come up a lot in games, that's not a particularly motivating example for game design. I chose it because it is a classic computer science example of two ways to solve a problem, where both are subject to analysis and one is obviously better under some initial assumptions. That kind of thinking is important for sophisticated design, both in creating mechanics and in analyzing strategies under them.

                    There are also many algorithms and data structures that suggest under explored spaces of mechanics. The games of Reiner Knizia are essentially a playground of set theory and computer science algorithms, disguised by evocative themes of exploration, battle, mythology, and statecraft.

                    Diablo
                    Finally, it is important to be aware of the inherent computational limits and current technological limits of computers when designing a video game, even if someone else will perform the programming of it. Often these limits are not particularly intuitive without a computer science background.

                    A game designer who specifies that each of 100 units in a real-time strategy game will compute the a good path from itself through a complex terrain map to a goal 30 times per second has actually asked for something reasonable, even though it sounds hard. Depending on how that terrain is configured, it is probably possible to find the best path for each unit independently in very little time.

                    In contrast, a designer who says that the inventory system will automatically pack objects on a 20x20 grid into the best arrangement in a fraction of a second has asked for something impossible, even though it sounds like an easy problem for a computer. (If the designer instead asked for a pretty good inventory arrangement on average, then that might be reasonable.)

                    Some Game Design Skills

                    I've repeatedly mentioned mechanics, but resisted concretely defining them or naming them. Some simple ones have fairly standard names that I'll admit. Others have ad hoc names in some texts, but best described by listing the games that use them and drawing the connection. Let's start with some simple ones to at least make concrete what a "mechanic" might be, but not seek a rigorous definition:
                    Warcraft III
                    • Cool-down abilities come with little timers. Once an action is taken, it has to recharge before future use. These are popular in role-playing games and some tactical strategy games like Warcraft. They let the designer grant the players power while restricting the rate at which that power can be deployed. They also create texture to the game, since every turn cannot be played in the same way.
                    • The leader-bonus mechanic (e.g., as found in Puerto Rico, Race for the Galaxy, and Eminent Domain) allows the current player to take an action, but in doing so allows all other players the option of taking a weaker version of that action. This speeds play in multiplayer board games; prevents one player from dominating a particular strategy; and creates situations of "chicken," where players try to force the opponent to pay the cost of a move that they both wish to make.
                    • Bidding ensures that most items are assigned fair prices in a game and makes information a commodity: placing a bid reveals the strength of a player's hand or the magnitude of a player's desire for an item, so must be balanced against the value of winning the round.
                    • Having a non-player character support the player's goals creates empathy for that character and affection for him or her. This can be deepened by also making the character dependent on the player at another stage. This encourages the player to value that character, creating an emotional lever for the designer. The Last of Us, IcoPrince of Persia (2008), and Papa and Yo base their gameplay primarily on this mechanicPortal famously creates great affection for the inanimate "companion cube" (crate) by presenting it as a useful new tool in the game and forcing the player to carry it through a level. Left 4 Dead and Team Fortress extend the mechanic to creating relationships between players, which then generates narrative as well as gameplay.
                    Desert Golfing
                    Learning to recognize these kinds of techniques across games and understand how and why they are applied is the first skill of a game designer. They're also the first skill of a master player, both for rising to strategic instead of emotional and intuitive play, and for making optimal choices in the game.

                    After acquiring a mental toolbox of mechanics, the next major skills of game design are in service of tuning and arranging the mechanics. These include:
                    • Mastering statistically-driven processes, either through randomness explicit in the game's rules or as a way of modeling the players. The most fundamental concept here is the distribution, e.g., through understanding uniformly distributed; normally distributed; poisson distributed; variance, median, mode, and mean; sampling with and without replacement; conditional probability, and confidence intervals and tests. Naive designers make everything uniformly random and only see a range to manipulate, which usually leads to systems with large swings and unsatisfying play. Sophisticated designers adjust distributions to create a texture of mixed common and rare occurrences that players at least intuitively understand and are excited by.
                    • Reward cycles are patterns, skills, and rewards at layered time scales. A player should simultaneously be incentivized by the next move, the next turn, the next upgrade, etc. through winning the game. A good designer applies different mechanics at different scales, and then links them to one another to create a continuous experience while restricting the complexity of any one decision. A game like XCOM or Ocarina of Time builds a dizzying tower of cycles that compel play.
                    • Manipulating tension keeps challenges fresh and sustains emotional impact over the long timescale of some games. An action film can't keep the hero constantly under the same threat for two hours without numbing the audience. A board game might take just as long without the stimulation of a movie, and a video game has that stimulation but might be a 20 hour experience played over many months. Just as in the film, a game must build and release tension. The weakest form is narrative tension. That creates extrinsic goals that the player only pursues halfheartedly. A stronger form is mechanical tension. Bring players to critical points and then release them, or adjust the mechanics to suddenly alter the power balance. The Last of Us frequently deprives the player of weapons and even movement to renew the game's challenge, and then relaxes the player with humor or quiet, contemplative stretches. Yinsh removes the scoring pieces from the board, reducing the winning player's advantage and clearing large areas for a new battle.
                    • Learning to deploy a variety of concepts from economics in an entertainment context. These include revealed preference, perfect substitution, hidden information, perfect complements, discriminatory pricing, and auction theory. Most good board games rely on such ideas.
                    • Geometric and algebraic tools; square and hexagonal grid arithmetic, numerical approximations, solving simple polynomial systems, derivatives and integrals, awareness of cumulative rounding issues, and so on. 

                    Process

                    Minecraft
                    Creating anything is hard, in any medium. It takes vision, self-discipline, careful time and motion management, resource management, and a willingness to kill your darlings. To make games you must create an effective creative process tailored to your own psychology and resources.

                    Fortunately, there are some common elements of most effective processes for game development. You should begin with productivity and workflow techniques that others espouse, but constantly reevaluate how appropriate they are for you. As perhaps the top lifecoach for indie game developers, McFunkypants'energetic and supportive guide is a very good place to start.

                    Here's my advice for prototyping potentially complex games: board games with a large team and many mechanics, or any video game. It is in line with most other experts.

                    Settlers of Catan
                    Don't begin by diving into your first idea. You're going to invest at least a hundred hours in this project, and should make sure that you're spending that time on a worthy idea. So begin by discussing and writing down your vision. Use prose, diagrams, screenshots, or whatever else helps you make it concrete and on paper instead of vague and in your head. In a group, you can build on each other's different visions to generate a collective idea. If you're alone, force yourself to generate three or four ideas even if you're certain that you're going to reject them. Forcing yourself to consider more options will often lead to new and better ones. I might write half a page by hand and scribble some images on the first draft.

                    Once you've articulated your idea, pause for a day or so and to reflect on it. Research existing related games to see how they handle the mechanics. Collect concept and reference art. Then, revisit your idea in light of what you've learned. Your design on paper will probably change at this point, and might firm up to a page or so. Your goal is not length (in fact, brevity is much better) or a specific form of a "game design document," but to use the act of writing to ensure that you've thought things through enough to commit to your ideas.

                    The Last of Us Remastered
                    Keep iterating for a few more days. Modify and flesh out details of features. Draw up a schedule, start working out algorithms and equations...and cut some features. I have a specific one-page format that I use for my proposals, but it takes me about a week to collect the ideas into that format and I often start implementation before the proposal is complete. The idea isn't to reduce design to filling out a form, but to use the form to remind myself of issues that I should consider early in the process.

                    Once you have a firm idea, you should stop researching and start implementing. Ultimately the answers to design questions will come from your own game and players, so stop looking elsewhere once you understand the field.

                    While implementing, keep modifying the plan and reflect daily on your process and path. It is usually bad to drive from start to finish on the same plan by force of will, determined to execute on the original vision as if it were a specification. Implementing exactly the first design merely means that you didn't react to what you discovered about the game during development.

                    Bean Dreams
                    A good game design will change significantly over the course of implementation and testing, and lots of changes to the plan are signs that you're reacting well by incorporating new information. The frequent pauses for reflection are important. Before even a weekend game jam, many developers will draw up plans. They'll then revise them several times, with hours or days between revisions to gain distance from the ideas and judge them well.

                    Revising the design should often be a spontaneous and enjoyable process, not something that feels like a day job or administrative task (even if it is your day job). Many people report that good ideas come while in the shower, exercising, or talking over meals. Don't stare at a computer and expect inspiration on a schedule; provide yourself with other stimulation and situations that relax the pressure on your creativity.

                    This process is designed to improve the quality of your design and avoid a show-stopping redesign in the middle of development.

                    Hohokum
                    Perhaps the most important productivity tip is to always focus solely on the most important gameplay feature, ignoring all else until you're certain that the game is worth playing. That is, when reducing your design to a playable form, don't polish early. Don't make menus, title screens, credits, multiple levels, graphics or fancy sound for a video game.

                    For a board game, don't print pretty art on your cards and wordsmith the rule-book layout during early production. The gameplay is always the highest risk and needs the most work. Everything else is that cargo-cult trap that I mentioned earlier: mimicking the wrong aspects of creating games.

                    Make video games with colored rectangles, no user interface, and inefficient, quickly-written code. Make board games by using existing components and a cheat-sheet of entries such as, "the Ace of Spades is the Unicorn, which can bring any character back to life. The 2 of diamonds is..."

                    A good craftsperson micromanages every aspect of workflow. Efficient programmers have a full-screen code editor that they know by heart and rarely touch the mouse. Digital artists have hot-keys for their tools and digitizing tablets; natural media ones have everything that the need in arm's reach and plan their work to minimize downtime of drying paint or switching tools. A good designer knows when a conversation is getting off track or the research on ancient cooking implements has become an interesting rathole.

                    A Syllabus

                    Games to Make

                    Tetris
                    Artists first study their craft by re-drawing masterpieces, singer-songwriters begin by performing existing music, and film-makers imitate shots from great films. For both computer and board games, it is helpful to begin by mimicking good, simple examples.

                    You can then modify your recreations to explore related designs. For computer games, you'll learn a lot about game software design and a little about game design from this process, because that's where you'll spend your time. For board games, you'll learn a little about producing the materials and a lot about game design.

                    I recommend exploring modification more in board games--you can see all of the rules outright, so you spend much less time reverse engineering. A good way to mimic board games is to try and recreate them with new pieces and writing out a rule book without looking at the original. Like the beginning art student redrawing Monet in charcoal, this will force you to attend to detail and work through the design challenges.

                    Most people learning game design want to focus on video games. I recommend spending a lot of time at first with board games, playing, modifying, and analyzing them. Modern board games benefit from advances in video game mechanics, while emphasizing game design instead of technology for the aspiring developer.

                    Space Invaders
                    Below are some thoughts on sequences of games to clone and modify when learning. The idea is to focus on games that contain some core design elements common to large families of games.

                    Chain your exploration of these games in a way that presents each as an evolution of its predecessors. One could make many syllabi around this idea, and I welcome suggestions. In sketching one below, I'm inspired by the diagram from page 79 of Koster's A Theory of Fun. That image shows that classic arcade games were designed by copying previous games and adding a single rule variation (Levy provides more evidence for the examples Koster uses). Board games can be arranged this way as well; my favorite example is the evolution Tic-Tac-Toe to Go-Moku to Pente.

                    Board Games

                    Your goal is to gain both theoretical and intuitive understanding of mechanics by trying to recreate or modify these games. Measure how small changes improve or imbalance these games. Don't polish. Use existing pieces and standard playing cards with a decoding table wherever possible. Don't even write down the rules most of the time--explain them to the players, and feel free to modify them during your playtests as your learn more. You're playing to improve the games, not to win them.
                    1. Uno (Recreate the game and rule book using two standard playing card decks, and then introduce your own variants)
                    2. Hive (Try changing the rules while using the original pieces. What if there are two queens per player? Make pieces move differently. Add new constraints on when pieces can be deployed. Add exception abilities.)
                    3. Dominion (Try to recreate and balance the recommended 10-card starting set without looking at those cards, and then invent some new cards of your own. Playtest with many different styles of player.)
                    4. Settlers of Catan (Make your own variants. Introduce new victory cards. Adjust the board size, point limits, trading rules.)
                    5. Pandemic (Play with the cooperative mechanic. Do you need a traitor, as in Shadows Over Camelot and Battlestar Galactica?)
                    6. Choose Your Own Adventure (Make a graph of the branches in an existing CYOA book. Add new branches by replacing some pages. Experiment with new mechanics like state, multiple players, and randomness).

                    Computer Games

                    Defender
                    Your goal is to discover algorithms and data structures appropriate for the increasingly complex mechanics in these games, and to gradually increase the quality of input handling and output (graphics and audio).

                    Nested games on the list show a spur path from their parent that can be pursued before returning to the main line.

                    Don't polish. The graphics should be minimal colored primitives. Don't even implement sound. No menus. Consider what the minimal game that references the named one would be and then implement that.

                    Sometimes it is helpful to add further, extreme constraints to keep yourself focused on mechanics over all else. For example, the LowRezJam required games to render to a 32x32 pixel, or smaller, display. It is hard to get too distracted by painting sprites under such limitations.
                    1. Pong
                      1. Desert Golfing (turn-based, world state, procedural generation)
                      2. Scorched Earth (destructible terrain, two-player)
                      3. Stretch: Angry Birds (rigid body)
                    2. Breakout (world state)
                      1. Asteroids (dynamic entity creation, free-direction movement)
                    3. Space Invaders (NPCs, increased state, multiple dynamic objects)
                      1. Shariki (turn-based UI, grid state)
                      2. Bejeweled (grid-shifting)
                      3. Tetris(more complex grid state, lots of corner cases, constant tuning)
                    4. Defender(complex controls, multiple simulations)
                      1. R-Type (scrolling shooter: significant state and graphics)
                    5. Donkey Kong (single-screen platformer: gravity, multiple traversal modes)
                      1. Pac-Man (power-ups, NPC AI)
                    6. Super Mario Bros (scrolling platformer)
                      1. Metroid (area replay, ability evolution, multiple traversal mechanics)
                    7. Contra (two-player platformer)
                    I chose mechanics first for this list and then found a relatively canonical game for each. You could easily say "Castlevania" instead of "Metroid,""Arkanoid" instead of "Breakout," and "Choplifter" instead of "Defender." The point isn't to replicate the theme of the game, anyway, so your Asteroids clone might be themed around special forces eliminating terrorist cells, or psychotherapy addressing painful memories. (Another example: Fe[26] is a great 2048 clone using the superior theme of nuclear fusion.)

                      Games to Play

                      There are a lot of great games and game series that every developer should know, or at least know about. These include:
                      • Nearly everything popular in the Golden Age of arcade games
                      • The games of Miamoto, Valve, Shaffer, SpectorWright, Knizia, Jackson, MeretzkyMeier/Firaxis, Mechner, Church, Naughty DogGarriott, Packardid software, thatgamecompany
                      • Zork, Skyrim, Call of Duty, Halo, Guitar Hero, Skylanders, Splinter Cell, Grand Theft Auto, Madden, Myst, Fallout, Diablo, Warcraft, Starcraft, Age of Empires, Battlefield, Tomb Raider, Need for Speed, Grand Theft Auto, Assassin's Creed
                      • Tetris, Monument Valley, Limbo, Braid, DayZ, Monaco, Jet Grind Radio, Minecraft, Wing Commander, M.U.L.E., Kerbal Space Program, Mirror's Edge, The Stanley Parable, 80 Days; Papers, Please; That Dragon, Cancer; Dwarf Fortress
                      • Chess, Go, Mancala, Checkers (Draughts), Othello, Backgammon
                      • Poker, Blackjack, Bridge, Whist, Blackjack, Mahjong, Scrabble
                      • World of Warcraft, Dungeons & Dragons, Magic: The Gathering
                      • Risk, Monopoly, Chinese Checkers, Connect-Four, Trivial Pursuit, Rubik's Cube, Simon Says, Stratego, Battleship, Mastermind
                      • Settlers of Catan, Carcassonne, Puerto Rico, Citadels, Rush Hour, Ticket to Ride, Agricola, Race for the Galaxy, Dominion, Flash Duel, Eminent Domain, Shadows Over Camelot
                      Most of these games are amazing in many ways. All excel at least one way (albeit, possibly sales), and were historically influential.

                      Myst
                      Although it would take decades to cover even that incomplete list, I recommend that you immediately start reading about those games that you aren't familiar with and playing as many as you can.

                      No creation is unique and many of the greatest are almost wholly derivative, with the twist and interpretation being the act of genius. Since even your best games will reinvent some other game, it you can save yourself time by first learning about a lot of other games.

                      There are many ways of grouping games, including themes, eras, markets, and mechanics. I had some in mind when I created the list above and organized the games to imply that. I didn't explicitly name the categories. That's partly because wanted focus on the games themselves instead of external distinctions, and partly because it is hard to give a good name to some of the groupings.

                      This War of Mine
                      However, for my limited agenda of combining rigorous mechanics and artistic expression, I'll commit to some named categories within which that one should deeply study at least one game. I don't list these categories on the syllabus of my course. I'm showing the final list from which I selected eight to describe how I chose the games that I'm using next semester.

                      I began by listing about two hundred games that I thought were  appropriate for the class (including the ones above). I then extracted the ones that are practical to use in the classroom: not too long to learn or play, broad cultural representation without compromising quality, appealing to college students, and affordable.

                      I grouped the remaining games intuitively into ones that were roughly interchangeable for educational purposes. I named the groups to try and rationalize my intuition, and then chose the game from each group that would be the most practical, or least familiar (to put most students on a footing of equal ignorance). The result of this process is below. If you're looking for a starting set of games to learn from, you might want to choose the one from each category that appeals to you instead of the one that I chose.
                      Mirror's Edge

                      • Abstract Strategy: tight single-mechanic games that act like poems
                        • *Hive
                        • Tetris
                        • Abalone
                        • Yinsh
                        • Othello
                        • Rush Hour
                      • Simulation: Driven by emergent properties of physical simulation
                        • Minecraft
                        • Burnout
                        • Octodad
                        • Starwhal
                        • Little Big Planet
                        • Element4l
                      • Party Game: Easy to learn games for many players that rely on social skills
                        • *Spyfall
                        • Mafia
                        • Charades
                        • Werewolf
                        • Balderdash
                        • Apples-to-Apples
                      • Card Games: Modern Euro-style card games
                        • *Dominion
                        • Eminent Domain
                        • Race for the Galaxy
                        • Magic: The Gathering
                        • San Juan
                      • Fine Art: Nuanced, emotional games
                      • Economic: Engine-building games with commodities
                      • Epics: Polished mechanics hybrids, comparable to novels
                      There are plenty of categories one could make, including first-person shooters, racing games, rhythm games, sports games, and adventure games. Those aren't in this list. Something needs to be culled to yield focus, and while there are undeniably important games in those other areas, few are at the core of what I'm trying to teach: rigorous mechanics and emotional, meaningful experiences. I think that a lot of the independent game scene is aligned with this agenda, although It's reasonable if you're not.

                      While you should study and practice making all games, put your heart into the ones that you care about and not the ones that I do. If they're good enough, you can show everyone why they should care about them too.

                      Further Online Reading

                      This isn't a list of hardcore games articles or textbooks that you should read. Recall that I believe you should be spending most of your time making and playing games, not studying other resources. A guide like this one or a single textbook will cary you through the first stages well enough, and after that you'll know enough to select books on your own.

                      Metroid
                      However, I collect short, interesting articles about games (and short interesting games themselves) and resources for programmers, artists, and designers. I don't necessarily agree with all of these, but they are the kinds of articles that you're probably be interested in. At the least, they're probably pleasant diversions on the days that you've worked too hard to make further good progress on your creations. Some of these are assigned reading for my course. 







                      Morgan McGuire (@morgan3d) is a professor of Computer Science at Williams College, a member of NVIDIA Research, and a game developer. His most recent games are Rocket Golfing and work on the Skylanders series. He's written several books, including the Graphics Codex, an essential reference for computer graphics now available in iOS and Web Editions.
                      Viewing all 48 articles
                      Browse latest View live