Need for Speed: Most Wanted Decompilation
Need for Speed: Most Wanted
OrigenXbox 360
TecnologíaDescompilación y Reconstrucción en C/C++
Disponible paraWindows, Linux, macOS
Ver proyecto oficialSobre el proyecto
Need for Speed: Most Wanted es un videojuego de carreras de la saga Need for Speed desarrollado por Electronic Arts y Criterion Games para Xbox 360, PlayStation 3, Wii U, PlayStation Vita y PC. El juego fue lanzado el 31 de octubre de 2012. Se trata de una versión renovada del Most Wanted (2005) original, por lo tanto no es una secuela directa.
8 versiones de Need for Speed: Most Wanted
Estás viendo: Need for Speed: Most Wanted Decompilation
Need for Speed: Most Wanted Decompilationgithub.com/dbalatoni13/nfsmw
Recompiled · Android (WINDROID-EMU)github.com/WINDROID-EMU/NFSMW-RECOMP
Need for Speed: Most Wanted (2005, Android)github.com/codepdbh/nfsmwpc-recompiled
Need for Speed: Most Wanted (2012, Switch)github.com/SantiBros/NFSMostWanted2012-Android-Switch
Need for Speed: Most Wanted (Android)github.com/codepdbh/nfsmw-android
Need for Speed: Most Wanted (Black Edition, PC)github.com/veritr1x/nfsmw-recomp
Need for Speed: Most Wanted (nfs-most-wanted-mac)github.com/elforeign/nfs-most-wanted-mac
Need for Speed: Most Wanted (nfsmw-ios)github.com/bep1s69/nfsmw-iosInformación oficial del proyecto
Need for Speed: Most Wanted Decompilation

A work-in-progress decompilation of the GameCube, Xbox 360, PS2 and PC versions of Need for Speed: Most Wanted.
This repository does not contain any game assets or assembly whatsoever. An existing copy of the game is required.
Supported versions:
GOWE69: Rev 0 (GC USA)EUROPEGERMILESTONE: Oct 21, 2005 prototype (Xbox 360 PAL)SLES-53558-A124: Sep 20, 2005 prototype (Alpha 124) (PS2 PAL)SLUS-21351: Black Edition (PS2 USA)SPEED_EXE_1_3: PC version 1.3
SAY NO TO SLOP
We expect that as we progress on this decompilation, vibecoders will attempt to take what we have and slop out a broken port before us. Please do not give sloppers attention. Any releases and ports will be available here when they are ready.
LLMs have been used on this project. Here's why, dispite this, our project isn't slop.
-
LLMs are ONLY used as a rough pass to get code somewhere in the ballpark that we can then reference or to create tooling. All LLM code must go through extensive manual review to clean it up to the point of being usable. No slop is allowed to be merged into main. If we accepted slop we could have been "done" months ago. Raw LLM output is unacceptable due to the mistakes it makes, such as:
- Manually assigning registers to variables to force a fake match
- Accessing struct members by pointer offsets
- Replacing every string and float value with something completely random
- Renaming parameters and variables randomly
- Reimplementing the same code multiple times and using include guards to fix the compile errors
- Redeclaring every referenced function at the top of each file, often incorrectly
- Casting variables to the type they already are
-
We are matching compiled machine code and debug symbols against multiple versions of the game accross multiple platforms, as well as other games in the series with shared code. To match all at once the code must be accurate to the original. This project has a large focus on accuracy to what the original code might have been. This includes matching macros, inlines, and static constants stripped from usage sites.
-
No feature or porting work is to be done until we have a near-perfect matching base to work against, and no AI will be used for this work.
As long as this canary remains here, NO AI has been used for any feature or porting work.
Dependencies
Windows
On Windows, it's highly recommended to use native tooling. WSL or msys2 are not required.
When running under WSL, objdiff is unable to get filesystem notifications for automatic rebuilds.
- Install Python and add it to
%PATH%.- Also available from the Windows Store.
- Download ninja and add it to
%PATH%.- Quick install via pip:
pip install ninja
- Quick install via pip:
macOS
-
Install ninja:
brew install ninja
wibo, a minimal 32-bit Windows binary wrapper, will be automatically downloaded and used.
Linux
- Install ninja.
wibo, a minimal 32-bit Windows binary wrapper, will be automatically downloaded and used.
Dev Container
-
Install docker
-
VSCode
- Ensure the VSCode extension Dev Containers is installed
- When prompted to "Reopen folder to develop in a container" select "Reopen in Contianer" or run
Dev Containers: Reopen in Container
-
Zed
- When asked "Would you like to re-open it in a container?" select "Yes, Open in Container" or run
projects: open dev container
- When asked "Would you like to re-open it in a container?" select "Yes, Open in Container" or run
Dependencies and extensions will be included automatically
Run objdiff by running objdiff -p . in the editor's terminal
Building
-
Clone the repository:
git clone https://github.com/dbalatoni13/nfsmw.git -
Install dependencies (PS2 only)
python -m pip install -r requirements.txt -
Configure:
python configure.pyTo use a version other than
GOWE69(USA), specify it with--version, for example--version EUROPEGERMILESTONE. -
Build:
ninja -
Extracting the binaries
-
GC: Extract
NFSMWRELEASE.ELF, copy it intoorig/GOWE69, and convert it into a DOL using the following command:./build/tools/dtk elf2dol ./orig/GOWE69/NFSMWRELEASE.ELF ./orig/GOWE69/sys/main.dol -
Xbox 360: simply rename
NfsMWEuropeGerMilestone.exetoNfsMWEuropeGerMilestone.xexand copy it to./orig/EUROPEGERMILESTONE/ -
PS2: Copy
NFS.ELFto./orig/SLES-53558-A124/
-
Diffing
Once the initial build succeeds, an objdiff.json should exist in the project root.
Download the latest release from encounter/objdiff. Under project settings, set Project directory. The configuration should be loaded automatically.
Select an object from the left sidebar to begin diffing. Changes to the project will rebuild automatically: changes to source files, headers, configure.py, splits.txt or symbols.txt.

