Play Games | PC | Console | News | Files


GameSpy
Grudge


 Who Wins?
 Civ 3 Advisor
 Little Droid

 



03/05/02
Top 30 Gaming Influences: Part II

03/04/02
Top 30 Gaming Influences: Part I

03/04/02
Diggles: The Myth of Fenris

03/02/02
Strategy Gaming:
Part VI -- Where the Genre is Headed


03/01/02
Strategy Gaming:
Part V -- Turn-Based vs Real-Time


02/28/02
Strategy Gaming:
Part IV -- In the Beginning


02/27/02
Strategy Gaming:
Part III -- Defining the Genre


02/26/02
Strategy Gaming:
Part II -- History of the RTS


02/25/02
Strategy Gaming: Part I
A Primer


02/20/02
Empire Earth Postmortem

02/18/02
NYC Toy Fair: Part II

02/17/02
NYC Toy Fair: Part I

02/17/02
Mod Week 7: Renegade Mod College

02/16/02
Mod Week 6: Counter-Strike, Tactical Ops

02/15/02
Mod Week 5: Bid For Power, Vampire Slayer

More Articles


Tim Sweeney of Epic Games:
A Critical Look at Programming Languages

All this week GameSpy is opening the doors and lending an open microphone to some of the brains behind our favorite games. Find out what they have to say about the current state of gaming and its future.
Edited By - Dave "Fargo" Kosak, Illustrations by Penny Arcade

Digital Circuits

Chips may seem a bit too low-level for this discussion, but we can learn some useful things by contrasting digital circuit design with its true predecessors, analog electronic development; and its higher-level successor, assembly language.

The great advancement brought on by solid-state electronics was the "digital abstraction"--the realization that one can design circuits purely by viewing all signals as being either a binary one or zero. In the past, all circuit designers worked in the analog world where interrelated voltages and impedances of all components were a vital consideration. With the advent of digital, none of that mattered--everything could be regarded as a one or a zero--and that enabled designers to create far larger and more complex circuits, using simpler primitives like NAND gates. The digital abstraction freed a new generation of circuit designers to focus on high-level design, which freedom made Moore's law possible.

Assembly Language

Early videogames relied heavily on low-level assembly code to make the magic happen.
In the early days of MS-DOS, Apple ][, Atari 2600, and early game consoles, most programmers worked in assembly language. Programmers now regard assembler as the ultimate low-level tool, but if you look at the lower levels of IC design, and analog circuit and process design below that, you can start to appreciate that assembly language is refreshingly higher-level.

Assembly language enabled users and budding developers to write programs, inasmuch as you no longer had to own a soldering iron to join in the fun. Assembly programmers lived and breathed CPU registers and instructions all day long, so the focus was on low-level programming. Assembly programs tended to be very fast, even in places where they didn't need to be, and where development time could have been dramatically reduced by using a higher-level language. Assembly programmers didn't ever think about objects or inheritance, and gave limited thought to functions and data structures. The value of such constructs is hidden when the language has no native way of expressing them.

However, as programs grew larger, assembly language didn't scale up gracefully. Programs were very hard to extend and maintain. Meshing code from multiple programmers was extremely problematic. Testing and debugging grew exponentially more difficult with program size. Porting code was impossible. Change was on the horizon...

The C Language

The C language was designed in the late 1960's, focused on enabling developers to write procedural programming code independent of any particular processor. C programs could be recompiled and run on any processor, and C compilers performed significant amounts of type-checking to detect major classes of programming errors at compile-time.

C made large-scale programming possible. Since it universalized the concept of functions, programmers suddenly found it practical to share large amounts of code, and to have large development teams working on projects together. Like other advancements, sharing code was also theoretically possible in assembly language, but was difficult to put into practice because it required tremendous detail to calling conventions, register usage, and other details which C was able to fully automate. C programmers had great tools for creating simple data structures and simple functions, so C programs were focused on functions, data types, and data flow.

DOOM wasn't just a huge commercial hit and a fan favorite, it also foreshadowed the ways games were to be developed from then on...
Mainstream application programmers switched to C in the early 80's. Game developers were slower to switch, because their small teams and focus on performance kept assembly language viable till the following decade. When id Software released DOOM, they surprised much of the industry by having no reliance on assembly code--despite excellent game performance, and by successfully cross-developing the game (in NeXTstep and DOS), then successfully porting it to an astounding variety of platforms.

But, just as soon as the death bell had rung for assembly language, C was showing major signs of weakness. Modeling complex systems uniformly--like thousands of actors moving around in a game, or windows and controls in a graphical user interface, became difficult. A typical big application contained hundreds of different kinds of linked lists; tens of hardcoded sorting routines; and enormous amounts of code to covert data between the different formats that different programmers used.

The large multi-programmer projects which C had initially made possible, were becoming increasingly bottlenecked on the lack of uniformity inherent in hundreds of thousands of lines of loosely-coupled code that was becoming an increasingly ad-hoc mix of functions and data structures. Change was on the horizon...

C++ and Java (also UnrealScript)

The object-oriented languages merge the concepts of "functions" and "data" into a single unified construct, the class. Augmented with inheritance, object orientation became an extremely powerful way of modeling hierarchies of classes. In a user interface, for example, instead of the C style of writing a different set of functions and data structures for all possible GUI controls, an object-oriented language models them as a "tree" of classes, beginning with a base class which encapsulates all the common functionality of a GUI control. Specific controls then extend that base class and add new features.

"C++ failed to deliver binary platform-independence, and Java failed to deliver high performance. Now, change is on the horizon..."

Object orientation has proven incredibly valuable in modeling all sorts of complex systems, ranging from objects in games, to graphical components of user interfaces, to web pages, to models of business and accounting data. C++ and Java gave programmers great tools for creating uniform objects and modeling their operations. Java went a step further with advances such as garbage collection, freeing programmers from the worry of memory management. Whenever a tool eliminates an entire class of potential problems which programmers no longer have to worry about, a significant productivity boost results.

While object-oriented languages handled pure objects well, they modeled complex relationships between objects poorly. Frameworks and collections turn out not to be truly modular or extensible because the languages can't represent families of objects. C++ failed to deliver binary platform-independence, and Java failed to deliver high performance. Now, change is on the horizon...

Next: The Next Generation...



(Or skip ahead to the forum discussion on this topic...)


[send feedback]     [send news]     [jobs]     [home]     [corporate]     [developers]     [advertise]     [legal stuff]    

© 1996-2002 GameSpy Industries.