GDC 2003: Porting a PS2centric Game to the Xbox: A Case Study of State of Emergency By Jonathan Dobson and Peter Brace Gamasutra, March 7, 2003 URL: http://www.gamasutra.com/gdc2003/features/20030307/dobson_01.htm This article describes the challenges that were encountered when porting State of Emergency (SOE) from the PlayStation 2 to the Xbox. SOE was developed as a PS2 game; the underlying rendering and animation technology consists of over 5000 lines of hand written vector unit assembly code. The biggest hurdle to overcome was the fact the entire game was built around code that was hand-tuned to derive the maximum performance from the PS2 architecture. This article shows that the approach taken was to develop a very specialized Xbox rendering engine that was optimized to perform extremely well in areas of the engine that had relied on the high-performance of specific PS2 hardware. In particular, the code that previously had utilized the vector unit processors. The resulting Xbox engine is capable of displaying the same number of characters as the PS2 version, but at 60 frames-per-second (fps), as opposed to 30fps. The article also shows that different high and low-level optimizations were required make SOE work on the contrasting architecture of the Xbox, and to achieve higher levels of performance. The Original Concept The original concept for State of Emergency (SOE) was that of a riot simulator. The player would control hundreds of characters, who in turn, could fight hundreds of other characters. The game would be a hybrid of the strategy and action genres. Development on SOE started on the Dreamcast, the intention was that SOE would be a game that was truly "next-generation". The core feature of the game, namely the number and complexity of the characters contained within it, would simply not have been possible on previous generations of consoles. SOE's target audience more close fitted the PS2's target demographic than the Dreamcast for which it was originally planned. A 2D prototype of the game was produced. This demonstrated the gameplay, but not the graphics. However the gameplay was not engaging enough, so the style of game was changed to a 3rd person action game, rather than a mix of two quite different genres. It was also decided to change the lead platform. During the pre-production period on SOE, Sony announced the development of the PlayStation 2 (PS2). The developers of SOE, VIS entertainment, and the publishers, Rockstar Games, decided that the target demographic for the PS2 more closely fitted with the target audience of SOE. We saw SOE as an opportunity to develop a high-performance PS2 engine, close to the release of the PS2, which could be used as the basis for a number of titles throughout the PS2's lifetime. Requirements For PS2 Version The main requirement of the game on the PS2 was that it should be able to display as many characters as is possible. This meant that a highly specialized renderer was needed. Not only was it a requirement that large number of animated characters should be displayed on the screen, but these characters had to have complex Artificial Intelligence (AI) and route finding code controlling their behavior. The approach taken was to develop a PS2 renderer with an integrated character animation and rendering subsystem. This was designed to exploit the relationship between the PS2's main CPU (the Emotion Engine, or EE) and its Graphics Processor Unit (GPU, made of up two Vector Units, or VUs). The PS2 renderer performs as much of the character animation as possible on the VUs. This maximizes the available EE time, so that the AI computations can happen in parallel with the rendering. The renderer was developed to minimize the amount of online processing needed for scene rendering. To achieve this, an offline exporter was written that converted geometry data from Maya, into the final format that would be sent via Direct Memory Access (DMA) to the VUs on the PS2. This introduced a certain amount of inefficiency in terms of the memory usage, since the data was optimized for speed, and not necessarily storage. In addition, the geometry data was not in a format that was readily accessible by the game engine, which meant that game data, such as collision information, needed to be stored separately, and in addition to the display data. The maximizing of the parallelization, and the offline generation of renderer specific data, especially with the character rendering and AI, was the key feature of the PS2 renderer that allows SOE to display and process so many characters simultaneously. In a typical scene within SOE, over 100 characters are visible, with the behavior of up to 250 characters being processed within a single frame. Conversion Timeline It should be noted that the conversion of the code to other platforms, specifically the Xbox, was not considered during the development of the original PS2 game. The reason for adopting this development methodology was because the game engine, and the renderer were specifically geared towards the hardware of the PS2. To achieve the required number of visible characters, over 5000 lines of VU assembly language was produced. If cross-platform requirements had been considered at that point, then the performance of the PS2 version would almost certainly have been compromised. Following the release, and subsequent success of SOE on the PS2, the decision was made to port the game to the Xbox. The decision was spurred on by investigations, implemented on the PS2, into multiplayer split-screen modes, immediately following the games release. The best focus testing available for a game is achieved by releasing it to the public, and in the Xbox version an opportunity was seen to evolve the gameplay of SOE, based on feedback from the people who actually bought it. The content of the Xbox version, and the scope of work involved, was also influenced by the fact that the game had a twelve-month exclusivity deal on the PS2. From the outset it was known that the game would not be released until February 2003 at the earliest, so this allowed more time than is often available for an average game port. SOE Xbox was an eight-month project, from May to December 2002. There was a core team of fourteen people, although a number of these people were part time, and the exact size of the team fluctuated throughout the development, depending on the needs of the project. On average there were eight full-time people on the project. The majority of the work was software development, with between three and four programmers working on the renderer engine, and the conversion of the game code itself. In addition, there was one full-time game designer, who was responsible for producing the mission scripts, a Director and Producer, and finally up to seven artists, who were responsible for increasing the resolution of both textures, and meshes. The eight months were broken down into five months production, two months alpha-to-beta, and one month beta-to-gold-master, with the game passing Microsoft final submission on Christmas Eve 2002. The Initial Conversion The first three months of development involved work progressing on three different fronts. Firstly the Research and Development team started to develop the Xbox renderer; secondly the game designer and Director began reviewing and revising the missions on a PS2, and thirdly the game programmers started converting the game engine to run on the Xbox. Since the game engine did not directly access the render data for the PS2 version, it was possible to compile and run the game by simply stubbing out the renderer function calls. In addition, the virtual memory management system on the Xbox allowed the conversion of the game code to be achieved very quickly. It was possible to allocate memory for the game engine data at exactly the same address used on the PS2, this meant that the binary map data could be loaded in completely unchanged, even though it included absolute memory addresses. The game was compiling and running on the Xbox within a few hours - although without anything visible on the TV screen! Since the Xbox development kit is based around DirectX, a functional (albeit un-optimized) renderer was produced within a short space of time. The renderer functions used by SOE on the PS2, which had been stubbed out during the conversion of the game code, were now re-implemented in a wrapper library that converted the DirectX based renderer, to function calls that were identical to those used on the PS2. This initial conversion took about three months, with much of the work being the development of the DirectX renderer, and the wrapper library that allowed SOE to use the renderer without many changes to the game code. The result of the first playable version on the Xbox was disappointing. It had been assumed (incorrectly, with hindsight), that the raw power of the Xbox would result in an implementation that was as fast, if not faster than the PS2 version. However, this was the not case. SOE on the Xbox actually ran slower than on the PS2. While the PS2 maintained 30 frames-per-second (fps) in nearly every scene, and about 50% of the time could theoretically render at 60fps, on the Xbox SOE maintained 30fps less than half the time, and often dropped down to 15fps, or even 10fps on many occasions. The Architectural Differences This initial conversion of SOE to the Xbox instantly showed how the different architectures of the PS2 and the Xbox resulted in a radically different performance. On the PS2, the relationship between the game engine CPU requirements, and the renderer performance was finely balanced. In fact, as described in Section 2, SOE achieved the results on the PS2 because the parallelism between the EE and the VUs was maximized. The EE processor cycle requirements for the rendering, of everything within the game, was very small. This left a large amount of CPU time available for the game engine, specifically the AI behavior. This was very important, since the AI processing and route finding needed to be performed for many Non-Player Characters (NPCs) in every frame. The nature of the AI engine, and the design of the PS2 meant that this behavioral processing required as much processor time as could be made available. The AI engine did not perform particularly efficiently in terms of data and instruction cache usage. At the most basic level, the AI engine is a loop, with a large amount of complex code to be performed on a different data set, for each iteration. The EE does not aggressively attempt to improve the performance of this sort of code automatically, in the same way that some other processors do. So, if anything, the bottleneck on the PS2 was the AI processing. The complete reverse was true on the Xbox. The rendering side of the application was written in DirectX, which is an additional layer of abstraction from the hardware level. This means that the rendering of geometry had a significant CPU requirement, and the same scenes actually took longer, in time, than the PS2 version to render. Conversely the game engine, and the AI code in particular, performed significantly faster without any changes. This was to be expected, since the raw power of the Xbox CPU is arguably higher than the PS2's EE, and the AI code was more suited to Xbox processor. However, the overall performance on the PS2 had been achieved by balancing the CPU and GPU load to maximize parallelism. This parallelism was not immediately apparent on the Xbox, so initially, the same performance levels could not be reached. Xbox Specific Optimizations To reach the same level of performance the game achieved on the PS2, it was apparent that some significant optimizations would be required. It was also thought that by spending some additional time on the optimization, performance levels could be increased so that the game could run at 60fps for the single player mode, and 30fps for the split-screen multiplayer modes. There were three main optimizations that were implemented: pushbuffers, animation caching, and reorganizing the frame processing to maximize parallelization. Before any optimization was started, the main bottleneck was the CPU usage. § Pushbuffers. Pushbuffers are the native rendering format of the Xbox GPU. When DirectX is used on the Xbox, the rendering instructions are converted into pushbuffers for execution on the GPU. A small subset of commands within the main render loop: draw primitive, z-writes, set vertexbuffer, select vertexshader, set pixelshader, etc, were reverse engineered to determine the resulting pushbuffer code. This was then used to develop an offline converter application that constructs a large pushbuffer for the whole level. Each object in the pushbuffer is preceded by a null operation (NOP), which is conditionally set as a NOP, if the following object is visible, and a jump, if the following object is not visible. The concept is similar to "execute buffers" rendering techniques in DirectX 3.0. This pushbuffer technique resulted in a reduction in the CPU set up time required for the rendering, essentially halving the frame time. § Animation Caching. The animation system on the PS2 was implemented using VU assembly code, which had a negligible CPU requirement. However, on the Xbox the animation code is implemented on the CPU, which contributed to the CPU bottleneck. To optimize the animation code, it was assumed that many characters would be using the same animations, since the majority of the visible NPCs spend their timing running about in a panic! In addition, there are only three different skeleton types in SOE; therefore most of the animation matrices could be pre-calculated even with very limited extra storage. A chunk of memory was set up to store the final animation matrices, half of this storage is used as a cache. Each cached set of matrices has a header describing which skeleton, animation, and frame is stored, together with a score of how useful this set had been so far and a reference counter. The score is decremented each frame, and the slot is considered free if the reference count reaches zero, and the score is low. To improve the search speed, the first x slots were set aside for frames 0, 10, 20, the second x slots were set aside for frames 1, 11, 21, etc. If the cache is full, or the matrices need changing, there is non-cached space at the end of the memory; these entries contain the set of joint matrices, but no additional information, except the reference count. § Renderloop Restructuring. The two solutions I just described massively reduced CPU usage, but towards the end of the project, the GPU usage in the game started to increase. This was partly due to the change from DirectX primitives to pushbuffers, but also as the performance of the engine increased, we increased the volume of data rendered. There was an additional problem, during the first third of a frame there was a large amount of CPU usage, followed by a large amount of GPU usage, with small amounts of CPU code, which blocked waiting for the GPU to become free. The final optimization was to spread the processing over two frames, so that at the start of a frame, the pushbuffer is executed. This takes lots of GPU, but requires no CPU after it has started. While this is running, all of the CPU intensive, game engine code is run, and the render lists are stored for the next frame. This balanced the CPU and GPU usage in a similar way to the PS2, maximizing the parallelization, and allowing the Xbox to maintain 60fps for most of the gameplay. Differences In The Xbox Version Since SOE Xbox was not a direct port from the original we had the opportunity to evolve the game beyond what achieved with the PS2 version. Specifically we revised the missions contained within the "Revolution" mode, we also made some improvements to the art within the game, and finally we added a multiplayer, split-screen extension of the arcade mode. Missions Revisited The core mechanic of SOE was the crowd, and the behavior of the NPCs. Specifically NPCs would react to events, and other NPCs would react to those reactions. From essentially simplistic building blocks, fairly complex, and non-design behavior would evolve. This made the world of SOE feel alive. The player might follow some enforcers around a street corner, and discover that they were running to break up a fight between two rival gangs. However, since this behavior was emergent, and not designed into the game from the start, it was quite incidental, and did not play a significant part during the mission game. For SOE Xbox, the mission game was reviewed extensively. Because of the three month gap between finishing the PS2 game, and starting the port to the Xbox, the development team could take a fairly detached view concerning the quality, and "enjoyablity" of the missions. Missions that the majority of the development team did not enjoy, were either removed, or significantly revised, with the intention of making the game more fun. For example, a mission that required the player to prevent an unarmed, pacifist from being killed by large number of armed enforcers was not enjoyable! Missions that involved the player being aided by a large number of armed allies, killing an even larger number of enemy NPC were much more fun! Unfortunately this latter type of mission was in the minority, specifically because the mechanic that allowed that type of gameplay had evolved from the emergent AI implementation. Art Improvements The Xbox port gave the art team the opportunity to revise some of the game art in SOE. On the PS2, the memory usage was very tight, with the majority of levels using all but a few kilobytes of the 32Mbytes of main memory available. Since the Xbox has 64Mbytes of RAM, it was possible to include some additional artwork. Firstly, the textures were increased in resolution. For memory and texture cache issues, the PS2 predominantly had textures with the dimensions of 64x64 texels. In many cases the texel to pixel ratio in SOE was actually 1:1, but an in depth review of the textures revealed a number of instances where this wasn't the case, and those textures were increase to 128x128 texels. In addition, the PS2 used palletized texture to reduce memory, and increase rendering speed. The Xbox version uses the original 24-bit source textures, with DXT compression. Secondly, the additional memory allowed the team to produce some mission specific characters to add variation to the game. For example, in SOE PS2 all of the mission givers were identical, but on the Xbox there are six variations. Finally, some elements of the maps were augmented with some exotic shaders. Selected cars, windows, and street signs had environment, and specular maps added, and in some cases an additional gloss map component. Specifically the floor in The Mall level was given a reflective environment map surface. To improve the appearance of these surfaces, some of the object using them, such as the cars, were increased in polygon resolution. Multiplayer Modes The biggest addition to SOE Xbox was the multiplayer versions of the arcade mode. From the beginning the renderer was designed with split-screen capabilities, even on the PS2. In fact, the game modes were initially prototyped on the PS2 before the Xbox renderer was functional. It was quickly found that some of the elements of SOE do not lend themselves to multiplayer gaming. For example, the hand-to-hand combat works in the single player game when the opponent is as "up for the fight" as the main player. However, even in the single player SOE, fighting against civilians who try and run away when attacked, is quite difficult. It would have be possible to redesign the combat so that it is more applicable to multiplayer fighting, however this would have resulted in a the mechanic that was different from the single player game. It was decided to bias the multiplayer modes away from ones that concentrated on hand-to-hand fights with human opponents. As noted in Section 5, the scene rendering in the SOE Xbox requires more CPU time that the game engine processing of the same scene. Much of this is the geometry setup time, so the multiplayer modes run at 30fps, as opposed to 60fps. Unanticipated Challenges This section describes a number of issues that arose during the development of SOE Xbox, that were not originally anticipated during the planning stages of the project. Incorporating Multiplayer Functionality SOE was designed as a single player game from the start. This meant that the multiplayer element had to be retrofitted to the existing game engine. On top of this, the existing game was required to continue to work with all of the single player game modes. The initial extension of the game to multiple players was fairly straightforward, and was implemented in roughly two days. This was aided by the inclusion of split-screen functionality in the renderer. Also, the main player character, and the NPCs were stored as the same basic datatype within the engine. This meant that it was relatively straightforward to alter characters that were previously AI controlled NPCs, to be player controlled characters. While this allowed the initial multiplayer code to be added quickly, a lot of game code assumed that the only user controlled player was character zero, and that all other characters where under AI control. A significant amount of QA and programmer time was spent identifying and fixing instances where the game logic didn't behave consistently for all of the human controlled characters. Bugs Due to Hardware Differences When converting a project from one platform to another, during the conversion process it is not unusual to discover bugs that had existed in the original. However the effect of these bugs was not anticipated during the initial stages of converting SOE to the Xbox. Specifically a number of code errors were discovered that produced undesirable effects (i.e. crashes) on the Xbox. In many of these cases, these bugs didn't result in anywhere near as fatal behavior on the PS2. Most of these bugs were due to errors in floating point calculations, specifically ones that resulted in "not-a-number" (NaN) values. On closing inspection, it was found that the floating point unit (FPU) on the PS2 is much more robust when dealing with arithmetic operations that result in, and subsequently operate on, NaN values. In addition to the FPU errors, bugs due to the slightly different memory map in SOE Xbox resulted in memory corruption errors that could not have occurred on the PS2. As usual, these proved particularly tricky to track down. Results For most of the scenes in SOE Xbox, the game runs at 60fps in the single player mode, and 30fps in the multiplayer split-screen modes. This compares favourably with the single player only PS2 version, which mostly maintains 30fps. There are some areas and occasions within the game where the framerate drops below a constant 60fps, although these are also areas where the PS2 version sometimes has issues maintaining a consistent framerate. The two player game is capable of running at 60fps for about 50% of the time, but it was decided that the optimizations required to maintain this performance would have resulted in a reduction of quality in both the art and gameplay, so it is locked at 30fps. The three and four player games also maintain 30fps for much of the game. Conclusions This article has described the conversion of SOE from the PS2 to the Xbox. It has shown that the original game engine was highly optimized for the PS2 architecture, and the resulting performance was due to the development of an in-house rendering written primarily in VU assembly language. This allowed the engine to maximize the parallelization between the CPU and the GPU. The resulting performance on the PS2 would not have been achievable without this finely tuned low-level renderer that was designed to perform very efficiently in the areas that SOE required. Since the performance of the game was a result of this exploitation of the PS2 architecture, the initial conversion to Xbox, resulted in lower overall performance than the PS2. Even though, based on raw processing power, the Xbox might have been expected to perform at least the same, if not better, than the PS2. This necessitated a change to the Xbox renderer, specifically converting the code from using DirectX drawing primitives, to pushbuffers, the native rendering format of the Xbox GPU. The result is that SOE on the Xbox runs at 60fps in the single player mode, twice the frame-rate of the original PS2 version. Overall, the performance of SOE on both platforms was only achieved by the development of a specific renderer that performed well in areas that required dedicated low-level processing, namely the character animation. In addition, the increased frame rate on the Xbox could only be achieved by processing the geometry offline into a format ready for executing directly on the GPU. This increased the available CPU time for the game engine code, and maximized the parallelization of the engine.