Grand Theft Auto: Vice City demonstrates advanced game engine optimization techniques developed for the PlayStation 2's 32MB RAM and 300MHz CPU, including object pool memory management with contiguous memory blocks for pedestrians and vehicles, a grid-based world system with 80x80 cells for efficient collision detection, a two-layer state machine for pedestrian AI, and a generation counter system for weak references that predates modern ECS engines, all while implementing clever streaming algorithms and physics optimizations like doubled gravity (20 m/s²) for better gameplay feel.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
GTA Vice City Code Review: Bugs, Cops & Clever C++ Tricks
Added:Howdy. Today, we're going to break down the code behind one of the most iconic games ever made, Grand Theft Auto: Vice City. It's a game we all grew up playing, and honestly, it brings up so many memories. Like the first time you picked up a the first time you got busted by the cops with a five-star [music] wanted level, and probably the very first time we all experienced [music] what a true open-world game felt like. Even though it's been over 20 years since its release, the code of the game is still fascinating. Not only does it manage to run on a 300 MHz CPU, well, because it was made for PlayStation 2 in the first place, it also manages to work without loading screens for map segments while being [music] limited to only 32 MB of RAM. However, keep in mind this is not the original source code written by Rockstar. It's a community-driven reverse-engineered C++ code based on the game's binaries. And this video is intended purely for educational purposes. We'll discuss the specifics of PS2 era code and why it almost never allocates, how the entire city is 25 pedestrians and 12 cars, how the physics works, and how collision detection is managed. [music] There is even a replay system that is used for stunts that only takes 1 MB of memory to record everything that moves around the player. Rockstar also shipped the exact data handle mechanic modern ECS engines use, an integer packing a slot index with a generation counter, so a stale reference resolves to nothing.
Finally, we're going to look at the famous cheats in the game and how GTA fought piracy by breaking a sniper rifle mid-game or spawning a permanent hurricane or even corrupting a save data.
With that being said, let's start with the hardware limitations Rockstar devs faced back in the day. As far as I know, Vice City was developed specifically for PlayStation 2 console, which means there was only 32 megabytes of main RAM available, a 300 megahertz CPU famously called the Emotion Engine, a Graphics Synthesizer GPU with 4 megabytes [music] of quite fast ED RAM for that time, and a DVD drive that had to be used to stream game assets with approximately 5 megabytes read speed. Funny enough, despite the low clock speed of Emotion Engine CPU, it was actually quite performant, [music] delivering up to 6.2 gigaflops of pure power. Although it mostly came from two vector units, VU0 and VU1. And we can actually see VU0 being used in the code guarded behind GTA PS2 condition. It's used for the collision system [music] that contains a handwritten vector unit assembly. For the read speed, 5 megabytes per second doesn't sound like much, but in reality, it was never a hard part. Moving the laser head was though, because every random seek operation took about 10th of a second, which is like half a megabyte that you lose every time you jump somewhere else on the disk. Thus, the file reading code doesn't read files in the order game asks for them. Instead, it sorts them by a physical position on the disk, and then moves the laser head accordingly, picking them up as it passes. By the way, that's a good example of a circular elevator algorithm, also known as C-Scan, [music] which is used in the code. I mean, cheers. Today it sounds crazy, but back then, being a developer meant fighting with hardware limitations and [music] manual memory management.
However, even today, when there are tons of learning materials available, let's be honest, most of them are boring or expensive, which feels like a limitation on its own. But what if I told you there is a brand new way of learning where you watch a tutorial and video magically turns into a live IDE, allowing you to pause the teacher and edit or run the code at any point. I [music] know, sounds like magic, but it's a real thing. Let me introduce you today's video sponsor, Scrimba, an awesome platform with high-quality courses on everything from HTML to advanced data structures and algorithms taught by well-known seasoned teachers like Kevin Powell, Bob Zirol, and Cassie Williams.
Sign up using my link in the description below and you'll unlock an extra 20% of their pro plans. And with that being said, let's continue with our GTA code breakdown.
Now, probably the first thing I've noticed right away is that Vice City almost never allocates for gameplay objects. And literally every object in the game has a compile-time budget. 140 peds, 110 vehicles, 7K buildings, 460 objects, etc. [music] Each type lives in its own pool, a contiguous memory block allocated once at startup. Zero heap walk and no fragmentation. And when the pool is full, the spawn system simply fails.
Fewer pedestrians will appear, thus the city will look a bit more emptier. There is also a clever trick for pointer validation. The code takes an arbitrary pointer and asks [music] the ped pool, "Is this address your memory range?" And because every ped lives in one contiguous block, that's just a pointer math. Subtract the base address and see if the index lands inside the pool.
Pointer validation by address range. A cheap yet effective solution. Well, almost. As you can see, the original game code had a bug where it accepted one slot past the end of the pool as It's one. And the reverse engineers managed to fix it. So, the working code is now behind a fixed bugs condition.
When I was playing Vice City in my childhood, I always wondered how they managed to implement physics. I mean, it feels arcade-y, but no other games felt this good. Especially when you jump, run, or just move around. Not going to lie, it delivers even today. Gravity in the world of Vice City is 0.008 units per tick squared, which converts to 20 m/s squared, which is double Earth's gravity. [music] Apparently, someone at Rockstar thought that realistic gravity feels too floaty and boring. So, they went with double gravity to make the game feel much more fun. But, they only changed the constant. The method itself stands [music] honest. Exactly one line of code combines linear mass and moment of inertia [music] to answer this single question. How heavy does this object feel when pushed at this point [music] in this direction? Thus, if you hit the car's corner, it'll spin. And if you hit its center, it will feel heavy. All of this makes GTA's iconic bouncy physics.
Oh, and the cars in the game apparently have no wheel simulation. It's just a forward downward ray cast so with a damped [music] spring applied at the hit point. Literally, a suspension built by four laser beams that shoots out of a cube that we call a car. And if you ever played Vice City on PC, you probably have noticed how things breaks when you have high FPS. [music] Well, that's because of time step variable. At 50 FPS, its value is 1.0. At 100 FPS, the value is 0.5. At 200 FPS, it's going to be 0.25.
And like most of the game code assumes this value somewhere around 1.0. So, when the difference is noticeable, the game breaks. I also kind of like how Rockstar deals with anti-piracy.
However, the piracy detection code itself is [music] not here because the PC port was shipped with a SecuROM, which is a special copy protection layer that I believe was applied after the game compilation. Anyways, even when the piracy was actually detected, the game didn't refuse to run. A pirated Vice City was running just fine, except for, uh, let's say, minor differences. There are exactly eight separate sabotage mechanics in the code, and every one of them is delayed, random, or conditional.
For example, whenever a player tried to use a sniper rifle, it fired [music] nothing, no bullets at all. The entire road and pedestrian navigation graph was also turned off, and after like 35 minutes in the game, all the garages refused to work, so that the garage-related missions could never be completed. There was also a one in four chance for the weather to turn into a permanent hurricane each time the player completes or fails a mission. And whenever a fire truck spawns somewhere, a one in eight chance rolls to remove every pickup item from the whole map.
Oh, and this one is my favorite, actually. Whenever a roadblock is created, the one that appears after a certain wanted level, the radar on the player's HUD completely disappears. And also, for whatever reason, if your save file was created after 72K frames of playing the game, which is like, what, 20 to 40 minutes, every time you try to load it, your save data becomes corrupted. I mean, what makes it funny is that all of this looks like plain bugs in the game, which I believe was the whole point. By the way, as far as I can tell, But out the protection layer doesn't fully restore the game. The code here is a bit more complex than you might expect. For example, an integer variable called sniper [music] pirate check is assigned to some gibberish value in the code. And if it's not zeroed, sniper rifle will not work, which means sabotage here is an initial state of the game. Thus, only when the protection is actually present and it confirms the game is a legit copy, then it sets the value to zero, making the sniper rifle to work as intended. One more question I always ask myself, how exactly the open world of Grand Theft Auto: Vice City is written in the code?
I mean, there are zero loading screens mid-game. And let me remind you, it was working perfect on a PS2 [music] hardware. Of course, at first glance it looks like a pure magic. But after reading the code, now I know it's actually a clever approach that makes it work. First of all, the world of Vice City is an 80 by 80 grid with each cell represented as a 50-m square. It's a flat, statically allocated two-dimensional array. Each sector of the map also holds 10 intrusive linked lists. Buildings, vehicles, peds, objects, dummies, etc. [music] And this simple approach allows for collision detections to work very fast. Because whenever the game asks questions like, "What can this bullet hit?" or "Which [music] vehicles are near this explosion?" "What's under the wheels?"
it always comes down to the single formula. Convert coordinates to a range of cells and walk a few short lists.
That's it. And as you remember, game objects was already pre-allocated, which means adding a new object to the sector allocates nothing. It's also worth to mention a clever trick devs used to deal with objects that crosses multiple boundaries. Say a huge truck can be inside [music] four different sections at the same time. Obviously, we need some kind of visited flag for this object. But, what's the proper way to implement it?
Nowadays, lazy developers would probably loop through like all 10K plus entities and set visited flag to false. [music] And then, during the query, just change it to true and call it a day. The problem is that reset loop will run every single query, which means thousands of queries per second. [music] And that's a huge waste of resources that the devs of GTA just couldn't afford. [music] Instead, they came up with a clever skin trick. Don't store a boolean, store a number, and keep one global counter. Thus, when a query starts, it increments the global counter. And then, up and touching an entity, stamp it with this number. So, when you touch another entity, you just have to check the stamp value. And if it's equal to our current global counter, just skip it. This way, the visited flag now costs nothing in terms of performance. One simple increment wiped the whole world's visited state.
Although, of course, at some point, it has to reset the stamp values because the global counter is 16-bit value, which means the maximum number it can hold is 65,535.
So, it still kind of runs the slow all entities iteration time to time, but the performance hit is negligible. Now, [music] while you move around the world of Vice City, various assets get loaded from a disk in real time. [music] And literally, a single 3K lines of code file named streaming.cpp is all responsible for this. And this is [music] a second piece of puzzle that lets GTA to run an open world without a constant preloads. Once again, let me remind you, PS2 had only 32 megabytes of main RAM. So, models, textures, collisions, and animations was all streamed from a disk [music] while you play the game. And the whole thing was heavily optimized. And while we already discussed how it managed to read the data from a disk with an elevated algorithm, there was one more interesting rule. No two pedestrians and no two big files in one batch. It meant to keep the decode budget manageable cuz it was performed on the main thread. By the way, the IO code has its own separate [music] thread called CD stream, whose only job was to sit on the DVD drive and read the requested bytes.
Funny enough, when read fails, the error debug message printed was a bit too emotional. And when at some point the memory runs out, the code unloads unused stuff with two functions. Remove list used model and delete RV objects behind camera. First one unloads an object with a reference [music] count of zero and the second one straight up unloads assets behind the camera until it has freed enough. And obviously, [music] it was kind of cheap because you cannot see the city unloading behind your back. In Vice City, there was also a replay system. So, whenever you perform a stunt, a replay of it fires. Or you can run a replay manually. But the question is how it's implemented. The whole game already barely runs on the hardware.
Thus, they could easily get rid of the replay system. I mean, it's not that important. And I guess the reason they kept it is once more because of a clever optimization. The whole feature only requires under 1 MB of memory for roughly 30 seconds of world history. And it fits because nothing is stored raw.
The world state gets quantized into typed packets. Vehicle updates, head updates, weather, clock, and even pets' complete animation is squeezed down to a byte per field. And as for the positions and orientations, they are sampled every frame and interpolated back on playback.
So, when a replay starts, it actually does not [music] simulate things. Every vehicle and pedestrian turns into a puppet, which then drives directly from the recorded stream. And it also quite cheap, since replaying doesn't require running any of the physics. And of course, while the replay is playing, simulation around the player stops, which is similar to how a kill cam is implemented in other games. Once again, a brilliant solution. Honestly, I was also excited to check out how the peds AI code works. Of course, the AI in Vice City is nothing too special, but for the time, it was awesome. And if you played the game, you should remember the feeling. The world here felt [music] alive, and those was not just dummies.
So, the whole AI brain is actually [music] a two-layer state machine. Ped state is responsible for the low-level actions like walk, flee, aim, jump, etc. And E objective is the high-level goal: enter car as a passenger, buy an ice cream, attack a player, guard spot, etc. This way, the objective layer decides what to do, and the state layer decides how. [music] By the way, the whole living city is only 25 people. There is a variable in the code named max number of peds in use and max number of cars in use. [music] So, there could be at most 25 active pedestrians and 12 active traffic cars. And interiors bump this number up to 40. Which exact models will spawn is a data-driven per map zone and time of day. It's inside a file pedgrp.dat, which is shipped with the game and can be opened and edited with just a notepad. And that's actually one of the reasons why Vice City is so easy to mod.
Thus, at daytime, there will be all golf players around and zero at night. Same goes for the beach. Lifeguards, skaters, and other people will spawn during the day and leave during the night. Gang members will appear more often at night, [music] and in some areas, there will be more police. There's even a somewhat a perfect personality [music] in the code.
Every entity carries a small U 16 variable called m_random_seed, [music] which is used to change the animation speed so that every pedestrian walks at their own pace. Funny enough, the crime system literally has a variable named m_n_chaos that accumulates crime points. So, that more crimes a player commits, the higher wanted level will be. And the start to chaos level is a hand-tuned constant table with seven values starting from zero. Also, the individual crimes a player commits [music] increases the chaos level quite differently. Punching a ped adds five chaos points. Hitting a cop is 45, and for some reason, destroying a Cessna bumps this value to 500. And of course, the more chaos points you have, the more law enforcement vehicles and cops will be spawned. All of these are pretty much hard-coded values, which is perfectly fine for this system. Now, one more technical thing I wanted to highlight is how exactly weak references are handled without smart pointers. This is interesting because Rockstar pretty much shipped the exact data handle approach that modern ECS engines utilize way back in 2002. And as you might know, one of the biggest problems in open-world game, where objects constantly gets destroyed, is a dangling pointers. Say some mission script targets a truck vehicle that then gets destroyed, and the free slot is recycled, say for a taxi vehicle. How does this script not accidentally control the wrong vehicle? The solution Rockstar came up with is a generation counter. Each slot has one flag byte.
Bits zero to six are representing an ID and bit seven reports if it's free. This generation gets incremented every time the slot is reused [music] and the handle itself is an int 32 data type. So resolving a handle rechecks the whole byte and if the slot was actually reused or freed since handle was made, it returns nil. This is the code that responsible for the whole check. It also worth mentioning that the generation is only seven bits, which means [music] it wraps. So after a slot is reused 128 times, the generation returns to the original value, which means a stale handle can resolve to whatever occupies the slot right now. However, as far as I know, modern ECS engines like Unity's [music] entity ID uses a 32-bit on the generation to make things like that impossible. And Rust's generational arena uses what? Like 64 bits? Anyways, Rockstar only spends seven because in 2002, seven was what a spare byte had left over. That's pretty much a weak reference in one integer. No reference counting and no atomics. Only one simple comparison that worked perfectly for this game. Probably the last thing I wanted to mention is a cheat system. And if I remember correctly, in the previous game GTA 3, all the cheats were sitting in the executable as a reversed plain text, which is why all of them were extracted straight away on day one after release. But this time with Vice City, Rockstar decided to use a simple kind of a Caesar style cipher to hide the cheats in the game. This way this gibberish string turns into a fax tools if you decode and reverse it. They also left a note in the code for anyone who manages to decode it. It was a cheat code whose name itself reads like cheats have been cracked. By the way, it's a real working cheat and if you type it, you will play as a Ricardo Diaz. And the whole game contains like 58 hard-coded cheats with one of them being a programmer. If you type it, Tommy will become skinny with thin arms. Anyways, that wraps up our video today. I hope you enjoyed it as much as I did. Make sure to subscribe to the channel and leave a like. There are plenty of related videos coming soon.
Thanks for watching. I'll see you in the next one.
Related Videos

