SFML community forums

General => Feature requests => Topic started by: Mr. Wonko on September 18, 2010, 05:04:43 pm

Title: timestamps for events
Post by: Mr. Wonko on September 18, 2010, 05:04:43 pm
Hi,

for precise input handling it'd be nice to know when an event occured. How about adding this information to the Event class? At least optionally, with an #ifdef?

Mr. Wonko
Title: timestamps for events
Post by: Nexus on September 18, 2010, 05:53:23 pm
What exactly do you need the timestamp for?
Title: timestamps for events
Post by: Mr. Wonko on September 18, 2010, 06:01:53 pm
Example: If the forward key is pressed and released in the same frame, the player character should still be moved a little.
The Quake 3 Engine does this, I just saw it and wondered if something similar was possible with SFML.
Title: timestamps for events
Post by: Xorlium on September 18, 2010, 06:40:53 pm
Hmm... at what fps does your game run at??
Title: timestamps for events
Post by: Mr. Wonko on September 18, 2010, 06:56:58 pm
I have no running game yet. Usually you think about such things before the game is done anyway.

Eventually I'm planning to have a game/engine with all the nice features of modern games, programming-wise. That's isn't easy and it might take long to get there, or I may never achieve it at all.

Therefore I'll start with something simple (currently I'm building a Space Invaders kind of game), but the projects will be increasingly more complex while reusing code. Thus I'd like my code to be as reusable/flexible/robust as possible, which includes such things as still working at low framerates.
Title: timestamps for events
Post by: Nexus on September 18, 2010, 07:33:08 pm
Quote from: "Mr. Wonko"
Example: If the forward key is pressed and released in the same frame, the player character should still be moved a little.
Okay, I see. So you'd like to subtract the times and find out how far the character is moved.

I think, it's quite unlikely that the user presses the key for such a short time. If your game runs at 30 FPS (you can't go far below if you want fluent graphics), the key must stay pressed for less than 3.3 centiseconds. I can however imagine a separate input thread working at a lower framerate.

But only Laurent knows if this feature is relevant and useful enough to be integrated into SFML... ;)
Title: timestamps for events
Post by: Mr. Wonko on September 18, 2010, 09:22:05 pm
I just realized that another use of this is for axis input:

Imagine someone moves an analog stick (left = -1, right = 1) from left to right within one frame. 90% of the frame are spent left, 5% on the way to the right, 5% right. If you only look at the current position you'll get a value of 1, but if you take into account all the places and the time spent there you get -1*0.9+1*0.05 = -0.85.

This could be important at lower framerates, I don't know... I'd like to take it into account anyway.
Title: timestamps for events
Post by: Laurent on September 18, 2010, 11:06:52 pm
This is not a feature, this is a solution to a problem. And I don't like solving problems before they actually exist for real ;)
Title: timestamps for events
Post by: Mr. Wonko on September 18, 2010, 11:15:25 pm
Quote from: "Laurent"
This is not a feature, this is a solution to a problem. And I don't like solving problems before they actually exist for real ;)

So you're saying a problem shouldn't be avoided until it's encountered? Isn't it a little too late by then?

But thanks, you just made input handling so much easier for me :)

I'll tell you if the problem starts existing for real one day.
Title: timestamps for events
Post by: Laurent on September 18, 2010, 11:19:47 pm
Quote
So you're saying a problem shouldn't be avoided until it's encountered?

I say that a solution shouldn't be found to a non-existing problem. I agree that what you describe may be a problem, but I'm not sure it will.
Title: timestamps for events
Post by: Xorlium on September 19, 2010, 12:40:56 am
It may only be a problem if you can move your finger and press and release a key faster than in 1/30th of a second (and that's a pretty low frame rate. Usually framerate will be about 500 fps). I don't think that's physically possible.
Title: timestamps for events
Post by: Spodi on September 19, 2010, 01:32:30 am
I don't see this being much of a SFML issue, rather an issue with your design. If you want input to be handled faster than your frame rate, run the input in a separate thread.

If you have a game without thread-safe input handling, grab it in a separate thread, add your own time stamp, lock a shared queue, enqueue the event(s), then let the main thread dequeue and handle.

Throwing in a timestamp for every event would just be a lot of overhead for the vast majority of users who won't need it.
Title: timestamps for events
Post by: Xorlium on September 19, 2010, 02:35:17 am
Why is everyone suggesting weird alternatives to an utterly non-existent problem? Try pressing a key/moving a joystick 30 times in one second. Can you do it? No? I rest my case.
Title: timestamps for events
Post by: Spodi on September 19, 2010, 03:24:36 am
Quote from: "Xorlium"
Try pressing a key/moving a joystick 30 times in one second. Can you do it? No? I rest my case.


Not really a relevant point, though. For games with either very high keypress rates (RTSes) or twitch-based games (FPSes), high resolution input is important. If you grab input once a frame, your input response rate is only that of your game loop. Normally, about 60 times a second (assuming vsync or fixed/capped update rates), but for slower machines, its lower. So its not "pressing a key 30 times a second", its pressing a key and releasing in fractions of a second, and that is completely possible, especially when the times the input took place align poorly with the current step in the game loop.

For most people and in most cases, no, it won't be noticeable. But not noticing doesn't mean it doesn't make a difference. Taking into consideration small aspects like these can, and do, contribute quite a lot of the playability of a game.

So yes, it is a completely valid point, but not one that should be added to SFML since most won't utilize it (making use of "fractional input" requires special design considerations) and most also won't need such high input resolution.
Title: timestamps for events
Post by: Mr. Wonko on September 19, 2010, 09:33:03 am
Quote from: "Spodi"
Throwing in a timestamp for every event would just be a lot of overhead for the vast majority of users who won't need it.

Which is why I suggested making it optional using an #ifdef.

Quote from: "Xorlium"
(and that's a pretty low frame rate. Usually framerate will be about 500 fps)

I don't know what kind of supercomputer you have, but in most games my fps aren't even close to 500. A couple of sprites, sure. But a more complex 3D game? (Which is what I'm ultimately aiming for, like I said.) Nope.

Quote from: "Spodi"
For games with either very high keypress rates (RTSes) or twitch-based games (FPSes), high resolution input is important.

This.

Quote from: "Spodi"
If you have a game without thread-safe input handling, grab it in a separate thread, add your own time stamp, lock a shared queue, enqueue the event(s), then let the main thread dequeue and handle.

That would be a possible workaround, thanks.

Quote from: "Spodi"
So yes, it is a completely valid point, but not one that should be added to SFML since most won't utilize it (making use of "fractional input" requires special design considerations) and most also won't need such high input resolution.

I can understand that. Well, there's nothing keeping me from adding it to SFML myself, right?


Unfortunately this is something that has to be designed from the very beginning, but won't be noticed until the very end... I'm only thinking theoretically here, since it'll be another couple of months/years before I'll have a game where this might make a difference. (I'm planning to keep the Input Handling though, which is why I'm thinking about it now.)


Anyway it's good to discuss stuff before adding it, thanks for all the thoughts so far.


Mr. Wonko
Title: timestamps for events
Post by: Nexus on September 19, 2010, 03:05:45 pm
Quote from: "Mr. Wonko"
I can understand that. Well, there's nothing keeping me from adding it to SFML myself, right?
No, as long as you respect the license. :)

Although you risk incompatibilities with newer SFML versions or other user's code. If you find a way to handle it non-intrusively, you should probably prefer that.
Title: timestamps for events
Post by: Mr. Wonko on September 19, 2010, 07:11:13 pm
Quote from: "Nexus"
If you find a way to handle it non-intrusively, you should probably prefer that.

I thought I had found one.

I thought I could inherit from (Render)Window and overwrite the OnEvent() method.

The problem is: Events are not received (and subsequently sent to the EventListeners, like the (Render)Window) in realtime (via callback). Events are received on request (via WindowImpl::ProcessEvents(), called by Window::GetEvent()).

So I'm not going to do this. We'll see whether I regret this decision in a couple of years.
Title: timestamps for events
Post by: Spodi on September 19, 2010, 08:13:17 pm
Quote from: "Nexus"

Although you risk incompatibilities with newer SFML versions or other user's code. If you find a way to handle it non-intrusively, you should probably prefer that.


I was just coming here to say that same thing. ;) That is why I proposed a workaround that doesn't change SFML itself. Its best to, whenever possible, avoid altering external code. Otherwise, it just becomes harder to update the external code since now it is cluttered with your own code. If you really must alter external code, though, the I recommend at least heavily commenting it so you know where your changes took place and why. I usually use a comment with a unique tag, such as:

Code: [Select]

// !!CHANGE: <reason>


Quote from: "Nexus"
The problem is: Events are not received (and subsequently sent to the EventListeners, like the (Render)Window) in realtime (via callback). Events are received on request (via WindowImpl::ProcessEvents(), called by Window::GetEvent()).


And that is why you'd want to grab them using an external thread - so you call it as frequently as you want.