Recreating my old game in Construct 2
Week before Ludum Dare I decided to try Construct 2 and see if it’s worth my time. First two attempts were not successful, but third time’s a charm!
This is Post Mortem and almost tutorial showing the process of creating my game “Mash for Three” while trying to understand how Construct 2 works.
I should start by saying that I had zero experience with this engine, but I’m not a newbie. I've been taking part in Game Jams for almost 4 years and made over 40 games using mostly GameMaker. But now I’m looking for some alternative 2D game engine.
While GameMaker is incredibly powerful engine with many export platforms allowing me to publish one game to desktops, mobiles, HTML5 and even consoles without single change in code… sometimes it just has a bad day. After 2 games ported to HTML5 with bigger problems than expected, and upcoming Ludum Dare, I decided to give Construct 2 a try.
I downloaded the free version, and started my journey. After 5 minutes I already knew how to add resources, edit them and place on Layouts. I run a preview and saw what I made in my browser. It was really intuitive and easy.
I discovered Project Properties and started changing fields there. What I found was more than I expected. Window size, fullscreen scaling, sampling and many more in one place.
I think I got everything I needed. It was time to check some tutorials.
First one I tried was Platformer Template. It had premade Layout with some solid platforms, few moving ones, and even jumpthru platforms. I saw tab with Event sheet. There I found what I was missing. Programming! Quickly glancing I saw something what looked to be responsible for movement of the player. Without changing anything I launched example… and I was really disappointed with what I saw. Incredibly laggy Box2D platforming. Unplayable. I laughed and wanted to close Construct 2.
I hope you didn't stopped reading this. I’m sure it’s not that bad. It’s just my point of view that isn't crystal clear. I’m a person who loves to have full control over my game. I hate Box2D and never could came up with a game idea that could use it. I’m always designing my own physics and trying to get as much as possible from it. I’m also really sensitive to how game is optimized. That’s why I’m testing my games on Pentium 4, and in GameMaker I learned how to make miracles. That is why you shouldn't take my word for it and should probably try it for yourself.
I looked into the Event sheet to get more familiar with it. It is made from 3 basic elements: Events, conditions and actions.
If conditions in event are meet then all actions and sub events are executed.
I learned that really quick. Adding new events and actions is simple. Right clicking on event opens menu with all options. I made event to work as ‘or’ block and created subevents. I didn't needed any explanation. Everything was clearly visible. Then I started playing with actions. I was welcomed with window in which I have chosen an object, and then list of all actions I could perform. The only thing I didn't liked is that I could not use my fourth and fifth mouse buttons to move back and forward. I also learned that you need to add keyboard to game resources to use it. Same with mouse, gamepads, arrays or functions for WebStorage or Kongregate API.
That was enough for me to start planning. I've had one game I wanted to port to HTML5 for a long time. After a few hours I gave up because it would take too long, and I started working on smaller one. This also wasn't a success. Quickly I realized that WebStorage functions from Construct 2 will not let me do what I wanted. I could somehow use JSON to do what I wanted, but that would be a waste of time because unexpectedly keyboard functions are limited to checking single key or keycode, and I needed to read player input and save it to string. Probably it is possible but I will not try to do this again in Construct 2.
Creating a game
I finally found game I wanted to do and thought Construct 2 could help me make it.
Really simple game I made in two or three hours for Ludum Dare 31, of course using GameMaker. I remember that I had no idea what to do, my friends band was playing and I was invited. I got few hours before the concert so I came up with an idea for this Match-3 variation.
9 buttons that change color after clicking on them, and if 3 or more is swiped they give bonus points.
I fell really comfortable and knew that all of this could be done in Construct 2.
I began by importing all assets. 4 sounds, 4 button sprites and one sprite of a finger used in tutorial screen. I knew that I needed few global variables to store values i.e. player score. I placed button objects on Layout and changed what I wanted in properties. I wanted to leave sharp pixels and scale it at least two times. My Layout Size and Window Size is 128 ,128. I set everything to low quality, and changed Sampling to Point. Preview showed me effect I exactly wanted.
It was time to start working on Event sheet.
First event I created was “System > On start of layout” where I put an action to set animation speed to zero, and set array Selected size to (1,1,1). Yes, all arrays in Construct 2 are three dimensional. I set it to this size because I wanted to use it as a stack or queue. It didn't matter which one. I just wanted to have an array that I could iterate over, but after all trouble I got with understanding how exactly the events worked, I realized that I haven't even used that array. I only checked it’s size so all I really needed was another global variable to hold how many buttons are pressed.
The whole gameplay is based on three events: Clicking on buttons, pushing buttons while mouse is pressed, and releasing mouse to “collect” pushed buttons. Clicking means that only one button was pushed and when this happens this button’s color changes to “next one”. When the mouse button is held down all buttons under mouse cursor become pressed. They don’t need to be in line, it’s not a rule. Last event is when mouse is released. That’s when game checks if your selection was valid, and you can be awarded with bonus points.
Let’s start with pressing buttons down. In game I needed 4 variables: Two integers color and Randomize, and two booleans isBomb and isSelected. The rest was used in transitions which I’m not going to cover in this article.
Booleans are self explanatory, Randomize is used later, and color is value used to compare our selection. I didn't wanted to compare color values, and it’s easier to think about it as first or third color.
In GameMaker I used blend modes to draw colored buttons. I've found similar option in Construct 2, but it didn't worked for me as well as Effects.
I decided to draw by hand all buttons, so I made 4 animations: Default, Set, Bomb and BombSet. Each one with 6 frames where single frame was different color.
I created new event “Mouse > On Left button Clicked on Button”, as action I increased global score by 1, added 1 to color and played sound. Another event was to test if color was larger than the number of colors (global colorCount) in my game. If true then subtract colorCount from color. Later I changed that first event to more complex one, but that was basic concept and it worked.
That was moment when I had to learn about expressions. Construct 2 doesn't let you to make mistakes. It took me few tries to understand what is going on. When I tried to set animation frame to color Construct 2 wasn't let me to do this. I was kind of lost, because I knew what I wanted to do, but I was making it wrong. Fortunately there is a drop down menu with all possible expressions. Solution was to address my object and then I could do everything fine.
This is really good part of Construct 2 and for me probably the biggest advantage of this engine. Not that I need this feature but I realize that for real newbies this is live saver. Actually this feature was a pain in the ass for me, because most of time I’m used to writing my code in one go and going back to initialize all variables. Here I had to first create variables because Construct 2 would not let me use variables that didn't existed beforehand.
It was time to dig deeper into events. I already knew how to make subevents, ORs and NOTs, but I didn't knew that a bigger enemy awaits me. Something really chaotic and used everywhere without me knowing. It was event picking. I bet it’s described in a basic tutorial but I was shocked by it’s magic.
Basically it means that if event is executed it picks only those objects that passed that conditions. It’s really convenient and for most times it works great. In example when I clicked on a button its value isSelected changed to true, and only in the one button I clicked on. Problem was when I tried to do something more advanced. But first let’s have a look at how I changed my base three events.
I could no longer test simple clicking on Button because more important was to check if player is connecting Buttons, and only if he wasn't I could check for clicking. What I did is I made two events. First was checking if mouse button is pressed down and also if mouse is over Button. Then for that button if isSelected = false set isSelected to true and push value of Button.color to array Selected. That’s the same array I said I didn't used. I could change it to variables now but I’m not going to bother.
The second event is on mouse button released. That’s when 80% of the game happens. Inside we have three events: first is to checks if collection was valid, on outside it’s just if array Selected size >= 3.
Second event is just else, so it triggers when array size is < 3, but then I check if size is <= 1 and it is our single click.
But what’s most interesting is the last event which doesn't have any conditions and I use it to clean up after events and to unselect all buttons.
Let’s start with “combo”. So if player pushed three or more buttons I’m setting temporal variable c to first value from our array. Then for each pressed Button I’m checking if it’s variable color is same as what I've found in array. If it’s not then it means one of the buttons that player pushed was in other color and I’m setting c to -1. In the following event I’m checking if c != 1. If “combo” was good then c should hold color number.
As I said, instead of an array I could use two global variables and everything would be fine, but here you can see that before I found working solution I was trying to use a loop to iterate over that array. Later, I talked with a friend who worked on Construct 2 before, and he told me that arrays do not always work like we want them to. I still don’t understand what was wrong, so I think he was right.
But let’s get back to what is happening when player makes a valid combo. If all conditions are meet I’m adding points to player score based on how big combo was, then I change background color, play sound, send data to Kongregate, but most importantly I give value to global variable bombsToCreate. Then for each pushed Button I set variable Randomize to 20 and disarm it if it was mined.
Randomize is used as animation response to player that his combo was right. All it do is while Randomize is larger than zero I set button to random color and subtract one from Randomize. So it shows random colors on button for less than second.
I wrote before that second event is else, and then I again check if size is <= 1. That’s because I don’t want anything to happen when player selects only 2 buttons. It’s Match-3 right? So when only one of the buttons is pressed I’m triggering actions for normal clicking.
Last thing worth mentioning now is event where based on values isSelected and isBomb I’m setting right animation.
Game needs goal. Not every game, but this one do. In most Match-3 games player loses when there’are no possible moves or after clearing whole level. In my game I've got mines or bombs. I’m not sure which one. I've never named them.
Every time player successfully collected 3 or more buttons of the same color, global variable bombsToCreate was set to random value between zero and 5 based on score. That variable is responsible for changing random buttons into mine buttons. Mines explode after few seconds if they are not matched with buttons of the same color before that. Additionally player can’t change color of that button.
I started having real problems with designing conditions for choosing which buttons to change. Nothing crazy, but because of event picking it was incredibly hard. Let’s see how finished event looked like.
In a while loop if bombsToCreate is larger than zero, pick one random Button that his variable isBomb is false. Now on your picked instances you can execute actions.
That doesn't seem to be complicated, but on that single event I was learning how event picking works. That event has been changed maybe ten times, and twice while writing this article. Why? Because I still don’t fully understand how it works.
Finally I've found condition named “Pick all”, but we all should know it by name “for each”. In its description is written “Resets the picked instances to select all of them again”, but why it needs to reset them? It’s because Picking filters instances from one condition and only they are allowed for the next condition test. Like I wrote before, if you test for clicking on button it will trigger actions only for that one instance. But what if after clicking on one button I want to do something on all of them? That’s when “Pick all” is used. Maybe if I started from from simple example like that I would understand it quicker, but I jumped right into hell.
Differences between GameMaker
There are still few things in game I didn't explained, in example that buttons will change their color on they own to make it harder for player to collect all 9 every time, or how I made transitions and tutorial. But it’s not point of this article.
I want to compare here Construct 2 and GameMaker: Studio. I am aware that I worked with Construct 2 only for few days and that I haven’t used it fully, but that was enough for me.
Construct 2 is not engine for programmers, and if you call yourself one then better forget about it already. It’s based on behaviors and they are not always flexible. Designing events sometimes is overly complicated but whole interface is easily readable. That’s big advantage over GameMaker where finding place where you type your code into object can be nearly impossible for newbie.
While we talk about code, let’s get back to what I wrote before:
In Construct 2 you can’t make mistake. There is no possibility for user to make typo or address not existing object. In GameMaker it is not easy to understand concept of objects and instances, but in Construct 2 it is really hard.
Right now the thing I hate most about GameMaker is the room editor. It’s not place to write about how broken it is, but it’s really good comparison to Construct 2 where Layout Editor is incredibly intuitive and easy to use.
I think last thing I wanted to compare are free versions of both tools. GameMaker let’s you create games for Windows for free but with GameMaker logo in game start, and can be upgraded enabling you many export platforms. Construct 2 free version got one big disadvantage: limit of 100 event conditions. This limits game complexity a lot. My game exceeded this limit, and I had to make few cuts. Thankfully without changes in game. Keeping it in 96 conditions, but for so small game it is clearly visible that this limit is really low.
But HTML5 games created in Construct 2 are more stable than the one created in GameMaker: Studio.
Construct 2 and I in future?
None of the arguments appeal to me. Construct 2 for me is really slow, limited and not powerful enough to even think about starting new game using it. It is stable and error forgivable, but I’m far too experienced to profit from it.
Still if I will meet someone on a Game Jam who want to use it, I’ll think about working with it… if I can’t convince him to GameMaker.