Kandria
A brief look into gamedev complications
While we're still hammering away polishing the new demo, preparing the Kickstarter, and rounding out content for the full game, I thought I could give a brief look at the kinds of things that seem simple from the outside, but can be quite annoying and complicated in development.
Before that though, remember to subscribe to our Kickstarter so you get notified when it goes live!
Gamepads
As an example for this kind of thing I want to talk about game input, and specifically gamepads. The funny lil devices that primarily consoles and specialty games used to use. Nowadays, it's pretty much expected that any game on PC supports gamepad input methods, and for good reason! Keyboards and mice are really uncomfortable for a large class of games, Kandria included.
However, implementing gamepad support is far from trivial, especially in our case with a custom engine. So let's take a brief look at the kinds of pitfalls there are.
Gamepad input
First, gamepads live in a different device class than keyboards and mice. Many low-level layers will handle the latter for you, but not gamepads. They are still "Human Interface Devices" (HID), but have very different means of reporting inputs.
So, if you want to provide support yourself, you'll have to integrate with the operating system directly. If you want to be cross-platform, that means you have at least 3 interfaces you need to interact with: DirectInput on Windows, evdev on Linux, and IOKit on MacOS. But wait! It gets better. On Windows there's actually ... four APIs! DirectInput, RawInput, Xinput, and yet another that is only available for WPF applications.
Even better: all of these APIs are quite different, especially the ones on Windows, and they can also lie to you about what they report depending on how well the device is supported in the system drivers.
I'm not going to go into the details of how to interact with all of these, as it's quite hairy. However, I will say that the situation on Windows is especially horrible. Xinput, the "de facto" library for gamepads has support for Xbox controllers, but not for Joysticks or other things like steering wheels. It also supports up to four controllers, but no more, and there's no way to identify which controller is which, you only get an opaque "this is controller 1". So if you want to support other stuff, you need to support DirectInput. DirectInput has been marked as deprecated however, with no real successor. Nice!
Better yet, the controllers that appear in Xinput also appear in DirectInput, but because Xinput gives you no information on the devices other than "1", you need to do some horrible heuristic matching to attempt to figure out which DirectInput device corresponds to which Xinput device, and switch how you process inputs depending on that.
Overall though it's worst on MacOS, as Apple simply does not give a darn and most gamepads you find will not be properly supported by their drivers and thus either not work at all, or have their inputs mapped in completely messed up ways.
Anyway, once you implement an interface with all of these APIs you now get inputs from gamepads in the form of: "device X reports input Y in state Z". Such as "device X425AN-2532 reports input 203 in state 235". This is pretty bad, but at least you can let the user configure which input to map to which action, so in this case, "203" would be mapped to be an axis that is used for horizontal movement. This, by the way, is why in some games and applications when you manually configure your gamepad, it just shows weird numbers for whatever you mapped.
Gamepad support
A lot of games stop here. They support input from gamepads, but they don't make it convenient. There's a whole range of additional things that need doing, and many of these you need to take care of as a dev even when you're using an already established engine like Unity.
Interpreting the inputs as the actual buttons and axes they are on the device. We don't want the player to have to figure out if "analog input 205" is their left stick's horizontal movement axis. The engine should automatically know which input is what, and unfortunately there is no consensus out there on how this is done. Pretty much every single device is different, even ones from the same manufacturer, and sometimes even the same device depending on whether it's used via bluetooth or USB. What a nightmare!
Displaying the proper prompts within the game. When the game asks you for a certain input, it should show a glyph that is appropriate for the device you're using. To a certain degree this can be generified so that you only need one set of symbols for all gamepads, but ideally you'd have symbols appropriate for the device the user is using. This again means keeping track of what kind of glyphs are on each device, and that needs to be manually hard-coded in a database. Did you know that all three (Nintendo, Xbox, Sony) disagree about what the triggers should be called?
Allow switching between gamepads and keyboard at any point. When the player switches, the game should accept inputs from either, and also switch the prompts it displays to be appropriate. Otherwise the prompts can be very confusing.
Allow configuring which action is triggered by which input. Most PC games allow this for keyboard and mouse, but a surprisingly large amount don't allow it for gamepads. Bizarre! Also important here is to allow the user to map multiple inputs to the same action, and multiple actions to the same input. Otherwise the 1:1 mapping restriction can make a number of actions difficult to execute for impaired players.
I'm happy to say that Kandria handles all of these cases now. Unfortunately, it still doesn't have a huge gamepad database, despite the literal pile of devices I have amassed at home to test the game with and manually map the inputs. Fortunately it'll still work even with an unsupported pad, though some of the prompts will not show optimally and some inputs won't be automatically mapped correctly. The only solution here, I'm afraid, is for people to submit more device mappings as I don't have the money or time to buy every possible device out there.
Conclusion
Game development is hard. There's a huge number of things that seem like they should be trivial on the surface, but turn out to be wildly more complicated than anticipated. Honestly, it's much more of a miracle that games get made at all!
I'll see if I can share more dev stories in the future, but for now it's back to working on the Kickstarter material and all of that stuff. Please share the page with your friends as well!