Copied from ProjectSpark.com
Who should read this guide
If you already understand why you’re here, then feel free to skip to that last “Implementing…” section of this guide.
If you’re completely new to Project Spark, I suggest you come back to this guide later when you’ve gained some experience, otherwise this will probably be too much too soon.
Whatever your experience, if the example in the “What problem are we trying to solve” section below seems completely harmless to you, then you should read this guide 🙂
Why was this guide written
More and more, I see people asking why their level sometimes works fine, and sometimes not. Very often, the issue is observed when the level first loads up (right after you click “Play”).
While it is definitely possible that there is an actual bug with Project Spark itself, it is quite likely that the issue is caused by not having implemented a startup sequence.
So what’s a startup sequence?
A startup sequence allows you, to specify the ORDER that things “come to life” when you first launch a level, and that is very important!
Why is it important to specify the order?
The short answer is that there is no guaranteed order at which objects (props) in your level will “come to life”, and there’s absolutely no way for Project Spark to make that guess. Since this order is unknown, you will encounter problems when you have props that are dependent on the state of other props, especially when the level first loads.
In what situation is a startup sequence required?
Simple. The moment you have one (or more) prop/brain that is dependent on the state of another prop/brain, then a startup sequence is pretty much mandatory. This is especially true when the level first loads and you are initializing values using a [once] tile…which is a typical thing to do.
What problem are we trying to solve?
As mentioned above, it is impossible for Project Spark to guess the order at which objects should “come to life”. So let’s use a small example and see what problem could come up.
Say all you have are the following props placed at random locations in your level:
prop 1: cube
prop 2: plant
prop 3: goblin
— Keep in mind this example is only used to make a point.
Let’s say you are using the cube to indicate the starting location where all other props should be located; e.g., wherever you place the cube, the plant will be located to its left, and the goblin will be located to the left of the plant. The idea being that no matter where you place the plant and goblin, if you move the cube around in edit mode, the plant/goblin will always be aligned properly when the level starts. That’s the goal.
*** You can download my “Sparkotron howto” level. It’s much easier to follow from there.
step 1: put the cube, plant and goblin at random locations in the world
step 2: put this Kode in the plant’s brain:
When:[once] Do:[position][x][increment by]
step 3: put this Kode in the goblin’s brain:
When:[once] Do:[position][x][increment by]
step 4: Done (don’t run it yet)
I’d wager many of you expect that running this level will result in the plant being 4 units to the left of the cube, and the goblin will be 4 units to the left of the plant. And you’d be correct…sometimes. While it might run “correctly” once, twice or even 50 times in a row, it will eventually not deliver what you expect. And why not?
As mentioned above, there is no guaranteed order at which objects in your level will “come to life”. Keeping this in mind, what happens if the goblin “comes to life” BEFORE the plant does? Since the goblin’s position relies on the plant, then we have a problem, don’t we?
In this example, if the goblin comes to life before the plant, then the Kode inside the plant will not have executed yet, so the plant will still be in the position where you placed it while in Edit mode, and the goblin’s position will be based on that. The end result will not be as expected.
Go ahead and try running this level a few times. The problem might come up quickly or take several tries, but it will happen eventually.
I have a bug in my level. How do I know if the problem you’re describing is the cause?
Well, bugs can be tricky. If there is an issue in your level, it could be a number of things (obviously).
But if your level randomly alternates between “working fine” and “not working fine” (even though you haven’t changed anything) then it might be related to a startup sequence issue *especially* if the problem seems to occur right at the start of the level, where (presumably) you are initializing everything. That (in my experience) is a good indication that this might be the problem…although not guaranteed.
Wait a minute! things need to start at the right time? Then I’ll use timers!
Using timers to synchronize everything will quickly become a nightmare to manage. If you refer to the example above and use timers, then sure, it wouldn’t be a big deal to do. But the moment your project starts to grow and you’re adding more stuff to your level, you’ll quickly get overwhelmed with figuring out what the correct timing for each prop should be, and all will get quite messy.
Even if you do manage to find all the right timing (which is doable), there are a number of other factors (beyond your control) that could mess things up. For example, when your PC (or xbox) needs to access the hard drive, this can momentarily slow down your system which could be sufficient to throw all your precious timing calculations out the window.
If you still need convincing, consider this: as the amount of stuff in your level increases, you will see the startup time of your level decrease proportionally. Imagine if you have 1000 props in your level, each waiting 0.1 seconds for the other to start…that’s 100 seconds (1 1/2 min) of waiting for the game to load…..every time.
Trust me on this, stay away from timers. Use a proper startup sequence.
Do you always need a startup sequence?
Nope. As stated previously, you only need a startup sequence *if* you have at least one prop that is dependent on the state of another prop.
No need for a startup sequence. I can fix your example (above) by just removing the [once] tiles
Some of you might have picked up on the fact that removing all the [once] tiles would fix the issue. Yes indeed it would. While the problem would have as much chance of happening as it did before, the issue would fix itself a split second after you’ve started the level: in this case, the plant would eventually go to the right position, and right after, the goblin would relocate itself based on the plant’s new position.
While this is technically perfectly valid, you would end up with code getting executed over and over for absolutely no reason (instead of just once as it should be), and you’d be wasting resources that could be better used elsewhere. In a small level, this would be a non-issue, but if you’re level gets bigger and more complex, you will want to keep your logic as lean-and-mean as you possibly can to make sure you can add all you have planned.
Do yourself a favor. Write good, efficient Kode. Don’t go down the path of becoming a lazy programmer who doesn’t care at all about efficiency.
Implementing a startup sequence…FINALLY!
You will see that implementing a startup sequence is actually pretty straight forward and logical. Just start with the thing that has the most dependencies and work your way towards things that don’t. In the case of our example above, everything relies on the cube being “all good and ready” before anything else, so that would be our first thing on the list. We’d then be left with the plant and the goblin. Well, we already know that the goblin depends on the plant, therefore the plant should be next. The goblin doesn’t have any dependencies, so he’ll be last…poor goblin 😦
The following is how I do it. There are other ways…this is just the approach I use.
*** For starters, download my “Sparkotron howto” level. It’s much easier to actually be there.
In the level, there are two sets of cube/plant/goblins. On the left is the one with no startup sequence. On the right a startup sequence is used. You may have to run the level a few times, but you will see that the left side props eventually not align properly.
Overall steps to follow:
1) For every prop you need to have control over their starting sequence:
– go into their properties page and set “Properties->Brain->Brain Enabled” to False
– Add an “Init” page, with a boolean variable to indicate when initialization has actually completed.
2) Add a logic cube. This will be used as the sequence controller. In it do this:
– Add (in the order desired) the props you want to initialize
– For each prop, set its “Enable” property to “true” only if the previous prop’s “initialized” boolean is “true”. By doing this, each prop will have to wait its turn in the proper order.
Note: instead of using a boolean variable like I’m suggesting, you might be tempted to just check if the enabled property is “true”. The problem with this is that even if the prop has not completed its initialization, checking its “Enabled” property will still return true. So this is not a reliable approach.
Anyway, that’s the whole thing…lot’s of writing for such a small thing, but if you made it this far, it was probably a bit interesting 🙂