Monday, July 16, 2018

battleMETAL - Why Quake / Darkplaces - Part 7 - Input Layer

It's a bit more tricky than one thinks 
One very important aspect of game engines is reading player input. Kind of hard to play a game if a player can’t actually control anything, right? Avoiding a more technical conversation of engine frames, processor cycles, and the like, game input is important because it needs to be timely. When picking game engines to use, input configuration is also a specific feature to compare. Quake has a few points towards itself in the area of game input, making configuration and custom behavior easy to create and maintain. Starting at the top level, Quake has multiple ways for a player to assign keys and bindings for behavior.

The 2 primary ways to change key bindings are using a console command ‘bind X key <action>’ and the second is modifying the .cfg config file. Using the bind console command, a player can change key bindings at anytime during gameplay. This is great for players and programmers. The config file is just another format of console commands, rather then being used in the console, the commands are loaded from a text file on start up or whenever the user enters the ‘reloadconfig’ command.

In the Quake C code, there exists functions to get the action bound to any given key and a way to programmatically set a keybinding. This allows the programmer to determine what keys are being used, and how, as well as make easier the task of custom key actions. Both the server and the client (remember Client-side Quake C?) can intercept key button presses for even more custom code or to consume a key press so that it does not go on to the other end of the network. A fun extension to the Quake engine provided by Darkplaces are key bindings for controllers and joysticks. Controllers and Joystick bindings aren’t a priority but if possible to implement, it’d be a welcome addition to the types of players of battleMETAL.

Custom, game-specific action code can read for player input within 2 ‘channels’ so-to-speak of input. There are impulse commands, and button commands. Impulse commands are used for one-off key presses. The engine can only read 1 impulse per frame - wait, that sounds limited? Ah ha, says the game engine, consider this: Although the game engine can only read 1 impulse per frame, the entire engine is running anywhere between 60 frames per second or higher on modern systems. This frame rate is high enough where the player will never notice that the engine is only reading 1 impulse per frame! Impulses are stored in a variable on the player’s entity under the name ‘impulse’. The engine runs the function, ImpulseCommands() on every player on the every frame. The programmer puts their custom code into that function, allowing for custom code to be bound to specific impulses.
 

The second piece are ‘buttons.’ These are slightly different than impulses. The state of a Button is not cleared every frame, whereas impulses are. So if the player is holding down the ‘forward’ button, then every frame knows the player is holding down that button. This difference is important because Buttons are used for constant-on commands such as moving forward, or jumping, or attacking. Another key difference between Buttons and impulses is that there are only a set number of ‘Buttons’ that the engine can recognize. These aren’t buttons on your keyboard, but a specific set of buttons numbered 0 to 9 internal to the engine. Quake generally uses ‘button0’ as the ‘fire weapon’ button, and this is generally bound to Mouse1 - your left mouse button.
 

In summary, Quake and by extension Darkplaces, have a tight handle on player input. Allowing for both player and programmer a level of flexibility not seen in most other engines. Out of the box, Quake’s input system is understandable by both player and programmer. Of all the parts of battleMETAL that had to be coded, the input system was one of the easiest. 

And this wraps of the 'Why' of using Quake/Darkplaces, in the next segment we will see why that was a really bad idea in the long run!

No comments:

Post a Comment