-
Notifications
You must be signed in to change notification settings - Fork 26
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
feat: Support custom input prediction (WIP) #83
base: main
Are you sure you want to change the base?
Conversation
Introduces a new associated type parameter for Config that controls the input prediction approach used. See extensive documentation on InputPredictor and its implementations.
/// [RepeatLastInputPredictor] is a good default. | ||
/// | ||
/// See documentation for [InputPredictor] for more information. | ||
type InputPredictor: InputPredictor<Self::Input>; |
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.
Note to self: I also need to update the Sync+Send variant of the Config struct to include this param.
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.
Cool that you're working on this. I think it could add some nice flexibility while still leaving simple usage simple :)
Don't have time to actually review this, so just commenting on the API, and showing my appreciation :D
EDIT: also, I see you addressed some of this in the pr body. Sorry I didn't read it properly.
/// it is typically good to return `None`, `Some(I::default())`, or a Some with a value of `I` | ||
/// that means "this player sent no input" for your game. | ||
/// | ||
fn predict(previous: Option<I>) -> Option<I>; |
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.
What's the benefit of having this return an Option
? Couldn't you just choose a ZeroedInputPredictor
instead? or zero the input yourself if a previous input is not available?
Also is only the previous input enough? Maybe you'd want to estimate the velocity of change for an input and extrapolate?
Maybe take a slice of I
if possible?
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.
What's the benefit of having this return an Option?
Yep, see point C
in PR body (as per your edit to your parent comment); in hindsight I agree it's silly and would be better to not allow returning Option
.
Also is only the previous input enough?
Partially discussed this too under point D
in PR body; exposing more information is possible but I don't personally have a use case for it (and seems like nobody else has requested it?), so I'm wary of making the API unnecessarily complicated (or not useful) to support that - or worse, introducing a subtle bug, as the code in InputQueue::input()
is already a bit fiddly.
take a slice of
I
if possible
Conceptually that'd be reasonable, but the inputs are stored in a Vec-based ring buffer so we'd have to pass 2 slices or do a bit of copying to achieve that. A good example of how the implementation/API would get complicated by supporting such more advanced input predictors!
A less invasive (for ggrs) way to do it might be to pass the frame number for both the current prediction request and the last confirmed prediction over to the input predictor, plus the player handle; then the input predictor can store as much of that as it wants in some separate data store. I had partially implemented that at one point before I backed it out - totally doable but some more data needs to be passed to InputQueue::input() to make it happen - if anyone ever actually requests it, of course!
converted to draft as you stated (WIP) in the title. |
Sure, makes sense to have this be a draft PR. But if I do spend the time to clean this up by addressing the points I suggested in the ways that I suggested, are you willing to merge it? (subject to further feedback from review then of course) I don't want to spend some time polishing this if you're not happy with the approach I'm taking :) |
In that case, please wait a little while until I find time to look at it properly. In general, I like the idea a lot, seems like a useful option for special cases. |
Introduces a new associated type parameter for Config that controls the input prediction approach used.
See extensive documentation on InputPredictor and its implementations.
This addresses #69 (cc @johanhelsing, @aleksa2808) and accidentally also addresses #74 (cc @MaxCWhitehead ).
Some off the cuff design decisions I made when I hacked this together (before I got carried away writing documentation):
zeroed()
does not equate to "no input", like @MaxCWhitehead over in Default predicted input on first frame (zeroed Input) assumes zeroed is equivalent to no movement #74.None
, in which case we just fall back to usingzeroed()
. This makes it a tiny bit more convenient to implement a prediction function if you are okay with usingzeroed()
as your default in the case where there is no prior input to base your prediction on, but it's super minor. Might be better to just require a prediction to be made.I am not strongly opinionated about any of those, so please let me know what your preferences are and I will adjust the code to suit. If you are also not strongly opinionated, I recommend:
But I haven't made those changes yet because they'd be wasted if you don't want to merge something along the lines of this PR! And also I've already spent a few hours on this today so I need to get back to actually implementing rollback in my game ;)