thyme tutorial: the basic and advanced techniques

45
1 Thyme Tutorial Thyme Tutorial Thyme Version: 1.5.6 Last Update: 2009

Upload: bruno-philipe-resende-silva

Post on 27-Apr-2015

1.973 views

Category:

Documents


28 download

DESCRIPTION

The basic and advanced programming techniques for programming in the Algodoo machine creation software.

TRANSCRIPT

Page 1: Thyme Tutorial: The basic and advanced techniques

1 Thyme Tutorial

Thyme Tutorial

Thyme Version: 1.5.6

Last Update: 2009

Page 2: Thyme Tutorial: The basic and advanced techniques

2 Thyme Tutorial

Tutorial 1: Creating Variables ....................................................................Page 3

Tutorial 2: Scene.my.* ...................................................................................Page 5

Tutorial 3: Declaring a New Identifier .....................................................Page 7

Tutorial 4: Structures ....................................................................................Page 8

Tutorial 5: Creating an Array ......................................................................Page 9

Tutorial 6: Actions and Pointers .............................................................Page 11

Tutorial 7: Action Arrays ...........................................................................Page 13

Tutorial 8: Key Binding ..............................................................................Page 15

Tutorial 9: Tick Based Timers .................................................................Page 17

Tutorial 10: Argument-Taking Functions ............................................Page 19

Tutorial 11: Infix Operations ...................................................................Page 21

Tutorial 12: If Structures ...........................................................................Page 23

Tutorial 13: Time Based Timers .............................................................Page 25

Tutorial 14: onCollide .................................................................................Page 27

Tutorial 15: .phz:.phn Editing ..................................................................Page 29

Tutorial 16: General Thyme Notes .........................................................Page 31

Tutorial 17: Advanced Techniques: Object Pointers .......................Page 32

Tutorial 18: Adv. Tech.: Deletion via Code ..........................................Page 34

Tutorial 19: Adv. Tech.: Custom Local Variable Declaration..........Page 36

Tutorial 20: Adv. Tech.: Extending for Structures ............................Page 38

Tutorial 21: Adv. Tech.: Update Links ..................................................Page 40

Tutorial 22: Adv. Tech.: Widget → Object Links ................................Page 41

Tutorial 23: Adv. Tech.: eval ....................................................................Page 42

Tutorial 24: Adv. Tech.: Element Modification .................................Page 44

Page 3: Thyme Tutorial: The basic and advanced techniques

3 Thyme Tutorial

Tutorial 1: Creating Variables

What is a variable? A variable is something that can hold something, like a number, or a letter, or an array of numbers and letters. Most if not all programming languages use variables in some form, which allow the user to build their own functions and do calculations.

How would I go about making a variable? You would follow a few steps

1. Bring down the console using F11 or tilde("~").

2. Type a name for your variable, like Power or Example or Ex123 or P0W3R.

3. Type an equal sign ("=").

4. Type a value, like 6 or 2.1 or 13.

5. Check you haven't made any mistakes, it should look something like Power = 6.

6. Press Enter.

NOTE: If you are putting more than one variable declaration in a code, separate them with ;

What types of variables are there? There are 4 different types: integer, float, string and boolean, each having different applications.

What is an integer?

An integer is a whole number, which has no decimal part, it can be used in list indices.

What is a float?

A float is a floating point number, which has a decimal part, it can be used in most situations, if the number is more than 3.39e+37 it will be treated as +inf.

What is a string?

A string is a group of letters and numbers, strings can contain spaces, new lines (\n), and a range of other things, (like tab spaces (\t)), strings are mainly used in textures, text boxes and a few other things.

What is a boolean value?

Page 4: Thyme Tutorial: The basic and advanced techniques

4 Thyme Tutorial

A boolean value is a true or false value, boolean values can be used for if structures, and a whole lot of variables.

What is an identifier? An identifier is the name of your variable, like in "Example = 60.7", "Example" is the identifier in that statement.

Can I put a space in my variable's name (identifier)? No, you cannot, as thyme will assume that you want to send the tertiary words as arguments, so, you wont be able to, you can however, use underscores in place of spaces.

Why would I want to use a variable? Variables are required for most functions, and can allow for a point of entry for another function (by linking from an object). Variables can also be used for clarity of what each number does (a variable with the name "PowerLevel" is a much easier to recognise use than 6.1).

Example:

Thomas needs 3 apples, Thomas currently has no apples.

Code:

NumberOfApplesNeeded = 3;

NumberOfApples = 0;

Page 5: Thyme Tutorial: The basic and advanced techniques

5 Thyme Tutorial

Tutorial 2: Scene.my.*

What is Scene.my.*? Scene.my.* is a serialised (saved to file with the rest of the scene) structure, that you can declare variables in, it is favourable to objects not in the scope, and offers quite a few benefits, most scenes on algobox will be found to use these variables as opposed to the normal variables.

How would I go about using Scene.my.*? You would follow a few steps:

1. Bring down the console using F11 or Tilde ("~").

2. Type Scene.my. (which is the structure's name).

3. Type the name of your variable, like Variable12A or Variable or Party.

4. Type an equal sign ("=").

5. Type a value, like 2 or 2.3, or 92.5 or true.

6. Check you haven't made any mistakes, it should look something like Scene.my.Variable12A = 2.

7. Press Enter.

Why would I want to use Scene.my.* over normal declarations? The Scene.my structure is serialised with scenes, so, if you upload them to algobox, people will be able to use all your variables, and it should all load properly. Another reason for using Scene.my.* as opposed to normal variables is that normal variables slow down so little it's hardly noticable on their own, but if you get hundreds of thousands of variables, phun becomes slightly noticably slower, but, because phun runs so much faster than when it was "common" to use normal variables (when Scene.my did not exist yet), it is probably not much of a problem now.

What is an expression? An expression is basically an action, for example, in the code: "Scene.my.Variable12A = (2 + 5)", "= (2 + 5)" is the expression.

Example:

John wants to know how many apples Thomas needs, Thomas knows he needs 3 apples, and Thomas currently has no apples, Thomas has to save these to a scene and put it on algobox.

Page 6: Thyme Tutorial: The basic and advanced techniques

6 Thyme Tutorial

Code:

Scene.my.NumberOfApplesNeeded = 3;

Scene.my.NumberOfApples = 0;

Page 7: Thyme Tutorial: The basic and advanced techniques

7 Thyme Tutorial

Tutorial 3: Declaring a new Identifier

Isn't this just declaring a variable? No, this is different, declaring a variable the way you have been shown will modify that variable if it already exists, and will not make a new identifier.

Why would I want to declare an identifier over a variable? Though the majority of the uses of declaring an identifier can be replicated the same way using a variable, there are some which you will require declaration of a new identifier.

How do I go about declaring an identifier? You would follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type your variable name, like Scene.my.Variable1 or Scene.my.Vari or

Scene.my.Var23Ia56ble. 3. Type a colon and an equal sign (":="), this is the symbol for declaration of a new

identifier. 4. Type a value, like 4 or 7.9 or "haro,". 5. Check you haven't made any mistakes, it should look something like

Scene.my.Variable1 := 4. 6. Press Enter.

What happens if I try to re-declare the same identifier twice the same way You cannot use the identifier declaration (":=") for resetting values, it will set your value, but it will also output an error message saying that you already have an identifier by that name declared, it can be best to use the normal declaration symbol ("=") in situations like these.

Example:

Thomas knows he needs 3 apples, and he also knows how many apples he has, which is none.

Code:

Scene.my.NumberOfApplesNeeded := 3;

Scene.my.NumberOfApples := 0;

Page 8: Thyme Tutorial: The basic and advanced techniques

8 Thyme Tutorial

Tutorial 4: Structures

What are structures? Structures are objects which contain variables, or, can if the user tells them to. The most commonly used structure is most likely Scene.my, which is contained in the structure Scene.

Why should I use structures? Structures make code more easily readable, for example, Sim.time shows the time that the simulation has been running, whereas System.time shows the time that the application has been running, this is an example of how it makes code easier to read, as they are all categorised into their own sections based on what their actions may affect.

How would I go about making a variable in a structure? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type your structure's name, like Scene. or Sim. or App.. 3. Type your variable's name, like Vari123 or Va2r8i0 or VariableExample. 4. Type your expression, like = (1 + 2) or := (1 * 6) or = (6 / 3). 5. Check you haven't made any mistakes, it should look something like Scene.Vari123 = (1

+ 2). 6. Press Enter.

NOTE: You can only use declared structures to store variables.

Are there any structures that don't contain any variables to start with? Yes, Scene.my is a structure, and it begins without any variables in it, you can add variables as you want (Tutorial 2).

Example:

Thomas knows he needs to get 3 litres of milk from the Scene. store, and 2 litres of milk from the Keys. store, Thomas has no milk at the moment.

Code:

Scene.LitresOfMilkNeeded = 3;

Scene.LitresOfMilkGathered = 0;

Keys.LitresOfMilkNeeded = 2;

Keys.LitresOfMilkGathered = 0;

Page 9: Thyme Tutorial: The basic and advanced techniques

9 Thyme Tutorial

Tutorial 5: Creating an array

What is an array? An array is basically a container for data, it can have as many elements (data) in it as you want.

How would I go about making an array? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type your identifier, like Scene.my.ArrayOne or Scene.my.Array2 or Scene.my.Arr. 3. Type an equal sign ("="). 4. Type a starting square bracket ("["). 5. Type data, separated by commas, the data can be heterogeneous, like "Value", "1", 1,

1.2, true or 1,2,3 or 1.1,true,Scene.my.Vari123. 6. Type an ending square bracket ("]"). 7. Check you haven't made any mistakes, it should look something like

Scene.my.ArrayOne = ["Value", "1", 1, 1.2, true]. 8. Press Enter.

NOTE: You can stack arrays inside arrays.

Why would I want to use an array? Arrays are very useful for storing large amounts of data, and perhaps placing them all in an accessible array, indicies for arrays can be easily accessed using integer numbers, and may help largely with organisation of sets of variables, for example: Var1 = 2; Var2 = 3; Var3 = 2; could be arranged in an array like: Array = [2,3,2]

What are indicies? An index is the method for accessing different elements from an array.[/i]

How do I access an individual element two arrays deep? [b]To access an element within an element, you add a second element specification (Array(2)(0) as opposed to just Array(2)), and you can continue to add element specifications until you reach the end of your stack of arrays.

Example:

Thomas wants to buy the following items: Bread, Milk, Apples, Bananas, Cheese and Ice Cream, he needs to buy the following quantities: 1 loaf, 3 litres, 4, 3, 500g, 4L. At the moment, he has none of the things in the list.

Code:

Page 10: Thyme Tutorial: The basic and advanced techniques

10 Thyme Tutorial

Scene.my.ShoppingList = ["Bread","Milk","Apples","Bananas","Cheese","Ice Cream"];

Scene.my.ShoppingQuantities = [1,3,4,3,500,4];

Scene.my.ShoppingProgress = [0,0,0,0,0,0];

John also needs to buy the same items, but orders it differently.

Code:

Scene.my.ShoppingList = [["Bread",1,0],["Milk",3,0],["Apples",4,0],["Bananas",3,0],["Cheese",500,0],["Ice Cream",4,0]];

Page 11: Thyme Tutorial: The basic and advanced techniques

11 Thyme Tutorial

Tutorial 6: Actions and Pointers

What is a pointer? A pointer is something that points to another value, you can use these to create a constantly modified variation of another variable.

What is an action? An action/function can be a modification to another variable permanently, or, could print something, or calculate a value.

How would I go about creating a pointer? You could follow a few steps:

1. Brind down the console using F11 or Tilde ("~"). 2. Type an identifier name, like Scene.my.PointerExample or Scene.my.Point12Er or

Scene.my.P34R. 3. Type an assignation operator ("=" or ":="). 4. Type an opening curly bracket ("{"). 5. Type another identifier, like Scene.my.VariableExample1 or Scene.my.V4r14bl3 or

Scene.my.VariableExample. 6. Type a modification to make, like + 6 or * 2.4 or / 3.2. 7. Type an ending curly bracket ("}"). 8. Check you haven't made any mistakes, it should look something like

Scene.my.PointerExample = {Scene.my.VariableExample1 + 6}. 9. Press Enter.

How would I go about creating a function? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type an identifier name, like Scene.my.FunctionExample or Scene.my.Function12E or

Scene.my.Activity. 3. Type an assignment operator ("=" or ":="). 4. Type an opening curly bracket ("{"}. 5. Type another identifier, like Scene.my.VariableExample1 or Scene.my.Variable222 or

Scene.my.VariableExample. 6. Type an assignment operator ("="). 7. Type the remainder of the expression, like Scene.my.VariableExample1 + 1 or

Scene.my.VariableExample1 * Scene.my.VariableExample2 or 6.5. 8. Type an ending curly bracket ("}")

Page 12: Thyme Tutorial: The basic and advanced techniques

12 Thyme Tutorial

9. Check you haven't made any mistakes, it should look something like Scene.my.FunctionExample = {Scene.my.VariableExample1 = Scene.my.VariableExample1 + 1}.

10. Press Enter.

Why would I want to use a pointer? Pointers can be very useful for saving modifications for variables that you can change without modifying all your variables (for example, if I have 30 modifications, I only have to modify one variable as opposed to 30 or 31).

Why would I want to use a function? Functions are used for modification of variables and other functions, and might calculate information based on information contained in variables.

Example:

Thomas always needs to keep 5m^3 of space in his cupboard, he only stores apples in his cupboard (we assume that each apple takes up 1m^3 (which is quite a bit for an apple )).

Code:

Scene.my.NumberOfApples = 3;

Scene.my.SpaceNeededAvaliable = {Scene.my.NumberOfApples + 5}

Thomas makes sure he keeps the space in his cupboard, but, every now and again, he'll buy a new cupboard, which means that his capacity for apples goes up.

Code:

Scene.my.NumberOfApples = 3;

Scene.my.SpaceNeededAvaliable = {Scene.my.NumberOfApples + 5};

Scene.my.SpaceInCupboard = {10 * Scene.my.NumberOfCupboards};

Scene.my.NumberOfCupboards = 2;

Scene.my.BuyNewCupboard = {Scene.my.NumberOfCupboards = Scene.my.NumberOfCupboards + 1};

Page 13: Thyme Tutorial: The basic and advanced techniques

13 Thyme Tutorial

Tutorial 7: Action Arrays

What is an action array? An action array is an array of functions, they are seldom used in phun, but are a good way to organise a lot of function levels.

How would I go about making an action array? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type an identifier name, like Scene.my.ActionArrayExample or Scene.my.Sandwich or

