tulamide's little corner of tips'n'tricks

Post your own tutorials, guides and demos.

Post » Fri Jul 27, 2012 6:40 am

Hi fellow game designers,

I decided to open this thread to post tips and tricks here from time to time. I will concentrate on programming rather than on design, and on more simple but effective tricks rather than the next 20000 line code segment.
If you are an experienced programmer, you probably won't find anything new or exciting here. But if you have made your first steps into programming and want to go deeper, than you're at the right place.

I don't know how frequently I will post here, so don't ask or try to force me^^

If you have suggestions, I'd be happy to read them.tulamide2012-07-27 06:45:37
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Fri Jul 27, 2012 6:44 am

Tips'n'Tricks #1: Automatic Loop Counter

You might already know about the trick to automatically switch between 0 and 1, by simply writing
pv = 1 - pv

if you start at 0, consecutive calls of the event will set pv to:
pv = 1 - 0 = 1
pv = 1 - 1 = 0
pv = 1 - 0 = 1
etc.

So far, so good. But what if you wanted to switch between 1 and 2? Or count from 1 to 5, repeatedly?
There's a treasure, we can use here. It's called mod (short for modulo, or modulus), and in CC you use the %-sign to indicate modulo calculation. Modulo calculates the integer remainder of a integer division. For example, 5 % 4 equals 1. To better understand it, let's look at the calculation from the other end. 4 fits into 5 exactly one time (remember: integer division)) and it remains 1. Got it? Ok, what about 11 % 4 ? 4 fits into 11 exactly two times and it remains 3 (2*4 = 8, 11 - 8 = 3). So 11 % 4 equals 3. But why the heck do I tell you this? Because the remainder will never exceed the second number of the calculation. See this list:
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0

See? It loops. And with a simple but clever trick you can use this to your advantage and implement an automatic loop-counter that doesn't need any bounds check.
pv = (pv % [upperbound]) + 1

Fire and forget. Let's say you want to count from 1 to 4 in a loop. 4 will be your upperbound. If you start at 1, consecutive calls of the event will set pv to:
pv = (1 % 4) + 1 = 2
pv = (2 % 4) + 1 = 3
pv = (3 % 4) + 1 = 4
pv = (4 % 4) + 1 = 1
pv = (1 % 4) + 1 = 2
pv = (2 % 4) + 1 = 3
etc.

You can do a lot of other things, too. Say you want to switch between 3 and 5. Take an upper bound of 4 but add 2 instead of 1. Here you go:
pv = (pv % 4) + 2

pv = (3 % 4) + 2 = 5
pv = (5 % 4) + 2 = 3
pv = (3 % 4) + 2 = 5
pv = (5 % 4) + 2 = 3
etc.

You prefer switching between 3 and 4? Alright:
pv = (pv % 2) + 3

pv = (4 % 2) + 3 = 3
pv = (3 % 2) + 3 = 4
pv = (4 % 2) + 3 = 3
pv = (3 % 2) + 3 = 4
etc.

Or maybe you want to count from 4 down to 2 in a loop? Tricky, but possible:
pv = (pv % 3) + 2

pv = (2 % 3) + 2 = 4
pv = (4 % 3) + 2 = 3
pv = (3 % 3) + 2 = 2
pv = (2 % 3) + 2 = 4
pv = (4 % 3) + 2 = 3
etc.

"Right", you say, "now do something completely weird. Your dumb trick will never succeed. I want you to automatically calculate the numbers 5, 2, 4, 6, 3 exactly in this order and looped. HA!" ...Hmm, you mean like so?
pv = (pv % 5) + 2

pv = (3 % 5) + 2 = 5
pv = (5 % 5) + 2 = 2
pv = (2 % 5) + 2 = 4
pv = (4 % 5) + 2 = 6
pv = (6 % 5) + 2 = 3
pv = (3 % 5) + 2 = 5
etc.

You can even do an addition that doesn't add anything, but always stays at the number you add. Ok, it doesn't make sense, but it is possible :
pv = (pv % 1) + anynumber

pv can be any number too, e.g. 143
pv = (143 % 1) + 5 = 5
pv = (5 % 1) + 5 = 5
etc.

Now that you learned the magic of modulo, go out and spread the word. Find wonderful rows of looped numbers, or find new ways of using modulo. The fantastic world of modulo counting awaits you...tulamide2012-07-27 06:47:19
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Fri Jul 27, 2012 6:50 am

Tips'n'Tricks #2: nth Root Calculation

Here's another one you might find useful. Say, you want to take the squareroot of a number. You'll use the expression sqrt():

pv = sqrt(16) = 4

That's good, but what if you need to take the 3rd root or the 5th root? There are quite some situations, where you need them (e.g. when working with audio)

Here's the trick. Instead of looking for an nth-root expression (which doesn't exist in CC), head towards raising to a power. While 2^3 means 2*2*2, you can calculate the root of a number by using (1 / nthroot) as the exponent.
For this example we will take a number that we know the 5th root of: 32. The 5th root of 32 is 2 (2*2*2*2*2=32)
1/5 equals 0.2

32^0.2 = 2

Test it in CC. Create a text box and set the text in runtime to 32^0.2 or 32^(1/5). I prefer to use the calculated value (0.2 in this case), because divisions can get inaccurate with single precision floats that are used in CC.

So, just remember:
nth root of a number is the same as number^(1/nthroot)
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Fri Jul 27, 2012 7:26 am

Nice.
You should make something up for the tutorial section sometime.
Forum threads get lost so easily.

