In this edition, we’re making Tails and Knuckles playable in Sonic 3D Blast on the Saturn! In doing so, we’ll learn something about how the Sonic Team games for the Sega Saturn handle character models - something that will be useful in future hacks.
Sonic 3D: Flickies’ Island (a.k.a. Sonic 3D Blast) was one of two Sonic games developed primarily by Traveller's Tales. It was supposed to be a 16-bit only game, but Sega’s failure to ship Sonic X-Treme in time for the 1996 holiday season led to a rush to port Sonic 3D to the Saturn.
The Saturn version plays like the Mega Drive / Genesis version, but it has some enhancements: there are some nice graphical effects, and a CD quality soundtrack. In addition, there’s a totally new set of special stages.
These special stages are inspired by the ones in Sonic 2. They’re considered by some to be the best in the Sonic series (and I agree!). They were contributed to the game by Sonic Team Japan, and rumor has it that they are built on the remnants of a scrapped 3D Sonic game.
The code for the main game looks nothing like the code for, say, NiGHTS or Burning Rangers. But the code for the special stages is another story: character models, player input, the camera, and objects are all processed like they are in those games.
In the Sonic Team Saturn games, there’s a set of doubly linked lists that control which functions execute for each frame. There’s a pointer to the next and previous items, a pointer to a function handler, and various parameters. Here’s the item for the main player character handler in NiGHTS:
The byte at +07 from the start of the parameters controls which character model is active. 00 is NiGHTS; 10 is Elliot; 20 is Claris; 30 is Reala; and 40 is Sonic (Christmas NiGHTS only). You can switch among NiGHTS, Elliot, and Claris anywhere.
Here’s the item for the main character handler in Sonic 3D:
The character control parameter is in a different spot, but it’s still there. 00 is Sonic; 01 is Tails, and 02 is Knuckles. If you switch during gameplay, you’ll see the characters swap before the game crashes.
Can we fix the crashes? Yes! Let’s patch the game to let us play as Knuckles…
The main problem is that Sonic has several different models, but Tails and Knuckles only have one. If we can change the code to prevent the model changes, we can play most everything with Tails or Knuckles.
One of the model change triggers is jumping. Sonic has a “spinball” model that gets used when his jump animation is active:
He also has a “running fast” model that gets used when he hits a speed bumper:
And another model is used for the checkpoint “thumbs up” sequence:
In the U.S. version, the model selection is done by the function at 06048bd4. Here’s Ghidra’s decompilation of that function, with my comments:
We want to avoid the lines where the model index gets set to anything other than 0. That’s all controlled by the animation number check. We can set that to some innocuous value like FF so that we fall through to the final else. The patch is:
Before: 06048bf4 85cb
After: 06048bf4 e0ff
Now when Sonic jumps or spins, we see him curled up rather than as a ball:
One thing left to do: the function at 0604B058 reads the character parameter. It uses it as an index into a table that points to the “normal” models for Sonic, Tails, or Knuckles:
We just need to put Knuckles’s pointer in Sonic’s index. The patch is:
Before: 0604b1b8 0604b028
After: 0604b1b8 0604b050
That’s it - playable Knuckles!
To do Tails, we just use his pointer instead:
Before: 0604b1b8 0604b028
After: 0604b1b8 0604b048
Follow-ups:
In a future edition, we’ll do a similar trick to play as Tails in Sonic Jam.
We’ll also look at giving Knuckles and Tails custom jumps to simulate gliding and flying.
Also, we’ll check the compatibility of these 3D models in other Sonic Team Saturn games.
Very nice article!