swfans / swars

Syndicate Wars port, alternative binary for the classic Bullfrog game
Other
101 stars 14 forks source link

Gameplay speed #24

Open geist22 opened 2 years ago

geist22 commented 2 years ago

Let's talk about gameplay speed.

I think the speed at which the game runs during the missions is way too high, by about 30% or so. For reference, I remember playing in 1996 on a 90MHz Pentium, which is 15MHz more than the recommended specs, as well as on a crappy 500MHz laptop in 1999, and I don't remember any significant difference in speed between the two. I still remember more or less how fast the game played, just how long it took to reload LR Rifles, to destroy cars with miniguns and recover from depleted energy bars, etc.. It definitely was a lot slower, for example missing manual LR Rifle shots was never once an issue, though with "modern" speeds it happens to me all the time when enemies are not moving in a straight line.

Unfortunately, other people who played back in the day on original hardware are hard to find today. I've searched some old forums and the general consensus seems to be that DosBox with between 65'000 and 75'000 CPU cycles emulates the original gameplay speed relatively well. Though DosBox with those settings is practically unplayable, because massive slowdowns happen whenever buildings, explosions or lots of people are on the screen.

Nowadays people usually run DosBox with very high CPU cycles because they either don't know better or to combat the slowdowns that make slower speeds unplayable. The GOG version for example has its DosBox configured with 130'000 cycles as default, which runs way too fast but makes slowdowns mostly a non-issue.

The slowdowns that plague the game on DosBox do not happen in the port, so the gameplay could be slowed down to match how it played in 1996 on original hardware. If people do not find the slower speed desirable, making the speed adjustable with a setting could work. Syndicate Wars does in fact already have a feature like that, it's possible to manually decrease (but not increase) the speed with the + and - keys (on american keyboards? It's the two keys left of backspace). Though it doesn't work in the port.

mefistotelis commented 2 years ago

The game does everything in one thread:

  1. apply last user inputs
  2. update the world
  3. get user input
  4. wait until it's time for next frame
  5. draw the game on screen
  6. repeat

So, it is easy to measure game turns per second by just counting FPS - in both original game and in the port. If you can provide me with correct value of FPS, I can implement that. And make a parameter for people who will still consider it too fast, or too slow.

geist22 commented 2 years ago

Hm, I tried measuring in DosBox, but my fps are wildly fluctuating between around 20 and 50. I could try to test more later but it might not get much more accurate. And the program I'm using for measuring fps doesn't work in the port.

But wouldn't capping fps so low be a terrible idea? I already feel the cursor in the port is so choppy like it moves at 10 fps, almost painful to play like this. Planned to open an issue about that too later...

mefistotelis commented 2 years ago

Separating game turns from drawing frames is hard. It would require a lot of the code to be rewritten to C.

For mouse cursor - that's easier, as input could be gathered by a separate thread, and bflibrary already provides ability to move the cursor on the same frame. The original game receives interrupts from mouse events, so can update the cursor at any time - like we would have with separate thread.

Oh right - that also means you shouldn't touch the mouse to measure FPS correctly in the original.

geist22 commented 2 years ago

Indeed it was mainly the mouse which was responsible for fps fluctuating so badly, kicking it up to 70 which seems to be the cap in DosBox.

It's a bit hard to get a good value but I think 15-20 fps would be a good start. If there's an easy way to change it in the code, like just changing a number somewhere, I could compile a bunch of different versions for myself to test it further.

But if it means limiting fps to such low numbers I'd have to think twice about it. While I'd love to play with a more accurate gameplay speed, limiting fps like that is something I'm usually opposed of. Though SWARS certainly didn't run at high fps back in the day, fluid motions and responsive inputs should be minimum standards in this century. Might have to check how playable lower fps is and maybe put this on hold for the time being.

geist22 commented 2 years ago

Interestingly, the TODO file in /doc/, which dates back to 2015, mentions that the screen should be updated at ~22fps.

Is this a leftover from the old developers? And if so, how did they arrive at that number? A guess or did they know more?

mefistotelis commented 2 years ago

Sounds like empirical value.

The original game had FPS capped, but the algorithm seemed dodgy to me, making the limit quite high and assuming that rendering takes considerable time. And inside menu, there's no cap at all. I think the game requirements were so high that Bullfrog never hand to properly control FPS. When I played it on my 700MHz AMD Duron years after release, I had a feeling the speed it too high.

Dungeon Keeper had a better timing control, but the limit was also a bit too high.

I defined GAME_FPS within SW Port, but at the moment it isn't used everywhere. Actually it mostly controls minor things, like outro speed and level initialization screen. That will change over time.

mefistotelis commented 2 years ago

The frame rate is now controlled from a single value, but still hard-coded: https://github.com/mefistotelis/swars/commit/ce24d13158966529d161aaf7899d92c50b1f25be

To make it configurable, would be nice to have config files: https://github.com/mefistotelis/swars/issues/32