gemrb / gemrb

GemRB is a portable open-source implementation of Bioware’s Infinity Engine.
https://gemrb.org
GNU General Public License v2.0
970 stars 181 forks source link

[feature] Customize AI Frame Rate #144

Closed cygarniczka closed 1 year ago

cygarniczka commented 5 years ago

BG, BG2, IWD, and IWD2 (not sure about PST) allows for advance option customization which one of them being is setting FPS. In all four games the ini setting responsible for AI Frame Rate is Maximum Frame Rate=30. 30 being default in all four games.

AI Frame allows for change in game dynamics. IMO the game best work when set between 38-43. Game feels a lot smother than hardlocked 30.

Description from the BGConfig.exe

AI Frame Rate controls the overall speed of the game. Baldur's Gate II is designed to run with an AI Frame Rate at 30. Increasing this option on a fast machine will increase the overall speed of the game. Reducing this option on a slow machine may increase playability by reducing frame-rate slowdown. WARNING: This option must be equal on all players' machines during a multiplayer game.

lynxlynxlynx commented 5 years ago

From another user's testing, I believe this also changes the display FPS (currently hardcoded to ~30 in the video driver). The ai frame rate is hardcoded as AI_UPDATE_TIME, which is definitely 15, so my guess would be it was set to half of that config value.

Maybe a script using SmallWait could be made for testing this in the original. One actor with a block that does SmallWait(1) DisplayMessage(...) repeated half the config value times, while another actor with just Wait(1) DisplayMessage(...), to signal a stop after 1 second. Both triggered at the same time, so first a hotkey needs to set a var ... it can get complicated fast.

burner1024 commented 4 years ago

The other user is probably me. I don't quite understand, what's needed to test?

There's actual frame rate - displayed fps, and there's Maximum Frame Rate, which is a cap on game fps, or "game speed". With CTRL-D, they are displayed: Captura de pantalla de 2020-02-13 01-49-13 Game speed is capped by MFR, MFR itself is hard capped at 90, displayed FPS is capped by both game speed and monitor FPS limit: Captura de pantalla de 2020-02-13 02-18-30 Captura de pantalla de 2020-02-13 02-21-08

I always run 60/90, and I'd probably even try 120 if that was possible. So I think this is a very important issue. In fact, it's a deal breaker, preventing me from even attempting a playtest. Bugs and glitches and crashes can be dealt with, but going back to original speed is not an option.

Anyway, from what I remember from the conversation, the issue is quite deeper than just hardcoded parameters. Presumably because the engine was only ever tested with one speed, playing with AI_UPDATE_TIME doesn't necessarily provide the desired result. Basically, both increasing and decreasing it make the game slower, only in the first case it's jumpy slow, and in the second it's smoothy slow. It might be an overall performance issue. (Granted, I'm running it on what could be considered a potato by today's standards, with integrated video. But classic engine works faster even over wine wrapper.)

lynxlynxlynx commented 4 years ago

AI speed can't fluctuate or it would make scripting unreliable, therefore MFR was surely only a cap for drawing.

