Warning: This Might Be Really Boring Or Too Detailed In Some Spots!
For the last few weeks, since Wag Royale launched I have been working on what I’ve been calling MDK, a Mobile Dev Kit. Essentially it’s my toolbox for making mobile games going forward, with (hopefully) all the tools I need to make creating a game a lot smoother, easier, and quicker. I don’t want to have to re-engineer pop up messages or a menu system every time!
Nothing here is revolutionary, but I wanted to streamline any of the headaches I had in Wag Royale, and also add any features I thought about but didn’t want to get distracted too from shipping at the time.
First up is fairly simple: I made some scripts to make my life easier. Creating popups, setting up the tweens (Tween GMS Pro) for a menu or a popup all used to take multiple lines. Now I do them all in one with a set of arguments passed into a script that handles it all correctly for me. Speaking of pop ups, now they use a queue system so the player will never miss a message. Whether they read them all or not is another problem.
Something else fairly simple but that can make a big difference is using inheritance. I was not using it as much as I should have. Now all my buttons, menus, popups are all derived from parent objects. This means when I decide on a style of UI for a game, or if the buttons should inflate or squish when pressed, I only need change it once. (I know this is maybe obvious, and I was using parent/children objects before, but just not as much as I could have)
One change I went through and made to all my menus is to move their origin from their top left corner to the centre of the menu. Before you got problems if you wanted to scale the menu, it shrank up into the corner rather than nicely shrinking in place. It also means I now don’t need to calculate positions much for menus and popups based on their size, just put it in the middle off the view!
While on menus, I also created some sliders which will probably be used mostly for music/sfx volume control. Before I just gave the option to mute and that wasn’t great really. The sliders can also be passed an option to have them “soft lock” to certain increments, say you used the slider for choosing difficulty, or something that only has certain applicable values.
A terrible way to do your dialogue is to hard code the strings wherever you needed them, so that translating the game would be far too much effort and nobody would want to do that. This is what happens when you start off by figuring things out a long the way rather than planning properly! So now I have a system to load strings from a file, and this allows me to swap which part of the file I load from, allowing easy language swapping! Of course the translation still has to be done with care, and each tested in their own right. Some might need some forced line breaks (Japanese for example). Non latin langauges also pose a problem with very large fonts required if you want to have every glyph loaded. Thankfully Gamemaker has a tool when setting up fonts that can help here. You can feed it a file (for example, the file holding all your dialogue) and it will load the necessary glyph ranges into the font you are using.
I’ve implemented Scribble for rendering text. A lot off the time the regular draw_text functions are fine, but if you want to do anything fun like change the colour mid string, or have in-line icons as part of text, then it gets very complicated to do yourself. Scribble makes all of that so much easier. It’s also meant to be much more efficient than doing lots of regular draw text calls, as it is vertex buffer based and uses shaders to process effects efficiently. It also supports events, so I can play a sound on a certain word being revealed, or trigger an in-game event, or tell my text box to change the avatar and name of who is talking, all by tags written in the string itself. It also allows for clickable text, meaning making dialogue choices is incredibly easy to set up.
Along with Scribble I also made my text boxes creatable with a single script, and if set by the text, will draw the text to the side and display a sprite and name (so you can see who is talking to you, if the game has characters that do!). The avatar can also change sides, to make it feel more like a back and forth conversation. Again this is all defined by tags in the text itself, so very easy to create and also very easy to modify.
Something else that wasn’t really up to the task was my saving and loading system. Before I would copy anything I wanted to save into a map (dictionary-like data structure) giving it a key, and then in the load script I would just do the inverse. This meant I had to remember to add a variable to both the save and load script, and each variable needed its own line. It got pretty long, and more than once I typo’d a key and loaded garbage incorrectly.
Now, I pass an object, along with all of the variable names I want to save, to one script. Due to how Gamemaker accesses data structures, they need their own special script. But at most each object will now need 2 lines to save every variable and data structure it has. The real time saver is the loading. Now with the information I save, I can run a generic loading script over everything that is saved, and it finds the object to copy the variables to, or creates it if it does not exist. So this can be used at the start of the game, or it could take a snapshot of a level and re-create it again later.
I spent some time checking out a few free to play games to see if there were any common features around that I should try and implement, and one that stood out to me was, well, loot boxes essentially. Spending the currency you earn to roll the dice at getting a cosmetic seemed quite common. So I decided I should make a loot drop system, but I wanted to make it pretty adaptable. So first it needed to be weight based, I didn’t want to go in and change percent chances on everything just because one objects drop rate needed changing. Next it needed duplicate protection. If an item is tagged as unique, or one time only, and it is listed in an inventory, don’t include it in the drop table. I also included rarity tiers, just in case I want to make a game with actual classical loot mechanics some day, or maybe just make some tiers of cosmetics, who knows. But it felt like a worthwhile thing to have, even if some games only use one tier and have even odds on everything.
So now I can set loot tier weights, and in those tiers add items, which then have their own weights, and this can just be defined on the creation of an object, so I can have different types of boxes to open with different odds, for example. The slider in the image is changing a bias parameter, changing which tiers will be chosen to drop.
Finally comes the camera and view system, along with managing the UI alongside it. Wag Royale used Gamemakers built in screen scaling. It would make sure the aspect ratio was kept, meaning depending on the device you could have black bars on either the sides or top and bottom of the game. This works but it isn’t really much of a solution. It looks weird, and people (especially with expensive iPhone X’s) can get a bit upset that something doesn’t take advantage of the whole screen. So now going forward all my background templates will take these screen sizes into account, and the view of the game will expand to fit the screen. This may change game-to-game, as some types of game may not have much extra to show in that larger space, like a puzzle game, everyone needs to see the same board. But the board can be enlarged for larger views, and at least now I can have a nice background graphic rather than black bars.
Along with the view/screen changes, I’ve put in a camera system so I can zoom in and to places/objects. This might not be needed in every game, but a nice feature to have. Of course I also added in screen shake because everyone loves screen shake.
With a moving camera and view, the UI needs to stay in place. So it does! The main system I have now is for deciding where a UI element should be on the screen. I have made 2 ways of handling it, the first is to anchor the object to a point (top middle, bottom middle, middle right, etc..) with a pixel offset for both x and y, so an element can always cling to the edge if required. The second method is to divide the screen up into rows and columns and return the normalised distance the object should be placed. So if the number of buttons along the side of the screen is dynamic, they will evenly space themselves out nicely without any extra effort, or me putting in numbers of pixels by hand to make things look nice.
Something I won’t really touch on because I didn’t change much was the Ad system and IAPs. These are also in there so I hopefully never have to fiddle with the extensions ever again, as they are temperamental, and have required a few hacky fixes to get working right for both platforms.
And that’s pretty much it! Hopefully this will save me time and effort in my next mobile projects, and if any features in future games give me a good idea for a general tool, I’ll be back to add them to this base project.