Monday, March 3, 2025
8:20 PM
I've only been using Construct and developing for six months but I've come up with a few tricks to keep my own sanity that I haven't seen in this thread yet.
1. Use "Lookup Variables" for strings that need to be passed as parameters in expressions/conditions.
a. e.g. Prevents having to remember the tag string you used in a timer/timeline/flowchart somewhere else and from mistakes from typo's.
2. Use families to create organized "variable groups" within objects you are using as global variable banks.
a. You can reduce the number of global objects you use as global instance variable banks.
b. Looks cleaner and more organized when looking at the instance variables in the Properties bar
c. Keeps the global variable name space tidy. Just enter the family name of the subset of variables you want to enter into an expression and get a smaller autocomplete set.
d. My examples below show me using this for a set of lookups (I think of these as the construct version of lookup tables) but you could use them for any set of variables in a global variables object.
3. Make logging work for you and your visual style.
a. The more complicated your project with logic broken out in more event sheets, the harder it is to debug.
b. Create your own logging functions to give you information in the console that makes sense to you and helps you debug your particular logic structure
Here is a vertical slice example of how I use "lookup variables" in family-organized "variable groups" to support my logging functions which give me visual clarity into what my application is actually doing.
Set up multiple families for each group of variables on the same object:
NOTE: Here I am using ForConstruct's "Globals" object plugin, but you could do the same with any sprite on a layout that you mark "Global"
Now create FAMILY-LEVEL instance variables on your global object:
Now your variables (in this case they are being used as global constants) are divided into easy to read groups (Construct 3's version of lookup tables in this case).
NOTE: I am creating an underwater game, so I was actually able to find corresponding emojis to many of my enemy types. I use them in the console logging because I'm a nut.
Now you can search the autocomplete namespace by using the family name when using in expressions:
Now for my logging. My undersea enemies have complex movement that can't be replicated by a single movement behavior in Construct 3. In order to get the different movement patterns I want I have a hierarchy of actions named Phases, Modes, and Behaviors.
• Phases call a specific Custom Action which starts a specific movement/animation combination. (e.g., signal you are about to move, move to location, pause for a duration)
• Modes are combinations of one or more Phases
○ e.g. Mode "Pulse" = Signal Move, Glide to position, Pause
○ Mode "Drift" = Drift slowly to ocean floor.
• Behaviors are combinations of or repetitions of Modes,
○ e.g. Behavior "Rise_And_Fall" = Set Mode "Pulse" repeated till you hit the surface, then switch to "Drift" until you reach the ocean floor, repeat.
But I have this logic spread out among different event sheets, Phases and Modes in their own sheet and Behaviors in a master Enemy Logic sheet, plus another sheet for Advanced Signal Listeners (Thanks
Overboy!) and triggers, which control the shifts between the different states
. It can be tough tracking bugs across all this.In this console screen shot I use indents and icons to visually show the filtered behavior of a single enemy and I can see its entire behavior cycle across my various event sheets.:
I can now see the enemies AI lifecyle in a visual manner that makes sense to me and allows me to easily spot when things are happening out of order or are missing. For instance:
All game events call signals to logging functions so I know exactly what is happening, for instance when a player is struck by an enemy:
The attack is resolved in its entirety before the system moves on to anything else.
But when I hit an enemy with a projectile I see this:
The game is allowing the enemy to call parts of its action AI before the attack is entirely resolved. Even though this isn't causing any bugs right now, I know this is asking for trouble. There are almost certainly going to be bugs where an attack results in an enemy death, but the proper animations don't fire because its calling the AI which is also messing with animations and variables. I now know I need to fix this to avoid problems in the future.
Anyways, curious to see people's thoughts on the above. Has anybody been using families with global variables like this already? Does anybody else have console logs that look children's picture books? Am I just weird with this stuff?