• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

 need advice for my settings menu

I'm finally designing the settings menu for the rpg adventure game that I've been working on since 2017 and am looking for suggestions... And the last thing that I want to have happen is that a user says to themselves, "How did they not include (such and such), or why did they include (so and so)?"

Here's a bit of background on what my game is, and is not:

This is a single-player, top-down action/adventure rpg which will be available for Windows. Users will be able to play the game with either a gamepad or keyboard/mouse. Fullscreen switching will be available. The resolution for the game is 1920 x 1080 (16:9).

These are the settings that I have thus far:

Music Volume: The user will be able to adjust the music volume from "Mute" to "Max" with 8 levels between.

Effects Volume: The user will be able to adjust the effects volume from "Mute" to "Max" with 8 levels between.

Keyboard/Gamepad: The user will be able to toggle between "Keyboard" or "Gamepad."

Fullscreen/Window: The user will be able to toggle between "Fullscreen" or "Window."

So regarding the fullscreen/window switching, this is something that gets set in the IDE before publishing... How important is it that this adjustable setting be made available to the user also?

Do I need to worry about any graphics stetting?

Regarding specific control settings for buttons on either the gamepad or keyboard, I've already decided that I won't be doing that... I will just have set functions for the buttons/keys designated at publishing.

What else might I be missing?

thx
 
Last edited:

woods

Member
So regarding the fullscreen/window switching, this is something that gets set in the IDE before publishing... How important is it that this adjustable setting be made available to the user also?
is the game something that i can take a few minutes away from, or pause-able ... so i can go to another window and do stuff on the side?
can i fiddle with my music player without having to alt+enter and take 3 minutes for it to reload?
..personally for me, i am focused on what i am doing.. playing the game. ..but there are plenty of kids out there that CANT do one thing at a time.
every time i start my game i have to scoot the window around and get it where i want it.. or resize it or ..or.. or..
having options saved and remmbered makes things alot more pleasant for people.
having the option to set fullscreen and have it remembered seems like such a trivial thing.. but a simple QoL setting is very nice ;o)


Regarding specific control settings for buttons on either the gamepad or keyboard, I've already decided that I won't be doing that... I will just have set functions for the buttons/keys designated at publishing.

of the bagillions of games ive played, i think i have set the buttons to something other than the default maybe in ten games total.. or less.
for the most part, the dev team has a rather intuitive format designed as teh game is being built.. there is very few button assignments that really need to be adjusted.. if it makes sense to you the builder.. then it will most likely make sense to the player.
that doesnt mean that every person out there will be happy with the keybinds.. but for the most part, they should flow nicely.. as you build the game, the keybinds will flow naturally.

the biggest change up for me, is up is up and up is down argument with a 1st person shooter and the joysticks (i prefer flight controls)
from the little bit i know of setting up a system for changing the keybindings.. it can be rather involved..
the question is... is it really needed? ... if the controls are intuit enough, prolly not necessary... but again.. options are nice to have ;o)
 

kburkhart84

Firehammer Games
So regarding the fullscreen/window switching, this is something that gets set in the IDE before publishing... How important is it that this adjustable setting be made available to the user also?
I think this is an important setting to supply. I personally am used to multi-monitor and prefer the borderless window type of thing so my mouse can just move everywhere I want. Others for whatever reason prefer a smaller window and don't care if the game is even full-screen. Others do prefer a fullscreen at max resolution.

Do I need to worry about any graphics stetting?
If your game can run a lower-end systems at full graphics settings, then the only one I would worry about besides the previous mentioned window type is the resolution. If you have some things you could change, like massive particle systems, different shaders, or similar, that would make the game run better on lower end systems, then I would include settings for those things. If you didn't already design your game with those ideas in mind, you are probably better off just leaving it alone and making sure the minimum requirements are high enough that it can run fine.

Regarding specific control settings for buttons on either the gamepad or keyboard, I've already decided that I won't be doing that... I will just have set functions for the buttons/keys designated at publishing.
Its your call...but input configuration is one of my big things...I can't stand playing a game that I can't get comfy controls for. And I'm not the only one. I've even seen strange things like people wanting to use multiple different gamepads(like the DPad on one but the buttons on another), or a gamepad with keyboard keys for some inputs. This isn't just about changing keyboard keys either... so XInput gamepads(devices 0 - 3) are standard pretty much...but DInput gamepads(devices 4 - 11) can be quite varied. Some don't even have proper axes for DPads, and read those like a POV hat. If I wanted to use that and your game hard coded gamepad settings to use the axes...I would be stuck. So yeah, IMO, hardcoding inputs is not the way to go. I don't think it will completely break your game's sales...but I'm sure you are going to get some reviews/complaints about it.
 

Psycho_666

Member
What else might I be missing?
- It's probably a bit too late for this now, but maybe UI scale setting? Like what Banished does?

- Also maybe some sort of Colour Blind option, where the UI and the important elements will change their default colors depending on the color blind condition the people have.

- Is there a difficulty option? I would love to have a difficulty option I can change on the fly.

- Tooltips? Mouse over tooltips are a nice thing. Showing what each button is and what this UI element is and what is that glowing item over there? Mouse over - oh, the super-duper megaultra sword of hyper bass assery...