Scene.my.Action1Array2I. 3. Type an assignment operator ("=" or ":="). 4. Type a beginning square bracket ("["). 5. Type functions, separated by commas, like {Scene.my.Variable1 = Scene.my.Variable1

+ 2},{Scene.my.Variable6 = Scene.my.Variable6 + 2;Scene.my.Variable2 = (Scene.my.Variable6 + "")} or {Scene.my.Function;Scene.my.Variable3 = Scene.my.Variable2 + "Hello"},{Scene.my.Function2},{Scene.my.ExampleVariable4 = 3} or {Scene.my.Value6 = Scene.my.Value6 + 22.1},{Scene.my.Value12 = Scene.my.Value6 + 2.4}.

6. Type an ending square bracket ("]"). 7. Check you haven't made any mistakes, it should look something like

Scene.my.ActionArrayExample = [{Scene.my.Variable1 = Scene.my.Variable1 + 2},{Scene.my.Variable6 = Scene.my.Variable6 + 2;Scene.my.Variable2 = (Scene.my.Variable6 + "")}].

8. Press Enter.

Why would I want to use an action array? An action array can be used for a range of different situations, perhaps to save time in calculating which function path to take, or to contain a very large range of functions in an easy to access array, after the introduction of a few features to thyme, this function is much less important, but can still be used for tick-based timers and are a good way to organise your functions into a long line, allowing you to modify other values that may not always line up the same way.

I typed the correct number for the function, but it didn't execute, how can I make it? Action Arrays work differently to normal arrays, you require one set of brackets ("()") to execute the function.

Page 14: Thyme Tutorial: The basic and advanced techniques

14 Thyme Tutorial

Example:

Thomas has a set of tests he has to do based on how big each apple he picks is, which determines how it is categorised, and how much it is going to cost, if an apple is under 1dm^3 it is placed in the category "Small", small apples cost $3.50, if it is above 2dm^3 it is placed in the category "Medium", medium apples cost $2.50 per dm^3 ($5), if it is above 3dm^3 it is placed in the category "Large", large apples cost $1.50 per dm^3, Thomas wants to know how much the apple is whenever he tests it.

Code:

Scene.my.TotalValueOfApples = 5.0; Scene.my.AddAppleCost = [{},{Scene.my.TotalValueOfApples = Scene.my.TotalValueOfApples + 3.50},{Scene.my.TotalValueOfApples = Scene.my.TotalValueOfApples + 5.0},{Scene.my.TotalValueOfApples = Scene.my.TotalValueOfApples + 4.50},{Scene.my.TotalValueOfApples = Scene.my.TotalValueOfApples + 6.0}];

Thomas has an apple weighing about 1dm^3, and so he puts it in his test, then Thomas puts in an apple weighing about 4dm^3 then 3 apples weighing about 3dm^3.

Code:

Scene.my.AddAppleCost(1)(); Scene.my.AddAppleCost(4)(); Scene.my.AddAppleCost(3)(); Scene.my.AddAppleCost(3)(); Scene.my.AddAppleCost(3)();

Thomas then reads how much he would have made (keeping in mind he started with $5 worth of apples already calculated before the previous calculation)(Scene.my.TotalValueOfApples) and it says: $28.00.

Page 15: Thyme Tutorial: The basic and advanced techniques

15 Thyme Tutorial

Tutorial 8: Key Binding

What is Key Binding? Key binding is where you set up keys to do specific things whenever the certain key is pressed, this allows you to build things that allow for controlling thyme systems without working too hard to build elaborate mechanical mechanisms to change variables (so, basically, key binding saves a few resources).

How would I go about binding a key? You could follow a few steps:

1. Bring down the console using F11 or tilde ("~"). 2. Type Keys.bind. 3. Type a beginning bracket ("("). 4. Type the string value for the key you want to link, like "a" or "b" or "c". 5. Type a comma (","). 6. Type your function, like {Scene.my.Variable3 = 9} or {Scene.my.Function} or

{Scene.my.Array(Scene.my.Variable3)}. 7. Type an ending bracket (")"). 8. Check you haven't made any mistakes, it should look something like

Keys.bind("a",{Scene.my.Variable3 = 9}). 9. Press Enter.

Why would I want to use key binding? You can use key binding in a lot of things, you can emulate most the behaviour using a collision script, though, collision scripts require the simulation to be running, a bound key should work without the simulation running.

How would I go about unbinding a key? You could follow a few steps:

1. Bring down the console using F11 or tilde ("~"). 2. Type Keys.unbind. 3. Type the beginning bracket ("("). 4. Type the string value for the key you want to unbind from all functions, like "a" or "b"

or "c". 5. Type ",())". 6. Check you haven't made any mistakes, it should look something like

Keys.unbind("a",()). 7. Press Enter.

Page 16: Thyme Tutorial: The basic and advanced techniques

16 Thyme Tutorial

Example:

Peter has a button, which adds one to his counter whenever he puts a banana on it.

Code:

Scene.my.NumberOfBananas = 0;

Keys.bind("a",{Scene.my.NumberOfBananas = Scene.my.NumberOfBananas + 1});

Peter eats a few bananas, and realises he doesn't like bananas, so he gets rid of his counter link.

Code:

Keys.unbind("a",());

Page 17: Thyme Tutorial: The basic and advanced techniques

17 Thyme Tutorial

Tutorial 9: Tick Based Timers

What is a tick based timer? A tick based timer is a timer that is based on ticks rather than set time, very few people have used this method since the release beta 5.

How would I go about making a tick based timer 1. You could follow a few steps: 1. Bring down the console using F11 or tilde ("~"). 2. Type the name of an identifier, like Scene.my.Count or Scene.my.Progress or

Scene.my.Value123. 3. Type the expression, keeping in mind that this value is your progress (it's best to use

integers for this value), something like = 0 or = 100 or = 20. 4. Type a semi-colon (";") and Type the name of a new identifier, like Scene.my.Step or

Scene.my.Interval or Scene.my.Value234. 5. Type the expression, keeping in mind that this value is how many ticks between each

new step, like = 500 or = 750 or = 27. 6. Type a semi-colon (";") and Type the name of a new identifier, like Scene.my.Action or

Scene.my.Functions or Scene.my.Value345. 7. Type an action array, to keep with the timer function, set the first identifier to the first

identifier + 1 in a function to increase the value, for the action array you could choose an action array like [{Scene.my.Count = Scene.my.Count + 1},{Scene.my.Variable = Scene.my.Variable + 1;Scene.my.Count = 1000},{Scene.my.Count = Scene.my.Count + 1;Scene.my.Variable2 = Scene.my.Variable2 + 1},{Scene.my.Count = 0}] or [{Scene.addBox{size = [1,1];pos = [0,0]};Scene.my.Count = Scene.my.Count + 1},{Scene.my.Count = Scene.my.Count + 1;Scene.my.Variable3 = Scene.my.Variable3 + 1},{Scene.my.Count = 0}] or [{Scene.my.Count = Scene.my.Count + 1},{Scene.my.Variable4 = Scene.my.Variable4 + "|";Scene.my.Count = 0}].

8. Type a semi-colon (";"). 9. Type a default variable (not user created) that wont change and type its name, like

Sim.frequency or App.numColorsInRainbow or Sim.timeFactor. 2. 10.Type an assignment operator ("="). 3. 11.Type a beginning curly bracket ("{"). 4. 12.Type a beginning bracket ("("). 5. 13.Type the first identifier. 6. 14.Type a division operator ("/"). 7. 15.Type the second identifier. 8. 16.Type )();. 9. 17.Type the original value of the third variable (default variable). 10. 18.Type an ending curly bracket ("}"} 11. 19.Check you haven't made any mistakes, it should look something like

