• Advertisement
Sign in to follow this  

Unity Concept for an input library - thoughts?

This topic is 1056 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm thinking of building a small input library which would streamline the way input events are managed and make it a lot easier to observe complex input event combinations. The library would be designed to be plugged into whatever input source is desired, i.e. if you're using GLFW, or RawInput on Windows, or whatever, you would just point any events fired at this library and it would take care of the rest.

Conceptually, usage of the library would look like this:
 
// fires on ctrl+A, followed by ctrl+B, then ctrl+C, with a maximum of 1000ms between keypresses
auto observer = input::observe("ctrl+a,ctrl+b,ctrl+c", 0, 1000);

// fires when the mouse is moved
auto observer = input::observe("mouse:move");

// fires when the left mouse button is clicked
auto observer = input::observe("mouse:lclick");

// fires when the right mouse button is clicked while shift is down, followed by the space bar being pressed
auto observer = input::observe("shift+mouse:rclick,space");

// fires when the A key is pressed followed by a specific delay of between 500-2000ms, followed by B, then C
auto observer = input::observe("a,delay(500,2000),b,c");

observer.then([&](state) {
    // respond to input state here (the state object can be queried for any arbitrary keyboard/mouse/etc. state)
});

I haven't actually started writing any code yet, as I wanted to (a) see if anyone else has already written (and open-sourced) something similar, and (b) get some feedback on the idea. I'd be happy to open source this if others feel it might be useful to them.

Edit
Some extra thoughts:
  • The library could easily adapt to different platforms, e.g., you could add gamepad events and so forth
  • The library could be implemented as a template class allowing you to define your own event object that is passed when an event is triggered, and internally the library would provide an opportunity for the host application to add the input state object to the templated event argument object before it is passed to an observer, meaning that your event argument object could contain information such as the window handle where the event was triggered, and anything else (your game context object, game time class, whatever).
  • Registering an input observer could provide the option to ignore input of a given type, e.g. to handle situations where a key sequence is being observed irrespective of mouse state.
  • Gestures could hypothetically be supported as a future development...
Edited by axefrog

Share this post


Link to post
Share on other sites
Advertisement


get some feedback on the idea. I'd be happy to open source this if others feel it might be useful to them.

A simple to use lib would be pretty cool, just some thoughts. It would be nice if such a library

1. would be able to forward events.

2. would hold the current state of buttons, mouse position etc

3. would be able to hold the current input string/stream.

 

I love single-header only libs, it could work for a small header like this. If you make it open-source, think about the license. GPL/LGPL are restrictive, whereas others like MIT are more flexible.

Share this post


Link to post
Share on other sites

A simple to use lib would be pretty cool, just some thoughts. It would be nice if such a library
1. would be able to forward events.


Could you describe what you think this might look like, as opposed to the sample code I suggested above? What sort of scenarios are you envisioning that would require what you're describing?

2. would hold the current state of buttons, mouse position etc


This would be the purpose of the event argument object, which would be passed when you subscribe to the observer that is returned. It would contain the current state of the keyboard, mouse, etc. In many cases you wouldn't need to pay any attention to it, because the fact that the event fired would imply that your original input combination was already satisifed.

3. would be able to hold the current input string/stream.


That would be included in the state object.

I love single-header only libs, it could work for a small header like this.


Yeah I agree, and that's the approach I'd take.

If you make it open-source, think about the license. GPL/LGPL are restrictive, whereas others like MIT are more flexible.


I hate GPL and its derivatives. The license I choose would be BSD-compatible. i.e. do whatever the hell you want; I don't care.

Share this post


Link to post
Share on other sites

Sometimes it is necessary to track all events and not just the state.

 

Eg. if you have low FPS and hit three times a key and you need to execute an action three times, then the state alone (keyboard has been clicked at time X) would not be enough. One simple test would be to write a keyboard input string reader only based on a keyboard state, once the fps go down your key-press starts to go over board. But the same could be valid for mouse buttons etc., it is just annoying to have the feeling that pressing a button is not registered by the application.smile.png

Share this post


Link to post
Share on other sites

Sometimes it is necessary to track all events and not just the state.
 