You know, stuff like that...
 
is the game something that i can take a few minutes away from, or pause-able ... so i can go to another window and do stuff on the side?
can i fiddle with my music player without having to alt+enter and take 3 minutes for it to reload?
..personally for me, i am focused on what i am doing.. playing the game. ..but there are plenty of kids out there that CANT do one thing at a time.
every time i start my game i have to scoot the window around and get it where i want it.. or resize it or ..or.. or..
having options saved and remmbered makes things alot more pleasant for people.
having the option to set fullscreen and have it remembered seems like such a trivial thing.. but a simple QoL setting is very nice ;o)





of the bagillions of games ive played, i think i have set the buttons to something other than the default maybe in ten games total.. or less.
for the most part, the dev team has a rather intuitive format designed as teh game is being built.. there is very few button assignments that really need to be adjusted.. if it makes sense to you the builder.. then it will most likely make sense to the player.
that doesnt mean that every person out there will be happy with the keybinds.. but for the most part, they should flow nicely.. as you build the game, the keybinds will flow naturally.

the biggest change up for me, is up is up and up is down argument with a 1st person shooter and the joysticks (i prefer flight controls)
from the little bit i know of setting up a system for changing the keybindings.. it can be rather involved..
the question is... is it really needed? ... if the controls are intuit enough, prolly not necessary... but again.. options are nice to have ;o)
Yeh, definitely the type of game that you can pause the actual gameplay and mess with settings... And I'm beginning to concur on the key settings... I'm confident that myself and the programmer will come up with the most ergonomic set-up for both gamepad and keyboard. I was just sort of feeling intimidated that so many games allow for users to assign everything custom, but then again, this particular game will not be nearly as complex in matters of melee and items handling, etc.
 
- It's probably a bit too late for this now, but maybe UI scale setting? Like what Banished does?

- Also maybe some sort of Colour Blind option, where the UI and the important elements will change their default colors depending on the color blind condition the people have.

- Is there a difficulty option? I would love to have a difficulty option I can change on the fly.

- Tooltips? Mouse over tooltips are a nice thing. Showing what each button is and what this UI element is and what is that glowing item over there? Mouse over - oh, the super-duper megaultra sword of hyper bass assery...

You know, stuff like that...
I'm currently working on a "user's guide" page off of the main menu which will explain all of the controls and UI utilities and messaging.
 
I think this is an important setting to supply. I personally am used to multi-monitor and prefer the borderless window type of thing so my mouse can just move everywhere I want. Others for whatever reason prefer a smaller window and don't care if the game is even full-screen. Others do prefer a fullscreen at max resolution.
Yeh, I think I'm going to have about as much variation as possible in this regard.



If your game can run a lower-end systems at full graphics settings, then the only one I would worry about besides the previous mentioned window type is the resolution. If you have some things you could change, like massive particle systems, different shaders, or similar, that would make the game run better on lower end systems, then I would include settings for those things. If you didn't already design your game with those ideas in mind, you are probably better off just leaving it alone and making sure the minimum requirements are high enough that it can run fine.
I'm probably going to end up buying a very cheap laptop to see how this game hold up and then go from there —it's hard to say... Thankfully, I'm not going to be using partial systems or shaders.


Its your call...but input configuration is one of my big things...I can't stand playing a game that I can't get comfy controls for. And I'm not the only one. I've even seen strange things like people wanting to use multiple different gamepads(like the DPad on one but the buttons on another), or a gamepad with keyboard keys for some inputs. This isn't just about changing keyboard keys either... so XInput gamepads(devices 0 - 3) are standard pretty much...but DInput gamepads(devices 4 - 11) can be quite varied. Some don't even have proper axes for DPads, and read those like a POV hat. If I wanted to use that and your game hard coded gamepad settings to use the axes...I would be stuck. So yeah, IMO, hardcoding inputs is not the way to go. I don't think it will completely break your game's sales...but I'm sure you are going to get some reviews/complaints about it.
These are concerns that I'm going to have to broach with the programmer, as some of the things you've mentioned here are over my head. :)
thx
 
In my opinion, there's no such thing aa too many options or accessibility features.
I feel like custom controls are a must these days. No matter how intuitive and well placed you think your controls are, there will always be someone with a different preference, or some other situation where customisation is needed.
If you have screenshake, an option to disable it is always nice, and adjusting the strength can be nice too.
As for audio, it's nice to have music and effect volumes, but I also like to include a master volume too, just in case.
 
In my opinion, there's no such thing aa too many options or accessibility features.
I feel like custom controls are a must these days. No matter how intuitive and well placed you think your controls are, there will always be someone with a different preference, or some other situation where customisation is needed.
If you have screenshake, an option to disable it is always nice, and adjusting the strength can be nice too.
As for audio, it's nice to have music and effect volumes, but I also like to include a master volume too, just in case.
So do you think that both the keyboard and gamepad should be completely customizable?
 

kburkhart84

Firehammer Games
So do you think that both the keyboard and gamepad should be completely customizable?
I say yes....but I know that wasn't meant for me :)
EDIT****
But then I personally think there should be no limits at all on it, as in they should be able to combine keyboard and gamepads as they see fit, like using the gamepad axes for moving but keyboard keys for other stuff.
 
