How to synchronize a game speed for both PAL and NTSC?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
How to synchronize a game speed for both PAL and NTSC?
by on (#224461)
I was thinking about how to synchronize a game speed for both PAL and NTSC systems. My first guess is a kind of "downclocking" the NTSC cpu by skipping 1 every 6 frames to emulate the PAL's 50Hz like this:

Code:
Pseudo code
-----------------
// game loop
while(true) {
   
   // nmiDone is a flag updated during NMI
   // frame is a counter from 0 to 60 updated during NMI
   if (not nmiDone or (system == NTSC and isMultipleOf6(frame) )) {
      continue;
   }

   //game logic
   ...
}

Am I on right direction or totally wrong?
Thanks in advance!
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224462)
Yes. neslib has a function for this. I think Streemerz uses it.

First you must do (at init) some counting between 2 frames to figure out which system you have (PAL takes longer).

I believe it's count 5 frames, skip the 6th. (Instead of counting to 6).
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224463)
You can find more information here and here.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224469)
As you have pointed out, now I see that an "overclocking" can also be emulated by bypassing the "wait for vblank" on every 5th frame of a PAL system.
Now it's all more clear. Thanks again!
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224476)
Quote:
"overclocking" can also be emulated by bypassing the "wait for vblank" on every 5th frame of a PAL system.


I didn't say that. What I was describing is slowing down NTSC to match PAL.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224477)
NOOPr wrote:
As you have pointed out, now I see that an "overclocking" can also be emulated by bypassing the "wait for vblank" on every 5th frame of a PAL system.
Now it's all more clear. Thanks again!

I do that for music, but music only takes like 1/20 of a frame normally so it doesn't have much of an impact.

If you're going to double a whole frame's worth of stuff, though, you need to have a game that is underusing the CPU enough that doubling that part of the workload still fits in a single frame... otherwise it will take too long, and that frame that you were trying to get a 2-for-1 in will end up lasting 2 frames anyway. (At the very least, skip building the sprites for the first of the 2 updates, that should cut out some of the workload.) If you end up hitting that slowdown it's worse than if you're just let the game run slower, because instead of seeing 2 frames, you'll see the same frame for 2 frames, and then everything will move twice as fast/far to reach the next frame. It does help a little that there are more CPU cycles per PAL frame, though overall per second it is a slightly slower CPU.

So... as a general technique this is not something i'd recommend. The practice of double-ticking your game engine is simple to write, but the part about managing CPU so that the extra update doesn't produce slowdown that negates is a lot more complex. Also for the user this makes an uneven frame of motion that they didn't get to respond to with new input, and for a smooth action game this will be felt.

For just music though it is a good technique. I do recommend it there. In most cases in PAL I'd probably think just running the game slower is the best compromise (but I definitely think there are situations where it'd be good to adjust the speed).
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224486)
When I was porting Driar down to NROM (from its original SGROM), I experimented with slowing down the game on 60Hz decks to run at the same 50Hz as the original. As suggested above, it did this by running the engine for 5 vblank, then doing nothing on the 6th vblank.

It looked terrible. It played terrible. The jerkiness was perceptible.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224488)
I did it in STREEMERZ out of necessity (the original game runs at 50 Hz, and running it at 60 Hz with the original physics etc constants was unacceptable). I don't think it's too bad in that one (never heard any complaints), but it's not perfect by any means. I'm actually much more bothered by the jerky music than the gameplay (but that could just be me).

In my next game (if that ever happens) I'll probably just target 60 Hz and accept that the PAL version will be slightly slower.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224509)
I skip every 6th frame for game logic in NTSC, but not for palette / scroll position update / splits. It doesn't look that bad.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224542)
I've used the skip every 6th frame. I think it looks OK. Best thing is obviously to have all calculations be done from 2 different set of constants that would result in the same behavior in both worlds. But that can become quite messy, take up room and/or be slower if not hard coding constants in calculations.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224567)
Nioreh wrote:
Best thing is obviously to have all calculations be done from 2 different set of constants that would result in the same behavior in both worlds.