Scene.my.Count = 0;Scene.my.Step = 500;Scene.my.Action = [{Scene.my.Count = Scene.my.Count + 1},{Scene.my.Variable = Scene.my.Variable + 1;Scene.my.Count =

Page 18: Thyme Tutorial: The basic and advanced techniques

18 Thyme Tutorial

1000},{Scene.my.Count = Scene.my.Count + 1;Scene.my.Variable2 = Scene.my.Variable2 + 1},{Scene.my.Count = 0}];Sim.frequency = {Scene.my.Action(Scene.my.Count / Scene.my.Step)();100}

Why would I want to use a tick based timer? Tick based timers are good if you have a rough estimation of when you want the effects to happen, and being spot on isn't necessary, they also start from 0, so that if you have been running a scene for 10 minutes, you are going to know exactly where you are, also, tick based timers are pretty quick to set up.

Why is a tick based timer so complicated? A tick based timer is not really complicated, you just have to learn how to use it, after you have, it's quite easy to build.

Example:

Sam was building a "magical" clock, he had a rough estimation of when each tick would happen, so he used a tick based timer method to build his machine.

Code:

Scene.my.Second = 0; Scene.my.Minute = 0; Scene.my.Hour = 0; Scene.my.SecondStep = 60; Scene.my.MinuteStep = 60; Scene.my.HourStep = 24; Scene.my.MinuteHourTransfer = [{},{Scene.my.Minute = 0;Scene.my.Hour = Scene.my.Hour + 1;Scene.my.HourTransfer(Scene.my.Hour / Scene.my.HourStep)()}];

Scene.my.HourTransfer = [{},{Scene.my.Hour = 0}];

Scene.my.TimeTransfer = [{Scene.my.Second = Scene.my.Second + 1},{Scene.my.Second = 0; Scene.my.Minute = Scene.my.Minute + 1; Scene.my.MinuteHourTransfer(Scene.my.Minute / Scene.my.MinuteStep)()}];

Sim.frequency = {Scene.my.TimeTransfer(Scene.my.Second / Scene.my.SecondStep)();100};

Page 19: Thyme Tutorial: The basic and advanced techniques

19 Thyme Tutorial

Tutorial 10: Argument-Taking Functions

What is an argument taking function? An argument taking function is a function that will take an input, these functions take input and generally use it in some form in the functions, they are very useful and have a large range of uses.

How would I go about making an argument taking function? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type the name for a new identifier, like Scene.my.ArgFunctionExample or

Scene.my.ABC123 or Scene.my.TheArgumentTakingFunction. 3. Type an assignment operator ("=" or ":="). 4. Type a beginning bracket ("("). 5. Type argument place-holders to send into the function, seperated by comma, like v or

value,variable,Number or AValue6. 6. Type an ending bracket (")"). 7. Type =>{. 8. Type a function, you can use your place-holders' names to show where each value will

be used, like v * 6 or v^3 or v / (v + 1). 9. Type an ending curly bracket ("}"). 1. 10.Check you haven't made any mistakes, it should look something like

Scene.my.ArgFunctionExample = (v)=>{v * 6}. 2. 11.Press Enter.

Why would I want to use argument taking functions? Argument taking functions are very useful for a lot of purposes, like calculating distances between two points, modified mathematical functions and a large amount of other functions, argument taking functions allow you to complete the same task using less variables and less code, which saves time.

Example:

Thomas was noticing that his calculation for the apples could be more accurately tailored to give him a more accurate result of how much an apple would be worth, which meant that he would be able to sell for a more proper price, he decided to set the price at $1.50 per dm^3.

Code:

Page 20: Thyme Tutorial: The basic and advanced techniques

20 Thyme Tutorial

Scene.my.TotalValueOfApples = 5; Scene.my.AddValueOfApple = (dm)=>{Scene.my.TotalValueOfApples = Scene.my.TotalValueOfApples + (dm * 1.50)};

Thomas put in 5 apples, and his machine told him exactly how much his apples would earn him, he put in a 3.2dm^3 apple, a 7.3dm^3 apple, a 0.2dm^3 apple, a 16dm^3 apple and a 3.5dm^3 apple.

Code:

Scene.my.AddValueOfApple(3.2); Scene.my.AddValueOfApple(7.3); Scene.my.AddValueOfApple(0.2); Scene.my.AddValueOfApple(16.0); Scene.my.AddValueOfApple(3.5);

Thomas read the machine's output and it said "$50.30", he then compared it against his old system, and his old system read "Invalid Input" and exploded.

Page 21: Thyme Tutorial: The basic and advanced techniques

21 Thyme Tutorial

Tutorial 11:Infix operations

What is an infix operation? An infix operation is binding certain objects that appear in the middle of two parts to perform certain modifications to the parts, "+" is an infixed operation, "++" is an infix operation.

How would I go about infixing an operation? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type infix. 3. Type a space (" "). 4. Type the number of arguments to send to the argument taking function, like 2 or 1 or

3. 5. Type a space (" "). 6. Type the reading order of your infix operation ("left" or "right"). 7. Type a colon (":"). 8. Type a space (" "). 9. Type where to take your variables from using an underscore ("_") and place infix

operator(s), like _*\*_ or *-_-*_ or _+*_. 10. Type a space (" "). 11. Type =>. 12. Type the identifier of an argument taking function, like

Scene.my.InfixOperationExampe or Scene.my.Infix123 or Scene.my.GenericFunction. 13. Check you haven't made any mistakes, it should look something like infix 2 left _*\*_

=> Scene.my.InfixOperationExample. 14. Press Enter.

What's the difference between Left reading order and right reading order? For the function a*b*c: in left reading order, functions will be executed like: ((a*b)*c) whereas, in right reading order, functions will be executed like: (a*(b*c)).

Why would I want to use infixed operations? The main reason to use infixed operations is an increase in productivity, and to make a long code shorter, it may also make a code easier to read.

Example:

Damien's system is short of storage, because of his use of extremely long functions, he then fixed it using infix operations. It was about the number of points scored

Code:

Page 22: Thyme Tutorial: The basic and advanced techniques

22 Thyme Tutorial

Scene.my.TotalNumberOfPointsThatWereScoredByASpecificTeamWhosnameisnottobeincludedforthepurposeofkeepingitopenforanyteam = 0;

Scene.my.SetPoints = (x)=>{Scene.my.TotalNumberOfPointsThatWereScoredByASpecificTeamWhosnameisnottobeincludedforthepurposeofkeepingitopenforanyteam = Scene.my.TotalNumberOfPointsThatWereScoredByASpecificTeamWhosnameisnottobeincludedforthepurposeofkeepingitopenforanyteam + x};

infix 1 left: _+++ => Scene.my.SetPoints;

Scene.my.AddPoints = (x,y)=>{(x * 10)+++ ; (y * 3)+++ };

Scene.my.AddSuperPoints = (x)=>{(x * 100)+++ ;};

Damien's new system was well within its storage limitations, Damien later planned to add more to the code, so he upgraded his HDD.

Page 23: Thyme Tutorial: The basic and advanced techniques

23 Thyme Tutorial

Tutorial 12: If Structures

What's an if structure? An If Structure is an infixed operation, allowing for questions to be asked, and action to be taken based on whether it's true or false.

How would I go about making an if structure? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type a true/false statement ("true" or "false"). 3. Type a question mark ("?"). 4. Type an action to take if it is true, like {Scene.my.Value123 = 6} or {Scene.my.Array =

[1,2,3]} or {Scene.my.Function153}. 5. Type a colon (":"). 6. Type an action to take if it is false, like {Scene.my.Value123 = 9} or {Scene.my.Array =

[2,6,8]} or {Scene.my.Function932}. 7. Check that you haven't made any mistakes, it should look something like true ?

{Scene.my.Value123 = 6} : {Scene.my.Value123 = 9}. 8. Press Enter.

NOTE: You must always include both true and false actions.

I don't have all my functions in true and false statements, what do I do? You can set up these by typing statements like: "Scene.my.Variable6 > Scene.my.Variable7", assuming that that statement is true, it will return true, if it is not, it will return false, you can find a full list of these functions in the Math.comp.* section of the Thyme commands/variables list.

Why would I want to use an if structure? If structures are very useful for determining which course to take, they can also be used for simplifying mechanical systems into a less laggy format, and making the switch from true/false statements to actual usability.

Example:

Tyson was working on a machine that determined whether his apples were in the "Small", "Medium" or "Large" range, Apples in the "Small" range are within 0 - 1dm^3, Apples in the "Medium" range are within 1dm^3 - 2dm^3, Apples in the "Large" range are above 2dm^3.

Code:

Page 24: Thyme Tutorial: The basic and advanced techniques

24 Thyme Tutorial

Scene.my.AppleCategory = (x)=>{x < 1 ? {"Small"} : {x < 2 ? {"Medium"} : {"Large"}}};

Page 25: Thyme Tutorial: The basic and advanced techniques

25 Thyme Tutorial

Tutorial 13: Time Based Timers

What is a Time Based Timer? A time based timer is one that relies on a consistent and accurate value for time (Sim.time/System.time), this system allows for exact time set-ups where a varying calculation would impact negatively on the system, and cause the un-desired result.

How would I go about setting up a Time Based Timer? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type a new identifier, like Scene.my.TimerBase or Scene.my.Function or

Scene.my.Value23E. 3. Type an assignment operator ("=" or ":="). 4. Type a curly bracket ("{"). 5. Type a time link (Default time links are "Sim.time" or "System.time"). 6. Type a more than symbol (">"). 7. Type the number of seconds that you want to have been running (if System.*,

application, if Sim.*, simulation) when the action is carried out, like 6 or 12.4 or 92.843.

8. Type a question mark ("?"). 9. Type your action, like {Scene.my.Variable62 = 94} or {Scene.my.Value12 = true} or

{Scene.addBox{pos := [1,1];size := [1,1]}}. 10. Type a colon (":"). 11. Type {}}. 12. Check that your haven't made any mistakes, your code should look like

Scene.my.TimerBase = {Sim.time > 6 ? {Scene.my.Variable62 = 94} : {}}. 13. Press Enter. 14. Choose one of two paths, path A will run regardless of whether the simulation is

running or not, and path B will run if the sim is running. Aa. Pick a default variable (not user created) that wont change and type its name,

like Sim.frequency or App.numColorsInRainbow or Sim.timeFactor. Ab. Type an assignment operator ("="). Ac. Type a starting curly bracket ("{"). Ad. Type the name of your first identifier. Ae. Type a semicolon (";"). Af. Type the normal value of the second identifier. Ag. Type an ending curly bracket ("}"). Ah. Check you haven't made any mistakes, it should look something like

Sim.frequency = {Scene.my.TimerBase;100}. Ba. Create a box that will collide, and give it a script on one of its variables that will run the function at all times.

Page 26: Thyme Tutorial: The basic and advanced techniques

26 Thyme Tutorial

Why would I want to use a time based timer? Time based timers allow you to make an action appear after a set amount of time, this set amount of time is very accurate (when compared with the tick system), and as a timer system, you are able to make things happen by themselves after a certain amount of time.

Example:

John is a pineapple grower, he has a sprinkler system, he once tried using his friend's "magic" clock, but it wasn't accurate enough to get the sprinkler system to run after 3 hours, so he built a new system that worked with enough accuracy to get the right time to start (it was 3am when the system was started).

Code:

Scene.my.SprinklerSystem = false;

Scene.my.SprinklerClock = {Sim.time > 21600 ? {Scene.my.SprinklerSystem = true} : {}};

Sim.frequency = {Scene.my.SprinklerClock;100};

Page 27: Thyme Tutorial: The basic and advanced techniques

27 Thyme Tutorial

Tutorial 14: onCollide

What is onCollide? onCollide, onHitByLaser and onLaserHit are all triggered by events, onCollide is triggered for a collision between two geometries, onHitByLaser is triggered on a geometry when it is hit by a laser, onLaserHit is triggered when a laser hits a geometry, each of these events send a class object into the function (as an argument).

How would I go about making an onCollide script? You could follow a few steps:

1. Select an object and open the script menu. 2. Select all the onCollide script. 3. Type a starting bracket ("("). 4. Type the argument place-holder (this will hold a classObject), like event or

argPlaceHolder or Transferal. 5. Type an ending bracket (")"). 6. Type =>{. 7. Type the function, accessing the classObject that you put as your argument place-

holder, like Scene.my.Value = event.pos(0) or Scene.my.Function6(event.pos) or Scene.my.Function7(event.normal);Scene.my.Function9(event.pos).

8. Type an ending curly bracket ("}"). 9. Check you haven't made any mistakes, it should look something like

(event)=>{Scene.my.Value = event.pos(0)}. 10. Press Enter.

NOTE: All onCollide variables can be found in the Thyme commands/variables list.

What is .this. and .other.? this.* refers to the current object in an onCollide event, other.* refers to the other object in the collision in an onCollide event.

Is there any difference between onHitByLaser, onLaserHit and OnCollide? Yes, onLaserHit and onHitByLaser both use .laser and .geom as opposed to .this and .other, .laser always refers to the laser, and .geom always refers to the geometry.

Example:

Quinn was working on a car when he realised he wanted a GPS, so he put a refreshing circle which sent out a wave every time it hit, which gave Quinn his position.

Code:

Page 28: Thyme Tutorial: The basic and advanced techniques

28 Thyme Tutorial

Scene.my.Position = [0,0];

He fed the position to his tracker.

Code:

(GPSSignal)=>{Scene.my.Position = GPSSignal.pos};

Page 29: Thyme Tutorial: The basic and advanced techniques

29 Thyme Tutorial

Tutorial 15: .phz:.phn Editing

What is .phz:.phn editing? A *.phz file is a phun scene package, it contains a few things, like textures, checksums, thumnails and the scene itself. A *.phn file is a phun scene, before beta 5, this was the only file, but, with the release of beta 5, this was packed into *.phz files, which allows you to move the file wherever you want and the scene should still work just as well. *.phz:*.phn file editing may possibly need a tutorial because keys.bind functions aren't serialised.

How would I go about opening a *.phz file? You could follow a few steps:

For opening these files, you may need a program that can open *.zip archives like 7zip or WinRAR.

Choice A) Rename.

1. Select the *.phz file and press F2 or open the context menu and click rename or click on the File → Rename.

2. Select the ".phz" part of the file name. 3. Type ".zip". 4. Press Enter. 5. Press Enter or Double Click on the file.

Choice B) Open.

1. Select the file. 2. Drag the file into the zip archiver.

How would I go about opening a *.phn file? You can open almost any text document reader (like Notepad or Wordpad or OpenOffice Writer or Microsoft Word or Notepad++, etc.) and drag the file in (*.phn from the *.phz).

Where do I put my code? It is best to place your code near the top of the file.

How do I put the file back in? Just re-zip up the file using an archiver (like WinZip, WinRAR, 7zip, Filzip or in some cases, Windows).

Page 30: Thyme Tutorial: The basic and advanced techniques

30 Thyme Tutorial

I get a warning on my edited file, is this normal? Yes, this warning means the checksums do not match, which is not a problem, this will only stop you from uploading it to phunbox/algobox, but, sending it to your friends wont be a problem, the reason the system does this is so that people can't just put files in the archive and upload non-scene files to algobox/phunbox.

Page 31: Thyme Tutorial: The basic and advanced techniques

31 Thyme Tutorial

Tutorial 16: General Thyme Notes

Is Thyme case sensitive? No, though, some functions are case sensitive, but these functions are uncommon (like infix), VariableNAME is the same as VARIablename in access.

What is ->? -> Is a redirection, it is used to direct you to a different structure, for example, in: Scene->{my->{*}}, * is in Scene.my, it can be very useful, as you can type variables like: Scene->{my->{Variable123 = 6;Variable456 = 2;Variable93 = 4}}, and it will come out as: Scene.my.Variable123 = 6;Scene.my.Variable456 = 2;Scene.my.Variable93 = 4. Which can save a lot of typing when a large amount of modifications need to be made.

I've heard about "comments", what are they? Comments are mainly for when you are archiving your file (perhaps one that runs from time to time or on start-up), comments allow you to leave notes that may say how a variable or function is used by the program, or what the purpose of the program is, you can create a one lined comment by putting "//" at the beginning of the comment, you can make multi-line comments by starting with "/*" and ending with "*/", comments are ignored when placed into the console.

What are "scopes"? There are a few scopes, the main ones are the [ROOT] scope, which is where the console declares variables, and objects are another scope, which allows for you to have airFrictionMult declared on a very large number of objects without the parser getting confused.

How do I add two or more strings together? You can type each string, then place a "+" in between it, if you have a string contained in a variable, you may have to add "+ """ to the end of the variable, to make sure to convert it to a string.

Page 32: Thyme Tutorial: The basic and advanced techniques

32 Thyme Tutorial

Tutorial 17: Advanced Techniques: Object Pointers

What is an object pointer? An object pointer is a constant link to all an objects properties and its last collision position and normal, object pointers can be very useful, mainly because any properties on the object can be modified and the link will still remain.

How would I go about making an object pointer? You could follow a few steps:

1. Create a new object (geometry or laser). 2. Select all the script in either onCollide, onHitByLaser or onLaserHit. 3. Type a beginning bracket ("("). 4. Type the argument place-holder, like event or geom or object. 5. Type an ending bracket (")"). 6. Type =>{. 7. Type a variable name, this will contain the object, like Scene.my.Object or

Scene.my.Box35342 or Scene.my.ClassObject. 8. Type an assignment operator ("=" or ":="). 9. Type a beginning curly bracket ("{"). 10. Type the argument place-holder, like event or geom or object. 11. Type an ending curly bracket ("}"). 12. Type another ending curly bracket ("}"). 13. Check you haven't made any mistakes, it should look something like:

(event)=>{Scene.my.Object = {event}}. 14. Press Enter.

Are object pointers serialised? No, I'm trying to find a way to get a serialised object pointer that wont leave anything behind though, when I think of a way to do this, then it should be serialised, which will be useful, but, for now, you'll just have to give a collision on the run of the scene.

Are there other methods of making object pointers? Yes, when I was experimenting with these methods, I found them to be too problematic (conflicts of scopes, resulting in rendering a lot of scenes broken).

Example:

Ian wanted to build a car, but found that people would always adjust his steering, he had an automatic steering system set up, so he connected it using object pointers.

Page 33: Thyme Tutorial: The basic and advanced techniques

33 Thyme Tutorial

The Forward/Backward direction control. Code

onCollide = (carSteering)=>{Scene.my.RemoteSteeringFB = {carSteering}};

The Left/Right direction control. Code

onCollide = (carSteering)=>{Scene.my.RemoteSteeringLR = {carSteering}};

Directional control. Code

Scene.my.SteerForward = {Scene.my.RemoteSteeringFB.this.density = 0.01};

Scene.my.SteerBackward = {Scene.my.RemoteSteeringFB.this.density = 10.0};

Scene.my.SteerLeft = {Scene.my.RemoteSteeringLR.this.density = 0.01};

Scene.my.SteerRight = {Scene.my.RemoteSteeringLR.this.density = 10.0};

Ian's car worked just the way he wanted it, he could now use buttons to control his car.

Page 34: Thyme Tutorial: The basic and advanced techniques

34 Thyme Tutorial

Tutorial 18: Advanced Techniques: Deletion via Code

What is deletion via code? Deletion via code is where you can delete an object without using key triggers, this means you could have a new game, where you have explosions and it takes apart an object and builds a new one with the modified area, it means you don't have to set a destroy key and work it in with the rest of the controls.

How would I go about deleting an object via Code? You could follow a few steps:

Option A) Object Pointer.

1. Create an object pointer. 2. Bring down the console using F11 or Tilde ("~"). 3. Type the name of your object pointer, like Scene.my.ObjectPointer or Scene.my.Box1

or Scene.my.Value8374. 4. Type ".this.". 5. Type a variable, airFrictionMult usually works best. 6. Type an assignment operator ("="). 7. Type "NaN". 8. Check that you haven't made any mistakes, it should look something like:

Scene.my.ObjectPointer.this.airFrictionMult = NaN. 9. Press Enter, and the object will delete when the simulation is run.

Option B) Dynamic Variable Link.

1. Bring down the console using F11 or Tilde ("~"). 2. Type a new identifier, like Scene.my.Value or Scene.my.Variable6 or

Scene.my.Delete234. 3. Type an assignment operator ("=" or ":="). 4. Type a numeric value, like 2.1 or 1 or 7.2345. 5. Check that you haven't made any mistakes, it should look something like

Scene.my.Value = 2.1 6. In the script menu of the object make a pointer to your first identifier in the

airFrictionMult property, like {Scene.my.Value} or {Scene.my.Variable6} or {Scene.my.Delete234}.

7. Bring down the console using F11 or Tilde ("~"). 8. Type the first identifier. 9. Type an assignment operator ("="). 10. Type "NaN".

Page 35: Thyme Tutorial: The basic and advanced techniques

35 Thyme Tutorial

11. Check that you haven't made any mistakes, it should look something like Scene.my.Value = NaN.

12. Press Enter, and the object will delete when the simulation is run.

Why would I want to use deletion via code? Deletion via code can be useful for a lot of things, it can be suitable to use it to delete other objects while still executing a collision script (killers don't execute collision scripts), it can be useful for keeping an area clean, there are lots of uses for this function.

Example:

William was walking wildly through a storm when he saw a tree had gotten in his way, he made a machine quickly to clear the tree.

Code

onCollide = (e)=>{e.other.airFrictionMult = NaN};

William realised that his machine wasn't too effective, so he built a new machine that linked to the main stem of the tree.

Code:

Scene.my.Machine.other.airFrictionMult = NaN;

William cleared the majority of the tree, but he linked the rest of the tree to a new machine.

Code:

Scene.my.RestOfTreeAirFrictionMult = NaN;

William safely got home that night.

Page 36: Thyme Tutorial: The basic and advanced techniques

36 Thyme Tutorial

Tutorial 19: Advanced Techniques: Custom Local Variable Declaration

What is custom local variable declaration? Custom local variable declaration is declaring variables in objects, and functions, these values don't leak to the [ROOT] scope.

How would I go about making a custom local variable? You could follow a few steps:

Option A) Function local variables.

1. Bring down the console using F11 or Tilde("~"). 2. Type a new identifier, like Scene.my.Function or Scene.my.CLVD or

Scene.my.CLVDF123. 3. Type an assignment operator ("=" or ":="). 4. Type a beginning curly bracket ("{"). 5. Type the name of a new variable, like CLV or Custom or Variable123. 6. Type a new identifier assignment operator (":="). 7. Type a value, like 6 or 2.0 or "Example!". 8. Type a semi-colon (";"). 9. Type the rest of a function, like CLV = CLV * Sim.time or CLV = CLV^0.2 or CLV = CLV *

9. 10. Type an ending curly bracket ("}"). 11. Check that you haven't made any mistakes, it should look something like

Scene.my.Function = {CLV := 6;CLV = CLV * Sim.time}. 12. Press Enter.

NOTE: These functions can still take arguments if you place the place-holders in.

Option B) Inside an object.

1. Go into the script menu of an object. 2. Click in the box at the bottom of the script menu. 3. Type the name of a new identifier, like ExampleCLV or CLV123 or Cust0m. 4. Type an assignment operator (":="). 5. Type a value, like 6 or 2.4 or "A String". 6. Check that you haven't made any mistakes, it should look something like ExampleCLV

:= 6. 7. Press Enter.

NOTE: If you place a structure in the identifier, these values will be declared in the structure that you wrote.

Page 37: Thyme Tutorial: The basic and advanced techniques

37 Thyme Tutorial

Why would I want to declare custom local variables? Custom local variables can mean that you can calculate 12 different values, then put them all together, it may make this process a lot easier than putting the entire function into one single statement.

Example:

Vincent was looking at his flower pot and realised that it carried no information on it's type so, he made some information and put it in the flower.

Code:

MainType := "Orchid";

SubType := "Cypripedioideae";

Genus := "Cypripedium";

Species := "Acaule";

ScientificName := "Cypripedium acaule";

Vincent was looking at his flower pot and realised that he couldn't see the information, so that he could see the information, he set it all up.

Code:

text = {MainGroup := ("Main Type: " + MainType + "\n"); SubGroup := ("Sub Type: " + SubType + "\n"); Family := ("Genus: " + Genus + "\n"); Name := ("Species: " + Species + "\n"); SciName := ("Scientific Name: " + ScientificName + "\n");Information := (MainGroup + SubGroup + Family + Name + SciName);Information + ""};

Page 38: Thyme Tutorial: The basic and advanced techniques

38 Thyme Tutorial

Tutorial 20: Advanced Techniques: Extending for Structures

What is extending for structures? Extending for structures is the method for extending for structures past the default structure's limitations (about 50 loops).

How would I go about building an extended for structure? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type a new identifier name, like Scene.my.ForExtended or Scene.my.For10 or

Scene.my.Function. 3. Type an assignment operator ("=" or ":="). 4. Type a beginning bracket ("("). 5. Type three argument place holders, like a,r,c or x,y,z or func,times,progress. 6. Type an ending bracket (")"). 7. Type "=>{". 8. Type a run for the first function, as usual, like c < r ? {a(c)} : {}; or z < y ? {x(z)} : {} or

progress < times ? {func(progress)} : {}. 9. Type a semi-colon (";"). 10. Type a run for the second function, but, this time, add one to the 3rd argument, like (c

+ 1) < r ? {a(c + 1)} : {} or (z + 1) < y ? {x(z + 1)} : {} or (progress + 1) < times ? {func(progress + 1)} : {}.

11. Repeat step 10 for the number of maximum for loops you want avaliable (~50 * the number of repeats of step 10).

12. Type a test if structure to check whether there all the for loops required were fulfilled or not, like (c + 10) < r ? {Scene.my.ForExtended(a,r,(c + 10))} : {} or (z + 10) < y ? {Scene.my.For10(x,y,(z + 10))} : {} or (progress + 10) < times ? {Scene.my.Function(func,times,(progress + 10))}.

13. Type an ending curly bracket ("}"). 14. Check that you haven't made any mistakes, it should look something like

Scene.my.ForExtended = (a,r,c)=>{c < r ? {a(c)} : {};(c + 1) < r ? {a(c + 1)} : {};(c + 2) < r ? {a(c + 2)} : {};(c + 3) < r ? {a(c + 3)} : {};(c + 4) < r ? {a(c + 4)} : {};(c + 5) < r ? {a(c + 5)} : {};(c + 6) < r ? {a(c + 6)} : {};(c + 7) < r ? {a(c + 7)} : {};(c + 8) < r ? {a(c + 8)} : {};(c + 9) < r ? {a(c + 9)} : {};(c + 10) < r ? {Scene.my.ForExtended(a,r,(c + 10))} : {};}.

15. Press Enter.

Why would I want to extend a for structure? By default, if structures only have an about 50 deep recursion limit, this limits the chance of making a problematic code that will render a copy of phun completely useless until it is closed. Extending for structure's limits doesn't make them infinite, but you can extend them to

Page 39: Thyme Tutorial: The basic and advanced techniques

39 Thyme Tutorial

whatever level you like, which means that you probably wont have any trouble with limitations.

Example:

Larry was working on a machine that would create one hundred boxes of the same type, but, he had a problem, his system only handled about 50 deep if recursions, so Larry built a machine that would do what he wanted by extending the for structures.

Code:

Scene.my.ForExtended = (a,r,c)=>{c < r ? {a(c)} : {};(c + 1) < r ? {a(c + 1)} : {};(c + 2) < r ? {a(c + 2)} : {};(c + 3) < r ? {a(c + 3)} : {};(c + 4) < r ? {a(c + 4)} : {};(c + 5) < r ? {a(c + 5)} : {};(c + 6) < r ? {a(c + 6)} : {};(c + 7) < r ? {a(c + 7)} : {};(c + 8) < r ? {a(c + 8)} : {};(c + 9) < r ? {a(c + 9)} : {};(c + 10) < r ? {Scene.my.ForExtended(a,r,(c + 10))} : {};};

Scene.my.ForExtended((number)=>{Scene.addBox{pos := [number,number];size := [1,1]}},100,0);

Page 40: Thyme Tutorial: The basic and advanced techniques

40 Thyme Tutorial

Tutorial 21: Advanced Techniques: Update Links

What is an update link? An update link is a local link that allows for a variable to retain it's value, this is very usefull for springs and hinges.

How would I go about making an update link? You could follow a few steps:

1. Go into the script menu of the object you want to build an update link for. 2. Select all of a variable you don't plan to change any time soon, like opaqueBorders or

dampingFactor or constant. 3. Type a beginning curly bracket ("{"). 4. Type the name of the variable you want to update, like length or constant or motor. 5. Type an assignment operator ("="). 6. Type the value you want to set it to, like {Scene.my.lengthVariable} or 62.5 or

{Math.sin(Sim.time)}. 7. Type a semi-colon (";"). 8. Type the normal value of the variable. 9. Type an ending curly bracket ("}"). 10. Check you haven't made any mistakes, it should look something like {length =

{Scene.my.lengthVariable};false}. 11. Press Enter.

Why would I want to use an update link? Some objects lose their values when they are saved, update links preserve these values, and should keep the values as what they should be.

Example:

Arthur was building a spring controlled fork-lift, but all his length settings kept on dissapearing, so he set up a guard system.

Code:

opaqueBorders = {length = {Sim.time / 10};true};

Page 41: Thyme Tutorial: The basic and advanced techniques