So do you think that both the keyboard and gamepad should be completely customizable?
As much as possible in my opinion. Though, in the case of gamepad, I feel in most cases it's fine to leave some things as default, such as left stick for movement, there's little benefit I can see to mapping that to anything else.
As long as your game isn't too complex, I think at least allowing the face and shoulder buttons to be remapped is a good option to have.
In some cases, a user's gamepad may have the button IDs ordered differently which may make your default controls a mess for them(I used to have a gamepad where pressing the left bumper was equivalent to pressing A on an Xbox controller, for example).
For Keyboard-only games, 100% all buttons should be remappable. This also helps solve any potential control issues with different region keyboards(Like AZERTY for instance).
Anything that uses the mouse, should let you remap any of the mouse keys too.

It's a lot of work, I know. But I feel like it's worth it in the end.
 
I've been doing some research on gaming peripherals and was wondering about macro keys... I've seen as many as 18 extra keys built in to a full-size keyboard, and 12 keys on a gaming mouse... So when someone has those, would there need to be programming options for their respective macro/programmable keys/buttons in my control settings menu, or are these kind of keys/buttons something that the user can take care of apart from in-game control settings?

And while I'm asking, I'll mention that I've browsed about 30 different gamepads for which some have what seems to be extra macros as well. How difficult would it be to have my game programmed to detect any key or button under the sun of any peripheral "under the sun?"

I'm very much leaning in the direction of what kburkhart84 has suggested in this thread (allowing seemingly limitless customization and combination of peripherals). Although this extent of versatility might smack of overkill for the game in question, its prequel that I'm planning right now will make excellent use of it... The prequel will be at least 3 times more complex, —in terms of items and actions especially— so I might as well get the users of the first game acquainted with these control options.
 

kburkhart84

Firehammer Games
Generally, mice and keyboards that have macro keys, or buttons beyond the standard 3 for mice, also have configuration software for them. You don't really want to try to handle those yourself, rather let the user do it. I have both a keyboard and mouse like this. I set my extra buttons in the software to other keys where it makes sense. So my extra mouse keys end up mapping to 6 keys around Ins, Del, Home, etc... And my keyboard ones end up off on the number pad. This works for what I'm doing because the only games I play that need that many keys are FPS Sim games like Mechwarrior Online. So if you simply let them choose whatever they want for input, then like in my case, your game would detect PageUp when I hit that extra key on my mouse.

My recommendation is to get or make an input system that handles this stuff directly for you, leaving your game's objects out of it. My input system uses the keyboard, mouse, and all 12 gamepads(4XInput, 8 DInput) as detected by the runner. There is code that updates data automatically in a single object. That data includes what device and input is set for each "action" and then the status of that action. I store the current status(up or down), the "just pressed" and "just released" status, raw values for anything assigned to an axis, and just in case, time held down both in steps and seconds. The system also handles searching for inputs, so you just tell it to search for player 1's jump action input, and the thing searches for a set amount of time(after a small configurable delay to avoid false positives), and whatever the first input moved is then assigned to that action. It also handles collisions if you want, or lets you simply check if there are collisions and you can handle it yourself. Finally, the objects don't check any inputs at all, they simply check the status of an action to know whether to move left, jump, etc... There is also a bunch of string data representing the inputs, so you simply query what input is set for this action, and you get something like "Space Bar" or "X-Axis +." The good thing about a system like this is that you can easily re-use it in almost any game.

I'm currently re-writing my system, both just to make it better using the 2.3 features, and to add some features. The new 2.3 stuff is letting me make tings easier for future features than they would have been before. I'm likely going to release it with 2.3, but I may not wait if I finish it before they do and it looks like they aren't going to be breaking anything. The old system is perfectly usable though, but this version isn't directly back-compatible.
 
Generally, mice and keyboards that have macro keys, or buttons beyond the standard 3 for mice, also have configuration software for them. You don't really want to try to handle those yourself, rather let the user do it. I have both a keyboard and mouse like this. I set my extra buttons in the software to other keys where it makes sense. So my extra mouse keys end up mapping to 6 keys around Ins, Del, Home, etc... And my keyboard ones end up off on the number pad. This works for what I'm doing because the only games I play that need that many keys are FPS Sim games like Mechwarrior Online. So if you simply let them choose whatever they want for input, then like in my case, your game would detect PageUp when I hit that extra key on my mouse.

My recommendation is to get or make an input system that handles this stuff directly for you, leaving your game's objects out of it. My input system uses the keyboard, mouse, and all 12 gamepads(4XInput, 8 DInput) as detected by the runner. There is code that updates data automatically in a single object. That data includes what device and input is set for each "action" and then the status of that action. I store the current status(up or down), the "just pressed" and "just released" status, raw values for anything assigned to an axis, and just in case, time held down both in steps and seconds. The system also handles searching for inputs, so you just tell it to search for player 1's jump action input, and the thing searches for a set amount of time(after a small configurable delay to avoid false positives), and whatever the first input moved is then assigned to that action. It also handles collisions if you want, or lets you simply check if there are collisions and you can handle it yourself. Finally, the objects don't check any inputs at all, they simply check the status of an action to know whether to move left, jump, etc... There is also a bunch of string data representing the inputs, so you simply query what input is set for this action, and you get something like "Space Bar" or "X-Axis +." The good thing about a system like this is that you can easily re-use it in almost any game.