TOP 15 Data compression Interview Questions and Answers 2019 Part-2 | Data compression | Wisdom jobs
wisdomjobs
281 views•2019-06-28

CTS 158: 802.11w Management Frame Protection
ClearToSend
4K views•2019-02-04

NDSS 2019 Send Hardest Problems My Way: Probabilistic Path Prioritization for Hybrid Fuzzing
NDSSSymposium
496 views•2019-04-02

How realistic is Cities: Skylines?
CityBeautiful
159K views•2019-02-14

GUIs & TUIs: Choosing a User Interface for Your Python Project | Real Python Podcast
realpython
2K views•2025-04-04

The OSI Model - Explained by Example
hnasr
225K views•2019-05-12

Cloud Computing - Introduction
elithecomputerguy
98K views•2019-10-07

From Traveler's Dilemma to Dynamic Routing | Demystifying Networking
IITBombayJuly
5K views•2019-08-04
Trending

WOW! Judge TURNS THE TABLES on Trump in His OWN $10B LAWSUIT!!!
MeidasTouch
197K views•2026-07-23

Playstation NO DISC/NO BUY Fight Is Over...
DavidJaffeGames
4K views•2026-07-23

Steam and Xbox Just Dropped The Hammer On PlayStation
OhNoItsAlexx
9K views•2026-07-23

Americans Confused in Australia for 17 Minutes Straight
IWrocker
17K views•2026-07-23