Eg. if you have low FPS and hit three times a key and you need to execute an action three times, then the state alone (keyboard has been clicked at time X) would not be enough. One simple test would be to write a keyboard input string reader only based on a keyboard state, once the fps go down your key-press starts to go over board. But the same could be valid for mouse buttons etc., it is just annoying to have the feeling that pressing a button is not registered by the application.smile.png


The way it would work is that you would control when input events are passed from their source to the input manager, so it would synchronise with your game loop. If you want to implement a debounce and drop some events before you pass them to the library, you can. If you want to debounce in your event handler on the other end, you can do that too. In essence, you'd pass in an input event, that event would be applied to any observable patterns you've defined, and any that have their sequence matched would then trigger for any subscribers. More than likely I would provide the ability for you to tell the library how much time has passed since the previous tick, rather than trying to handle that myself, as people are generally using their own game timers that handle that kind of thing. As a result, if you want your game timer to flex a bit when you have frame-rate lag, you could do that. Edited by axefrog

Share this post


Link to post
Share on other sites

You'd usually want to separate the low-level hardware events and high-level logical events.

Gameplay code shouldn't care if you hit Space or not. It cares if the user pressed Jump or not. Which matters for multiple platforms, because Jump might be Space or it might be the A button on a controller or an up-swipe gesture on a touch phone. And which matters especially on PC because users like to be able to rebind keys in a configuration dialog, so the user might even decide to move Jump from Space to Alt or some such.


I am a fan of keeping libraries tightly-focused for maximum flexibility when integrating with existing code. For this library, my thought was that the mental mapping between some combination of input events and a particular game-related intent would be up to the developer. You would watch for your input sequence and then do whatever you want in response. If that means funnelling the input event into a queue, you'd simply write a single event handler again the library's global observable, and in your handler you could perform the insertion into your queue.

I believe something like this would address your concerns:
 
// You know what's important to your game, so define your own structure containing the information you want in an
// input event, and probably also include the original input state object

struct YourGameInputEvent
{
    // your own properties
    MyGameContext *context;
    PlayerIntent intent;

    // the state object provided by the library
    InputState *inputState;
}

// construct your input sequencer with a custom function that will be called any time an input sequence event is
// about to be fired, allowing you to construct and populate the input argument with data that you care about

input::Sequencer<MyGameInputEvent> myInput([&](InputState& state, const std::string& inputSequence) {
    YourGameInputEvent data;
    data.context = yourGameContext; // captured via closure
    data.state = &state;
    return data;
});

myInput.observe("up,up,left,right,space", [&](YourGameInputEvent& arg) {
    // here you'd fill out the event argument data for this input sequence
    arg.intent = PlayerIntent::PERFORM_DONKEY_FATALITY;
});

// this would be called after any individual input sequence has been handled
myInput.observeAll([&](YourGameInputEvent& arg) {
    // here you could add all captured events to your own event queue
    arg.context.input_queue.push_back(arg.intent);
});

Note that I'd provide the ability to observe on more complex sequences (think AND/OR, etc.) when calling observe, if desired, as an overloaded alternative to just providing a string argument.

Thoughts? Edited by axefrog

Share this post


Link to post
Share on other sites


// fires on ctrl+A, followed by ctrl+B, then ctrl+C, with a maximum of 1000ms between keypresses
auto observer = input::observe("ctrl+a,ctrl+b,ctrl+c", 0, 1000);
 
Why strings? The keys themselves have nothing to do with strings.

Cross-platform'd enums would make more sense to me.

std::vector<KeyCombo> = {Key::Ctrl|Key::A, Key::Ctrl|Key::B, Key::Ctrl|Key::C};
It doesn't look as nice in code, but most of the time, it wouldn't be hardcoded anyway.


Tiny point of order - ORing keys together only works if you pre-define certain keys as "modifiers" and make sure their bit patterns don't overlap "non-modifiers".

Admittedly, this is fine for lots of games - as Shift, Ctrl, etc are logical "modifier" keys.

However if you're making a fighting game that uses button combos this won't work as well. Since you might want "A" to punch, "B" to kick, and "A+B" to throw.

Just something to consider - based on the type of game you're making.

Share this post


Link to post
Share on other sites

Why strings? The keys themselves have nothing to do with strings.

Cross-platform'd enums would make more sense to me.
std::vector = {Key::Ctrl|Key::A, Key::Ctrl|Key::B, Key::Ctrl|Key::C};
It doesn't look as nice in code, but most of the time, it wouldn't be hardcoded anyway.


I'm a big fan of code that is easy to read and scan at a glance. The overhead of parsing a string would be minimal, and a one-time cost anyway. As a result, you get nice, succinct code that is immediately obvious without having its readability compromised by syntactic pollution. You get to represent complex combinations in a short amount of code, e.g. "ctrl+k, ctrl+shift+alt+q" or "a,a,b,c,space". That all said, I suppose there's no reason I couldn't provide an overload if you prefer to use pure strongly-typed values to construct a given input sequence. You'll note in my previous response that I suggested that I'd provide a way to define more complex sequences to observe on also, which provides yet another way to define your sequence, if you want.

All that said, KISS principle and all... I'm not interested in overengineering this, so I want to be careful not to go overboard.

You can provide functions for converting a string to a std::vector, or vise-versa, but the library wouldn't be dependant on string parsing for passing entirely internal information.


I'd just provide overloads I think. That'd be simpler and wouldn't enforce a particular style on users of the library.

