XaiJu
vitorvilela
vitorvilela

patreon


Race Drivin: the road for making games run smoother without making it too fast

When I initially analyzed Race Drivin, I said on Twitter that it was impossible to convert the game to SA-1, because the game would simply skip frames and make them so fast that it would be unplayable.

However, after hearing the game had different ports and each one ran at different frame rates (the original Arcade version is super cool, by the way!) and given that the game runs on average at 4.77 FPS, I wanted to it a second try. In case the game is actually 3D (and it is!) and I managed to improve the frame rate without making it faster, I could potentially do the same with more games (such as Another World and Star Fox). The advantage on Race Drivin is that it's written in 65c816 (the SNES/SA-1 CPU architecture), which is the one I'm the most used of.

As you can see on the chart, the frame rate varies between 2.40 FPS (worst case) and 12.00 FPS (best case and the maximum that the engine allows for). For making the chart less noisy, the line in the above chart is actually the moving average frame rate of the previous 5 measurements.

Adding FastROM didn't help much: initially a shy improvement of 1.35%. Why? Because of the game engine. Although it introduces a double buffering system at both CPU side and PPU side, the game won't render a new frame until the backbuffer is completely copied to the VRAM (this kind of beats the double buffering idea). In addition, even if the game logic/rendering itself takes over 8 frames to finish, the game makes sure that it passes another complete frame until it start doing the next frame. This makes no sense and just proves that the game has a lot of bottlenecks. The calculations are also slow: most of the calculations are complex, making it mandatory to chain multiple multiplication/division operations in sequence and most are done completely in software.

An interesting thing is that even if the game sometimes plays at 2 FPS, the counters (the counter down, score and time spend) and the joypad polling are still at 60 FPS. The game does this trick is firing an IRQ (an interrupt request, which makes the SNES CPU stop the currently executing code and starts executing another one). The IRQ is triggered at the middle of the frame and tells to the game do everything timing and joypad related, so even if the game lags a lot, you still have the clear the track in 1 minute.

The good news is after adding SA-1 and implementing my most recent architecture improvements from SA-1 Root for Super R-Type (the SA-1 CPU running as the master and doing asynchronous calls to the SNES CPU, you can read more about it here) the game runs at the maximum speed (12 FPS) and without lag. However, the bottlenecks are still present and the game is now running too much fast.

Technically, the SA-1 installation is done and I could even release the game as it is. But playing it too fast and at 12 FPS is not enough for me. We need to make it run smoother without being it so fast. The quality matters more for me than just the speed boost. We need to get rid of the bottlenecks to make the frame rate increase and adjust the engine to make it not run so fast.

I found an amusing way to measure bottlenecks: take a full trace (without trace masking) of some frames and count which SNES PC addresses range are the most frequent. If you have some experience with UNIX commands, it's an easy job. That's how I figured that $00B4XX (wait until the frame buffer is transferred) and $00F3XX (wait until the next frame runs). The other most frequent ones are related to rendering objects and scenery.

Removing the bottlenecks and adjusting the frame buffer to send frames at the maximum speed possible (30 FPS given the 2.68 MB/s SNES bandwidth limit), the game plays so fast that it's unstable: the scene starts flickering, the timers start blinking and the game controls get way too sensitive. The work is now adjusting the game until it gets stable at 30 FPS and adjust the game internal timers in a way that the it will generate more intermediate frames.

There are a few possible approaches I found while doing a few tests, such as:

Each one gave me trouble already: the game internal positions and counters has no decimal places: they are integers. This means that, for example, the X/Y/Z position of the car can only increase or decrease by 1 and not by 0.1 or 0.01, for example.

Another problem is the gravity and rotation speed: they are separate from the position calculations and reducing the car speed or adding more decimal places will still make them run as normal. We will have to add decimal places to them as well and analyze each game routine until we make all of them synchronized and ensure the gameplay is similar as possible to the original (using Arcade as quality reference).

Which is where we get to another problem: the 3D engine coded for the SNES is very limited. Apparently, slowering the game down is enough to the camera get inside some objects in some frames and generate flickering (with one frame being inside the object and other frame outside the object). With that issue, we will either have to revise how rendering is done or change the relative camera position to the car.

Ensuring the game behavior won't dramatically change and ensuring the gameplay won't get broken (as broken as it is already) is definitely the challenge I'm facing with Race Drivin. I even got questioned if it's worth doing that effort to the game and I can definitely say that it is. Getting a solution for this game means that other games with similar problems can be solved with the same approaches and I won't have the additional difficulty of using another enhancement chip like Super FX or cartridge architecture which I'm still studying and certainly I have a lot to learn yet.

Once again, my goal is modifying games that originally suffered with slowdown or low frame rate the quality they deserved. As far broken the game might be, IT IS possible to make it have a better gameplay than the expected.

Like my work? Please consider supporting me! Everything I do are pretty time-consuming tasks and most of my fixes are done by trial and error, since I have to disassemble everything by hand and later figure out how the game engine works from scratch.

Race Drivin: the road for making games run smoother without making it too fast

Comments

In the Super Stunt Track, you have to keep pressing left continuously to avoid falling from the platform. As for the autocross track, it's weird the crash, never the stage failing.

Vitor

https://youtu.be/HbP1cyVTQxs 👍🏽

Ethan Tabor

This is rad!

Andyways


More Creators