Skip to content

Add Rumble Racing (PS2)#909

Open
mattbruv wants to merge 5 commits into
magcius:mainfrom
mattbruv:rumble-racing-ps2
Open

Add Rumble Racing (PS2)#909
mattbruv wants to merge 5 commits into
magcius:mainfrom
mattbruv:rumble-racing-ps2

Conversation

@mattbruv
Copy link
Copy Markdown

Well, this was a marathon of a coding project... This PR adds Rumble Racing to noclip.

A few noteworthy things about this implementation:

  1. The original parsing code is in Go. I started the original research over half a year ago. This is the first noclip submission to use Go + WASM so I had to add support for it in the build pipeline. I may not have done this in the most ideal way, so please give feedback if it should be handled differently. (in retrospect had I known I would eventually get far enough with this project to submit it to noclip, I would have used TS or Rust to keep things easy for you guys, but here we are).
  2. The game calculates the actors' Y level, scale, and rotations at runtime using lots of heuristics based on the map's terrain, actor properties, etc. etc.. To get around having to spend another half year of my prime years in life reverse engineering all of this logic just to move a chicken up 0.1 meter (this is either genius or lazy, you decide) I took a save state using PCSX2 at the exact moment after loading the level, and scraped out the final actor Y levels and transformations. I've saved all of these in a JSON file based on the map and actor ID saved in the DATA folder. All of this data simply places the instanced actor models where they should be, and works for like 98% of the actors.
  3. I put the Go WASM parsing logic in its own web worker so it doesn't block the main UI thread when processing all the game's data for ~3-4 seconds. From what I can tell, nobody else uses web workers, so if you want me to change it to block the main thread I can do that.
  4. This is my first experience with rendering 3D geometry (outside of previously writing this data to a gltf file), so I have probably made some horribly naive decisions as far as rendering the scene. Please let me know if I'm doing something dumb.

Known Visual issues:

  1. I was never able to figure out the alternating unwinding face issue when manually unwinding triangle strips, so I don't attempt any back-face culling
  2. I have done no reverse engineering of how the game does lighting, so the scenes have very basic lighting. Luckily the maps are still fun and visually OK to look at despite this issue
  3. I have not looked into how the game creates the panorama / skybox.
  4. I do not handle some alpha/transparent textures/geometry correctly yet. While imperfect, it doesn't take away from things too much.
image

@mattbruv mattbruv force-pushed the rumble-racing-ps2 branch from 6f1078f to 75b3a01 Compare May 20, 2026 20:56
@mattbruv
Copy link
Copy Markdown
Author

A few more things I'd like to add when thinking more about this PR. Since the AI code in the other PR is getting torn up, I also want to be transparent up front about my AI usage before you review it so you don't go crazy wondering

First of all, please don't be dissuaded by reviewing this PR based on the 43,000 lines added. Almost 90% of that (37,000 lines) is just JSON data for actor transformations. Ignoring that, the actual amount of relevant LOC is like 5,000 LOC. I am definitely open to storing the JSON data in a different format/approach which would be more compressed and/or not inflate file size/LOC.

As far as how AI was used, I used Gemini/Claude to:

  • write decompress.go. The decompression routine was written entirely by AI
  • A fair amount of the Go code have been iterated on to varying degrees during the RE process, between both me and AI. In the Go codebase, I used AI as a tool to write out repetitive code in scenarios where it would have been annoying, (a majority of the VIF command parsing and VIF debug code for example).
  • The noclip specific TS code/structure is almost entirely AI written, and the shader code is 100% AI written). I basically started with the Example scene, and iterated on it with AI to start drawing simple models, then actors, and so on, until we're at the state it is in now.

There are lots of comments in the Go code which are remnants of earlier code, debugging code commented out, and so on. Since I basically copied the relevant code from my CLI tool and pasted it here, a fair amount of the comments and some code could be considered irrelevant.

As we briefly discussed a while ago, you guys said you'd be open to adding Go as a language to noclip. If, after looking at this PR, it seems like it would introduce more annoyances than it's worth, I am fine with re-writing the parsing code in TS / Rust in order to introduce less friction. If you'd rather have me scrap the Go stuff, it won't hurt my feelings.

@magcius
Copy link
Copy Markdown
Owner

magcius commented May 23, 2026

Thanks for the heads up. Sorry I'm so backed up with reviews.

Almost 90% of that (37,000 lines) is just JSON data for actor transformations. Ignoring that, the actual amount of relevant LOC is like 5,000 LOC. I am definitely open to storing the JSON data in a different format/approach which would be more compressed and/or not inflate file size/LOC.

For data like this, rather than have it be part of the initial code bundle, we could instead store it along with the game data, fetched at runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants