First Project - Lesson 4: Threads, Spawns, and Basic Loops
Now that we have a basic understanding of how functions and the code inside of functions work, it is time to find out what else we can do inside of a function. If statements are not the only statements that can be used inside of a function. Threads, spawns, and loops can also be used. We will cover threads, spawns, and the different types of loops that can be done in this tutorial.

We will continue from the project we created in the previous tutorials. If you are just now jumping in, go to the previous tutorial and create a project to match the project at the bottom of the page.

We will start with threads. Threads allow you to make things happen automatically and do so off on their own. Common uses for a thread is to make a monster move around, or simulate gravity in a side-scroller, or create a thread that handles many different actions for an NPC. The possibilities are endless. There is a built-in thread that acts as a game loop which is best to use (which we will go over in the next tutorial), but learning how a timed loop works is important. So let's take a look at what a thread looks like and see how it works during runtime.

Open the FirstProject project from previous tutorials and head to the main code file. Create a new onNew event function under the Mob/Monster type that looks something like the code below.

Mob Monster onNew() this.dir = 'east' thread(10) if (this.xCoord <= 3) this.dir = 'east' else if (this.xCoord >= 23) this.dir = 'west' this.stepDir(this.dir, 2)

There is a lot going on in the code above, as well as a built-in function and a built-in variable that we have not learned about yet. So let's go over the code.

The first line in the onNew event function is changing a built-in variable that all Movable types have called dir. This variable determines the direction that the movable is facing and can then be used to calculate different things. We saw a bit of these directions back when we made move states when working with the iconState variable. The dir variable can be equal to the following values: north, south, east, west, northeast, northwest, southeast, southwest. The reason we are setting the dir variable is because we will be using it to determine the direction to move later in the function.

You may have noticed that we are directly setting the dir variable without using some type of setDir function like we learned about previously. Using the get and set functions are optional. Sometimes it is better to use the functions, sometimes it is better to use direct variable access. What is best for certain situations is something you will have to learn over time. In these tutorials we will be using both methods.

On the second line in the onNew event function we are creating our first thread. All the code indented under this thread will execute over and over until the thread is interrupted. We'll learn how to interrupt it later. The 10 is telling the thread to execute every 10 milliseconds. So the code under the thread will execute every 10 milliseconds in this case. Once the thread starts, execution will continue on to the next line of code under the thread itself. Execution will never stop and wait for the thread to end, which allows us to have the thread do its thing while we continue on and do other things.

Now, inside the thread, we have an if statement and an else which check our monster's xCoord and then changes the dir variable depending on the value of the xCoord. This should all look familiar from the last tutorial. Then the last line under the thread calls a built-in function called stepDir. We pass this.dir and 2 into it. The first parameter is the direction we want this (in this case our monster) to move in, and the second parameter is the number of steps in positional units to move. Because our tile size is 32, 32 positional units make up one tile or coordinate, so our monster will move 2 units (or about 16% of the tile) inside of our coordinate every 10 milliseconds, which is an entire tile every 160 milliseconds.

So essentially what our thread is doing is moving our monster east or west by 2 positional units every 10 milliseconds. If our monster's x-coordinate is less than or equal to 3, we change the monster's direction to 'east', and if the monster's x-coordinate is more than or equal to 23, we change the monster's direction to 'west', forever.

Build and run the code and all your monsters should now move back and forth on the map. Some may teleport to the top because they run into an older event we created.

So we now have the ability to make things happen automatically, which is pretty much a must for every game. But sometimes we only want something to happen once, on its own, after a short amount of time. This is where the spawn operation comes in.

A spawn is very similar to a thread but the code under it only executes one time. So let's make use of a spawn to see it in action. In the main code file, edit the Mob/Player onNew event function to look something like the code below.

Mob Player onNew() spawn(5000) this.setLoc(1, 1) this.setLoc(this.xCoord + 5, this.yCoord + 5)

The last line under the onNew event function is from a previous tutorial, so we will skip the explanation for it, hopefully you know what is happening. But above that line is our spawn operation with the value 5000 in it. There are 1000 milliseconds in a second, so what our spawn does is wait 5 seconds before it executes the code indented under it, which happens to be a single line that sets our player's location to 1,1 on the map. Because the spawn waits, the code after the spawn executes right away, so our player will still be teleported to 10,10, then after the specified time, the spawn will execute.

Build and run. Move around for a bit, then after 5 seconds your player should automatically teleport to 1,1 on the map.

The most important thing to remember about the thread and spawn is that any code after will be executed right away and the code indented under will not be executed until the specified amount of time has passed. Execution will not wait until the thread or spawn has finished, this means any code after the thread or spawn will not know of any changes made under the thread or spawn and the function will most likely have finished executing and returning by the time the thread or spawn is finished. Think of the code under the thread or spawn as code put off to the side, floating around on its own branch.

Before we continue on to learn about loops, we will go over how to interrupt both a thread and a spawn. In order to do this, we will need to use one of the many static objects that VyScript has. We will not go into too much detail on static objects in this tutorial, we will be covering them in later tutorials, so do not worry too much about them. But basically a static object is an object in VyScript that always exists and can not be modified (well they can be modified, but they aren't meant to be). They contain useful functions and variables for various things relating to the engine and language. Because only one of each static object exist, we reference it directly with its name. The static object we will be using is the Event static object.

The two Event functions that we will be using are Event.interruptThread and Event.interruptSpawn. Basically what these do is interrupt a specific thread or spawn. In order for us to know what thread or spawn to interrupt, we need to get a reference to them, which we can simply do with a variable. We will start with interrupting our spawn. Under the Mob/Player onNew event function, make changes so that the event function looks something like below.

Mob Player onNew() var s = spawn(5000) this.setLoc(1, 1) this.setLoc(this.xCoord + 5, this.yCoord + 5) Event.interruptSpawn(s)

What is happening here is we are storing the spawn into a local variable called s and then later in the function we are calling the interrupt and passing the s variable into it. Basically we are stopping the spawn from ever executing. If you wanted, you could store the spawn in a non-local variable and interrupt it elsewhere in the code. In a future tutorial we can see an example of this.

If you build and run the game, your player should no longer be teleported to the 1,1 location on the map after 5 seconds.

Now for interrupting threads. Interrupting threads and interrupting spawns essentially work the same way, except we use different functions belonging to the Event static object. For our code, we will interrupt the thread from within itself, just to show that it can be done. In the main code file, under the Mob/Monster onNew event function, make the code look like the code below.

Mob Monster onNew() this.dir = 'east' var c = 0 var t = thread(10) c ++ if (this.xCoord <= 3) this.dir = 'east' else if (this.xCoord >= 23) this.dir = 'west' this.stepDir(this.dir, 2) if (c > 500) Event.interruptThread(t)

What we added here is a new local variable called c which we set to 0 upon creation. We then increase the value of it by 1 every time the thread is executed. Putting ++ after a variable will increase the value of it (if it is a number) by 1. Putting -- (two -) after a variable will decrease the value of it (also if it is a number) by 1. Finally, at the end of the thread we do a check to see if c is greater than 500 and if it is, we interrupt our thread. Basically our thread runs for 5 seconds and then interrupts itself. Every 100 thread executions will be a second.

Build and run the game and the monsters should now stop automatically moving after 5 seconds.

Now that we know about threads and spawns, let's dive into loops. Unlike a thread, a loop will not go off and do its own thing. Code execution for other code will not continue until the loop is finished. You want to avoid having the loop do too many things or last too long so that your game does not freeze. A loop that never ends or lasts a very long time can freeze your game forever.

There are many different types of loops. The first one we will go over is the while loop. A while loop is much like an if statement which executes the code indented under it over and over until the while is false.

Let's take a look at an example of a while loop. In the main code file, change the Mob/Player onLogin event function to look something like the code below.

Mob Player onLogin() var mes = this.myFunction(4, 5, false) var c = 100 while (c > 0) c -- alert(mes)

We have a mixture of old and new code here. The first and last lines in the onLogin event function are old, so we wont go over them, but the three lines in the middle are new. What is happening here is we are creating a new local variable called c, like we have done before, and then doing a while statement. Under the while we are decreasing the value of c by 1. The while is executed like an if statement and the code under it will execute over and over until the while returns false. In this case the while will execute until c is less than or equal to 0. Our while simply checks if c is greater than 0 and if it is, it executes the code in the while statement. Once the while is finished, code execution continues and our alert appears. For the most part this code is pointless, other than to show how it works, because the loop is executed so quickly that it's basically as if it is not there.

The while loop is not a very commonly used loop. A more common loop is the for loop. There are two types of for loops in VyScript. The first and most common is the for loop that executes until a certain thing is reached. It sounds a lot like a while loop, but it is more customizable.

Let's put one to use. In the main code file, replace our while loop and make the code under the Mob/Player onLogin event function look like the code below.

Mob Player onLogin() var mes = this.myFunction(4, 5, false) for (var i = 0; i < 3; i ++) alert(mes)

What we have here is basically a loop that executes three times and in our case displays three alerts. You'll notice that there are three sections in the for itself. Each section is divided by a semi-colon. The first section is where we can define variables to be used by the actual for statement in the later sections and inside the loop itself. The second section is where we do a calculation, much like an if statement, to see if the loop should end. If the statement is true, the loop will continue, if the statement is false, the loop will stop. And finally in the third section is what we want to do after each loop. In our case, we increase the value of the i variable we created by 1 each time the loop runs. So we create a variable, set it to 0, increase it by 1 after each loop, and then check if it is less than 3 before the next loop. If it is more than or equal to 3, we stop the loop.

Build and run to see the results.

The second type of for loop is a loop that executes for each value inside of an object, string, or array. We have not gone over arrays yet, and strings are much like arrays, so we will use an object for our example. We will cover arrays and strings in future tutorials.

Head to the main code file and change the code with our old for loop to look like the following.

Mob Player onLogin() var mes = this.myFunction(4, 5, false) alert(mes) var o = {'a': 1, 'b': 2} for (var n in o) alert(n)

The first two lines of the event function are old code, but after that we create a new local variable which holds a new basic object which has two variables a and b which are set to 1 and 2 respectively. Then we use the second type of for loop to loop every variable in the o object and alert the value.

So if we build and run the game, we should get three alerts. The first is our old message, the second should be an alert with a in it, and the third should be an alert with b in it.

If we wanted to get the values of the variables instead of the variable names, or both, we could put o[n] instead of just n in the alert. Change the code to look like the following.

Mob Player onLogin() var mes = this.myFunction(4, 5, false) alert(mes) var o = {'a': 1, 'b': 2} for (var n in o) alert(n + ': ' + o[n])

Now when we build and run the alerts should display a: 1 and b: 2 which is the variable names and then the values with a string containing a colon and a space in the middle of it. Do not worry about the string manipulation too much right now, we will cover it in the next tutorial.

Like mentioned before, arrays and strings can also be looped through with this method, so we will go over them in the coming tutorials.

Finally, we have the foreach loop. This loop is mainly useful for looping arrays, so we will cover it more in the coming tutorials, but essentially what it does is grab the value rather than the name or index of what you are looping. So to show how this works we will put some objects inside objects and use a foreach on them. Replace the previously used loop code to look like the following.

Mob Player onLogin() var mes = this.myFunction(4, 5, false) alert(mes) var ob1 = {'a': 1, 'b': 2} var ob2 = {'a': 2, 'b': 3} var ob = {'a': ob1, 'b': ob2} foreach (var o in ob) alert(o.a + o.b)

So, ignoring the first two lines, what we do here is create three new objects. The third object ob we set the a and b variables to be references to the first two objects. What this means is ob.a will be a reference to ob1 and ob.b will be a reference to ob2. Our foreach loop loops the variables inside of ob and sets o to be a reference to the value of each variable. So the foreach loop will run two times, since the ob object has two variables, and o will be equal to ob1 in the first iteration and then ob2 in the second. For each iteration we do an alert which adds the two variables for each object together and alerts the total.

If you build and run, the last two alerts should show up as 3 and 5 since ob1.a+ob1.b=3 and ob2.a+ob2.b=5.

So, we have now learned how to create our own threads and spawns, and how to work with basic loops, as well as learned a bit more about some of the built-in functions and variables VyScript has to offer. In the next tutorial we will dive into the engine's built-in game loop ticker, mouse events, and the appearance system.

If you followed everything in this tutorial, the source of your project should look something like this. https://vylocity.com/ide/Vylocity/FirstProject4/

References