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!

Tuesday, July 3, 2018

battleMETAL - Why Quake / Darkplaces - Part 6 - Menu Systems Layer



Click on the thingie, no wait, that thingie!

Quake was never known for its menus, in fact most iD games skip out on menus in any detail. There’s a workman-like quality to them, simple layouts and input. It also makes sense given that Quake came out in 1996, unless a game was menu-driven (like RPG’s or RTS) a game’s menu system were fairly plain. For Quake, it has all the necessary menus a player would need for an FPS. Building on DooM’s template, there are more options for graphics, and for multiplayer settings. Interestingly enough, iD did setup the code for their menu system fairly well, having console commands that can immediately bring up any particular menu.

Darkplaces however expands the capabilities. This being 2018, menus have advanced a bit since the days of 1996 and most people enjoy having a useable mouse for the menus. In Darkplaces, the source port exposes the menu entry functions to the Quake C code that modders can use. This in turn allows modders to create any and all menus they’d like to in almost any fashion they’d prefer. There are 2 layers to menus in Darkplaces, each being compiled to their own code base. The big one is called CSQC or Client-side Quake C. Original Quake, all custom code (written in Quake C) was packed into a single compiled file called progs.dat. However CSQC is packed into its own file and only used by the player’s local game of Darkplaces.

CSQC can access almost everything about the player’s game. The programmer can customize the HUD, can create their own menus, change runtime variables through the console, intercept input commands, and very importantly - define communications with the server. This last piece is helpful, this allows custom data transmission between the server and player. The coder can setup custom server-drive events, or pass specific game updates to the player for notification. Quake itself never needed to do a whole lot with this, but a mech game in 2016? Oh yes, this feature was very much needed.

The other big menu module is the specific menu layer. Quake source ports and modders never really settled on a ‘standard’ way of remaking / extending / modding Quake's original set of menus, so several options exist. One way many modders do is add the features to the CSQC described above. Another way is the menu.dat. Remember how CSQC compiles to its own file? Well its the same idea with the menu.dat code. Darkplaces looks for a menu.dat file, if it exists, Darkplaces then runs the menu code found in that file. The framework for the menu code is similar to CSQC but slightly more limited to just rendering menus and executing player input. I chose this solution for my main menus because I liked the separation of concerns that this approach offered - all the menu code is in its own folder and cleanly separated from all other code.

In summary, Darkplaces offered several flexible albeit a tad labor-intensive approaches to implementing new User Interface upgrades to the original Quake engine. I considered this sufficient at the time when selecting to go forward with Darkplaces. The available documentation on CSQC was easily found, but not the most detailed. The menu.dat code required going into the engine code to figure out how it worked. In hindsight now, despite the flexibility offered, both features actually incurred a large amount of technical debt. Newer engines handle UI systems more effectively both for the player and for the programmers.