Making Crash Bandicoot – GOOL – part 9

This is part of a now lengthy series of posts on the making of Crash Bandicoot. Click here for the PREVIOUS or for the FIRST POST. I also have a newer post on LISP here.

I’m always being asked for more information on the LISP based languages I designed for the Crash and Jak games. So to that effect, I’m posting here a journal article I wrote on the subject in 1996. This is about GOOL, the LISP language used in Crash 1, Crash 2, and Crash 3. GOOL was my second custom language. Way of the Warrior had a much simpler version of this. Jak 1,2,3 & Jak X used GOAL, which was a totally new vastly superior (and vastly more work to create) implementation that included a full compiler. GOOL (the subject of this article) was mostly interpreted, although by Crash 2 basic expressions were compiled into machine code. But I’ll save details on GOAL for another time.

[ Also I want to thank my reader "Art" for helping cleanup an ancient copy of this article -- stuck in some mid 90s Word format that can no longer be read. ]

_

Making the Solution Fit the Problem:

AI and Character Control in Crash Bandicoot

Andrew S. Gavin

Copyright (c) 1996 Andrew Gavin and Naughty Dog, Inc.

All rights reserved.

Abstract

Object control code, which the gaming world euphemistically calls AI, typically runs only a couple of times per frame. For this kind of code, speed of implementation, flexibility, and ease of later modification are the most important requirements. This is because games are all about gameplay, and good gameplay only comes from constant experimentation with and extensive reworking of the code that controls the game’s objects. The constructs and abstractions of standard programming languages are not well suited to object authoring, particularly when it comes to flow of control and state. GOOL (Game Oriented Object LISP) is a compiled language designed specifically for object control code that addresses these limitations.

Video games are the type of program which most consistently pushes the machine and programmer to the limit. The code is required run at blinding speeds, fit in tiny memory footprints, have no serious bugs, and be completed under short schedules. For the ultra high performance 5% of functions which run most frequently there is no substitute for careful hand coding in assembly. However, the rest of the program requires much more rapid implementation. It is this kind of code which is the subject of this article.

Object control code, which is euphemistically called AI in games, typically runs only a couple of times per frame. With this kind of code, speed of implementation, flexibility, and ease of later modification are often more important than maximizing execution time. This is because games are all about gameplay, and achieving good gameplay is about writing and rewriting object code time and time again. Programming languages are not immutable truths handed down from on high, but tools created by people to solve particular tasks. Like any tool, a programming language must be right for the job. One would not attempt to turn a hexagonal nut with a pentagonal wrench, neither is it easy to write a program in a language not well suited to the problem. Sadly, most programmers have only been exposed to a small set of similar and inflexible languages. They have therefore only learned a small number of ways to customize these languages to the task at hand. Let us stop for a second and take look at the abstractions given to us by each of the common choices, and at what price. But first a word about assemblers and compilers in general.

Assemblers and compilers are programs designed to transform one type of data (the source language) into another (the target language). There is nothing particularly mysterious about them, as these transforms are usually just a bunch of tabled relationships. We call one of these programs a compiler when it performs some kind of automatic allocation of CPU resources. Since most commonly found languages are fairly static, the transform rules are usually built into the compiler and can not be changed. However, most compilers offer some kind of macro facility to allow customizations.  In its most general form a macro is merely a named function, which has a rule for when it is activated (i.e. the name of the macro). When it is used, this function is given the old piece of program, and can do whatever normal programming functions it wishes to calculate a new expression, which it returns to be substituted for the old. Unfortunately, most languages do not use this kind of macro, but instead create a new tiny language which defines all the functions which are allowed to run during macro expansion (typically template matching of some sort). With general purpose macros, any transform is possible, and they can even be used to write an entire compiler.

Almost all programmers have had some exposure to assembly language. An assembler basically serves the purpose of converting symbolic names into binary values. For example, “add” becomes 20. In addition, most allow simple renaming of registers, assignment of constants to symbols, evaluation of constant expressions, and some kind of macro language.  Usually these macro languages consist of template substitutions, and the ability to run simple loops at expansion time. Assembly directly describes the instructions interpreted by the processor, and as such is the closest to the chip which a software engineer can get. This makes it very tedious and difficult to port to a different a machine. Additionally, since it consists primarily of moving binary words between registers and memory, and performing simple operations on them, most people find it tedious and difficult to use for large programs. In assembly, all details must be tracked by hand. Since knowledgeable humans are smarter than compilers, albeit much slower, they are capable of doing a substantially better job of creating smaller more efficient code. This is true, despite the claims of the modern OS community, compilers are still only about half as good as a talented assembly programmer. They just save a lot of time.

Many programmers learned to program with Basic. This language has an incredibly simple syntax, and typically comes with a friendly interactive environment. These features make it easy to learn and use. It however has no support for abstractions of any sort, possessing only global variables, and no macro system. Globals are great for beginners because the whole abstract arena of scope becomes a non issue. However, the absence of lexical scoping makes the isolation of code (and its associated bugs) nearly impossible. There is however an important lesson in basic which has been lost on the programming community: interactive is good. Basic typically has an interpreted listener, and this enables one to experiment very quickly with expressions to see how they work, and to debug functions before they are put into production.

The standard programming language of the last few years is C. First and foremost C provides series of convenient macros for flow control, arithmetic operations, memory reference, function calling, and structure access. The compiler writer makes expansions for these that work in the target machine language. C also provides expression parsing and simple register allocation for assembler grade data objects (i.e. words). C code is reasonably portable between machines of a similar generation (i.e. word size). As an afterthought a preprocessor provides rudimentary textual macro expansion and conditional compilation. The choice not to include any of the hallmarks of higher level languages, like memory management (aka garbage collection), run time typing, run time linking, and support for more complex data types (lists, true arrays, trees, hash tables etc.) is a reasonable one for many tasks where efficiency is crucial. However, C is crippled by an inconsistent syntax, a weak text based macro system, and an insurmountable barrier between run time and compile time name spaces. C can only be customized via the #define operator and by functions. Unfortunately, this makes it impossible to do many interesting and easy things, many of C’s fundamental areas, structures, setting, getting, expressions, flow of control, and scope are completely off limits for customization. Since functions always have a new scope, they are not useful creating flow of control constructs, and #define is so weak that it can’t even handle the vagaries of the structure syntax. For those who know C very well it is often a convenient language, since it is good at expressions and basic flow of control. However, whenever complicated data structures are involved the effort needed is obscene, and C in unable to transfer this effort from one data type to another similar one.

Modern operating system and fancy programs are filled with scripting languages.  MS DOS batch language, the various Unix shell languages, perl, tcl etc. are all very common.  These are toy languages. They often have inconsistent and extremely annoying syntaxes, no scoping, and no macros. They were invented basically as macro languages for operating system shells, and as such make it fairly easy to concatenate together new shell commands (a task that is very tedious in assembly or C). However, their ambiguous and inconsistent syntaxes, their slow interpreted execution speeds, and the proliferation of too many alternatives has made them annoying to invest time in learning.  Recently a new abomination has become quite popular, and its name is C++. This monstrosity of a language attempts to extend C in a direction it was never intended, by making structures able to contain functions.  The problem is that the structure syntax is not very flexible, so the language is only customizable in this one direction. Hence one is forced to attempt to build all abstractions around the idea of the structure as class. This leads to odd classes which do not represent data structures, but instead represent abstract ways of doing. One of the nice things about C is that the difference between pointer and object is fairly clear, but in C++ this has become incomprehensibly vague, with all sorts of implicit ways to pass by reference. C++ programs also tend to be many times larger and slower than their C counterparts, compile much slower, and because C++ compilers are written in C, which can not handle flexible data structures well, the slightest change to the source code results in full compiles of the entire source tree. I am convinced that this last problem alone makes the language a severe productivity minus. But I forgot, since C++ must determine nearly everything at compile time you still have to write all the same code over and over again for each new data type.

