GTA III and Vice City fully reverse engineered: re3
github.com
github.com
We turned the Karuma into a physics defying monster. It was 1000x heavier than the tank, so as you drove down the road other cars just bounced off and flew over the horizon, or exploded on impact.
Yet it still did 0-100 in 0.1 seconds and could drive up walls.
One time we jumped it from the third island, over the middle island and landed on a skyscraper roof on the 1st island.
From there we spent about an hour dropping grenades on police cars and the army who had no way to reach us up there.
Fun times. Shame Twitch or YouTube didn’t exist back then to tell anyone about it!
Really couldn’t believe my luck when I found something so obvious (I still felt like I had mad hacker skills)
I used to jump into the fire engine, get on the wrong side of the road on a freeway and activate the slow motion before driving head on into the traffic. Their was something mesmerising about smashing your way through the cars and seeing them lift off into the air and fly into the buildings on either side of the freeway.
Eventually the police would show up but what could they do against a fire engine that was as dense as a sky scraper!
Another fun thing I now remember was to turn the dampening on the Taxi’s suspension to a positive value, so if you even gave them the smallest possible knock they would gradually start to wobble like a jelly and then start bouncing and bouncing until they were leaping up higher than buildings.
The handling meta files are all XML now, in more or less plain English, and very well documented by the modding community.
I run an GTA:V multiplayer RPG server using FiveM[0] and the community around vehicle mods is really incredible. 3D modelers produce all kinds of real-world vehicles for GTA:V from Nissan GTR’s up to hyper-accurate law enforcement Dodge Chargers[1] with accurate Whelen lights, Setina bull bars, etc.
[0] https://fivem.net/ [1] https://redneckmods.com/product?id=3fbaf24e-7775-432e-87e1-f...
It was Kuruma, in Japanese it means just a "car".
Weapon damage was also controllable. I accidentally discovered a hack I used in the multiplayer (MTA mod) that made me receive 0 damage from non-projectile weapons.
Beats “div.container” in my book.
Now GTA V / GTA Online made half a billion dollars in 2019, six years after it was released.
For example, the races on crazy roads floating in the sky was a hallmark of MTA. It's far too abstract to think R* came up with that idea independently of the many years of prior art in MTA.
It's a shame they only copied the game modes and not the architecture, as GTA Online's biggest downfall is the P2P networking.
Anyway, I didn't know a lot of things, so at one point I got the test environment and production environment tangled up in the code. I don't even remember the details of this confusion and I'm not sure I'd be capable of understanding how this was possible, but the long and the short of it is that one time the boss came down and asked something like "Why am I a horse?", and the answer was that he was being logged in as a user on the test environment which had a name that was a horse pun and a horse for a profile picture. Fun times.
A debug line someone thought wouldn't ever see the light of day.
I don't know if the new development model of "hit release date and fix everything after we sell the DLC" has made this better or worse.
There are corners of game development that are more "chill" than others. Studios doing work-for-hire for other projects can build sustainable businesses. People in the "serious" game and simulation space seem to have a pretty normal work experience. Likewise shared tech teams at the biggest publishers/developers are more insulated from business variability and shifting project deadlines.
This is all anecdotal from interviews, news, etc that I've seen.
- the games do not run particularly well on the raspberry pi (any version really) and I have a feeling it's at least partially due to the OpenGL layer. We could really use someone with how to optimize OpenGL (especially on the pi).
- physics have always been wonky beyond 30fps. I think someone with a good knowledge of game physics could really help us here.
My recollection of Vice City is that the vehicle dynamics model is not particularly realistic but optimized for “fun gameplay with a hint of realism” whereas Papyrus optimized towards “realistic gameplay with a hint of fun”. :D
Our physics engine was deeply, deeply tied to a particular isochronous rate (30 Hz, then later 60Hz, IIRC) with all kinds of hackery to make that happen and divorce rendering rate from physics rate. (On the PSX, we ran physics engine tied to the VBlank.)
I suppose this is because the original developers knew exactly what hardware this would run on and the achievable framerate on the PS2 and so took lots of short-cuts in the code?
Edit: Incredible project by the way.
I hate to say it, but fixed frame rates these days seem very 'lazy'? Obviously depending on use case and hardware.
If you know the game is only going to run on certain hardware, and you make the most money during the launch period of the game, it doesn't make sense to spend time, effort and money on something niche for the future.
It might just be really unhappy with the number of draw calls that you are doing. Looks like you are currently doing a drawcall per mesh; You might need to pack multiple meshes into a single drawcall.
Do you have any idea how many drawcalls per frame you are currently doing?
Last time I profiled something graphically intensive on the pi 4, I found that touching any of the draw state or uniforms between draw calls would trigger an expensive re-validation on the whole pipeline. 50% of my cpu time was spent in the driver.
Of course, the app I was profiling was pushing quite a lot of uniforms per draw call. Your workload might be different, so profile before doing anything drastic.
I recommend building a version of mesa with symbols so you can see exactly where CPU time is spent.
BTW, try prepending `mesa_glthread=true` to your command to see if that gives you a free speed boost.
I don't know if these extensions are available on Pi driver, though.
The problem with graphics programming is that really you need to learn two things simultaneously: how 3d graphics are rendered, and how to use a GPU api. They can both be a significant thing to learn alone, and the complexity of cramming the two into your brain together makes things hard.
[1]: https://www.gamedev.net/articles/programming/math-and-physic... Edit: http://archive.gamedev.net/archive/reference/articles/articl...
Not sure that gonna help much.
I think what you should do instead, port your OpenGL code to OpenGL ES. Specifically, Raspberry Pi 1-3 support GLES 2.0, Pi 4 supports GLES 3.1. As a nice side effect, renderer will become portable to smartphones.
This may or may not be a lot of work, depending how exactly you use OpenGL.
Pi 4 introduced Vulkan as well, but unlike GLES I have not tested it and not sure how good is the support.
1. On the main rendering pass, your code renders stuff mostly back to front. Consider sorting opaque objects by Z and render then front to back. If you do that, early Z rejection gonna save tons of pixel shaders and fill rate. The sorting doesn’t need to be perfect, an approximate will do as well, but with these ~5k draw calls I’m pretty sure even C qsort gonna be adequate on Pi4.
Translucent objects need to be rendered back to front like you’re currently doing.
2. In your pixel shader you often have this code:
if( a < u_alphaRef.x || a >= u_alphaRef.y ) discard;
Where u_alphaRef is [ -1000; +1000 ] i.e. very large interval.Don’t do that. Write another pixel shader for cases when you don’t need alpha tests. GPUs disable some optimizations (early Z rejection is one of them) when you calling discard in GLSL/HLSL.
3. Up to EID 5328, the game rendered the next frame. Starting from EID 5377, the game was finishing rendering of the previous one. That’s a good idea by itself, the problem with that, the temporary texture has size 4096*4096 pixels. Only top-center 3840*2160 portion was actually used. My desktop PC is fast enough to deliver 60 FPS, but on RPi you should not use textures much larger than necessary. All modern GPUs support non-power-of-2 textures, Pi4 included.
4. You are using 2x MSAA for the main pass. At least for my test cases on Pi4 (see e.g. this project https://github.com/Const-me/Vrmac ), even 2x MSAA ruined performance, if you use the same setting on Pi4, I think that contributed the most to the performance issue.
Try to disable MSAA and see what gonna happen. If you’ll find out it helps with the performance but the quality is too bad now, try to implement a cheaper substitute somehow, search the web for FXAA and SMAA keywords.
For shaders I'm never sure if I should do something dynamically or switch to a different shader, but it makes sense of course to kill the alpha test code if it's not used.
As for MSAA, our support for that is pretty rather young and it gives artifacts. I'm actually surprised it's on at all by default...
It’s used, but only for some meshes like vegetation, u_alphaRef was like [ 0.50196, 1000.00 ] for them.
> I'm actually surprised it's on at all by default
I don’t think I have adjusted anything, just built and run your code on Win10 with GL. This doesn’t mean it gonna use the same defaults on Pi, but it might.
You write:
> re3 was started sometime in the spring of 2018, initially as a way to test reversed collision and physics code inside the game. This was done by replacing single functions of the game with their reversed counterparts using a dll.
How exactly? So the game EXE exported all the function symbol names? How did you know the function signature (arguments, return type)? And then it is enough to preload a DLL to replace the function? There is no global state or so which must be accessed?
We were very lucky that we had symbols for global things, which inludes function names and signatures but not return types. We then replaced the first instruction of a function with a jump to our own. global variables can be done with a reference to a raw address. virtual methods are a bit of a challenge but we found way to handle them.
Can the assets be "reverse engineered" as well?
Also, can R* shut this project down? Is there a legal basis for them?
Of course, R*/Take-Two could always make a case.
That would be copyright infringement. At that point, you might as well just hit copy files from the original game.
As for the legality of the whole project: there's several different legal objections one could raise under copyright law:
1. That the EULA prohibits reverse-engineering
2. That the resulting reverse-engineering project is infringing the copyright on GTA3's program code (which it kind of has to in order to be a faithful disassembly)
Sure, a company created it and it should be its intellectual property for enough time to return the investment etc. But something ingrained so much into people imo trancends that and should be considered belonging to the public realm.
The company doesn't have to be around anymore, rights don't have to be negotiated, etc.
Short of that I wish more companies would do it voluntarily. I'm not into id games, but they're one example that comes to mind.
All nice sounding laws, such as gov funded welfare, gov funded hospitals, gov funded schools, and the endless regulations, implicitly carry a threat of violence, and when judging the ethics of a carrying a law out, that violent threat must be included. Government is firstly about guns.
You're also conflating civil and criminal law. Copyright is civil law. The government doesn't send the FBI in to ensure some publisher respects that a book's copyright has lapsed.
This project enabled people to port GTA to the PS Vita device[3]. This device hasn't seen any games from the franchise, so this is a big thing.
[1] https://github.com/GTAmodding/re3/tree/lcs
I got into the GTA franchise when (after not playing video games for a long time) I happened to see an old PS2 Slim that someone had put out beside the trash on the curb, brought it home, and started buying old games on eBay for a few dollars.
Adolescent humor and terrible themes&glorification aside, GTA Vice City led me to GTA San Andreas, which was both a compelling open world, and some great gameplay. I came to very much dislike members of other gangs, who were always starting crap when I was just going about my business -- which I suppose fit the story, and was also good mechanics for a game.
At some point, I had to buy a PS3, for GTA IV, which had been out a while. The PlayStation was a GTAstation. At the end of the story mode, as the cast-of-thousands credits rolled, over a montage of views of the New York City world they'd built, my reaction was that this game was a significant achievement for humankind.
And it was engaging enough, that, by endgame time, er, I might've developed muscle memory for consistent PVP headshots, high-speed "chicken" drive-bys, and literally driving circles around another player's car while concentrating fire on their driver position. One of the highest compliments you can receive is being wrongly accused of cheating.
In the very limited time I have for gaming lately (none, at the moment), it's usually been Ubisoft open worlds, but, whenever I check back into GTA Online freeroam, I'm reminded that it's the most actively fun for me. Cycles of retribution with another player or three, for the most creative or spectacular ways of fighting each other. And sometimes I even have the personally fulfilling opportunity to teach-- OP Mk. II griefers, that the Buzzard is still to be respected. (But forget heist stealth missions with randoms... :)
(Story-wise alone, The Last of Us might be my all-time favorite game. I dislike zombie stories in any medium, but, by the climax, I was misty-eyed, caring for the child character I was protecting.)
Can you speak about what it took to achieve this? (required knowledge, process, etc...)
The strategy for gta3 was to replace function by function of the game until we had everything replaced. for VC we evolved our existing code base by, again, reversing function by function until we had everything done. Just not by dll injection this time.
What about adding just an option (e.g. `re3 --no-shaders`) for may it possible run re3 even on older hardware by disabling most of decorative shaders?
Is this a technical requirement to have compiler feature parity on all platforms?
It is an interesting feat to run SDLPoP (re'd prince of persia) on modern systems.
https://en.wikipedia.org/wiki/Decompiler
At that point they are handed off to a more expensive process which includes checking physics each frame.
Now i don’t have to use Wine to run my childhood game on Linux
* SaaS stuff can be built very quickly (if you use cached node_modules or PHP composer's vendor directory) and deployed to parallel CI test runners that don't have much requirements. In contrast, your typical game takes much longer to (re)compile and as soon as you touch anything that requires graphics, you need some sort of (beefy) GPU in the server. Anyone who has ever tried virtualization with PCIe passthrough knows what a pain that is to set up, not to mention NVIDIA explicitly disallowing to virtualize their GPUs.
* It's easy to do unit tests for simple entities and operations (e.g. collision detection, physics)... but games are full of global state mutated from across the place.
* For everything that tests visual (or, god forbid, audio) output, computers are bad at testing. Change a texture? Great, now you have to re-check all your tests if they're still accurate and working. Humans are, for now, still better.
* Hardware-specific bugs: these are one of a goddamn nightmare. For most software, it behaves identically across computers - let's take most Docker containerized software... it will essentially run on anything that's amd64. But games integrate with OSes, especially the OS 3D stack (DX, OpenGL, Vulkan, Metal and on top of that the GPU drivers and GPU firmware) so incredibly deep that there are lots and lots of potential issues and workarounds. It's simply impossible to test for these.
* Closed source components in the loop: Games ship with all sorts of blobs, from video codecs to sound effect libraries. These are in your address space, but you can't really test them.
* Human tests are cheaper than writing test suites and setting up CI test farms (see the first point in my list).
The other use-case for tests is explaining the expectation to new developers / teams under tight timelines. Example - we had a "surge" team come in - we were writing software that pulls data out of emails in hundreds of formats.
We set up infrastructure for it that says - here is your input, here is your ouput, here is 100 sample records, make unit tests pass for them. This worked amazingly well when you had a team writing RegEx, another team writing csv stuff, one team using ML, etc. Basically, the goal was "make it work, in 2 weeks, no one will ever touch this code again." Btw, the latter is ALWAYS, ALWAYS a lie - if a company sinks a few hundred thousand into a project, you WILL touch it again.
Anyway, this was more of a rant - basically unit tests ARE useless 90% of the time. Unit tests in Angular that are basically integration tests are absolutely disgusting.
Keep in mind that if you have coverage, any time you modify a class, you are now fixing a bunch of broken tests.
I guess that's why I am for testing individual methods and SRP.
Here is an example of a game called Factorio running its own unit tests. It’s a lot easier for this game as its deterministic and doesn’t need player interaction to function. https://youtu.be/LXnyTZBmfXM
There have also been attempts to use machine learning agents that act as human players. It’s going to be a while but the idea is that it would automate playtests which are used to hunt down the same bugs. https://youtu.be/ZZsSx6kAi6Y
That said, often game logic has some unit tests.
GTA III, Vice City and San Andreas had mod allowing to play online (multiplayer) called "Multi Theft Auto" (for Vice City there was another one called VC:MP)
As far as I remember, the MTA project was started by a guy who initially tried to build a trainer by reverse engineering one of the GTA games, in the end he ended with a multiplayer mod. Fun times.
Wonder if they plan to do further work on graphical improvements.
I've done some graphical improvements but we want to keep it mostly true to the original spirit. But yes, there are some things i would still like to improve upon a bit.
By the way, this project is so cool. Thanks for making this!
EDIT: you can just install premake from package management, and use that instead of the checked in binaries.
The binaries in the repo are from their github actions builds, from whenever I last updated the premake binaries in re3: https://github.com/GTAmodding/re3/pull/945
I hope someone takes on doing the same for GTA: Chinatown Wars