Contribution
Ghidra
To get a proper Ghidra output, you should either install the necessary extensions or ask me for access to the shared Ghidra project on decomp.dev.
Ghidra server
Manual setup
Dwarf1 extension to properly load the GC debug info into Ghidra
Unfortunately the vtables can't (currently?) be loaded from the GC ELF into Ghidra, so you'll have to copy them over from the PS2 ELF and adjust the corresponding classes. Nested classes have the same problem and solution.
Use Deprecated Demangler
For Gamecube binaries the standard demangler doesn't work and you have to use the deprecated version. For PS2 binaries the deprecated version gives nicer results.
- From the Ghidra project window, double-click the program file to open it in the CodeBrowser.
- In the CodeBrowser, navigate to Analysis > Auto Analyze... (or press Shift + F12).
- In the Auto Analysis options window, find the "Demangler GNU" analyzer in the list and select it.
- In the options area (usually on the right side of the window), locate the option named "Use Deprecated Demangler".
symbols/mw_dwarfdump.nothpp
./build/tools/dtk dwarf dump ./orig/GOWE69/NFSMWRELEASE.ELF -o ./symbols/mw_dwarfdump.nothpp
This is the dwarf dump of the whole GC version of the game. The .nothpp extension is to make sure that the IDE doesn't parse it on weak laptops. This should be your main source of information. It even shows which inlines a function calls. Namespaces only show up in generics. For regular functions and variables you can search symbols.txt for the right name.
symbols/PS2
This folder contains the debug info dump of PS2 build alpha 124. It is useful for figuring out member visibility and the declaration order of virtual functions.
symbols/debug_lines.txt
GameCube Address -> line mapping
symbols/file_names.txt
GameCube file list. Headers that don't contain any inlines are not listed.
ProStreet's PDBs
Another great source where you can see visibility and namespaces is the PDBs of the Xbox 360 builds of ProStreet. You can use resym to open them up in the browser.
symbols/vlt.txt
This file contains the hashes used in AttribSys.
symbols/hashes.txt
This file contains hashes used in different parts of the game. We are currently using a template solution to calculate the hash at compile time. But as you can see in the file, this is quite verbose, we'll want to find a better solution.
symbols/bchunks.txt
This file contains bChunk chunk IDs.
Ghidra CLI setup
-
Run
./build/tools/dtk dwarf dump ./orig/GOWE69/NFSMWRELEASE.ELF -o ./symbols/mw_dwarfdump.nothpp python ./tools/split_dwarf_info.py ./symbols/mw_dwarfdump.nothpp ./symbols/Dwarf -
Set up the project and Ghidra as described above (take the Ghidra repo from the decomp.dev server, you'll have to request access).
-
Import the ELF files from
orig/into the Ghidra project so the program names stayNFSMWRELEASE.ELFandNFS.ELF:ghidra import ./orig/GOWE69/NFSMWRELEASE.ELF ghidra import ./orig/SLES-53558-A124/NFS.ELF -
Download ghidra-cli and put it into your path.
-
Tell ghidra-cli your Ghidra installation's path
ghidra config set ghidra_install_dir <YOUR_PATH>/ghidra_11.4_DEV_20250425/ghidra_11.4_DEV -
Tell ghidra-cli the path to the Ghidra project
ghidra config set ghidra_project_dir <PATH> -
Set NeedForSpeed as the default project
ghidra config set default_project NeedForSpeed -
Set the GC version as the default program
ghidra config set default_program NFSMWRELEASE.ELF
Contributors
Special thanks to Brawltendo for helping with tooling and letting me use his partial decomp.
Special thanks to r033 and Toru the Red Fox for sharing their knowledge with us.
Special thanks to all the people who help us with decomp.me scratches, especially Roeming, chippy and Hummer12007.