Tails takes flight in Sonic Jam
Making Tails playable with custom moves in Sonic Jam's Sonic World
In this edition, we’re going to make Tails playable in Sonic Jam’s Sonic World, and give him some animations and control mechanics to distinguish him from Sonic.
You can get a patch and play this yourself from here. And there’s a video!
What follows is a based in part on Starman’s notes posted on Sonic Retro - check them out!
Our first post about Saturn 3D Blast mentioned how that game and NiGHTS Into Dreams both use the same method for tracking which character you’re playing:
There’s a set of doubly linked lists that control which functions execute for each frame.
One of the items in one of the lists is the for the main player control handler.
One of the parameters for that handler is an index into a table of characters.
Sonic Jam’s 3D world is no different. The parameter in position 0E
is 00
for Sonic’s handler. The one for Tails’s handler is 01
.
Indeed, if we change Tails’s parameter, we get two Sonics!
But if we change Sonic’s to Tails, the game immediately crashes - whoops. Don’t worry; we can fix it.
Part of the problem is that the Sonic code paths are expected to be able to do more than the Tails code paths. If we leave the character index parameter alone and just have the game change how things are rendered, we can make it think Sonic is active while it shows us Tails.
Sega Saturn assembly code is notoriously difficult, but the snippet above is refreshingly straightforward. All we have to do is replace the instruction that reads the character index parameter with one that reads a static value:
0604ca92 e001
That will show us Tails for a moment, but if we move him, the game will still crash. The problem is the same one we saw in the earlier Saturn 3D Blast post: Sonic has multiple models and we need to prevent the game from using trying to use them.
Above: Sonic’s “running fast” model. It gives him a flatter forehead and elongated spines.
Like in Saturn 3D Blast, there’s a function that changes Sonic’s model depending on his current action. We’ll patch that function to always assign the standard Sonic model. Here’s the Ghidra decompilation:
The patch is:
0604a726 a020 0009
Now Tails can at least move around. There’s one more issue: like in Saturn 3D Blast, Sonic has a “spinball” model that’s used when his jump animation is active. We can prevent the game from using it with the same trick: instead of having the game check the real animation number, we’ll give it a dummy value. The patch is:
0604cada e0ff
Tails now works, but he moves just like Sonic. What if we could make him fly? The normal Tails that appears in Sonic World has a flying animation, so we can use that when he jumps. And we can change the jump height so that he actually gets some air when he flies.
The game can set the jumping animation in five different places. When you’re standing, walking, running, skidding, or riding with Tails, the 06
animation gets set if you press the jump button.
We’ll make it so that if Tails jumps while running, he flies instead of doing the usual spin flip. The flying animation is 1D
, so the patch is:
0604e410 e01d
Now he flies, but not very high. Let’s patch the running jump height too. In the Sonic Team Saturn games, the “down” direction is positive. So a jump makes a character’s position more negative. The patch is:
0604e44c ffe00000
In the video above, I also patch the other jumps to use animation 09
(a slow flip). The patches are:
0604e1e2 e009
0604e306 e009
0604e68c e009
0604e6fa e009
Update: this YouTuber pointed out that the balloons won’t break if you fly into them. We can fix this by patching the code that checks to see whether Sonic’s jumping - it’s looking for the 06
animation again:
0605be28 0009
Future work: In a forthcoming edition, we’ll use these same tricks to help us transplant the Knuckles model from Saturn 3D Blast into Sonic Jam.