I'm currently re-writing my system, both just to make it better using the 2.3 features, and to add some features. The new 2.3 stuff is letting me make tings easier for future features than they would have been before. I'm likely going to release it with 2.3, but I may not wait if I finish it before they do and it looks like they aren't going to be breaking anything. The old system is perfectly usable though, but this version isn't directly back-compatible.
So just to clarify: For keyboards, I should just worry about the 80% (no macros or number pad), and for the mouse, I should just worry about right click, left click, and scroll?

EDIT: I looked up 4XInput and 8 Dinput, but couldn't find info. Do these just represent the standard controls on a playstation or xbox controller?
 

kburkhart84

Firehammer Games
So just to clarify: For keyboards, I should just worry about the 80% (no macros or number pad), and for the mouse, I should just worry about right click, left click, and scroll?

EDIT: I looked up 4XInput and 8 Dinput, but couldn't find info. Do these just represent the standard controls on a playstation or xbox controller?
So on keyboards, the numberpad is part of the standard keys, though macro keys are not. Also, I forgot to mention(though its not likely to matter), some keyboards have these "media keys" and those sometimes are detectable by keyboard_check_direct(). Since in my input system I literally loop through all 256 ASCII keycodes(except some that are not valid), my system picks those up. You may want to do the same, just in case. On the mouse, I would just worry about left click, right click, middle button, and then the scroll up and scroll down. My original input system doesn't account for mouse movement as input, but I'm adding that to this re-write as well.

About gamepads...if you check the documentation in the GML reference section on the gamepad functions, it mentions about there being 12 possible gamepads. The first four(0-3) are always reserved for XInput devices, which are exclusively XBOX gamepads(of different generations). The only other time they will be anything else is if something is set to emulate that. Those devices work well with the list of constants (like "gp_shoulderlb" etc...) that are in the manual. The next 8 devices are DirectInput gamepads/devices. Those will not have any set standard, and can be anything from a traditional gamepad type thing to things like racing wheels, flight sticks, etc... I don't use the gp_ constants for those, rather I just use axes 0 - 9 and buttons 0 - 32, and POV hats 0 - 3, as that is the max amount that can be supported by the DInput standard generally. Note that the only time you would be scanning for inputs that don't exist are when you are searching for inputs, as once you know what input is being used, you only poll that specific thing for each action.

Another tip, if you do the searching like I do, where you have an object each step poll all the inputs possible(and react when something is finally pressed), you will want to store the initial values for all axes beforehand, and then compare the old with the new to detect movement. If someone has some axis like a throttle that is a physical slider, it may read at say 0.75 tilt, and your detection would pick it up right away and never search for anything else. But nif you store that it is at 0.75 at the start of the search, then it won't pick up the false positive unless the player actually move that throttle(assuming they want to use it for input). In my personal case, I also have a Nintendo Gamecube Controller USB adapter that somehow gives me false readings for some DInput device, so storing initial values before the search starts lets me avoid that false reading and only detect real movement.

Yet another tip, in my system, I prefer each axis direction to be counted as a separate input. So the left thumb stick can go up, down, left, and right. That counts as four separate inputs in my system. The reason I do it that way is two-fold. One is that so there is no difference between that thumbpad and for example four arrow keys(except that my system will additional store the raw value for the axis tilting between 0 and 1). The other reason is in case the player wants to make each axis direction do two unrelated inputs, like something that isn't left-right, rather like left does one thing, and right does something completely unrelated. I've seen this for example with the Gamecube version of Ocarina of time using the C-stick for item selecting, which though involving the same system isn't directly related to actual physical directions.
 
So on keyboards, the numberpad is part of the standard keys, though macro keys are not. Also, I forgot to mention(though its not likely to matter), some keyboards have these "media keys" and those sometimes are detectable by keyboard_check_direct(). Since in my input system I literally loop through all 256 ASCII keycodes(except some that are not valid), my system picks those up. You may want to do the same, just in case. On the mouse, I would just worry about left click, right click, middle button, and then the scroll up and scroll down. My original input system doesn't account for mouse movement as input, but I'm adding that to this re-write as well.

About gamepads...if you check the documentation in the GML reference section on the gamepad functions, it mentions about there being 12 possible gamepads. The first four(0-3) are always reserved for XInput devices, which are exclusively XBOX gamepads(of different generations). The only other time they will be anything else is if something is set to emulate that. Those devices work well with the list of constants (like "gp_shoulderlb" etc...) that are in the manual. The next 8 devices are DirectInput gamepads/devices. Those will not have any set standard, and can be anything from a traditional gamepad type thing to things like racing wheels, flight sticks, etc... I don't use the gp_ constants for those, rather I just use axes 0 - 9 and buttons 0 - 32, and POV hats 0 - 3, as that is the max amount that can be supported by the DInput standard generally. Note that the only time you would be scanning for inputs that don't exist are when you are searching for inputs, as once you know what input is being used, you only poll that specific thing for each action.

