Dev Log Entry 8: An object shepherd?

This is a dev log about creating a game called Newtius in GameMaker Studio 2 (Indie edition). Starting with entry one might make this easier to follow.

In entry 7 I tried to “noodle through” some concepts I was trying to make fit in my head. This brainstorming along side re-reading some of the GML documentation entries I think has lead to some possible success this area.

As always, the Official newtius project page on itch.io is up, featuring the last playable version.


With some progress made in the last entry about understanding some relatively basic concepts I think I’m ready to try and attempt applying what I think I’ve learned to Newtius.

I had read this paragraph on the GML language reference numerable times previously, and I feel like I was vaguely aware that alarms are somewhat analogous to timers from back in the VB 6 days. But it wasn’t until last night the information started to click.

It should be noted that the alarm is not finished when it reaches 0 (although the event has been triggered) as the next step it will go down to -1, so if you need to stop an alarm for any reason you should set its array value to -1 not 0. Alarm times are calculated in game steps, with a value of 30 being 30 steps, 60 being 60 steps, etc…

GML Language reference on YoYo website

First and foremost the thing it seems like I was still missing at the end of the last entry was how the alarm “ended”. And it can be ended by setting the value to -1 (negative one). That last part is where I wanted to concentrate: to stop an alarm, set the alarm value to negative one.

Later update: turns out I had already tried setting the alarm to -1 and it didn't do anything. So apparently lesson not learned.

The second part is is how the slice of time that the alarm represents works. That part I was mostly familiar with, but really all I need to care about is 60 representing “one second”.

To combine those two things, if what I want to do this “spawn” five and only five instances of an enemy I would want to use a timer to generate these and when done kill the loop by setting the alarm to negative one.

The controller object

Almost all the tutorials I have followed – both in DND mode and GML mode – have ended up using a controller object of some kind. And most of those have also implement a “parent” object: something other objects could use as a foundation then customize from there.

I think I want to do this one step at time though, just starting with the controller object.

(~6 hours later)

I must have spent at least 5 or 6 hours on this today. Possibly longer. Just to get a stream of five equally spaced enemies to crawl across the screen.

Well I spent all that time and then broke something so the enemy ship weren’t showing up at all any more. I’m not still not sure what caused it to stop working. It was probably setting a room_height variable to a positive instead of negative number. That got me a couple of times today.

Anyway, I archived the broken version of Newtius and re-cloned the git hub repository. Since relatively little time was spent with the working version it wasn’t that hard to re-create what I had done: move the enemy spawn code from the enemy create event to the “obj_spawner” object create event and change the instance_create_layer call so it specified the enemy object I wanted, which I unhelpfully named obj_pattern_enemy. Eventually it will have a pattern to its movement rather than straight across the screen in a straight line.

This code actually still isn’t working the way I had it working: for some reason there’s a weird gap between the first and second spawned enemy. Which didn’t happen the first time I got it working. And I can’t tell where the difference in the code is.

Object: obj_spawner
Event: Create

// I later found a better solution 
// see below for corrected version of this
iEnemyCount = 4;
alarm[0] = 29; // closest i could to get same gap. 24 is too close
instance_create_layer(room_width - 10, room_height - 300, "EnemyLayer", obj_pattern_enemy);

Object: obj_spawner
Event: Create

// I later found a better solution 
// see below for corrected version of this
if ( instance_exists(obj_pattern_enemy) && (iEnemyCount--)  ) {
	instance_create_layer(room_width - 30, room_height - 300, "EnemyLayer", obj_pattern_enemy);
alarm[0] = 24; // gap I liked between enemies
} else { exit; } // no idea if exit is necessary

To try and lay this out: the create event creates variable iEnemyCount and sets it to four. Then there’s a reference to alarm[0] which effectively “calls” or you could say fires off the event for the code in alarm[0]. Then one instance of creating the enemy is created.

From there it’s all on alarm[0]: an if statement that makes sure the enemy exists and a short hand true/false with a iEnemyCount decrementer that will return zero/false when it gets to zero.

(Even more later)

I tried something else more while I was writing above. But instead of deleting above and writing it again I’m going to leave it as a learning exercise to demonstrate the the difference in behavior.

That inconstant gap between enemies drove me to try something a little different as I was writing this post.

First, in the Create event, I commented out the instance create. I think I had put that in there because the compiler kept giving a “called object before setting a value” error. So the spawn enemy object line was so that enemy object existed before the of the code would run over in alarm 0.

Object: obj_spawner
Event: Create

// slightly altered but better version	
iEnemyCount = 5;
alarm[0] = 24; // just leave as same value for "good gap"
//instance_create_layer(room_width - 10, room_height - 300, "EnemyLayer", obj_pattern_enemy);
	

Object: obj_spawner
Event: Alarm 0

//The real change: took out the check to make sure an enemy objects 
// exists and instead just check the enemy counter variable
// while also decrementing
if (  iEnemyCount--  ) {
	instance_create_layer(room_width - 30, room_height - 300, "EnemyLayer", obj_pattern_enemy);
alarm[0] = 24; // same as the create event. just to make sure.
} else { exit; } // no idea if necessary but doesn't break anything

So in the end it turned out to be not that complex of a problem. Or less complex than I assumed. Set a counter in the Create event and call Alarm 0 and in Alarm 0 do an if loop against the value of the counter and spawn the enemy objects.

As soon as I got it working I committed the changes and put it on GitHub. So hopefully I’ll have some kind of backup. Or I could learn git and how to roll back changes and create branches. Whatever.

I actually also put in a “instance destroy” in the step of event of the enemy object itself so they didn’t continue to exist once they left the screen (when enemy object x value is less than 0). I got this from the existing bullet object. Seems like something should go in a “parent enemy” type object since all enemy objects will need that. I used the step event instead of the “outside room” event because I might want to start the spawning from “off screen” or more accurately the width of the screen + 100 pixels or whatever.

Making these enemy objects something the player object can destroy or be destroyed by should a relatively easy task of adding collision events and decrementing a hit point variable. I already have an example of this from the original enemies of my first build, the orange circles that just start moving towards the player object.

It feels like I’m not quite conveying exactly what I went through today to get this to work event as it is: I explored the GML reference with instance_count and instance_copy as well as a few others. I used the show_message function as a debugger tool to try and figure out the value of difference variables at different times. I must have had ten different versions of the if loop I ended up with.

After all this I probably want to start the Space Rocks follow tutorial, Space Mods . That might take a while. Or maybe I’ll see if I can create Snake or some kind of Tetris-style puzzle game without any tutorials. That sounds…easy?


The latest version/progress of Newtius can always be found at my GitHub repo:
https://github.com/tildesarecool/newtius

One thought on “Dev Log Entry 8: An object shepherd?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s