We base everything on AI_UPDATE_TIME and the constants in the gametime tables: gemrb/unhardcoded/*/gametime.2da

SDLVideoDriver::SwapBuffers would need to be changed to take MFR into account (now 33). And of course AI_UPDATE_TIME, but some testing would not hurt first. The one test I suggested was to see if its value is indeed just half of MFR.

burner1024 commented 4 years ago

AI speed can't fluctuate or it would make scripting unreliable, therefore MFR was surely only a cap for drawing.

"AI Frame Rate" is just a bad description for it in BGconfig.exe. It's not limited to AI. It's the whole of game process. Drawing, casting, walking - everything. Going from 30 to 60 is literally doubling game speed. (The only exception I can think of is sound/movie playback, because that wouldn't look/sound good).

lynxlynxlynx commented 4 years ago

I don't have "AI Frame Rate" in my configured bg2 ini, though I'm not sure if you were implying it's a separate setting. Don't worry about the name though, of course it's not just about some iescripts.

burner1024 commented 4 years ago

I don't have "AI Frame Rate" in my configured bg2 ini, though I'm not sure if you were implying it's a separate setting.

I was referring to this (MFR):

Description from the BGConfig.exe

AI Frame Rate controls the overall speed of the game. Baldur's Gate II is designed to run with an AI Frame Rate at 30. Increasing this option on a fast machine will increase the overall speed of the game...

But if

Don't worry about the name though, of course it's not just about some iescripts.

then sorry, I don't understand what do you mean by

AI speed can't fluctuate or it would make scripting unreliable, therefore MFR was surely only a cap for drawing.

Could you clarify? (I don't think I said or implied that AI speed fluctuates. At least not in a way that could possibly affect scripting.)

lynxlynxlynx commented 4 years ago

Ok. So the exe and config only set MFR, right? And it defaults to 30, while AI_UPDATE_TIME is/defaults to 15. So it's natural to think that AI_UPDATE_TIME is not a constant, but MFR/2. On the other hand, the drawing fps can't be ensured to be constant, hence even the name of the variable has "maximum" in it.

burner1024 commented 4 years ago

Ok. So the exe and config only set MFR, right? And it defaults to 30, while AI_UPDATE_TIME is/defaults to 15. So it's natural to think that AI_UPDATE_TIME is not a constant, but MFR/2. On the other hand, the drawing fps can't be ensured to be constant, hence even the name of the variable has "maximum" in it.

I agree with everything you said, but I don't see how that can affect scripts.

What I'm saying is:

  1. AI_UPDATE_TIME (or its equivalent in original) is constant, but in frames, not in seconds of real time. And given the 15/30 default relationship, I'm reasonably sure there's a tick every second frame.
  2. Everything in game is tied to the actual frame rate. Increasing MFR to 60 is basically stuffing 2 seconds of game time into 1 second of real time. The same 60 frames are calculated and displayed, simply twice as fast.
  3. That is assuming your graphics card handles 60 fps, of course. If it doesn't, frame rate drops and everything in game slows down. Including scripts, animations, etc. There's no way for a game object to even detect if it's being slowed down "in real time", because there's nothing to compare to. So this can't possibly affect scripts.

If it helps, I could record samples from vanilla on max (60/90) vs GemRB compiled with AI_UPDATE_TIME 45 and no fps limit. The difference is quite obvious.

lynxlynxlynx commented 4 years ago

That's a good question, are the two synchronized and it had Roman timekeeping with time dilation. Not sure it matters in the end. This is something that could be tested the same smallwait/wait way in the original, together with something that would consistently degrade performance.

burner1024 commented 4 years ago

There's no question in my mind, but I'll test and report.

bradallred commented 4 years ago

assuming your graphics card handles 60 fps

No drawing in the master branch is hardware accelerated. Everything is rendered via software algorithms. Subviews branch with SDL2 is required for any hardware acceleration.

The video driver on the Subviews branch no longer has a hardcoded fps cap because videos are not always 30 fps so that is the first step done.

burner1024 commented 4 years ago

So here are some test results. Hotkey() didn't work for me for some reason, so I just set the var on game load. Dlgbg2* are logged with Tobex Log Dialogue Bar=1

As far as I can see, everything's pretty consistent on BG2: 15 smallwaits per 1 wait, with any MFR and/or actual frame rate. GemRB's log looks stranger to me, Jan's lines are doubled, but maybe I don't understand something about it. (And about missing actual DisplayMessages).

TP2 attached: gemrb_time_test.tp2.zip

Samples:

lynxlynxlynx commented 4 years ago

Crap, all the logs say 15/s. So it's indeed the length of a second that is changing. Thanks for the detailed data.

bradallred commented 4 years ago

@burner1024 regarding the python errors: you are using the wrong guiscripts. You can't use the scripts from master on another branch.

burner1024 commented 4 years ago

Crap, all the logs say 15/s. So it's indeed the length of a second that is changing. Thanks for the detailed data.

Coming to think about it, it's not that surprising. If game speed wouldn't be tied to actual frame rate, it would basically be client-server architecture, with "actual state" and "displayed state", like in online games. And online games have lag. And why have it, when you can just as well not have it, and save some CPU cycles on top.

@burner1024 regarding the python errors: you are using the wrong guiscripts. You can't use the scripts from master on another branch.

I just did make clean, switched branch to subviews and built it again. I assumed the files would be overwritten. Now I tried again, wiping the install dir beforehand. The result is that it's segfaults on launch.

I'm still not clear about the various oddities mentioned. Could you clarify? Should I open an issue about each one:

  1. DisplayString from the attached tp2 not being actually displayed.
  2. Strange string display order in GemRB log:
    [GameScript]: Displaying string on: keldorn
    [GameScript]: Displaying string on: keldorn
    [GameScript]: Displaying string on: jan
    [GameScript]: Displaying string on: keldorn
    [GameScript]: Displaying string on: jan
    [GameScript]: Displaying string on: keldorn
    [GameScript]: Displaying string on: keldorn
  3. Subviews not building without -DDISABLE_WERROR=1
  4. Segfault when launching subviews branch.
cygarniczka commented 4 years ago

Crap, all the logs say 15/s. So it's indeed the length of a second that is changing. Thanks for the detailed data.

This could actually be related to: https://github.com/gemrb/gemrb/issues/426#issuecomment-578428868

BGGRAPHICS

Spams you annoyingly with day/night move clip. BGGRAPHICS seriously messes up time. You would need someone who has that mod installed because this issue needs to be break down on its own. Too many factors just to generalize what the root of the problem could be. Kelsey and Viconia issue should be linked to BGGRAPHIC

S because I had them respawn in Government District after day/night movie clip played.

bradallred commented 4 years ago

@burner1024 I'm not sure about the segfaulting or building without DDISABLE_WERROR=1. Would you mind opening a couple of issues for them?

lynxlynxlynx commented 4 years ago

The compile thing is just a gcc issue, since only newer ones support the required flag. So you'll have to "suffer" without -Werror until an update.

burner1024 commented 4 years ago

Separate issues created, the crash turned out to be tied to a particular savegame, not subviews branch.