Download

Input is less responsive at low framerates.

Hi all. I posted this question on the AnswerHub but it went completely unadverted, which makes me fear this has no easy solution + nobody else cares about it.

I’m developing a fighting game and having some trouble with consistency of input speed at different framerates. Since I don’t care about analog readings, I started configuring the D-Pad and left thumbstick to pressed and released action events, then write to a dpad state variable and buffer them as fast as I can. At 60fps+, I spun the thumbstick as fast as I could and I got everything buffered just right, but as I capped the framerate lower and lower, I started losing inputs/getting wrong data since the pressed/released events fired in the wrong order and messed with my D-Pad state variable.

So what I did next was to setup the directional input to axis again and set a looping timer every 15ms or so, to periodically check the axis values with:


InputComponent->GetAxisValue();

which worked better, but still is less responsive at low FPS. As I noticed that the timer was not firing as it should when the frametime goes below the timer’s period, I moved the axis readings to a loop on a separate thread and the problem persisted, which indicates that the engine’s input refreshing is apparently tied to framerate.

Since this is a fighting game, I need the input polling rate to be consistent, since locking the framerate is not an option nowadays. Is there something we can do to sort this out?

Thanks in advance.

I think as you state it, the fighting game need consistent and minimum FPS so the thing is, rather than the game adapt to varying spec of computer (which can be very low), the game has to demand minimum computer spec from the users. So maybe you need to find the lowest FPS that your game can work with eg 20fps, and stick to it! In order to have more lower end computer to enjoy the game, you have to optimize the game nonetheless.

Edit: Other than that, you may need to be able to download UE4 code and do your own customization there eg check the input event more frequently or try to ensure the input event come exactly in the order it was received (currently may not be so - I am not sure)

Thanks for your response.
Well, I’m definitely willing to set a minimum target framerate for our game to work well as a requirement, but my problem here is that anything below 15ms (60fps) seems to be consistent enough for fast input. I thought on giving up on this and start working on some sort of “deductive” layer that fills in gaps in the input buffer, for instance in a hadouken-like move performed very fast, adding a DownLeft diagonal entry between a Down and Left that are too close together in time, because we know the player meant to do this even though the game wasn’t able to track it properly. But this, to me, should be the last resource.

I’m not completely sure what is happening but yeah, my guess is that they are firing in the wrong order. What I’m doing is using the pressed and released events to turn on and off the 4 LSBs of an integer which I then cast to an enum declared in this fashion:


enum class Dir{
None = 0U,
Up = 1U,
Down = 2U,
Left = 4U,
Right = 8U,
UpRight = 9U,
UpLeft = 5U,
DownRight = 10U,
DownLeft = 6U;
}

With this setup, I see invalid entries in my input buffer when I spin the thumbstick too fast for the game to keep up with, which makes me think the events are not firing in the correct order, but of course there’s always the possibility of being wrong (which is what I hope someone will point out here lol).

Quoting myself to say that, after doing some tests, I can confirm that at low framerates, the input events are firing in the wrong order. The test I did was printing numbers to the Pressed and Released events of the d-pad according to the order they should fire when spinning the stick. At 60fps they printed right “1 2 3 4 5 6 7 8” but at 30 fps, they printed something like “1 3 2 5 4 6 7 8”.
I took a look at APlayerController code and while processing the input stack, it’s stated that the delegates bound to input actions are dispatched in the same order as the input stack, so it seems like the problem comes from deeper…
I’m sorry for the insistence - I’ve always tried my best to solve my problems without relying too much on the community, but I’m lost here and really need advice.