I don't think that's possible with fixed-point math. Every time I try to think of a way to implement perfect PAL/NTSC support I give up in frustration.

I think that if you really need a game to run at the same speed in PAL and NTSC, skipping every 6th frame in NTSC is the only sane option. I would feel bad about sacrificing the smoothness of the NTSC version in favor of the PAL version though, so I wouldn't do it.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224572)
General question: is there a particular reason this has to be done within a single ROM/game, given that it cannot be implemented and timing and smoothness retained?

Rephrased: why not just have separate NTSC and PAL releases?
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224575)
Nioreh wrote:
Best thing is obviously to have all calculations be done from 2 different set of constants that would result in the same behavior in both worlds. But that can become quite messy, take up room and/or be slower if not hard coding constants in calculations.

I don't think this is ideal either. It's another compromise. It can solve the "different rate" problem, but introduces a new "different behaviour" problem.

The specific height and lengths of jumps will be different, and the arc passes through a different set of discrete points. A bullet moving farther per frame will do less collision tests against the things it is moving past. Etc. These are all behavioural changes that need to be tuned and tested, and IMO testing is the single biggest task in game development.

Every solution to this is a tradeoff between different kinds of problems. What's ideal depends on which problems affect your particular game the most, but for a lot of action games this is a rock and a hard place. For a menu driven RPG, on the other hand, all of these solutions might be "fine".

...though maybe worth reiterating: doubling every fifth frame to convert PAL to NTSC is a lot less of a problem than skipping every sixth frame to convert NTSC to PAL, at least for interactive things. There's a big difference between missing a whole frame of being able to hit that jump/attack button, and having 2 frames to do it. (However, I think both are an acceptable technique for music conversion.)
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224576)
koitsu wrote:
General question: is there a particular reason this has to be done within a single ROM/game, given that it cannot be implemented and timing and smoothness retained?

Rephrased: why not just have separate NTSC and PAL releases?

The only problem that solves is where to put and/or how to manage the data. It's mostly only helpful if ROM space is too limited to accomodate the changes you want to include. (There are code conveniences too, but I think they're a more minor issue than ROM space.)

All of the other problems of how to change the game remain, all of them with the same compromises. Changing stuff about how the game works means retesting the whole game, whether or not both versions are in the same ROM.

...and there's several advantages of their being only one ROM, I think especially for PAL region players where you might commonly have access to both kinds of machines in different situations.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224582)
koitsu wrote:
why not just have separate NTSC and PAL releases?

The problem is not supporting both in the same ROM, detecting the type of the console and using variables instead of constants is the easy part. The real problem is making something that updates 50 times per second and something that updates 60 times per second feel the same to a human being that's observing and interacting with those things.

The math is simple: if a character moves at 1 pixel per frame in NTSC, it'll move 60 pixels in a second - to make that character cover the same ground in the same time at 50Hz, it's gonna have to move 1.2 pixels per frame. The only problem is that 1.2 is not a value you can accurately represent as an 8.8 fixed point value. 1.2 * 256 = 307.2 which rounds down to 307, which represents 1.19921875, not 1.2. Doesn't sound like much of an error, but over time this error accumulates and causes the physics to behave differently. Even 1 or 2 pixels could make the difference between making a jump or not.

rainwarrior wrote:
doubling every fifth frame to convert PAL to NTSC is a lot less of a problem than skipping every sixth frame to convert NTSC to PAL

I think we have a terminology misunderstanding here: I thought that by "skipping every 6th frame" we meant not processing a frame (effectively repeating the 5th frame) for converting PAL to NTSC. "Skipping a visible frame" as in making everything move twice as much every 5th frame to make PAL catch up with NTSC would be way more problematic indeed.
Re: How to synchronize a game speed for both PAL and NTSC?
by on (#224589)
Hmm, yes, I think I might have interpreted OP's initial post in the opposite way it was meant.