Another tip, if you do the searching like I do, where you have an object each step poll all the inputs possible(and react when something is finally pressed), you will want to store the initial values for all axes beforehand, and then compare the old with the new to detect movement. If someone has some axis like a throttle that is a physical slider, it may read at say 0.75 tilt, and your detection would pick it up right away and never search for anything else. But nif you store that it is at 0.75 at the start of the search, then it won't pick up the false positive unless the player actually move that throttle(assuming they want to use it for input). In my personal case, I also have a Nintendo Gamecube Controller USB adapter that somehow gives me false readings for some DInput device, so storing initial values before the search starts lets me avoid that false reading and only detect real movement.

Yet another tip, in my system, I prefer each axis direction to be counted as a separate input. So the left thumb stick can go up, down, left, and right. That counts as four separate inputs in my system. The reason I do it that way is two-fold. One is that so there is no difference between that thumbpad and for example four arrow keys(except that my system will additional store the raw value for the axis tilting between 0 and 1). The other reason is in case the player wants to make each axis direction do two unrelated inputs, like something that isn't left-right, rather like left does one thing, and right does something completely unrelated. I've seen this for example with the Gamecube version of Ocarina of time using the C-stick for item selecting, which though involving the same system isn't directly related to actual physical directions.
Let me ask you this: What buttons out of a full-size keyboard should be included as user-programable? From I'll be able to better design the settings interface in a way that is intuitive. I went to the ASCII website and got really confused. :cool:
 

kburkhart84

Firehammer Games
I basically just assume ALL of them. I don't assume region(except in the descriptions of what key is what keycode), rather I just loop through all of them basically. The following is my current code for putting the description strings into an array. You can see what numbers match up to what keys there. Notice at the beginning I also set all of them to "unknown" first, that way if it detects a keycode that isn't part of it, it will still be usable and just won't have a description for it. You will want to change it to whatever array name you want of course.

Code:
__fhInputDescriptionKeys[255] = 0;
for(var i = 0; i < 256; i++)
{
    __fhInputDescriptionKeys[i] = "Unknown";
}
__fhInputDescriptionKeys[vk_escape] = "Escape";
__fhInputDescriptionKeys[vk_f1] = "F1";
__fhInputDescriptionKeys[vk_f2] = "F2";
__fhInputDescriptionKeys[vk_f3] = "F3";
__fhInputDescriptionKeys[vk_f4] = "F4";
__fhInputDescriptionKeys[vk_f5] = "F5";
__fhInputDescriptionKeys[vk_f6] = "F6";
__fhInputDescriptionKeys[vk_f7] = "F7";
__fhInputDescriptionKeys[vk_f8] = "F8";
__fhInputDescriptionKeys[vk_f9] = "F9";
__fhInputDescriptionKeys[vk_f10] = "F10";
__fhInputDescriptionKeys[vk_f11] = "F11";
__fhInputDescriptionKeys[vk_f12] = "F12";
__fhInputDescriptionKeys[145] = "Scroll Lock";
__fhInputDescriptionKeys[vk_pause] = "Pause";
__fhInputDescriptionKeys[192] = "Tilde(~)";
__fhInputDescriptionKeys[vk_tab] = "Tab";
__fhInputDescriptionKeys[49] = "1";
__fhInputDescriptionKeys[50] = "2";
__fhInputDescriptionKeys[51] = "3";
__fhInputDescriptionKeys[52] = "4";
__fhInputDescriptionKeys[53] = "5";
__fhInputDescriptionKeys[54] = "6";
__fhInputDescriptionKeys[55] = "7";
__fhInputDescriptionKeys[56] = "8";
__fhInputDescriptionKeys[57] = "9";
__fhInputDescriptionKeys[48] = "0";
__fhInputDescriptionKeys[189] = "Dash(-)";
__fhInputDescriptionKeys[187] = "Equals(=)";
__fhInputDescriptionKeys[vk_backspace] = "Backspace";
__fhInputDescriptionKeys[65] = "A";
__fhInputDescriptionKeys[66] = "B";
__fhInputDescriptionKeys[67] = "C";
__fhInputDescriptionKeys[68] = "D";
__fhInputDescriptionKeys[69] = "E";
__fhInputDescriptionKeys[70] = "F";
__fhInputDescriptionKeys[71] = "G";
__fhInputDescriptionKeys[72] = "H";
__fhInputDescriptionKeys[73] = "I";
__fhInputDescriptionKeys[74] = "J";
__fhInputDescriptionKeys[75] = "K";
__fhInputDescriptionKeys[76] = "L";
__fhInputDescriptionKeys[77] = "M";
__fhInputDescriptionKeys[78] = "N";
__fhInputDescriptionKeys[79] = "O";
__fhInputDescriptionKeys[80] = "P";
__fhInputDescriptionKeys[81] = "Q";
__fhInputDescriptionKeys[82] = "R";
__fhInputDescriptionKeys[83] = "S";
__fhInputDescriptionKeys[84] = "T";
__fhInputDescriptionKeys[85] = "U";
__fhInputDescriptionKeys[86] = "V";
__fhInputDescriptionKeys[87] = "W";
__fhInputDescriptionKeys[88] = "X";
__fhInputDescriptionKeys[89] = "Y";
__fhInputDescriptionKeys[90] = "Z";
__fhInputDescriptionKeys[219] = "Left Bracket([)";
__fhInputDescriptionKeys[221] = "Right Bracket(])";
__fhInputDescriptionKeys[220] = "Backslash(\\)";
__fhInputDescriptionKeys[20] = "Caps Lock";
__fhInputDescriptionKeys[186] = "Semi-Colon(;)";
__fhInputDescriptionKeys[222] = "Apostrophe(')";
__fhInputDescriptionKeys[13] = "Enter";
__fhInputDescriptionKeys[160] = "Left Shift";
__fhInputDescriptionKeys[161] = "Right Shift";
__fhInputDescriptionKeys[162] = "Left Control";
__fhInputDescriptionKeys[163] = "Right Control";
__fhInputDescriptionKeys[164] = "Left Alt";
__fhInputDescriptionKeys[165] = "Right Alt";
__fhInputDescriptionKeys[188] = "Comma(,)";
__fhInputDescriptionKeys[190] = "Period(.)";
__fhInputDescriptionKeys[191] = "Slash(/)";
__fhInputDescriptionKeys[vk_space] = "Space Bar";
__fhInputDescriptionKeys[93] = "Apps";
__fhInputDescriptionKeys[vk_insert] = "Insert";
__fhInputDescriptionKeys[vk_home] = "Home";
__fhInputDescriptionKeys[vk_pageup] = "Page Up";
__fhInputDescriptionKeys[vk_delete] = "Delete";
__fhInputDescriptionKeys[vk_end] = "End";
__fhInputDescriptionKeys[vk_pagedown] = "Page Down";
__fhInputDescriptionKeys[144] = "Number Lock";
__fhInputDescriptionKeys[111] = "Numpad Slash(/)";
__fhInputDescriptionKeys[106] = "Numpad Asterisk(*)";
__fhInputDescriptionKeys[109] = "Numpad Dash(-)";
__fhInputDescriptionKeys[vk_numpad0] = "Numpad 0";
__fhInputDescriptionKeys[vk_numpad1] = "Numpad 1";
__fhInputDescriptionKeys[vk_numpad2] = "Numpad 2";
__fhInputDescriptionKeys[vk_numpad3] = "Numpad 3";
__fhInputDescriptionKeys[vk_numpad4] = "Numpad 4";
__fhInputDescriptionKeys[vk_numpad5] = "Numpad 5";
__fhInputDescriptionKeys[vk_numpad6] = "Numpad 6";
__fhInputDescriptionKeys[vk_numpad7] = "Numpad 7";
__fhInputDescriptionKeys[vk_numpad8] = "Numpad 8";
__fhInputDescriptionKeys[vk_numpad9] = "Numpad 9";
__fhInputDescriptionKeys[110] = "Numpad Period(.)";
__fhInputDescriptionKeys[107] = "Numpad Plus(+)";
__fhInputDescriptionKeys[vk_left] = "Left Arrow";
__fhInputDescriptionKeys[vk_right] = "Right Arrow";
__fhInputDescriptionKeys[vk_up] = "Up Arrow";
__fhInputDescriptionKeys[vk_down] = "Down Arrow";
One thing I've learned with GMS...for some reason, some of the mouse buttons were showing up as keyboard keys, with low numbered keycodes...I never figured out why. So, what I do is check the mouse first, so if there is an input there, it registers as the mouse. Then, I check the keyboard keys.

The below function is what I'm calling to search the whole keyboard. I'll post the __fhInputCheckKeyboard() function below that as well, but first this one. You will see it checking a few keys first, before going through all 256 codes in a loop. This is because if I'm on Windows, I'm using keyboard_check_direct(), which lets me separate left and right shift properly. It doesn't work on other platforms though, so I'm using the regular keyboard_check() function there.

Code:
function __fhInputSearchKeyboard()
{
    if(__fhInputCheckKeyboard(vk_lshift) == 1)
    {
        return vk_lshift;
    }
    if(__fhInputCheckKeyboard(vk_rshift) == 1)
    {
        return vk_rshift;
    }
    if(__fhInputCheckKeyboard(vk_lcontrol) == 1)
    {
        return vk_lcontrol;
    }
    if(__fhInputCheckKeyboard(vk_rcontrol) == 1)
    {
        return vk_rcontrol;
    }
    if(__fhInputCheckKeyboard(vk_lalt) == 1)
    {
        return vk_lalt;
    }
    if(__fhInputCheckKeyboard(vk_ralt) == 1)
    {
        return vk_ralt;
    }
    for(var i = 0; i < 256; i++)
    {
        if(__fhInputCheckKeyboard(i) == 1)
        {
            return i;
        }
    }
    return -1;
}
The following code is where it actually checks the keys, the __fhInputCheckKeyboard() function.

Code:
if(os_type == os_windows)
    {
        if(keyboard_check_direct(keycode))
            return 1;
        else
            return 0;
    }
    else
    {
        if(keyboard_check(keycode))
            return 1;
        else
            return 0;
    }
So basically, I'm not assuming anything about any of the keys. Besides checking the mouse first(so I don't get false keyboard readings due to GMS's funky stuff), and checking the left/right keys first in case so they get picked up before the generic keycode for shift, I'm just looping through every single possible keycode and if it gets detected, it them saves that into the configuration, and is what gets checked for that action. And even if the description string isn't there, it still has "unknown" for it, and it will still work perfectly.
 
I basically just assume ALL of them. I don't assume region(except in the descriptions of what key is what keycode), rather I just loop through all of them basically. The following is my current code for putting the description strings into an array. You can see what numbers match up to what keys there. Notice at the beginning I also set all of them to "unknown" first, that way if it detects a keycode that isn't part of it, it will still be usable and just won't have a description for it. You will want to change it to whatever array name you want of course.

Code:
__fhInputDescriptionKeys[255] = 0;
for(var i = 0; i < 256; i++)
{
    __fhInputDescriptionKeys[i] = "Unknown";
}
__fhInputDescriptionKeys[vk_escape] = "Escape";
__fhInputDescriptionKeys[vk_f1] = "F1";
__fhInputDescriptionKeys[vk_f2] = "F2";
__fhInputDescriptionKeys[vk_f3] = "F3";
__fhInputDescriptionKeys[vk_f4] = "F4";
__fhInputDescriptionKeys[vk_f5] = "F5";
__fhInputDescriptionKeys[vk_f6] = "F6";
__fhInputDescriptionKeys[vk_f7] = "F7";
__fhInputDescriptionKeys[vk_f8] = "F8";
__fhInputDescriptionKeys[vk_f9] = "F9";
__fhInputDescriptionKeys[vk_f10] = "F10";
__fhInputDescriptionKeys[vk_f11] = "F11";
__fhInputDescriptionKeys[vk_f12] = "F12";
__fhInputDescriptionKeys[145] = "Scroll Lock";
__fhInputDescriptionKeys[vk_pause] = "Pause";
__fhInputDescriptionKeys[192] = "Tilde(~)";
__fhInputDescriptionKeys[vk_tab] = "Tab";
__fhInputDescriptionKeys[49] = "1";
__fhInputDescriptionKeys[50] = "2";
__fhInputDescriptionKeys[51] = "3";
__fhInputDescriptionKeys[52] = "4";
__fhInputDescriptionKeys[53] = "5";
__fhInputDescriptionKeys[54] = "6";
__fhInputDescriptionKeys[55] = "7";
__fhInputDescriptionKeys[56] = "8";
__fhInputDescriptionKeys[57] = "9";
__fhInputDescriptionKeys[48] = "0";
__fhInputDescriptionKeys[189] = "Dash(-)";
__fhInputDescriptionKeys[187] = "Equals(=)";
__fhInputDescriptionKeys[vk_backspace] = "Backspace";
__fhInputDescriptionKeys[65] = "A";
__fhInputDescriptionKeys[66] = "B";
__fhInputDescriptionKeys[67] = "C";
__fhInputDescriptionKeys[68] = "D";
__fhInputDescriptionKeys[69] = "E";
__fhInputDescriptionKeys[70] = "F";
__fhInputDescriptionKeys[71] = "G";
__fhInputDescriptionKeys[72] = "H";
__fhInputDescriptionKeys[73] = "I";
__fhInputDescriptionKeys[74] = "J";
__fhInputDescriptionKeys[75] = "K";
__fhInputDescriptionKeys[76] = "L";
__fhInputDescriptionKeys[77] = "M";
__fhInputDescriptionKeys[78] = "N";
__fhInputDescriptionKeys[79] = "O";
__fhInputDescriptionKeys[80] = "P";
__fhInputDescriptionKeys[81] = "Q";
__fhInputDescriptionKeys[82] = "R";
__fhInputDescriptionKeys[83] = "S";
__fhInputDescriptionKeys[84] = "T";
__fhInputDescriptionKeys[85] = "U";
__fhInputDescriptionKeys[86] = "V";
__fhInputDescriptionKeys[87] = "W";
__fhInputDescriptionKeys[88] = "X";
__fhInputDescriptionKeys[89] = "Y";
__fhInputDescriptionKeys[90] = "Z";
__fhInputDescriptionKeys[219] = "Left Bracket([)";
__fhInputDescriptionKeys[221] = "Right Bracket(])";
__fhInputDescriptionKeys[220] = "Backslash(\\)";
__fhInputDescriptionKeys[20] = "Caps Lock";
__fhInputDescriptionKeys[186] = "Semi-Colon(;)";
__fhInputDescriptionKeys[222] = "Apostrophe(')";
__fhInputDescriptionKeys[13] = "Enter";
__fhInputDescriptionKeys[160] = "Left Shift";
__fhInputDescriptionKeys[161] = "Right Shift";
__fhInputDescriptionKeys[162] = "Left Control";
__fhInputDescriptionKeys[163] = "Right Control";
__fhInputDescriptionKeys[164] = "Left Alt";
__fhInputDescriptionKeys[165] = "Right Alt";
__fhInputDescriptionKeys[188] = "Comma(,)";
__fhInputDescriptionKeys[190] = "Period(.)";
__fhInputDescriptionKeys[191] = "Slash(/)";
__fhInputDescriptionKeys[vk_space] = "Space Bar";
__fhInputDescriptionKeys[93] = "Apps";
__fhInputDescriptionKeys[vk_insert] = "Insert";
__fhInputDescriptionKeys[vk_home] = "Home";
__fhInputDescriptionKeys[vk_pageup] = "Page Up";
__fhInputDescriptionKeys[vk_delete] = "Delete";
__fhInputDescriptionKeys[vk_end] = "End";
__fhInputDescriptionKeys[vk_pagedown] = "Page Down";
__fhInputDescriptionKeys[144] = "Number Lock";
__fhInputDescriptionKeys[111] = "Numpad Slash(/)";
__fhInputDescriptionKeys[106] = "Numpad Asterisk(*)";
__fhInputDescriptionKeys[109] = "Numpad Dash(-)";
__fhInputDescriptionKeys[vk_numpad0] = "Numpad 0";
__fhInputDescriptionKeys[vk_numpad1] = "Numpad 1";
__fhInputDescriptionKeys[vk_numpad2] = "Numpad 2";
__fhInputDescriptionKeys[vk_numpad3] = "Numpad 3";
__fhInputDescriptionKeys[vk_numpad4] = "Numpad 4";
__fhInputDescriptionKeys[vk_numpad5] = "Numpad 5";
__fhInputDescriptionKeys[vk_numpad6] = "Numpad 6";
__fhInputDescriptionKeys[vk_numpad7] = "Numpad 7";
__fhInputDescriptionKeys[vk_numpad8] = "Numpad 8";
__fhInputDescriptionKeys[vk_numpad9] = "Numpad 9";
__fhInputDescriptionKeys[110] = "Numpad Period(.)";
__fhInputDescriptionKeys[107] = "Numpad Plus(+)";
__fhInputDescriptionKeys[vk_left] = "Left Arrow";
__fhInputDescriptionKeys[vk_right] = "Right Arrow";
__fhInputDescriptionKeys[vk_up] = "Up Arrow";
__fhInputDescriptionKeys[vk_down] = "Down Arrow";
One thing I've learned with GMS...for some reason, some of the mouse buttons were showing up as keyboard keys, with low numbered keycodes...I never figured out why. So, what I do is check the mouse first, so if there is an input there, it registers as the mouse. Then, I check the keyboard keys.

