Sonic R: The R&R mod
The ROM hack that takes the racing out of Sonic R (1997)
Everyone knows that Sonic R is a racing game. But what this article presupposes is… maybe it doesn’t have to be?
I’ve made a patch, the R&R mod, that changes how Sonic R works:
You have unlimited time to explore the five courses. You can retire from the Pause menu when you’re finished.
Each character’s controls have been adjusted to make exploration easier – everyone has a lower top speed, handles better, and is less prone to skidding uncontrollably.
If you find all five of a course’s Sonic tokens before retiring, you’ll unlock a special character. And if you find a Chaos Emerald before retiring, you’ll keep it.
It’s the Relaxed version of Sonic R. Get the patch (and instructions for how to apply it) from SegaXtreme. Here’s a video of it in action:
Below are details on how the modified game works.
Character controls
During gameplay, controller input is handled by the function at 0602d5b81. It refers to a table (at 0603b20c) with parameters that specify how each character behaves. These are things like top speed, steering responsiveness, and jump height – there are 10 values in total.
Here is a subset of the values, normalized to Sonic:
To make the game friendlier to exploration:
I decreased each character’s top speed, since small movements are difficult when you’re going too fast.
I turned up everybody’s turning ability, which makes it easier to backtrack.
I boosted all of the traction values, since you normally skid out of control if you change directions too quickly.
I increased each character’s ground friction – this makes coming to a stop easier.
Here’s a video that shows the difference between two extreme traction values – 0x0000 on the left, 0x7f00 on the right:
And here’s the difference between two ground friction values. Knuckles is shown with Tails’s value on the left, and his own on the right:
Chaos Emeralds
The Sonic R manual says:
Chaos Emeralds: And what would a Sonic game be without Chaos Emeralds? Race around the tracks to find the Emeralds, but only the best racers can keep them.
Normally, you have to finish a course in first place to keep the Emeralds you’ve found. The function at 0601bd90 has the logic that implements this. It looks like this pseudo-Python:
if place_finished == 1:
emeralds_acquired |= emeralds_table[stage_id][stage_emeralds]The variable I’m calling emeralds_acquired is a 1-byte field at 0600b1c0. Each emerald is represented by one of the bits. The mapping is determined by this table, which is indexed by stage and which Emeralds you found:
My patch removes the place_finished check, so you always get an Emerald after leaving a course.
Sonic tokens
For the Sonic tokens, I had to do some additional work. There’s logic in the primary game loop (in the function at 06017a78) that looks like this:
if (
game_type == 0x00
and stage_tokens == 5
and place_finished < target_place
):
set_up_rival_race()
else:
post_race_processing()That is, if you’re in the right mode; got all the Sonic tokens; and finished in the top 3, you race against a rival. Otherwise, the game does its post-race processing.
My patch skips the rival race setup and marks you as having won the race if you collected all 5 tokens:
if (
game_type == 0x00
and stage_tokens == 5
):
place_finished = 1
post_race_processing()The post-race processing then updates the 1-byte field at 0600b1c1. Each bit represents one of the unlockable characters: Eggman, Metal Sonic, Tails Doll, Metal Knuckles, Eggrobo, and Super Sonic.
Managing the race state
Sonic R keeps the current race state in the 4-byte value at 0600bd74. While you’re playing, it’s 0. When you win, it’s 1. When you lose, it’s 2. If you choose Retire from the Pause menu, it’s 7.
The function at 060288e2 updates the game state in response to Pause menu selections. I changed it to make Retire set the state to 1 instead of 7.
Two other things can set the race state: finishing three laps yourself, or the slowest character on the course finishing three laps. The function at 060181a0 manages these transitions with logic like this:
if laps_complete == 3:
race_state = 1
fade_out_mode = 2
...
if racers_finished == 4:
race_state = 2
fade_out_mode = 2
...My patch skips over the branches to allow you to keep playing until you retire.
Other changes
During normal Grand Prix mode races, the HUD shows your lap split times and your current place:
The HUD is managed by the function at 060279f8. I did some surgery on it to take out those elements:
The HUD can display different things based on the game type. For the Get 5 Balloons challenges, it shows your overall time rather than the lap splits, so my patch overrides the game type to use its display.
I undid that override in another section of the game code, since the Get 5 Balloons challenges don’t show the Ring counter.
I inserted jumps to skip over the code that renders the race rankings and the Reverse indicator.
I wound up with the Ring counter in the top-left corner, overall time in the top-right corner, Tokens in the bottom-left corner, and the map in the bottom-right corner:
Another change I had to make: since I’m always marking player 1 as having won the race, the positions of the characters in the scene after the course ends can get scrambled. I took a shortcut to dealing with that: I added a “move forward” offset to the 1st place finisher, such that that character gets separated from the others.
Outro
How necessary was all this? Not terribly – you can explore the courses in the Tag and Balloon modes in the normal version of Sonic R. But I liked the idea of being able to get the collectibles and unlock the extra characters without having to rush through the stages. And changing the controls does make moving around a lot more pleasant. If you try it out, leave a comment with your impressions!
For more Saturn game mods, see:
I’ll be back with more retro game reverse engineering articles soon. Subscribe here at Substack to get the next one as soon as it’s out:

All addresses in this article are for the NTSC-U version.









