I was leery to make my second post be a more technical one. However, it’s been a little over a month since my first post, and I wanted to give an update on what I have been doing.
In my about page, I mentioned that I started building the game in Game Maker Studio (GMS) 1.4. I did this because of how similar GMS 1.4’s interface was to what I used to use when I was a kid. When I was first coming up with the initial ideas of the game, I wanted to quickly get my ideas in code, much like how writers gets their thoughts down on paper. The last thing I wanted to do was learn a new interface while building out game ideas. Thus, I started making the game originally in GMS 1.4.
I decided about a month ago that it would be a good time to start porting. For one, my leave of absence is coming up soon. I figured it would be a good time to start using GMS 2 and learning the new interface. Secondly, GMS 2’s device support is much better than GMS 1.4. Being very ambitious, GMS 2 supports the Nintendo Switch — and I would love for Mario to play my game someday. Finally, there were a few new core features that GMS 2 has that I was really needing.
GMS 2 completely redid the way they handled tiles, and for the better. Violet the Game is using a tile grid, much like many games in this genre. Tiles are exactly what they sound like, squares in a game that represent some graphic. The tile engine in GMS 2 is much faster now, supporting tile maps too. This is really useful for the game as I can start using tiles for backgrounds, and not take a performance hit, which was happening in GMS 1.4.
Along the lines of tiles, I had created a concept called decor tiles. Decor tiles are pretty similar to standard tiles, except these tiles can be scaled and animated, unlike traditional tiles that are on a standard grid. When coming up with the idea of the decor tiles out with GMS 1.4, they were taking a performance hit due to how GMS 1.4 handled tiles. However, GMS 2 solves this by having what is known as assets, which are graphics with no other interactions.
With the open world, we needed a way to turn these assets on and off. Computers are pretty fast now compared to what they used to be. But, loading an entire open world of these assets would surely cause any game to crawl to a screeching halt. The way we solved loading all the assets at once is to break up the entire open world into zones. We defined a zone as a 960 x 960 pixel grid. These grids are loaded into the game based on the camera’s position. We will always load the zone the camera is in, plus a few surrounding zones. To do this, a zone name can be defined as assets_i_j
, where i
is the camera’s left position over 960, rounded down, and j
is the camera’s top position over 960, rounded down. For example, if our camera’s position is in location (2000, 1000)
, i
would be 2
and j
would be 1
. Thus, we can toggle an asset group called assets_2_1
and turn that layer on.
The final big feature that GMS 2 added was a new concept called layers. I have mixed feelings about this new function. On one hand, it solved my problem of these assets as when we say “asset group”, we mean a layer. It also solves the problem with tiles as that we can have multiple tiles on multiple layers. I think my biggest issue is how layers work with objects and the rendering order.
To give an illusion of a 3D perspective in a 2D game, objects need to have some kind of depth to them. In GMS 1.4, every object has a depth variable. Objects drawn at a smaller depth will be drawn closer to the camera versus objects with a higher depth. An easy way to give this illusion in Game Maker was to set an object’s depth
to -y
. Using an inverted y axis (like most game engines do), the farther down an object is in a room, the larger its y
variable will be. If we want that illusion of fake 3D in a 2D game, we can take an object’s y
position, which is larger the farther the object is from the origin, and negate the y
value, thus, being closer to the camera.
Though we can use a depth
variable in GMS 2, the engine prefers to use layers instead. GMS 2 will not let us mix depths and layers. In fact, if we assign an object a depth
, GMS 2 will automatically create a layer and manage it for us, giving one no access to this said layer. Depth according to the GMS 2’s manual is slower than using layers. However, I did not notice a slow down using depths, unless being called every frame by every object. So, we solved this by only changing the depth
variable when an object needed its depth to be changed.
Why is this depth and layer thing a big deal you may ask?
In order to do the 3D illusion with layers, we have to take every object in the layer, and make a list ourselves, sorting by the y
value descending. Then, once sorted, we can draw each object. I had a couple problems with this approach:
- Making a list and sorting every frame was CPU intensive. Sure, I could figure out ways to make a list pre-sorted, but…
- I had to turn off the default drawing functionality of Game Maker to do this. To turn off Game Maker’s draw event for an object, we can set a
visible
flag tofalse
. To me, setting a core built in variable like this seemed weird and counter productive to the readability of the code later on. - By doing this approach, we completely bypass the framework in which Game Maker works for rendering objects, almost side stepping an optimization.
For me, the depth = -y
approached seemed like a much better way of handling drawing. I just wish there was a native way to group objects using the depth = -y
approach with layers at the same time.
Those are the main core features that GMS 2 introduced in their latest version of Game Maker that I found useful. If you stayed with me through this post, then you’re a trooper! Thanks for reading.