Lower level of abstractions:
Support for key combos.
Support for gamepads, whether using XBox or non-XBox APIs
Support for gamepad rumbling (though that's really output)
Support for multiple mice and multiple keyboards (lowerpriority, difficult on Windows, but still desired if possible!)
Support for events and polling.
No assumptions made about gameplay logic at the lower level.
(we discussed this a little bit of this, here)

Higher level of abstractions: (basic thoughts - there may be better designs)
The concept of 'Actions'. (i.e. bind 'LeftArrow' to 'MoveForward', bind 'Spacebar' to 'Jump' action)
Multiple 'events' tied to the same 'action'. (i.e. bind 'LeftArrow' to 'MoveForward', but also bind 'Joystick' to 'MoveForward' action)
The same 'event' tied to multiple 'actions'. (i.e. bind 'Spacebar' to 'Jump' but also bind 'Spacebar' to 'NextPageOfDialog')
Support for gameplay-level-combos to trigger actions (i.e. bind [Down, Down-Forward, Forward + Punch] to 'Hadouken')
Must take into account game-specified timings between events.
Support for 1D and 2D axis at the high level (bind 'GamepadLeftJoystick' to 'MovementAxis', bind 'W','A','S','D' to 'MovementAxis', bind 'LeftArrow','RightArrow','DownArrow','UpArrow' to 'MovementAxis')


Responding to each of your points above:

Support for key combos
This is one of the defining features of the library

Support for gamepads, whether using XBox or non-XBox APIs
This is just a matter of including gamepad-specific identifiers to be used in input sequences

Support for gamepad rumbling (though that's really output)
Yes, that's output and wouldn't be relevant to this library, which is all about capturing and identifying input

Support for multiple mice and multiple keyboards (lowerpriority, difficult on Windows, but still desired if possible!)
I'm gonna call YAGNI here. Feel free to dispute me, but when does a game ever need to deal with two keyboards or two mice attached to one computer?

Support for events and polling
The library would be built around observables, so events are implicit in that regard. See the proposed code samples in my earlier posts. In those posts you'll also see how an event could be funnelled into a global input queue, if that's the pattern you prefer to use in your game.

The concept of 'Actions'. (i.e. bind 'LeftArrow' to 'MoveForward', bind 'Spacebar' to 'Jump' action)
Yep, the library would be designed to allow you to do this however you want. See the code sample above.

Multiple 'events' tied to the same 'action'. (i.e. bind 'LeftArrow' to 'MoveForward', but also bind 'Joystick' to 'MoveForward' action)
Definitely. The initial registration of the input sequence handler would be slightly more complex than the single string argument examples I provided earlier, but I would provide a solution for this. Possibly even as simple as: "kb:left|js:left" or something to that effect.

Support for gameplay-level-combos to trigger actions (i.e. bind [Down, Down-Forward, Forward + Punch] to 'Hadouken')
Yes, as above.

Must take into account game-specified timings between events.
It would be up to you to invoke the library in your game loop. The function would be something like:

void input::next(InputEvent ev, int timeElapsedMs)
{
    // In here the library will apply the event (e.g. The "A" key was released) to
    // each registered input sequencer to advance its internal state machine and thus
    // trigger any newly-matched sequences. The timeElapsed argument would be provided
    // by you so the library can keep track of the time elapsed between input events.
}

Support for 1D and 2D axis at the high level (bind 'GamepadLeftJoystick' to 'MovementAxis', bind 'W','A','S','D' to 'MovementAxis', bind 'LeftArrow','RightArrow','DownArrow','UpArrow' to 'MovementAxis')
This would just be a matter of working out all of the different input event types and modifier states that I'd need to support in the parser and enum list.

It's worth noting that input comes from many different sources, e.g. SDL, SFML, DirectX, GLFW, Win32 window events, etc. We could possibly provide a set of translations for each different type of event source and use preprocessor control flow to allow you to activate the one you're using in your game. I'd probably need people to contribute there though, and it'd be optional anyway. A useful option though, as building a big switch statement yourself could be kind of tedious, and it'd probably look the same for everyone using that input source anyway.

Share this post


Link to post
Share on other sites

Tiny point of order - ORing keys together only works if you pre-define certain keys as "modifiers" and make sure their bit patterns don't overlap "non-modifiers".

Admittedly, this is fine for lots of games - as Shift, Ctrl, etc are logical "modifier" keys.

However if you're making a fighting game that uses button combos this won't work as well. Since you might want "A" to punch, "B" to kick, and "A+B" to throw.


Naturally even in the A+B scenario, you're going to get the source input events in sequence, so I guess that might be handled by specifying "a:down,b:down" with a maximum of say 100ms between inputs, and I would provide an extra parameter/field as an option for making the keys match in an order-independent manner, thus meaning you'd match a:down and b:down when pressed together (within 100ms of each other), irrespective of which is pressed first. An :up on either of these, inserted in the middle, would abort/reset the sequence.

I haven't 100% decided on the semantics surrounding keeping some input sequences independent of others, versus input sequences that interrupt each other. FPS is a typical example of that. up,down,left and right, vs up+left, etc. all interfere with each other, as they should, but keys for jumping, shooting, etc. are independent and would trigger irrespective of movement. Similarly on a gamepad, movement with the stick would not impact sequences relating to kick/punch and related combos. I'll have to think about that a bit more.

Share this post


Link to post
Share on other sites

I'd just provide overloads I think. That'd be simpler and wouldn't enforce a particular style on users of the library.

 
Well, you'll still want to/from strings for displaying the string to the user, both in the keybindings menu ("Currently bound: [Ctrl+X]") and in-game during the beginning of the game ("Press [space] to jump") or in context-specific situations, and possibly also for serialization to config files, if not using a binary format.
 

Support for gamepads, whether using XBox or non-XBox APIs
This is just a matter of including gamepad-specific identifiers to be used in input sequences

Well, you'll need to support two (DirectInput + XInput, thanks Microsoft!), potentially three (Steam controller), different APIs to fully support the controllers.
 

Support for multiple mice and multiple keyboards (lowerpriority, difficult on Windows, but still desired if possible!)
I'm gonna call YAGNI here. Feel free to dispute me, but when does a game ever need to deal with two keyboards or two mice attached to one computer?

Cooperative games. The reason by most games don't support it, is because Windows doesn't provide a higher-level interface for it, so anyone wanting to use it must rewrite the code from scratch.

It's definitely a very lower priority, but something I've wanted in the past, and apparently only Linux supports it directly, but Windows can support it.

 

Rag Doll Kung Fu and and HammerFight both supposedly support it. Older non-Windows games used to support it. As it stands, any coop game on the PC requires a mouse/keyboard and a gamepad, or two gamepads, unless they manually write the low-level code themselves.

 

...but if you're writing as a layer over SFML/SDL/other-layers, it's definitely not worth the hassle.

Share this post


Link to post
Share on other sites

Well, you'll need to support two (DirectInput + XInput, thanks Microsoft!), potentially three (Steam controller), different APIs to fully support the controllers.


Is it important to make the distinction between DirectInput and XInput? I mean if you look at the last code snippet in my earlier reply, you can see that you need to supply a translation step where you take some kind of raw input event from your source of choice and translate it to a "common" raw input event, which you pass to the library, which does the rest. The library itself generally wouldn't be need to be concerned too much with whether or not a left stick event is sourced using XInput or DirectInput - the common translation would amount to the same thing.

Two things though; (1) Obviously certain gamepads have specific inputs which are unique to them (bumpers, buttons, whatever) and that distinction would need to be made, which leads me to... (2) It might be feasible to decouple the common event list from the core of the library itself. Really, the library doesn't care what the input events are, it cares about their composition, the way they are sequenced, and so forth. Given that the intent is to make this a header-only library, adding additional input event types that you want to support would probably be really easy, and I can foresee myself even providing examples of how to do that with only one or two lines of code, meaning if you wanted to support weird input sources from other device types (Leap Motion, for example), you'd just add a string/enum mapping at the top of the header file, and bam- it's supported.

Share this post


Link to post
Share on other sites

Is it important to make the distinction between DirectInput and XInput? I mean if you look at the last code snippet in my earlier reply, you can see that you need to supply a translation step where you take some kind of raw input event from your source of choice and translate it to a "common" raw input event, which you pass to the library, which does the rest. The library itself generally wouldn't be need to be concerned too much with whether or not a left stick event is sourced using XInput or DirectInput - the common translation would amount to the same thing.

 
So this is purely a middle layer between the other API layers and the game? Then you don't need to make any real distinction.

Share this post


Link to post
Share on other sites

Is it important to make the distinction between DirectInput and XInput? I mean if you look at the last code snippet in my earlier reply, you can see that you need to supply a translation step where you take some kind of raw input event from your source of choice and translate it to a "common" raw input event, which you pass to the library, which does the rest. The library itself generally wouldn't be need to be concerned too much with whether or not a left stick event is sourced using XInput or DirectInput - the common translation would amount to the same thing.

 
So this is purely a middle layer between the other API layers and the game? Then you don't need to make any real distinction.


Yes, though as stated earlier it might also be useful to provide a set of "prefab" translations from common input sources and include those in the library, hidden behind #ifdef blocks, ready to be activated as needed, as this would save a bunch of work for many people. I'd need contributions from others to make that reasonably comprehensive though. Edited by axefrog

Share this post


Link to post
Share on other sites

I think it is a noble thought, but not really feasible. See one of my many posts on input for reasons why.
http://www.gamedev.net/topic/650875-input-handling-design-frustration/#entry5115366

http://www.gamedev.net/topic/650640-is-using-static-variables-for-input-engine-evil/#entry5113267

http://www.gamedev.net/topic/641102-frame-independent-movement-and-slowdowns/#entry5049391


The main issue is that inputs are not events and should not be triggered as events. They should always be buffered and consumed in specific steps at specific times during the game loop, and a proper integration with this type of system requires more intimate knowledge of the programmer’s game loop.
You suggest using your events to create the buffer, which is okay….

But it doesn’t address another issue: Key mapping.
I’ve recently had a long discussion with someone on where and when it is appropriate to translate keys to in-game actions.
I go in great detail here explaining why when translating keys into actions it is the context at the time of in-game action-processing that matters, not the context at the time of the button-press being received.

 

 

The point where you are proposing to take the burden off the programmer by recognizing key combinations etc. is correct for applications, but incorrect for games.

At the level where you are working the only thing you can do is log inputs.  Parsing them to produce in-game actions can only be done in the middle of the actual game loop.

 

And even there you are split between high-level and low-level.

No matter where you do it, it’s not as simple as “send a jump command to the player”.  All commands sent to the in-game characters should be considered low-level and should not be questioned by the in-game characters.  Why?  Because the in-game characters are a slave to the physics engine and scene manager, not the other way around.  When you send a command to the character to jump, you’re telling it just to jump.  Not to check to see if it is on the ground or if the ceiling is high enough, etc.  That has to have already been done by the higher-level systems.

 

 

Ultimately I don’t see a good generic way to make a library out of input systems.  The only thing you can do is gather input from all possible platforms and devices and then keep a buffer.  After that, it varies as much as the number of programmers there are.

 

 

L. Spiro

Share this post


Link to post
Share on other sites


You're right. I do touch on that issue here, but since it's not a performance critical area, another solution is not making them actual enums, but lightweight classes (so you can support other things beside just keys), and overload the | operator.

An enum class would work for that, right?

Share this post


Link to post
Share on other sites
Spiro, your points are valid, but I believe you're quite wrong about this not being something that can be solved for most use cases. A well-designed game, as I understand it, is generally implemented as a complex hierarchical state machine, and the state of the machine is affected by signals it receives. I'm not sure how familiar you are with reactive programming, but input is just one stage of the combinatorial process.

Now, you are quite right that the input received is not universally applicable in the simplistic way that most new game designers are envisioning. Physics gets in the way (such as with your example whereby the space bar means jump, but not if they're already in the air). I think the reason you're having a conceptual problem with this is that you're not decoupling these concerns well enough.

With my library, the input sequencer is itself a hierarchical state machine, with each input sequence itself being a simple state machine. You still need to treat a sequencer as a child state machine in the larger state machine of your game! Each individual sequencer that you instantiate would be related to its own domain of concern, with its own group of mapped input sequences, and can itself be set to an "off" state, so that it doesn't trigger sequence-matched events when it's not relevant to do so.

Conceptually, think of it like this. Raw input maps to unified input, which is directed into my [proposed] library. You then use my library to build groups (my sequencer class) of domain-specific intents, where a domain is something like "main menu input", "inventory screen input", etc. and the intent is something like "Player Jumped" or "Menu Item Selected". The library maps the unified source input events to whatever intent group is active at the time. Those groups then fire events when any of their mapped input sequences are matched, and you then project that resultant event to a game-specific intent, which you can then filter using your own preferred model, whether directly, or via additional events, streams, queues or whatever.

In a nutshell, if you're having problems with universality of input because you're thinking that state matters, then your concerns don't have enough separation. Validating intent is not a concern of the input library.

Share this post


Link to post
Share on other sites

You’re focusing too much on what I would have considered the smallest point I was trying to make.

 

Translating actions into commands such as “jump” was a child point of the fact that looking for key combinations (auto observer = input::observe("ctrl+a,ctrl+b,ctrl+c", 0, 1000);) at the level where you library would sit.

 

You still have the exact same problem I mentioned in the link I already posted (or a variation of it based on how you handle what I discussed about “jump” commands).

First, as I have explained in many posts, and lightly touched here, input is to be buffered and then handled later (on a second thread even).

So if you perform key-combination checking at the wrong time, you could recognize an action whose context is no longer contextually contextual that will be out of context by the time the game processes it.

 

Your suggestion to swap out several combinations of key handlers (an “intent group” as you put it) depending on the game context (main menu, game, etc.) doesn’t fix it.

 

 

I posted the link twice in order to reduce how much I have to repeat myself.  It should be enough now to simply point out that you still have the exact same problem and then let you read the post already-written.

 

 

L. Spiro

Share this post


Link to post
Share on other sites

I posted the link twice in order to reduce how much I have to repeat myself.  It should be enough now to simply point out that you still have the exact same problem and then let you read the post already-written.


You seem to be irritated by the (I believe false) perception that I haven't understood the point you're trying to make. The last sentence of what I wrote was the most pertinent. A combination of keys still maps to an intent, irrespective of whether that intent becomes invalid before it has a chance to be processed. The point is that your game should process intents, not keys, at the point where the intent is to be translated to a game state change. The conditions under which validation is asserted are, as you clearly keep pointing out, unique to a given game engine, but the original intent itself doesn't change. It still up to you to validate the intent, and if you're applying a log processing concept as per your other examples, then what is logged is the chronological set of intents, not the set of keys. The area of code dealing with the outcome of the intent should not be dealing with the keys related to that intent. If it is, your code is too tightly coupled.

In your example, you gave the example of remapping 'K' to 'A' and that needing to be immediately reflected, even if it happens right in the middle of a subsecond succession of bot-initiated keypresses. In my system, it is immediately reflected, because you feed the raw input event in at the top end, and it flows out the bottom as an intent, and that intent *was* perfectly valid at the precise moment that the input sequence produced that intent. If you're asserting that perhaps the key will be remapped mid-sequence, then that's splitting hairs. The process leading to the remapping would cause the key-sequence state machine to be reset anyway.

Second, you talk about timing, which is again a valid concern, but it still doesn't invalidate my solution! Irrespective of timing, input sequences and combinations still translate to an intent, otherwise the player wouldn't have pressed that combination of keys to begin with. If it turns out that they were 100ms too late, then your processing of the intent at the point where the intent is to be processed is where you would validate that intent. Even if you completely took away the obvious feature of being able to disable and re-enable an input sequencer (to avoid redundant processing of inputs), your validation on the end of your intent queue should still be correctly validating the next intent in the queue in the context of the game state as it is during that exact slice of time.

Perhaps you're pointing out a subtlety that I have missed, but consider this. The library is intended to be inserted into your main game loop, and nothing happens in your game without your game going through that game loop in sequential cycles. I know you've been around the block here, so forgive any blindness surrounding this issue on my part, but basic input processing doesn't strike me as something so resource intensive that it can't be included as part of your primary game loop. Therefore, even at the very start of your game loop, the game will be in a precise state, which is still reflected when the intent is emitted by an input sequencer, as it will be part of the same cycle, before the input library call completes. What you do at that point is up to you. If you are dealing with a parallel system, then again, it is up to you to validate that intent in the context of your game's state at the precise moment that the intent is processed, even if you relegated input processing to a secondary thread. However my point is this:

Device inputs map to intents. That's why we have input, because the player is trying to effect a certain outcome using their knowledge of the input device's (current) mapping to your game's systems. The point of the library is to translate intents from input signals to a language that your game understands. If an input sequence is invalidated midway through reaching a "completion" state, no problem, it's reset. If the intent that is added to the queue turns out to be invalid at the point it is to be processed due to 100ms of latency, again, no problem - you validate that intent before you process it. The fact that it wasn't valid at the precise moment it was to be applied doesn't change the fact that the player intended a given effect as a result of that input sequence. It's up to you, the game designer, to validate the intent before it is applied.

If you still disagree with me, the present me with a use case you think I can't handle, and I'll do my best to explain why I don't think it's a problem, and if I can't, then I will happily yield the argument to you. Edited by axefrog

Share this post


Link to post
Share on other sites

You seem to be irritated

I’m not. That’s just the result the Internet has on things said as matter-of-fact.

I will edit the rest of my reply into this post later, as I need to go in a few minutes.


In the meantime, why don’t you explain where exactly your library will live within an engine?
Does it catch WM_KEYDOWN messages directly (does it live in the message loop?) or where?


L. Spiro Edited by L. Spiro

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By 3dmodelerguy
      So I am building a turn based rogue-like (think CDDA). The game is going to have a very large map (up to 1000's x 1000's) however to alleviate most of that I obviously can't render everything so there will just be render a certain radius around the player and just load in and out data as the player moves.
      The next major system I am prototyping is making interactive tiles destructible and pretty much everything will be destructible besides basic landscape (cars, doors, windows, structures, etc. will be destructible)
      While I am only rendering a certain amount of tiles around the player, I want to keep the amount of colliders active at one time to be as small as possible for performance and currently the tilemap tool I use automatically merges colliders together.
      So instead of creating a separate colliders for each of these tiles and having the destructible behavior tied to that object (which my tilemap tool would allow me to do) I was thinking that I would store an array of all the X and Y locations for the interactive tilemap layer and let the tilemap manage the colliders. 
      Then when I hit a collider on the interactive tilemap layer, instead of of getting the behavior for how to deal with the destruction for that tile from that game object, I would pull it from the array I mentioned earlier based on the tile I attempt to interact with which I already have.
      Does this sound like a good approach? Any other recommendations would be welcomed.
    • By NDraskovic
      Hey guys,
      I have a really weird problem. I'm trying to get some data from a REST service. I'm using the following code:
       
      private void GetTheScores() { UnityWebRequest GetCommand = UnityWebRequest.Get(url); UnityWebRequestAsyncOperation operation = GetCommand.SendWebRequest(); if (!operation.webRequest.isNetworkError) { ResultsContainer rez = JsonUtility.FromJson<ResultsContainer>(operation.webRequest.downloadHandler.text); Debug.Log("Text: " + operation.webRequest.downloadHandler.text); } } The problem is that when I'm in Unity's editor, the request doesn't return anything (operation.webRequest.downloadHandler.text is empty, the Debug.Log command just prints "Text: "), but when I enter the debug mode and insert a breakpoint on that line, then it returns the text properly. Does anyone have an idea why is this happening?
      The real problem I'm trying to solve is that when I receive the text, I can't get the data from the JSON. The markup is really simple:
      [{"id":1,"name":"Player1"},{"id":2,"name":"Player2"}] and I have an object that should accept that data:
      [System.Serializable] public class ResultScript { public int id; public string name; } There is also a class that should accept the array of these objects (which the JSON is returning):
      [System.Serializable] public class ResultsContainer { public ResultScript[] results; } But when I run the code (in the debug mode, to get any result) I get an error: ArgumentException: JSON must represent an object type. I've googled it but none of the proposed solutions work for me.
      Also (regardless if I'm in the debug mode or not) when I try to do some string operations like removing or adding characters to the GET result, the functions return an empty string as a result
      Can you help me with any of these problems?
      Thank you
    • By nihitori
      The Emotional Music Vol. I pack focuses on beautiful and esoteric orchestral music, capable of creating truly emotive and intimate moods. It features detailed chamber strings, cello and piano as the main instruments, resulting in a subtle and elegant sound never before heard in video game royalty-free music assets.

      The pack includes 5 original tracks, as well as a total of 47 loops based on these tracks (long loops for simple use and short loops for custom / complex music layering).

      Unity Asset Store link: https://www.assetstore.unity3d.com/en/#!/content/107032
      Unreal Engine Marketplace link: https://www.unrealengine.com/marketplace/emotional-music-vol-i

      A 15 seconds preview of each main track is available on Soundcloud:
       
    • By RoKabium Games
      Another one of our new UI for #screenshotsaturday. This is the inventory screen for showing what animal fossils you have collected so far. #gamedev #indiedev #sama
    • By eldwin11929
      We're looking for programmers for our project.
      Our project is being made in Unity
      Requirements:
      -Skills in Unity
      -C#
      -Javascript
      -Node.js
      We're looking for programmers who can perform a variety of functions on our project.
      Project is a top-down hack-and-slash pvp dungeon-crawler like game. Game is entirely multiplayer based, using randomized dungeons, and a unique combat system with emphasis on gameplay.
      We have a GDD to work off of, and a Lead Programmer you would work under.
      Assignments may include:
      -Creating new scripts of varying degrees specific to the project (mostly server-side, but sometimes client-side)
      -Assembling already created monsters/characters with existing or non-existing code.
      -Creating VFX
      -Assembling already created environment models
      If interested, please contact: eldwin11929@yahoo.com
      This project is unpaid, but with royalties.
       
      ---
      Additional Project Info:
      Summary:
      Bassetune Reapers is a Player-verus-Player, competitive dungeon crawler. This basically takes on aspects of dungeon crawling, but with a more aggressive setting. Players will have the option to play as the "dungeon-crawlers" (called the 'Knights', or "Knight Class", in-game) or as the "dungeon" itself (literally called the 'Bosses', or "Boss Class", in-game). What this means is that players can choose to play as the people invading the dungeon, or as the dungeon-holders themselves.
      Key Features:
      -Intense, fast-paced combat
      -Multiple skills, weapons, and ways to play the game
      -Tons of different Bosses, Minibosses, creatures and traps to utilize throughout the dungeon
      -Multiple unique environments
      -Interesting, detailed lore behind both the game and world
      -Intricate RPG system
      -Ladder and ranking system
      -Lots of customization for both classes s of customization for both classes
  • Advertisement