Srekel

Dot Big Bang, Tides of Revival

Making Tides of Revival, FOSS sillily scoped open world RPG.

Work: Community Engineer @ dotbigbang

Prev: Hammerting, JC2, GTA5, Vermintide, game jams


Well... what might turn into a Zig library at some point! :) Inititally, until it's been battle tested, it'll just be a part of Elvengroin Legacy. (https://github.com/Srekel/elvengroin-legacy)

The goal is not to write a low level library that interfaces directly with input devices and so on - I'm currently using GLFW for that. Rather, it is to provide a number of features on top of that, stuff that you frequently want from a game dev point of view. I'll try to list them here, please let me know if there are any other features an input system should have!

  • Access input by custom name ("jump") rather than key (KEY_SPACE)
  • Multiple devices writing to the same input.
    • E.g. gamepad A and keyboard Space both set "jump".
  • Expose inputs as bools, numbers, and axis
  • Query if an input has just been changed, just been pressed (positively changed), or just been released (reset to zero), compared to last frame.
  • Remap multiple inputs to other ones, typically WSAD to a 2d movement vector.
  • Record input and playback previous recordings. Should be diff based so that it produces minimal data.
  • Allow multiple instances, perhaps you only want to query the gameplay at a fixed 20hz but you still want the graphics to update every rendered frame.
  • Layers of mappings, so that you can overlay another layer of mapping when you enter a different state.
    • For example maybe you should still be able to walk around in a store but not be able to attack.
    • Or a special layer could be added when in interact range of an object.
    • Or when you're in a menu you want to keep movement enabled but disable all interactions
    • A debug layer could always sit on top during development but be removed for public release
    • Having separate layers, for example one layer for opening the main game menu or the map, and another layer for player controller related movement, will keep logic cleaner.
  • Layers should be named and disableable.
  • Layers should be optionally modal, preventing access to things below
  • Support for multiple players. This is not a priority for me since EGL is singleplayer, but I don't think it would be extremely complicated to add later if I manage to add all of the above stuff.
  • It should be fast to run and fast to query.
    • Possible optimization (just realized to writing it down in case I forget :D ) is to collapse the layers whenever something change, which should be a pretty rare event.

What do you think, did I miss something? :)

Currently the state of it is that I've written the basic remapping, device, and layer logic, but I haven't tested it yet. I'm going to clean up the code a bit and hopefully take it for a spin soon!


You must log in to comment.

in reply to @Srekel's post:

I like the layers, so much better than ad-hoc checking if some mapping should be evaluated or not, or functions arbitrarily not being called because you're in "that other mode of the game loop" as often ends up being the case 😆

How about queued inputs? I can see this being a big deal for an action game, or in the example you cited where inout/gameplay frames are processed at low Hz so players could feasibly execute multiple actions per tick.

Summing up a few of the comments and extra thoughts I've had since I posted:

  • Should process mouse input even when window isn't focused, since that's how normal applications work
  • Should optionally support buffered input so that you can get ordered input.
  • Should support text input (from the OS preferably so you get all special key handling and such).
  • Should make "remapping" a more general "processing" mechanic where you can massage inputs in various ways. Some examples:
    • The aformentioned WSAD -> 2d axis
    • Hold button for a second
    • Double tap
    • Hold button then press another button while holding
    • Axis + press
  • It shouldn't really need to allocate any memory except for "rare" events such as when layers are added and removed, and bindings are change, etc.
  • Querying should probably be done per layer, not "globally". This prevents cases where multiple layers accidentally use the same id for an input.

Some of these things are essentially "utility" stuff that could be handled on the game side, but this aims to be - ultimately - a fully fledged batteries included all-you-could-want input library.

I haven't yet decided to which degree it should be configurable and extendible.

  • I'm half tempted to force the GLFW dependency. It'll be relatively easy to switch out for anyone so inclined.
  • I think I'm going to essentially use hard coded enums that support all things I can think of and then add more things that way, rather than implementing it in terms of interfaces and function pointers etc.