Also something on order of operations might be nice, or perhaps conditionals.
Image Image
B
161
S
48
G
90
Posts: 7,353
Reputation: 66,761

Post » Thu Sep 20, 2012 7:02 am

No comments, but over 2200 views, so I guess you want more. I take newt's suggestion, so here's

Tips'n'Tricks #3: Conditionals

Construct Classic offers a shortcut for simple 2-state conditions. Let's say we have a game with a mean boss that talks to us. Whenever the player is near the left border, the boss should say: "I can see you!" but else the boss will say: "Where are you?"
With normal events, it would look like so:
+ Sprite: X Less than 200
-> Text: Set text to "I can see you!"
+ System: Else
-> Text: Set text to "Where are you?"

Already only two events. But you can express it in just one event, using conditionals. The way to use them is easy. Wherever you can enter an expression, you can use the syntax "condition ? a : b"
The condition will be either true or false. If true, a will be executed, if false, b will be executed. Easy. And this is how it looks like in an event:
+ System: Always (every tick)
-> Text: Set text to (Sprite.X < 200) ? "I can see you!" : "Where are you?"

Now you might think it is too restrictive, because it only knows two states? For example, you might want the boss to say "I can see you!" whenever the player is near the left or the right border. You shouldn't use "or" to evaluate events, but you can do it this way:
+ Sprite: X Less than 200
-> Text: Set text to "I can see you!"
+ System: Else
+ Sprite: X Greater than 440
-> Text: Set text to "I can see you!"
+ System: Else
-> Text: Set text to "Where are you?"

You can't use conditionals for something like that, can you? You can! The best about conditionals is that you can call a function.

We set up this function:
+ Function: On function "nearBorder"
-> Function: Set return value to 0
++ Sprite: X Less than 200
--> Function: Set return value to 1
++ Sprite: X Greater than 440
--> Function: Set return value to 1

Then we call:
+ System: Always (every tick)
-> Text: Set text to (Function.nearBorder = 1) ? "I can see you!" : "Where are you?"

Of course, you can create much more detailed functions. As long as they return one of two values, you can realize pretty much anything. And using conditionals can simplify your event sheets and make them more clear and well arranged.
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Thu Sep 20, 2012 11:36 pm

Valuable stuff, thanks for posting! I think you will get more feedback though if you provide some more examples of practical applications. There are all kinds of programming tricks like these, but it really comes down to where and when to use them.

So far I've used the automatic loop counter for pause menus, toggling global variables since global booleans don't exist, and making objects flash or flicker. It also helps with palette shifting (see: NES Megaman charging) and slot machine type stuff. I'm sure there's a lot more than can be done with it!

Modulus also allows you to check if numbers are odd or even, which can help make checker patterns and stuff (I've used it for a zig-zag health bar that consists of multiple objects).

Also, aren't "conditionals" called ternary operations? Tokinsom2012-09-20 23:38:22
Image
B
225
S
27
G
13
Posts: 1,774
Reputation: 18,024

Post » Mon Sep 24, 2012 6:26 am

@Tokinsom
Thank you! Yes, there are lots of ways, modulus can serve well.
I try to think of examples, but it's sometimes hard to build something, when you just wanted to quickly share some tricks.

[QUOTE=Tokinsom]Also, aren't "conditionals" called ternary operations?[/QUOTE] That may very well be so (and Wikipedia says it is^^). I learned about it not before using Construct, so I used the phrase Ashley used too.
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Thu Sep 27, 2012 6:51 pm

tulamide these are great. Modulus in particular I can think of a few uses for, and I would have never found out about that on my own. Eager to see what you put in here next!
B
7
S
2
Posts: 123
Reputation: 1,061

Post » Tue Jan 29, 2013 2:29 pm

Tips'n'Tricks #4: Urges

Unlike the other tips, this one is more about actual gameplay. Sometimes you may want to give more life to your npc to gain atmosphere. A lot of designers decide to script such behaviour. But it's not very convincing if the same npc type does exactly the same and in the same order than every other npc of the same type (like walking from a to b, looking around, walking back to a, etc.)

With a simple but effective technique you can give a much better impression of life. Let the npc be urge-driven.

The math behind this is simple, which means you can add a lot of urges - and the more the better. You can even get something like Little Computer People or maybe a simple 'The Sims' - just by setting up enough urges.

An urge is nothing more than a variable that raises over time from 0 to 1. As soon as it reaches 1, all other urges are pending and this one will be executed. It is still a scripted life, but this time you only offer a bunch of premade actions, and the npc decides when and where it executes them.

Below is a very simple example, where 5 npc each knows of 4 urges: Hunger, thirst, curiosity and rest. They all start with a 10-second idle part, but you will soon see, that their actions differ from each other. They start living. Of couse, this would be much more impressive with a dozen of urges and beautiful graphics, but it shows the math behind it and how to setup the events.

Bring life to your games!

urges.cap
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Tue Jan 29, 2013 3:11 pm

I really like how you handled urges using timedelta. It makes everything so much more elegant.
My current system was a mess of conditions and random numbers.

----------------------------------------------------------------
just a note for people about Modulo, it can be very cpu intensive if called to much in a single loop.

I tried to use it in my A* algorithm to simplify the code. but it slowed it down to about half the normal search speed.
--------------------------------------------------------------------
B
6
S
2
G
5
Posts: 249
Reputation: 2,323

Next

Return to Your tutorials & example files

Who is online

Users browsing this forum: No registered users and 0 guests