-
Notifications
You must be signed in to change notification settings - Fork 140
fix(input): Fix double-click fast drive timing in ParticleUplinkCannon #2012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix(input): Fix double-click fast drive timing in ParticleUplinkCannon #2012
Conversation
bedd3a9 to
4718d05
Compare
|
I could do a bit of testing and review for this For both 30hz and 60hz :
Does that seem right? |
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Show resolved
Hide resolved
4718d05 to
fdb318e
Compare
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Show resolved
Hide resolved
fdb318e to
d3e0024
Compare
|
Replicated to Generals in the most recent commit, which differs slightly and is worth giving a quick look |
8e53756 to
c01dbb2
Compare
|
Tested this by making a savegame of a skirmish at max gamespeed, then loaded it back at regular gamespeed. Trajectory of the beam and beam duration appeared the same also using fast drive Using the compatibility flags I loaded a retail gamesave, and also saved a game and loaded that in retail. That works fine I thought it would be interesting to test 30hz and 60hz with the same gamespeed the way GO does it, stephanmeesters@7491c32 Double click felt the same, trajectory and duration the same It did have problems with the replay as the beam duration was no longer the same, but the gametime was also reported wrong, so that's probably just because I hacked that GO code in |
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested and works. Looks good to me.
Edit: tested only in skirmish.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this fix is unsafe.
The safe fix likely is to scale m_doubleClickToFastDriveDelay with LOGICFRAMES_PER_SECOND/BaseFps (and other scales, see FramePacer).
| #if RETAIL_COMPATIBLE_XFER_SAVE | ||
| const XferVersion currentVersion = 2; | ||
| #if RETAIL_COMPATIBLE_CRC || RETAIL_COMPATIBLE_XFER_SAVE | ||
| const XferVersion currentVersion = 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be 2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Generals retail compat version is now 2
Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp
Outdated
Show resolved
Hide resolved
| const Bool useFasterSpeed = m_scriptedWaypointMode || (m_lastDrivingClickFrame - m_2ndLastDrivingClickFrame < data->m_doubleClickToFastDriveDelay); | ||
| #else | ||
| DEBUG_ASSERTCRASH(m_lastDrivingClickTimeMsec >= m_2ndLastDrivingClickTimeMsec, ("m_lastDrivingClickTimeMsec should always be >= m_2ndLastDrivingClickTimeMsec")); | ||
| const Bool useFasterSpeed = m_scriptedWaypointMode || (m_lastDrivingClickTimeMsec - m_2ndLastDrivingClickTimeMsec < data->m_doubleClickToFastDriveDelay); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not test this but just reading the code I expect that this can and will cause mismatch in Multiplayer. Mismatch probably will not happen always, but there is no guarantee that the delta between 2 timeGetTime calls on 2 different machines will always have the same delta between them, because timeGetTime is low-resolution and time itself is relative in the Network.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The timeGetTime values are no longer xfer'd. The double-click detection only affects the local player's beam speed selection and doesn't impact game state synchronization, right? Each player's clicks are processed locally before being sent as network commands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please test with 2 clients in Network match. The clicks are used to determine logic state. If these do not match exactly, then clients will use different laser beam speeds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I ended up going with frames and scaling the comparison in frame count so it behaves the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would work for GO 60 hz, but not for increased logic timescale, right? Maybe getActualLogicTimeScaleOverFpsRatio can help with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm - this comment says "void setLogicTimeScaleFps( Int fps ); ///< Set the logic time scale fps and therefore scale the simulation time. Is capped by the max render fps and does not apply to network matches." and yeah we check
if (TheNetwork != NULL)
{
return TheNetwork->getFrameRate();
so multiplayer should be just using whatever this is.
Are you talking about playing single player games and manually changing the logic fps? Are you asking about getActualLogicTimeScaleOverFpsRatio vs getActualLogicTimeScaleRatio?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you test the current code in skirmish mode with high logic time scale? Like is there still a 500 msec window to double click at a logic timescale of 4?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally this would also correct scale with logic time scale. For example set logic fps to 90 in skirmish, simulation will be 3 times as fast, and so double click duration needs to be trippled too I think (you can test it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I think I've got it right now, and it should work when we speed up logic in skirmish too. I can test soon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, but this caused CI replay mismatches :(
871e244 to
99e68e1
Compare
| const UnsignedInt scaledDelay = data->m_doubleClickToFastDriveDelay * LOGICFRAMES_PER_SECOND / BaseFps; | ||
| // TheSuperHackers @fix Scale delay threshold by frame rate and logic time scale to maintain consistent real-time feel | ||
| UnsignedInt scaledDelay = data->m_doubleClickToFastDriveDelay * LOGICFRAMES_PER_SECOND / BaseFps; | ||
| if (TheFramePacer != NULL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is not expected NULL
| if (TheFramePacer != NULL) | ||
| { | ||
| const Real timeScaleRatio = TheFramePacer->getActualLogicTimeScaleRatio(); | ||
| scaledDelay = (UnsignedInt)(scaledDelay * timeScaleRatio); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why this causes mismatch. Perhaps check value in headless replay. It is expected 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we must not scale it this way. It would mean we cannot use time scale to fast forward replays. Perhaps we must accept that double click will be jank then, or have an alternative code path that only works in Single Player and not in Multiplayer & Replay Playback, but this would increase complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking for single player / skirmish is trivial, right? I think I'd rather have that than a poorly working double click.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or how about we make it a proper game message instead of this frame trickery? Won't be Retail compatible, but much cleaner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add a new game message eg MSG_DO_SPECIAL_POWER_OVERRIDE_DESTINATION_FAST
or we could add an argument to the existing one MSG_DO_SPECIAL_POWER_OVERRIDE_DESTINATION
// In CommandXlat:
gameMsg->appendLocationArgument(*pos);
gameMsg->appendIntegerArgument(SPECIAL_INVALID);
gameMsg->appendObjectIDArgument(INVALID_ID);
#if !RETAIL_COMPATIBLE_CRC
gameMsg->appendBoolArgument(useFastDrive); // NEW
#endif
I'll run with this - but it does mean we can't use this feature until we break retail compat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is ok to fix for later. We do not need all fixes for VC6.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, happy to close this if you like. I also took a stab at using MSG_DO_SPECIAL_POWER_OVERRIDE_DESTINATION
…l-time milliseconds
…non retail builds
…ing, add debug assertions
…UplinkCannon xfer version
…or non-retail builds
…nstead of timeGetTime
…r fast-forward support
43b4d61 to
31559b2
Compare
…t beam mode behind RETAIL_COMPATIBLE_CRC
31559b2 to
6ea27b9
Compare
Closes #2011
Testing (TODO)
Fast drive mode activation via double-click now works consistently at any frame rate and logic time scale setting.