The below function is what I'm calling to search the whole keyboard. I'll post the __fhInputCheckKeyboard() function below that as well, but first this one. You will see it checking a few keys first, before going through all 256 codes in a loop. This is because if I'm on Windows, I'm using keyboard_check_direct(), which lets me separate left and right shift properly. It doesn't work on other platforms though, so I'm using the regular keyboard_check() function there.

Code:
function __fhInputSearchKeyboard()
{
    if(__fhInputCheckKeyboard(vk_lshift) == 1)
    {
        return vk_lshift;
    }
    if(__fhInputCheckKeyboard(vk_rshift) == 1)
    {
        return vk_rshift;
    }
    if(__fhInputCheckKeyboard(vk_lcontrol) == 1)
    {
        return vk_lcontrol;
    }
    if(__fhInputCheckKeyboard(vk_rcontrol) == 1)
    {
        return vk_rcontrol;
    }
    if(__fhInputCheckKeyboard(vk_lalt) == 1)
    {
        return vk_lalt;
    }
    if(__fhInputCheckKeyboard(vk_ralt) == 1)
    {
        return vk_ralt;
    }
    for(var i = 0; i < 256; i++)
    {
        if(__fhInputCheckKeyboard(i) == 1)
        {
            return i;
        }
    }
    return -1;
}
The following code is where it actually checks the keys, the __fhInputCheckKeyboard() function.

Code:
if(os_type == os_windows)
    {
        if(keyboard_check_direct(keycode))
            return 1;
        else
            return 0;
    }
    else
    {
        if(keyboard_check(keycode))
            return 1;
        else
            return 0;
    }
So basically, I'm not assuming anything about any of the keys. Besides checking the mouse first(so I don't get false keyboard readings due to GMS's funky stuff), and checking the left/right keys first in case so they get picked up before the generic keycode for shift, I'm just looping through every single possible keycode and if it gets detected, it them saves that into the configuration, and is what gets checked for that action. And even if the description string isn't there, it still has "unknown" for it, and it will still work perfectly.
This is starting to make a lot more sense —despite my not being a programmer. So it looks as though all of the bases would be covered, which is what I was most concerned with...
Regarding your designating each direction of the left thumbstick as a separate input, why or why not do that for the other thumbstick, or directional buttons below the left thumbtack too? I suppose I'm kind of concerned as to how a user might receive this level of versatility in one aspect, but then less so in others...?
 

kburkhart84

Firehammer Games
This is starting to make a lot more sense —despite my not being a programmer. So it looks as though all of the bases would be covered, which is what I was most concerned with...
Regarding your designating each direction of the left thumbstick as a separate input, why or why not do that for the other thumbstick, or directional buttons below the left thumbtack too? I suppose I'm kind of concerned as to how a user might receive this level of versatility in one aspect, but then less so in others...?
Your concern is valid...I DO in fact do the same for all of the axes, I just mentioned that specific one as an example.
 

kburkhart84

Firehammer Games
I don't know, don't have one of them. I haven't seen any constants for them in the documentation either. It wouldn't be a bad thing to mention in the 2.3 beta forum so it is at the least brought to their attention.

If it were a DInput device, I'd just assume they would be picked up as simply another higher button number...but since its XInput, there all constants for all the working buttons and axes.
 
Top