41 Thyme Tutorial

Tutorial 22: Advanced Techniques: Widget → Object Links

What are widget → object links? Update links can go two ways, widget → object links are sending out data rather than receiving it, this allows you to state what different parts of a widget will modify, like making the length slider modify the texture matrix of another object.

How would I go about creating a widget → object link? You could follow a few steps:

1. Go into the script menu of the object you want to extract data from. 2. Select all of a variable you don't plan to change any time soon, like opaqueBorders or

legacyMode or color. 3. Type a beginning curly bracket ("{"). 4. Type the name of an identifier, like Scene.my.TextureMatixXYScale or Scene.my.Value

or Scene.my.XV784. 5. Type an assignment operator ("="). 6. Type the name of one of the variables linked to a widget object (like a spring menu). 7. Type a semi-colon (";"). 8. Type the normal value of the variable. 9. Type an ending curly bracket ("}"). 10. Check you haven't made any mistakes, it should look something like

{Scene.my.TextureMatrixXYScale = length;true}. 11. Press Enter.

Why would I want to use widget → object links? Widget → object links are good for being user-friendly, they can also be useful for testing how things handle when slowly increased, or for linking one spring widget to lots of springs, so that one master spring will be able to control all the other springs, which means that there wont be a problem with not being able to select the specific springs you want to.

Example:

Edward was building a remote control car, he had 2 sliders, one which decides whether it goes up or down, and one which decides whether it goes forward or backward.

Code: (Spring)

opaqueBorders = {Scene.my.ControlUpDown = length;Scene.my.ControlForwardBackward = constant;true};

Page 42: Thyme Tutorial: The basic and advanced techniques

42 Thyme Tutorial

Tutorial 23: Advanced Techniques: eval

What is eval? eval is a function that allows you to execute a string as if it were typed, Reflection.executeFile works in the [ROOT] scope, whereas eval works in the local scope, eval is a safer function than Reflection.executeCode.

How would I go about using eval? Use of eval is quite simple, you can just follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type eval. 3. Type a beginning bracket ("("). 4. Type a string, or a variable containing a string, like Scene.my.String or ("Scene.my.Va"

+ Scene.my.NewString + "= 6.8") or "Scene.my.Value9 = 12.7". 5. Type an ending bracket (")"). 6. Check that you haven't made any mistakes, it should look something like

eval(Scene.my.String).

Why would I want to use eval? eval is a very useful command, it can save a lot of computation, for example, a 5000 deep for structure to check if a value is a certain value and to do something specific if it is could do exactly what you wanted, but, an eval replacement would be much more efficient, you could run thousands of eval functions before you'd reach the same resource usage as the for structure.

Example:

Yusei was working on improving his friend's machine, his friend made a 10 deep if structure, Malcolm's machine wasn't the most beneficial, especially because it was being executed at 100Hz

(Malcolm's Machine.)

Code:

(errorCode)=>{errorCode == "0" ? {Scene.my.errorCode0} : {errorCode == "1" ? {Scene.my.errorCode1} : {errorCode == "2" ? {Scene.my.errorCode2} : {errorCode == "3" ? {Scene.my.errorCode3} : {errorCode == "4" ? {Scene.my.errorCode4} : {errorCode == "5" ? {Scene.my.errorCode5} : {errorCode == "6" ? {Scene.my.errorCode6} : {errorCode == "7" ? {Scene.my.errorCode7} : {errorCode == "8" ? {Scene.my.errorCode8} : {errorCode == "9" ? {Scene.my.errorCode9} : {Scene.my.errorCodeERROR}}}}}}}}}};};

Page 43: Thyme Tutorial: The basic and advanced techniques

43 Thyme Tutorial

Yusei's Machine.

Code:

(errorCode)=>{eval("Scene.my.errorCode" + errorCode)};

Page 44: Thyme Tutorial: The basic and advanced techniques

44 Thyme Tutorial

Tutorial 24: Advanced Techniques: Element Modification

What is element modification? Every different object within an array is an element, each object with it's own index number is an array element. Element modification is not easily avaliable, because of this, you require a function to do it for you, if you want to modify individual elements.

How would I go about element modification? You could follow a few steps:

1. Bring down the console using F11 or Tilde ("~"). 2. Type the identifier of the array, like Scene.my.Array1 or Scene.my.Value or

Scene.my.Variable663. 3. Type an assignment operator ("="). 4. Type the identifier of the array again. 5. Type a starting square bracket ("["). 6. Type all of the element index numbers up to the element you want to edit, seperated

by commas. 7. Type an ending square bracket ("]"). 8. Type two addition operators next to each other (add lists)("++"). 9. Type a starting square bracket ("["). 10. Type the modified element, like 6 or 2.8 or "Malcolm's amazing error code machine.". 11. Type an ending square bracket ("]"). 12. Type two addition operators next to each other (add lists)("++"). 13. Type the identifier of the array again. 14. Type a starting square bracket("["). 15. Type all of the element index numbers after the element you want to edit to the end

of the array, seperated by commas. 16. Type an ending square bracket("]"). 17. Check that you haven't made any mistakes, it should look like Scene.my.Array1 =

Scene.my.Array1[0,1,2,3,4,5,6,7,8,9,10,11] ++ [6] ++ Scene.my.Array1[13,14,15,16,17,18,19,20,21,22,23,24,25].

Why would I want to use elemental modification? Elemental modification is easiest if you need to make a change to an array, but only one element.

Have you built a function to do elemental modification? Yes.

Page 45: Thyme Tutorial: The basic and advanced techniques

45 Thyme Tutorial

Code:

Scene.my.ElementChange = (Variable,Element,Size,SetTo) => {Scene.my.ElementChangeT (Size, Element, 0, SetTo, [], Variable)};

Scene.my.ElementChangeT = (Size, Element, CurElement,SetTo,CurArray,OrigArray)=>{Size > 0 ? {CurElement < Size ? {CurElement == Element ? {Scene.my.ElementChangeT (Size,Element,(CurElement + 1),SetTo,(CurArray ++ [SetTo]),OrigArray)} : {Scene.my.ElementChangeT (Size,Element,(CurElement + 1),SetTo,(CurArray ++ [OrigArray CurElement]),OrigArray)};} : {CurArray}} : {print ("Arrays require more than 0 elements")} };

Example:

Nathan has a machine that has a texture, when it is hit, its texture matrix is changed.

Code:

Scene.my.ElementChange = (Variable,Element,Size,SetTo) => {Scene.my.ElementChangeT (Size, Element, 0, SetTo, [], Variable)};

Scene.my.ElementChangeT = (Size, Element, CurElement,SetTo,CurArray,OrigArray)=>{Size > 0 ? {CurElement < Size ? {CurElement == Element ? {Scene.my.ElementChangeT (Size,Element,(CurElement + 1),SetTo,(CurArray ++ [SetTo]),OrigArray)} : {Scene.my.ElementChangeT (Size,Element,(CurElement + 1),SetTo,(CurArray ++ [OrigArray CurElement]),OrigArray)};} : {CurArray}} : {print ("Arrays require more than 0 elements")} };

Scene.my.MachineTextureMatrix = [0.4, 0.0, 0.5, 0.0, 0.6666667, 0.5, 0.0, 0.0, 1.0];

When something hit the machine.

Code:

onCollide = (e)=>{Scene.my.MachineTextureMatrix = (Scene.my.ElementChange(Scene.my.MachineTextureMatrix,2,9,1.0))};

Font:

http://www.algodoo.com/forum/viewtopic.php?f=13&t=411