The advent of the new class metaphor has brought to the fore C and C++’s weakness at memory management. Programmers are forced to create and destroy these new objects in a variety of bizarre fashions. The heap is managed by the wretched malloc model, which uses wasteful memory cookies, creates mysterious crashes on overwrites, and endless fragmentation.

None of these problems are present in Lisp, which is hands down the most flexible language in common use.  Lisp is an old language (having its origins in the 50s) and has grown up over the last 30 years with the evolution of programming. Today’s modern Common Lisp is a far cry from the tiny mainframe list of 30 years ago. Aided by a consistent syntax which is trivial to parse, and the only full power macro system in a commonly used language, Lisp is extremely easy to update, customize, and expand, all without fighting the basic structures of the language. Over the years as lexical scoping, optimized compilation, and object oriented programming each came into vogue Lisp was able to gracefully adopt them without losing its unique character. In Lisp programs are built out of one of the language’s built in data structure, the list.  The basic Lisp expression is the form. Which is either an atom (symbol or number) or a list of other forms. Surrounded by parentheses, a Lisp lists always has its function at the head, for example the C expression 2+2 is written as (+ 2 2). This may seem backwards at first, but with this simple rule much of the ambiguity of the syntax is removed from the language. Since computers have a very hard time with ambiguity, programs that write programs are much easier in Lisp.

Let me illustrate beginning with a simple macro.

(defmacro (1+ value)
	"Simple macro to expand (1+ value) into (+ 1 value).
	Note that backquote is used.  Backquote is a syntax
	sugar which says to return the 'quoted' list, all
	forms following a comma however are evaluated
	before being placed in the list. This allows the
	insertion of fields into a template.
	1+ is the operator which adds 1 to its operand
	(C uses ++ for this)."
  `(+ 1 ,value))

The above form defines a function which takes as its argument the expression beginning with 1+, and returns a new expanded expression (i.e. (1+ 2) > (+ 1 2)). This is a very simple macro because it merely fills in a template. However, if our compiler did not perform constant reduction we could add it to this macro like this:

(defmacro (1+ value)
	"Smarter macro to expand 1+.  If value is a number,
	then increment on the spot and return the new
	number as the expansion."
  (if (numberp value)
      (+ 1 value)
    `(+ 1 ,value)))

The form numberp tests if something is a number. If value is, we do the add in the context of the expansion, returning the new number as the result of the macro phase. If value is not a number (i.e. it is a variable or expression), we return the expanded expression to be incremented at run time.

These full power macros allow the programmer to seamlessly expand the language in new ways. For example, the lisp form cond can be implemented from if’s with a macro. Cond is a special form which is like a C “switch” statement except that each case has an arbitrary expression. For example:

(cond
  ((= temp 2)
   (print 'two))
  ((numberp temp)
   (print 'other number))
  (t
   (print 'other type)))

Will print “two” if temp is 2, “other number” if it is a number (other than 2), and “other type” otherwise. A simple implementation of cond would be as follows:

(defmacro cond (&rest clauses)
	"Implement the standard cond macro out of nested
	'if's and 'when's. t must be used to specify the
	default case, and it must be used last. This macro
	uses backquote's ,@ syntax which splices a list
	into the list below it. Note also the use of progn.
	progn is a form which groups multiple forms and has
	as it's value, the value of the last form. cond
	clauses contain what is called an implicit progn,
	they are grouped together and the value of the
	last one is returned as the value of the cond."
  (if (eq (length clauses) 1)
      (if (eq (caar clauses) t)
          `(progn ,@(cdar clauses))
        `(when ,(caar clauses)
            ,@(cdar clauses)))
    `(if ,(caar clauses)
         (progn ,@(cdar clauses))
       (cond ,@(cdr clauses)))))

This expands the above cond into:

  (if (= temp 2)
      (progn (print 'two))
    (cond
      ((numberp temp)
       (print 'other number))
      (t
       (print 'other type))))

After a single pass of macro expansion. The macro will peel the head off of the cond one clause at a time converting it into nested ifs. There is no way to use C’s #define to create a new flow of control construct like this, yet in a compiled language these compile time transforms are invaluable to bridging the gap between efficient and readable code.

GOOL (Game Oriented Object LISP) is my answer to the difficulties of using C and assembly for object programming. It is a compiled Lisp dialect designed specifically for the programming of interactive game objects. As a language it has the following features: Consistent syntax, full power macros, symbolic names, orthogonal setting/getting, layered computation, multiple ultra light threads, grouping of computations into states, externally introduced flow of control changes (events), small execution size, retargetable backend, and dynamic linking. The GOOL compiler is embedded in Allegro Common Lisp (an ANSI Common Lisp from Franz Inc. which I run on an Silicon Graphics workstation running IRIX). Common Lisp provides an ideal environment for writing compilers because you start off with parsing, garbage collection, lists, trees, hash tables, and macros from the get go. As a language GOOL borrows its syntax and basic forms from Common Lisp.  It has all of Lisp’s basic expression, arithmetic, bookkeeping, and flow of control operators.  These vary in many small ways for reasons of speed or simplicity, but GOOL code can basically be read by the few of us lucky enough to have been exposed to Lisp. GOOL is also equipped with 56 primitives and 420 macros which support its advanced flow of control and game object specific operations. Additional ones can be trivially defined globally or locally within objects, and are indistinguishable from more primitive operations.

The GOOL compiler is an modern optimizing compiler with all sorts of smarts built into various macros and primitives. It is a fully forward referenced single pass compiler. Unlike some other programming languages with single letter names, GOOL does not require you to define something textually before you use it, and you never need tertiary declarations (like prototypes). Computers are good at remembering things, and a compiler is certainly able to remember that you called a function so that it can check the arguments when it gets to the declaration of that function. GOOL is fully relocatable and dynamically linked. So it is not necessary to include code for objects which are not nearby in memory. C is so static, and overlays so difficult and incompatible, that almost no effort is made to do dynamic binding of code, resulting in much wasted memory.

The programming tasks involved in creating game object behaviors are very inconvenient under the standard functional flow of control implied by most programming languages. In the programming of game objects it is necessary for each object to have a local state. This state consists of all sorts of information: type, position, appearance, state, current execution state (program counter), and all types of other state specific to the type of object. From the point of view of a particular object’s code all this can be viewed as an object specific global space and a small stack. This state must be unique to a specific object because it is often necessary to execute the same code on many different copies of the state. In either C or assembly it is typical to make some kind of structure to hold the state, and then write various routines or code fragments that operate on the structure. This can be accomplished either with function syntax macros or structure references. GOOL on the other hand allows this state to be automatically and conveniently bound to variable names for the most straightforward syntax. For example the C:

object >transx = object >transx + immediate_meters(4);

becomes in GOOL the similar expression:

(setf transx (+ transx (meters 4)))

However if in C one wished to add some new named state to each instance of a particular object one would have to create new structure records, accessors, initializers, memory management etc. GOOL on the other hand is able to easily allocate these on the object’s local stack with just one line of code, preserving the data there from frame to frame as well. A standard programming language like C only has one thread of control. While this is appropriate for the general case, it is inappropriate for objects, which are actually better expressed as state machines. In addition, it is extremely useful to be able to layer ultra light weight threads of execution, and to offer externally introduced transfers of control (events). While threads typically complicate most applications programs with few benefits, they are essential to the convenient programming of game objects, which often have to do several things at once. For example, an object might want to rotate 180 degrees, scale up toward 50%, and move toward the player character all at once. These actions do not necessarily take the same amount of time, and it is often useful to dynamically exchange and control them. In traditional code this is very awkward.

The basic unit of code in GOOL is a code block (or thread). These often do simple things as above. An arbitrary number of these may be combined into a state, they may be borrowed from other states, and activated and deactivated on the fly. For example:

(defgstate turn scale and move toward
	:trans	(defgcode (:label turn 180)
		; set the y rotation 10 degrees closer to 180 degrees
			(setf roty (degseek roty (deg 180) (deg 10))))
	:trans	(defgcode (:label scale to 150 percent)
		; set the x,y, and z scales 10% closer to 150% scale
			(with vec scale
				(seekf scale (scale 1.5) (scale .1))))
	:trans	(defgcode (:label move toward target)
		; set the x,y, and z position closer to the target's
		; (another object) position at a rate of 5 meters per second
			(with vec trans
				(seekf trans (target trans) (velocity (meters per sec 5)))))
	:code	(defgcode (:label play animation)
		; play the animation until this object is colliding with
		; another, then change states
			(until (status colliding)
				(play frame group animation))
				(goto collided)))

A :trans block is one which runs continuously (once per frame), and a :code block is one which has a normal program counter, running until suspended by a special primitive (frame), as in “frame is over.” These code blocks can be run as threads (as above), called as procedures, converted to lambda’s and passed to something (function pointers), and assigned to be run under special conditions (events or state exit). In this example is also illustrated the kind of simple symbolic notation used in GOOL to make object programming easier. Vectors like rotation, translation, and scale are bound to simple symbolic names (e.g. roty is the y component of the rotation vector). Many new arithmetic operations have been defined for common operations, for example, seek, which moves a number toward another number by some increment, and seekf its destructive counterpart.

GOOL also has a sophisticated event system.  It is possible to send an event (with parameters) to another object or objects. The object may then choose to do what it wishes with that event, run some code, change state, ignore it, etc., and report something back to the caller. These event handlers can be bound and unbound dynamically, allowing the object to change its behavior to basic events very flexibly.  For example:

:event	(defgcode (:params (event params))
		(reject-event-and-return
			((and (event is hit on the head)
				(< (interrupter transy) transy)))))

Says to ignore the hit on the head event when the interrupter (sender) is below the receiver in the y dimension.

Another feature illustrated here is the indirect addressing mode, (interrupter transy), in which a variable of another object (whose pointer is in the variable interrupter) is accessed. Operations can locate and return object pointers, which can be used as parameters. For example:

(send event hit on the head (find the nearest object))

which sends hit on the head to the nearest object or:

(let ((target (find the nearest object)))
	(when (and target (type target turtle))
		(send event hit on the head)))

which sends hit on the head to the nearest object only if it is a turtle.

It is the GOOL compiler’s responsibility to turn this state into code that executes the abstraction (the above state becomes about 25 words of R3000 assembly code).  GOOL code is typically much smaller than traditional code for similar tasks because the compiler does all the book keeping for this interleaving, and it is all implicit in the runtime product.  In addition it has a degree of code reuse which is practically unachievable in a normal language without extremely illegible source.

GOOL has full power macros which allow the language to be brought up to the level of the problem.  For example, many game programming tasks are more descriptive than a language like C is designed for. The following code causes a paragraph of text to appear on the bottom of the screen and scroll off the top.

(credit list (1 14)
	("AFTER THE")
	("DISAPPEARANCE")
	("OF HIS MENTOR,")
	("DR. NITRUS BRIO")
	("REDISCOVERED HIS")
	("FIRST LOVE:")
	(blank 1)
	("TENDING")
	("BAR"))

It does this by expanding into a program which creates a bunch of scrolling text objects as follows:

(defgopm credit list (params &rest body)
	"This macro iterates through the clauses in its
	body and transforms them into spawn credit line
	statements which create new credit line objects.
	It book keeps the y position down ward by height
	each time."
   (let ((list)
        (y 0)
        (font (first params))
        (height (second params)))
     (dolist (i body)
        (cond
          ((listp i)
           (case
             (car i)
             (blank (incf y (second i)))
             (t (push (append '(spawn credit line)
                               (:y ,y :font ,font :h ,height))
                      list)
                (incf y 1))))))
     `(progn ,@(reverse list))))(defgopm spawn credit line (line &key (y 0) (font 0) (h 18))
  "This macro is purely syntactic sugar, making the above macro somewhat easier."
  (spawn 1 credit line
     (frame num ,line)
     (unit ,(* y h)) ,font))

The following state is the code for the actual credit line.  When one of these credit line objects is spawned it creates a line of text. It then proceeds to use it’s trans to crawl upward from the starting y position until it is off the screen, in which case it kills itself.

(defgstate credit line (stance)
  :handles (spawn credit line)
  :trans (defgcode ()
           (unless first frame
              (setf transy ((parent transy) transvy))
              (when (> transy (unit 140))
              (goto die fast))))
  :code  (defgcode (:params (text frame y font))
           (stomp action screen relative)
           (set frame group text)
           (setf transvy y)
           (setf transy ((parent transy) transvy))
           (sleep text frame)))

As a conglomerate the above code manages to create a scrolling paragraph of arbitrary length from a descriptive block of code.  It does this by using the macro to transform the description into a program to create a cluster of new line objects.  This line objects take their simple behavior and amplify it into a more substantial effect when they are created in concert. In a conventional language it would be typical to create some kind of data structure to describe different actions, and then interpret that. C in particular is a very poor language for description. Because C’s only complex data type, the structure, can not even be declared in line (e.g. “struct foo bar={1,0}” is not legal except as a global) it is extremely awkward to describe complex things. It must be done with code, and the poor textual macro expander is not up to this. Witness the wretchedness of descriptive APIs like that of X windows. The contortions necessary to describe widget creation are unbelievable. Is it no wonder that people prefer to do interface work with resource files or Tcl/Tk which are both more descriptive in nature?

Overall, having a custom language whose primitives and constructs both lend themselves to the general task (object programming), and are customizable to the specific task (a particular object) makes it much easier to write clean descriptive code very quickly. GOOL makes it possible to prototype a new creature or object in as little as 10 minutes. New things can be tried and quickly elaborated or discarded. If the object doesn’t work out it can be pulled from the game in seconds without leaving any hard to find and wasteful traces behind in the source. In addition, since GOOL is a compiled language produced by an advanced register coloring compiler with reductions, flow analysis, and simple continuations it is at least as efficient as C, more so in many cases because of its more specific knowledge of the task at hand.  The use of a custom compiler allows to escape many of the classic problems of C.


A new 10th Crash post can be found HERE.

Subscribe to the blog (on the right), or follow me at:

Andy:  or blog

Also, peek at my novel in progress: The Darkening Dream

or more posts on LISP,

GAMES or BOOKS/MOVIES/TV or WRITING or FOOD.

106 comments on “Making Crash Bandicoot – GOOL – part 9

  1. [...] Making Crash Bandicoot – GOOL – part 9 [...]

  2. aimee says:

    can you please get Mark Cerny to write an article regarding Crash aswell and his thoughts on Universal at the time and his thoughts on Crash now?

    • agavin says:

      I asked Mark, but he’s really busy — and constantly hopping back and forth between Ca and Japan.

      • aimee says:

        OK thanks, but tell him its highly requested please, it would be very interesting to hear from his point of view,

      • agavin says:

        He wants to write something, and promised to try. I’m not kidding when I say he’s busy. Mark is not a guy who wastes any time. He has almost super human throughput. He’s probably working on four games, two tech projects, and several other super secret ones.

  3. aimee says:

    Can you please do Crash 2,3 and Team racing? it would be VERY popular

  4. Adam Black says:

    It’s funny as the cover of (Crash Launch september 9, 1996) made me think at first oh Tawna has a blue dress on instead of a Red dress on. And it made me think maybe tawna will appear with a blue dress on at some point. And obviously she never did have appear with a blue one on. So far it’s been her as a cameo (Merlin) and (crash boom bang) as a playable character. :-)

  5. It’s really interesting to see Lisp being leveraged for success again, especially in Crash Bandicoot – so many lost homework hours.

    It just reaffirms my desire to learn the language more and more.

    Great article!

  6. Jose says:

    Hi Andy,

    I just want to thank you for posting these articles. It brought back a lot of memories when I got my first Playstation and my first game being Crash Bandicoot!

    I had a feeling that this game was pushing my PSX to its limits because when I’d spent long hours trying to beat a level, my PSX overheated and had to turn the game console upside to keep on playing. This makes me feel old and I am only 25-years-old! Kids these days with their Call of Duties and Halos! :)

    As for GOOL, funny thing I ran across this article today since lately I’m having an itch to program in PLT Scheme (now Racket) which I learned back when I was in college. I never got too in-depth with the language because you could only cover so much in one semester, but I intend to write something more complex with it this time.

    Maybe the next great CAG?! Hah, I doubt it, making a good game takes more than a programming language (as these posts have shown) but it’s cool to see that LISP was used to implement a vital part of the game, and you don’t need C#, or C++ for everything.

  7. Yusef says:

    Wow, what a great series of posts! I found this one on Hacker news and went back and read the whole thing. You’ve inspired me to give Lisp a chance. It looks so amazingly flexible; I’m excited to poke around with it. What a cool story! Crash is a great game; your efforts really paid off. Thanks for the excellent read.

    • agavin says:

      These days I use Ruby for what I used to use Lisp for.

      It’s a fairly easy language to learn (and crucially has an interactive interpretor — listener).
      It was Ruby that got me off Lisp (my prior favorite). It does most of what made Lisp great, and the support factor is huge. There are clean standard libraries for everything, the garbage collector is good (the one in ACL is was so awful and dated — I last used it in ’07 — you pretty much had to turn it off.
      I miss the S expressions and the macros. But you can do most macro like things with a good block expression in Ruby, and you can even do auto-generated macro like functions with strings. It just isn’t as elegant as Lisp.
      The Ruby class system is a bit baroque, but it’s actually better in many ways than CLOS, which suffers from being too dated. In Ruby you can do a lot of very cool things with extend and include. It’s just a slightly different way of thinking. It’s this more regular object system and syntax that makes it a much better learning language than Lisp ever was.
      The implementation isn’t the fastest, but it’s good. The Lisp implementations were all clunky and felt like 80s codebases. Oh wait, they are.
      Support. The rate of change in Ruby is 1000x that of Lisp. Some new website has an API — someone writes a Gem immediately. In Lisp you don’t even have a really standard networking library!

  8. Joe web surfer says:

    This article about GOOL is so inspiring! GOOL/GOAL seem to be light-years ahead of other game scripting languages like Lua, or UnrealScript, or the Scheme code in the game Abuse.

    Would you consider writing a more about the macro library you developed for GOOL/GOAL ? I’d love to read more about the 56 primitives and 420 macros that were developed.

    • agavin says:

      I was just reading over a huge set of GOAL documentation. I’ll put it up at some point, but it will be A LOT of work to reformat into HTML, so it will take a bit of time. GOOL and GOAL are very very different. GOOL was mostly interpreted, and used only for the gameplay code (Crash 1-3). GOAL is completely compiled, and was used for EVERYTHING in Jak 1-3 & X. Including all the renderers etc. GOAL was incredibly sophisticated, and probably took me about 4 man-years to write. It was crazy. Just reading the docs today had me shaking my head at what I did :-)

  9. Joe web surfer says:

    I’ve read the snippets of GOAL that appeared on the web over the years. I remember seeing an example that showed how you could write functions that contained both lisp and VU code.

    Are the docs in a format you could create a PDF of? That might be easer than HTML-izing everything.

    • agavin says:

      I’ve thought of that, But I hate to just post a link.

      • Ravi Mohan says:

        Just adding my vote to a future blog entry on GOAL. If converting GOAL docs to html is the road block I (and many others I am sure) would be glad to help.

        Thank you for writing this awesome and inspiring series.

      • agavin says:

        I’ll certainly do it at some point. Word Press is a bit finicky about formatting, so it can be tricky. It only supports a small set of HTML and is always fighting you — so I can’t just export it as HTML from Word or anything.

      • Ravi Mohan says:

        “Word Press is a bit finicky about formatting, so it can be tricky. It only supports a small set of HTML and is always fighting you — so I can’t just export it as HTML from Word or anything.”

        Yeah well I was thinking more of hand editing,cutting and pasting into a text editor, then manually adding (basic if reqd, so WP can handle it )html tags and so on. If I could convert (and send to you) 5 pages a day for 2 months, that is 300 pages done. More people volunteer => it gets done faster. To get more info on GOAL, I’d consider it time well spent.

      • Ravi Mohan says:

        Sent you the formatted goal doc (to your blog-admin mail id) . Please take a look (and remove this comment after you read it!) Working on goals asm. Thanks!

  10. Michael says:

    Hey. I don’t know if your doing a “making of” Crash 2 & 3 blog, but I have a few questions.

    1) Recently there was a foundage of an ‘unused’ snow track from Crash Bandicoot 2. It can be found here: http://www.youtube.com/watch?v=xX3lVsCKwX0
    Was it do to time concerns that you didn’t make this level? Is it still in the games code?

    2) We all recently heard of a canceled 2010 Crash game which would use the elements from the Naughty Dog games and Crash Nitro Kart. Did you know if their continuing it? Thanks.

    • agavin says:

      I don’t remember what that track was intended for. There were probably half a dozen songs that Josh wrote over the years that we didn’t use. Sometimes they just didn’t fit and we would ask him to do another one or change it — and he would (he’s a great musician). Then we might or might not use the extra track. We’d try, usually shoving it in over the credits or in some secret level. I’d guess from the sound of this one that we thought it was a little too slow. The Crash 2 snow one, with the sleigh-bells, that shipped, is pure genius.

  11. Yeah, this paper was pretty interesting when you first posted it.It’s also a good LISP sales pitch :P. In all seriousness though, LISP does sound like fun, I definitely do want to give it a go. Busy learning OpenGL and C++ at the moment though. Which brings me to ask: which graphics libraries did you use/create for the Crash and the Jak games? Considering OpenGL is coded in C/C++, did you find it difficult to use LISP and integrate your graphics libraries into GOOL/GOAL as well as your engine?

    • Sorry, should have better worded those questions.
      Did you use OpenGL, or did you use some Sony created graphics library, or were you genius/crazy enough to write your own graphics libraries AND a dialect of LISP?
      If you did use OpenGL, did you have any difficulties in porting it over to a LISP compiler?
      In addition, how did you find using LISP to write out your renderers/shaders/etc. as opposed to C/C++?
      Also, did you ever feel any downsides to GOOL and sometimes wished you used another language sometimes? Because while LISP may do something quicker, I’m sure there are other things that it doesn’t do quite as well/you had to write your own libraries for.

      Sorry for all the questions, on this post and all the others, but I find myself very interested in the making of Crash, Jak and GOOL/GOAL.

    • agavin says:

      OpenGL HAHAHAHAHAHA

      On the PS1, I would have been surprised if an OpenGL implementation could have gotten 100 polys a second (we did 2100 on Crash 1, 3100 on Crash 2 and Crash 3). The machine didn’t even have floating point.

      Every single machine instruction between the gameplay and the graphics was written by myself, Dave Baggett, or Mark Cerny, most of the graphics and vertex calculation part in assembly. You just couldn’t use libraries. The fixed point math hardware for example consisted of a collection of coprocessor vector instructions. Sony wrapped these in C calls that added about 20 bookkeeping instructions to each mathematical one. We had to ditch all the libs and reverse engineer the instructions in order to get any decent amount of vertex math through the pipeline.

      In Jak & Daxter this was even more extreme as we used GOAL to write all the Vector Unit assembly. Jak had no integration problems because it was all written in Goal.

      For Crash, I made GOOL functions/instructions for anything we needed to call. One advantage of having your own compiler is that if you need a new feature, you just throw it in, often in 15 minutes. So GOOL had no “missing” features of that sort. It did have issues.

      1. Being mostly interpreted, it was kinda slow if you had a lot of objects
      2. The compiler itself was fairly slow, although you could compile a single game object and reload it WITHOUT rebooting the game!
      3. The compiler was sometimes buggy.
      4. Sometimes functions would get too big for it, and you would have to chop them up — but hey, I used production compilers in the 80s that were like this too.
      5. There was no debugger. But on the other hand, you could inspect the objects dynamically and see their registers and modify them.

  12. Matteo Mazzarini says:

    Mr Gavin,
    I am putting the following question in this blog, as You asked me to do, so that You could answer me. I repeat the question:what do You personally think about the Crash Bandicoot games published after Eurocom’s “Crash Bash”?
    I mean…if You had to give a mark to the following titles, what would You give them? (Between brackets there is the score I’d give to the games)

    -Crash Bandicoot: The Wrath of Cortex (PS2 version – 4.75 out of 10)
    -Crash Bandicoot: The Huge Adventure (8.50 out of 10)
    -Crash Bandicoot 2: N-Tranced (6.50 out of 10)
    -Crash Nitro Kart (PS2 version – 7.00 out of 10)
    -Crash Bandicoot Fusion (without score; I just played it only one day)
    -Crash Twinsanity (7.55 out of 10)
    -Crash Tag Team Racing (PS2 version – 8.25 out of 10)
    -Crash Boom Bang (Never played, fortunately :D)
    -Crash of the Titans (PS2 version – 7.50 out of 10)
    -Crash Mind over Mutant (PS2 version – 6.00 out of 10)

    What emerges from this scores that I personally gave to the games, is that I consider The Wrath of Cortex the worst of all chapters in Crash’s series; on the contrary, Twinsanity was yes a good game, but I expected more and more from it, so it represents a kind of half-delusion for me.
    Tag Team Racing is the best for PS2, in my opinion, considering that, despite the bad graphics, it was able to give me a sense of fun that Twinsanity didn’t give to me. But things have become again annoying, considering that I cannot stand the last chapters and their idea of controlling titans to give Crash a possible success.
    If ever Crash has to come back to its glorious past, what developers should do is to give back the Old Crash.
    Of course, I am not a journalist, just a Crash Bandicoot fan. If I gave these scores to the games, it was just to quantify the idea of appreciation I have of them…consider that I would give the following scores to Crash 1 – 2 – 3 and CTR:
    Crash Bandicoot 1 (9.25 out of 10)
    Crash Bandicoot 2: Cortex Strikes Back (9.50 out of 10)
    Crash Bandicoot 3: Warped (10 out of 10)
    CTR (10 out of 10)
    Crash Bash (8.50 out of 10)

    What do You personally think? Do You agree with my considerations about after-ND Crash Bandicoot games?
    Matteo Mazzarini

    • agavin says:

      The only 3 I played:

      The Wrath of Cortex – abysmal pastiche of Crash 1-3. The 1.5 minute! load times for levels that took 2 minutes to complete were a doozy. But the levels were all uninspired, and the graphics looked just like our games with worse models and higher res textures. I played the whole game through and didn’t hear a SINGLE sound that I hadn’t myself cut into a Crash game (Universal had the rights to use our sound files).

      Twinsanity – This was better. It was crazy silly, and not in the way we would have done. Technically it was uninspired but fine. The concepts were kind of funny and there were a few new gameplay ideas. The level design however was very flat. Elements were combined in a way that increased tension (i.e. fun). But certainly a much better effort.

      After that I stopped looking, like avoiding your ex-girlfriend who has become a heroin addict and is turning tricks for highs.

      The iPhone Crash Racing game – Was actually kind of impressive looking for such an early iPhone game — but I never had the patience to play for more than 2 minutes at a time. I don’t really play longer games on my phone.

      It’s possible that some of the others are good. But I kept my eyes averted, so I wouldn’t know.

      • Michael says:

        “But the levels were all uninspired”

        Except he was in a hamster ball.

        I currently own the greatest hits version of the game and play it on the PS3. It downgrades the loadings from 80 seconds to 15 seconds. Though, to be fair there was going to be a mini-game while the loading screen was on, but that was removed due to copyright reasons. What really gave to me was it’s relic’s challenges. I found WARPED to be easy on Relic’s, but hard to beat the developers time (since you damn people at Naughty Dog did that when the game was in BETA. -.-) Really the most challenging were the under-water levels. The mines sometime get you, from being invisible to dropping un-expectedly fast. God, I use to spent five hours getting that platinum in Coral Canyon. Those were the good ol’ days. :) Speaking of Coral Canyon, I really love the music in the game. I didn’t really like WARPED’s music to be honest. I always thought Spyro’s music was far superior in Crash Bandicoot, except for the Wrath of Cortex. I mainly like all under-water levels, Eskimo Ball, Weathering Heights (clearly title stolen from a song. lol), Knight Time, Ghost Town, Solar Bowler (the best IMO), and the Cortex Vortex. Yeah, I’m not saying people at Naughty Dog did a bad job of the Crash games, it’s just that WoC was a more ‘updated’ version of yours, with nothing but great graphics (after-all, critics did praise the game for smooth, superior graphics! I’m not saying the NDI games were ‘ok’, there way better than ‘good’. It’s just that I think WoC is a bit more challenging.

        Might I ask, is there anymore cut-levels in Crash 1 – Racing in the games code accessible via cheats? Or for any matter, is there ANY cut levels still in the games code beside Stormy Ascent?

      • agavin says:

        I don’t think there is anything of the magnitude of Stormy Ascent left hiding in there.

        And boy, we will have to agree to differ if you think WoC was superior in any way. Except for having about 100x the machine horsepower. Defending my programming. Note that Crash 1-3 had 3-4 second load times (most PS1 games were 20-30 seconds) and Jak & Daxter had 0 seconds (nada, nil, none). But WoC had 1.5 minutes! I could hear the drive seeking back and forth when it loaded. The first rule of fast loading was never to seek the head. Loading isn’t fun. :-)

      • Andrea says:

        So, you’ve tried two of the decent Crash games post-ND.
        By the way, here’s what i think about the Crash games for console:
        /The bests/
        - Crash Twinsanity: that’s the best Crash game that I ever played, yeah, it sounds a bit confusing, but I really think that TT-Oxford did an excellent job with Crash’s franchise. They used a lot of love on making this game and also, a lot of references of the old Crash games, but not like WoC did, but with the Free-Roaming, something new in the Crash games. 10/10.
        - CTR: I think it’s impossible to decide which ND Crash’s game is the best, but if I have to decide, CTR is probably the best one. Not only because you can have the same fun you had with the first three games, but you can also play with your friends! 8.9/10
        - Crash 3: at first I thought there wasn’t something new on this game, but after the first level, I found that I was wrong. And now that I have back my old manual, I’ve started to remember how funny were those manuals in the old days. Really. 8.9/10
        - Crash 1: a simple, but hard game. I think this is the only Crash game that there are some…dark elements (like the Generator Room, the N.Brio monster…), but there are also a lot of impressive levels, like “Temple Ruins” or “Jaws of Darkness”. And I can still remember that this was the time when Crash was the new Mario’s and Sonic’s rival. Yeah, good times. 8.6/10
        - Crash 2: my FIRST videogame of all time! The levels with the ruins and the sewers were probably the best. Also, at the first time I thought this game had a PS2 graphic (same thing with Crash 3)! 8.6/10

        /Decent games/
        - Crash Bash: probably, the best non-ND game after Twinsanity. Still a good game. 7.9/10
        - Crash of the Titans: unlike the others, I enjoyed this game. Yeah, not so much the characters models, but the gameplay was very innovative and funny. 7.8/10
        - Crash The Wrath of Cortex: it copied a lot from Crash Warped, but it was good. The funny thing is that when I first played this game, I thought that ND didn’t want to continue Crash’s franchise because it would have been always the same. 7.0/10
        - CNK: like TWoC, but worse. This totally copied CTR and in a bad way. The only good things are the graphic models (which were made by Charles Zembillas) and the soundtracks. 6.3/10

        /The worsts/
        - Crash Mind Over Mutant: I had a LOT of hopes with this game….but later I discovered that it was a bad copy of CotT and a not the same open world like the one from Twinsanity. 4.9/10
        - CTTR: probably, the worst Crash game and I am sorry to say this, because I really LOVE the Crash’s serie. The gags in this game were really comic, right, but was a good idea to interact Crash with other humans?….meh, I don’t think so. 4.0/10

        By the way, didn’t Jason Rubin say that he would like to buy again the Crash Bandicoot’s franchise?

  13. yearofthe says:

    Own Crash 1-Team Racing here. Just wondering, where can I find a copy of the BETA Crash games (more importantly the first one)? There’s been videos floating in the site of YouTube of people playing the beta version.

    Like:

    http://www.youtube.com/watch?v=KKTVVSSi9y0

    Is there anyway you send me a file (or a ROM/ ISO) and send it to me? I really like to see the changes made through-out the games history.

    Also I want to point out at 0:37 at this video: http://www.youtube.com/watch?v=stzXP63tXtI The bonus looks awesome. Don’t know why you removed it.

    • agavin says:

      They shouldn’t (hopefully) be available. Sometimes these are “borrowed” from trade shows or magazine reviewers.

      • yearofthe says:

        So I suppose you can’t support a link to download via e-mail?

        I’m trained up with a user on YouTube named “lxshadow” who we find hidden beta stuff and see what was in it’s level during development. But I guess If you don’t want this ROM to leak on the internet (which If you give it to me, I won’t share it with anybody) I can understand.

      • agavin says:

        I’m not going to upload any beta copies of the game. The released version is the best one, and the only one we intended to sell :-)

      • yearofthe says:

        I guess I can accept that. But I just want to point out I like how you get a checkpoint in the beta. :P

      • SCE DevNet says:

        This is really funny, ask .ISO file on Developers, I advise you one thing “yearofthe” if want .ISO file of that Beta, go to buy! (This Beta is Available for Sale from one 4-5 People on World (90% is not Legally, i am sure) but they ask $ 800-1000 USD for this).

        Request .ISO file on Andy, to send you for Free, is too Rude.
        If you Really need, i Can give you the Contact for the Releaser, but you must Spend $$$$. :)

        Right Andy?
        I Know very well where is Copy of that and other Beta, I’m quiet, but I’ve also played this version. but i am… sssh! :D

        ————————————–
        http://www.flickr.com/photos/scedevnet
        ————————————–

    • Andreas says:

      I can see that Aku Aku shines in the same way as he does in Crash Twinsanity whilst being in lv. 2.

  14. manny says:

    Have you played Crash Bash

  15. its_not_a_me_mario says:

    I think that you guys(the creators) still haven’t realized what you did with CB. :)

  16. its_not_a_me_mario says:

    Eh , just made a copy of all the blog posts on my hdd just in case.

    Now im waiting for part10 with more tech details :D

  17. Gabriele says:

    Mr. Rubin,Thank you for this series of posts!
    I want to ask you: if you were still in possession of the rights of crash, how the series would continue? you had some projects in mind? maybe for play station 2?
    (Sorry for my English i’m italian)

  18. aimee says:

    What do you think of Spyros reboot?

  19. subzerotwitterer says:

    Hello, so I’m posting a few of those questions I had on my mind. It’s better here since Twitter has limited character space…

    1) Will you blog post a series also about the development of Crash 2 at some point? It’s the most popular and enjoyable game from the series I think. It was a huge leap. The early warp-room looks interesting, though there is sadly no high-resolution screenshot online.

    2) Is there a way to find out the minimal required time for gold/platinum relics in the two hidden levels of Crash 3? I haven’t found that info online and am stuck right now 104% now (collected everything else) :)

    3) Are the black PS1 promo discs of various Crash games different from the retail version in any way or are they just collector items with a different label/print?

    4) Do you think the first 3 Crash games will ever be released in HD as a trilogy pack on the PS3/PSN with Trophy support? Who should we bug about it now-a-days? Universal/Activision? Or could Naughty Dog be somehow involved? They probably still own some rights to the series, right? And if an HD remake was ever to be made, would you like to be involved?

    Thanks!

    • agavin says:

      1. Eventually, yes. But it’s a lot of work :-) Crash 2 is my favorite also BTW.
      2. You have to search the web. I can’t remember any of that stuff.
      3. I can’t remember that either. Probably not substantially different. Occasionally there were review copies that were exactly like the finals, but with a couple more bugs! (so worse)
      4. I can’t say. But we’d love to see that. Only time will tell.

      • aimmeee says:

        I personally don’t want to see Crash HD remakes Crash games were amazing back in the day, they should be left alone. Activision should just continue with the franchise from where Twinsanity left off from but make it miles better. Activision have brought Spyro back and Crash has sold more than double what Spyro did so I find it hard to believe that they are not doing anything about the Crash series. The Crash series is an IP goldmine and money hungry activision i think know that, so i hope that something will be released this year on PS3.

    • SCE DevNet says:

      3)

      the black disc, is just promotional (full game) but promo version (not for sale) but ebay sell this a lot! :D
      nothing special, only black disc to have wrote (preview or review) is different from final game, but is not available, those disc have some bad guys to sell copyes of that… really not understand that world.
      exist aslo a beta and proto, and this are fully different (menu / gameplay in arena / boxes, etc…)

      2) about you savegame, i have 149% on crash bandicoot 2 (but have only this video updated) old, because was on 148%…

      you can see here:
      http://www.facebook.com/video/video.php?v=1272686592911

      …and Crash Bandicoot 3, have on 111% or more, not Remember well. (but all of those is Errors in the game). i have got without Cheats or other Shit, but 80% of Video to found on web was Played on PC tramit PSX emulator, and this have a lot of cheats. (fake) and use aslo PSX savegame converter.

      ————————————–
      http://www.flickr.com/photos/scedevnet
      ————————————–

  20. its_not_a_me_mario says:

    Any chance to share the source code of the compiler ? :D

  21. Megah says:

    Greetings from Germany!
    Thank you so much for making the best video game series ever. It’s very interesting to read through this blog and have a look behind the curtains of Naughty Dog during the making of Crash. I hope there will be one on Crash2.
    I was sooo addicted to the ND Crash games back in the day,because I liked them so much. I still own the original PAL copies of all the Naughty Dog ps1 Crash games. (And even play them now and then)
    It’s really sad to see where the franchise is going since ND stopped making Crash games (Crash Bash is probably the best of those,mainly cause it seems to have a lot of original Crash content in it). I don’t get it why ppl would consider the new ones as good: They lack good gameplay,got bugs here and there,got hooorrrrrible music(aside from the Crash Nitro Kart theme which is quite nice),way too long loading times(WoC of course),the designs of the characters get uglier every time,the humour is quite forced,Dr. Neo Cortex doesn’t seem like an awesome villain anymore but rather a laughable sidekick and worst of all they don’t have any connection to the former storyline and no replay value. It’s as if they just made these games, because the title has “Crash Bandicoot” in it.
    That’s why I tell ppl, when they talk to me about the “new Crash”: “Haven’t you seen the credits in CTR? It tells that Crash is napping at a beach down under.” :D

    Anyways great Blog, hopefully you or Jason will have time to answer some of the questions I got:

    1. Post-ND developers didn’t follow the storyline at all. I mean we all know Dr.Neo Cortex and Dr.N Tropy got turned into infants and went back in time. Now in Wrath of Cortex they are back to their normal forms without explenation.. PLUS they are on the Cortex Vortex(which was destroyed in CB2). In the Wii titles there’s even Cortex’s castle again.
    What do you think about that they completely ignored the storyline you established and how would you have continued the story if you made a Crash4? (If you want to tell us that is.)

    2.If you’d be giving the chance to make a Crash 4 ,would it be an exclusive Playstation game again and would you reverse the design changes that were made with the characters?

    3.In Crash 3 after you manage to access the 5 lvls in the lower section of the Timetwister,theres that lvl called “Area 51?” , who came up with this ?

    4.Also in the lower section you can see the Lab-Assisstans,who all seem to be manufactured robots. Has Eric Iwasaki something to do with this?

    5.What do you think about the “punching,jacking and farting-attacks” in the new Crash games and that they completely removed the classic Crash-tasmaniandevil-spin, belly flop?

    6.Do you consider the “Tiny Stadium” from CTR as better or the “Wario Stadium” from Mario Kart64?

    7.How come Tawna was inappropriate but the CTR pit babes weren’t ?

    8. Why did Crash look like T-600 on the CD from Warped? It’s like an ode to Terminator 2, is it because you consider Warped the best sequel you ever made or is there any other reason behind it ?

    9.What do you think about that they gave Crash tatoos all over his body? Do you still see the original Crash in him?

    10. Have you played any of these games: Medievil(Ps1),Jade cocoon(Ps1),Hogs of War(Ps1),Crude Dudes(MD)

    Thank you :D

  22. [...] part of a now lengthy series of posts on the making of Crash Bandicoot. Click here for the PREVIOUS or for the FIRST POST [...]

  23. fromtime says:

    Hi Andy,

    Don’t you miss the hardcore nature of game development, especially the way you guys did things at Naughty Dog? What do you do these days that keeps you as interested? Given projects such as GOOL and GOAL (when you already had to master the platforms in the first place), it sounds like you have an unquenchable intellectual thirst, and taking a console to the limit definitely has content to solve for the likes of you. So I am just curious, are you enjoying things as much in your new ventures?

    • agavin says:

      I myself, for the last year and change have been working on novel writing. I finished my first, The Darkening Dream and recently started on my second. This is plenty challenging all in itself, although different. I have to do a ton of research too. There are four stacks of books each about three feet high next to my desk of research.

  24. [...] is part of a now lengthy series of posts on the making of Crash Bandicoot. Click here for the PREVIOUS or for the FIRST POST [...]

  25. ckoppenhead says:

    You need to raid Radical Entertainment and take back what is rightfully yours.

    And then Crash may rise from the ashes.

    Great Blog btw.

    • aimee says:

      I think you mean Activision not Radical, activision owns Crash, Radical only developed (poorly developed)crash

  26. Joe Labbe II says:

    Oh man, if I had a dollar for everytime I said “GOOL!!!”
    And hey, it must be user friendly if my non-progammer-self could make boxes float with it!

  27. crashcrazy555 says:

    Hey, Mr. Gavin, do you happen to have any photos of the original, artsy-looking map screen from Crash 1? I’d really like to see those. =D

  28. Victor says:

    Hello Andy

    Are there any plans to open source at least parts of the original Crash 1 or 2 games? I dont see this cutting into profits of current Crash franchise just as it didnt happen with Quake/Doom. I’m sure I’m one of many of the old time fans that would like to resurrect the original spririt of the series.

  29. Rafael says:

    Olá,Sou Brasileiro e Sou Super Fã De Crash Bandicoot,Passava Horas e Horas na frente Do Video-Game,Mais Me Divertia Muito!
    Agora Os Novos Jogos São Chatos Não Perco Meu Tempo Mais Jogando;Queria que Você (NAUGHTY DOG) Voltasse a Fazer o Jogo Para Essa Nova Geração De Video-Games (Nintendo Wii,XBob 360 e Playstation 3)Seria Bastante Lucrativo Para Vocês!
    Obrigado pela Paciência!

  30. Hello Andy!

    I would like to know your opinion about what Activision is doing with Crash Bandicoot, not releasing any game for almost three years, and there may be possibilities for the Sony buy the rights of the franchise and bring back the glorious Crash Bandicoot has always been . I am Brazilian, a big fan of Crash Bandicoot, and I look forward to a new game Crash Bandicoot.

    Thank you!

    • agavin says:

      Glad you like the games!

      The whole Activision Crash issue has been covered to death in various comments on these posts (but I can’t remember under which), so read through all the comments on the 9 posts if you’re curious.

      • Thank you for your attention, Andy!

        I was sad to know that Activision has canceled a Crash Bandicoot game that Radical Entertainment was developing in 2010. But back to the subject, but that really naughty dog stopped developing Crash Bandicoot games after Crash Team Racing? Question of contract?

      • agavin says:

        What happened after CTW is also covered in a bunch of comments. :-)

      • It is striking that, even here in Brazil, Crash fans discuss a lot about this subject:)

        I knew you and Jason Rubin, created a new company called Monkey Gods, is there any possibility of you developing games for PS3? Or maybe buy the copyrights of Crash Bandicoot and bring it to new generation? =)

      • agavin says:

        Who knows, but nothing like that in the works right now. Crash has tremendous fanbase all over the world, which is always very fun to see. I can tell from the stats on my blog that at least 30-40% of the hits are international, all over Europe and South/Central America! Thanks!

      • That’s true Andy, only here in Brazil there are many fans of Crash Bandicoot and found that the best games of the series were the Naughty Dog! It is a shame that Acitivision does not recognize the great popularity of Crash Bandicoot = (
        I’m still waiting for a new Crash Bandicoot game!Even as I hope you and Jason Rubin are able to back the right of the series!

  31. That’s true Andy, only here in Brazil there are many fans of Crash Bandicoot and found that the best games of the series were the Naughty Dog! It is a shame that Acitivision does not recognize the great popularity of Crash Bandicoot = (
    I’m still waiting for a new Crash Bandicoot game! Even as I hope you and Jason Rubin are able to back the right of the series!

  32. iso 9000 says:

    I read your post . it was amazing.Your thought process is wonderful.
    The way you tell about things is awesome. They are inspiring and helpful.Thanks for sharing your information and stories.
    iso 9000

  33. [...] posts on Crash: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, [...]

  34. [...] Making Crash series: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, [...]

  35. [...] 6. Attending the E3, premiere of the game 7. As a startup 8. An outsider’s perspective 9. The programming 10. Tools for the game 11. Teaching an old dog, new bits 12. A practical example 13. Russian fan [...]

  36. Omer says:

    Greetings from Poland :)

    I’d like to ask some short questions:

    -Did you use any other than Irix operating system?
    -What do you think about free and open source software?
    -Which operating systems do you and Jason use?
    -Which programming language would you recommend for beginner game programmer?
    I know some C already, have wrote simple programs in C++, Java and Scala as well.
    Scala even allows some functional programming, so I’d like to ask, what do you think about using a language with garbage collector (like Scala) in game development? Would it be too slow?
    -Should I practice programming in assembly language or rather concentrate on high level object oriented languages?
    -OpenGL or DirectX?

    This blog is awesome, I’m really happy to read it :)

    • agavin says:

      We had some machines with windows NT (not the normal windows usually).

      I love open source, use it all the time.

      Now days, both Jason and I are all Mac (OSX Lion myself)

      I’m going to write about starter environments, but I need to research. Off the top of my head: Ruby, Python, Lua, and Flash are all decent.

      Start with higher level. But don’t totally ignore lower level (like assembly).

      I hate MSFT stuff, and I have never programmed with any MSFT compilers, environments, or libs. I therefore can’t comment on DirectX. I have used OpenGL. It’s ok, and certainly very standard.

      • Omer says:

        Thank you for answering my questions, it’d be really great to read more about this stuff in the near future :)

  37. Mr. Andy, I found this Japanese commercial for Crash Bandicoot in 1996, and wish Happy Birthday 15 years to the Crash Bandicoot, We love Brazil’s Crash! =) http://www.youtube.com/watch?v=2g5wasC7bac&feature=related

  38. Andy, you might have some possibility of hiring Activision, you and Jason Rubin, Monkey Gods with your company, to develop a new Crash Bandicoot game for all platforms sometime in the future?

  39. If I were to learn some LISP, would it do me any good with earning some credibility from Naughty Dog. I’m to understand from Christophe that they use a language called DC, that also derives from LISP. Know anything about this?

    • agavin says:

      It’s a Scheme dialect that they use for gameplay scripting. Skillz and smarts are what will get you a job at NDI :-) It’s mostly about blowing away some phone interviews followed by in house interviews (if you make the cut).

      • I’m familiar with the process from other firms. Usually the phone interview is done by HR guys, right? Anything that they’d be looking for in a programmer in particular these days? I’m sure tons of knowledge and experience is a given, but I’m wondering about any examples.

    • agavin says:

      Currently NDI does at least 2 phone interviews, first with HR and then with a real programmer. I don’t know what they are currently looking for, but mostly it would be smart and knows his shit :-)

    • agavin says:

      I think they do (offer internships), but I don’t know much about it.

      • I’ll have to see if I can ask somebody at Naughty Dog, as I’m sure they’re very busy at this point in time. Thanks for answering my questions. I would definitely kill for an internship opportunity there (not to put too fine a point on it). Hopefully, after they’re done with their latest game they’d be easier to get a hold of. I appreciate you taking time to answer my questions (I know I have a lot).

  40. Dru Nelson says:

    Hey Andy,

    Great work on GOOL and GOAL! I remember reading a blurb about it on a Franz LISP brochure in the late 90s. I always wanted to learn more, but it was only recently that I finally saw the light on what LISP was about. After many years of C (and C++), I wish I saw that light a lot sooner.

    All that I ask, is that you eventually post some more about GOOL. I could write a bunch of questions about the doc. But I’ll just ask a few…

    Did GOOL support symbols with spaces in them or was there another special form?
    For example: (find the nearest object)

    In the credit line macro:
    (t (push (append ‘(spawn credit line)
    (:y ,y :font ,font :h ,height))
    Where does the actual text get inserted into ‘list’? I don’t see the :text keyword anywhere.

    Finally, the :code blocks are a little hard to understand. I see a sleep in the credit line and ‘play animation group’. When did these run? Did until collided run every frame?Did you use a PC or did you use continuations? If you have time, it would be good to get a little color on these.

    Again, fantastic work! Your technology architecture decisions put you guys in a #1 position.

    Dru

    • agavin says:

      The macro is building the list in macro space. It then converted to some kind of static data.

      The code blocks run until they exit (terminating the process) or a (suspend) in which case they let control go to the next process (it’s cooperative). The (play-animation-group) type stuff are all macros that are basically looping over animations and suspending once a frame.

      • Thanks.

        A couple of other quick questions.

        Did you allow symbols with spaces in them?

        How did GOOL handle GC. I suspect you had a model where you just had functions working on global structures and managed memory manually with those structures to avoid GC.

      • agavin says:

        Neither GOOL or GOAL had runtime GC. GOAL had a kind of runtime compaction. Most datastructures (including processes) were fully relocatable and the compactor would bubble up the empty spaces to compact them.

        GOOL didn’t have true runtime symbols. GOAL did, but the symbol table was global without name spaces. Chunks of symbols were loaded and unloaded with levels however.

      • hi, on spaces symbol names.

        in the text you have (find the nearest object)

        is that ‘find-the-nearest-object or are spaces acceptable in certain symbol names?

      • agavin says:

        Yeah, a typo. No spaces in symbol names, should be dashes.

      • Thanks Andy – great stuff. I’ll take some time again in the future to dig in some more and how you implemented lightweight threads to avoid state machines.

        take care

  41. [...] a LISP syntax state machine to pcode compiler. Then from Crash Bandicoot a much more elaborate language for coding all the gameplay objects called GOOL. In Jak & Daxter I went full on crazy and wrote a native compiler for an object oriented full [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s