[Tutorial] Variables explained: Make a town rebuild itself

#1
Hi everyone, I'm making a MOBA map where houses you own generate points over time. I might write a tutorial for that part later. For now I shall explain the builder, which is fairly complicated and therefore well suited to explain some hacks with variables I found:


How variables work in Besiege

Every time a variable is updated (it doesn't actually have to change, the new value can be the same as the old one), it broadcasts its new value to the objects in the "scope of change", which by default is everything (global). Immediately after, even though it keeps its value, it becomes silent again, as if it never existed. Note that by default, a variable will not update on game start and therefore not broadcast its value (which is 0).

Every trigger that listened to this variable (i.e. whose parent object is not deactivated), and whose condition is met by the variable, will now play its events. If the events were already playing (with a wait timer), it will replay them from the beginning. If the events are set to repeat, it will repeat them indefinitly, regardless of what the variable does. The only ways to stop a repeating event are to deactivate or reset the parent object.



How to plan your program

The best way to come up with a complex algorithm is to draw a program flowchart.
https://en.wikipedia.org/wiki/Flowchart

To understand how your variables work, you can write a timing diagram.
Every row represents a variable, starting with the input variables, then the internal calculation variables, then the output variables. The columns are the clocks, the moments in time. Every time a variable changes, write down the value. Then in the next column the values of the variables that change as a result of that, and so on.



Example algorithm

The objective

Your towns rebuild themselves over time when they're destroyed. Each object can take a different time to rebuild, and the builder can prioritize objects that are more important, as there is only one builder per town.
Here's how I did it.

You need a town consisting of destructible objects (e.g. houses) and a builder.
My builder is an invisible trigger box, but you can use anything really.

Variables
houses: this counts how many houses are destroyed. (-1 = one destroyed house etc.)
cycle: this is the unique "address" of each house, in order of importance. (1 = most important) 0 is the builder itself.
on a 1, the first house checks if it is destroyed. If it is, it rebuilds itself and then resets the cycle to 0. If it isn't, it increases the cycle by 1, activating the next house.
start: this determines if the builder should start rebuilding houses (there are destroyed houses AND the builder is unoccupied)
rebuild: this local variable determines if the house is destroyed AND if it is the house's turn in the cycle to be rebuilt

The logic for the builder

On houses = -1
start +1

# note this can happen twice: when the first house is destroyed and when the second to last is rebuilt. So start can become +1 or +2 by this, but these mean the same: there are destroyed houses.

On houses = 0
start = 0

# this resets the above. I used = to reset both a 1 and a 2.

On cycle = 0
wait = 0.01 s
start + 2

# when the cycle has completed and returns to the builder, the second condition for the start is met. The builder is unoccupied now.
# the wait ensures the +2 happens after the start = 0 event above.
# I used +2 because with +1 I wouldn't be able to tell if start is 2 because both conditions are met or because the second to last house just got rebuilt (see above). + 2 puts it out of range of this ambiguity.

On start > 2
cycle = 1
start -2

#when start is 3 or 4, the cycle starts at the first house. start -2 means the builder is occupied now.

On game start
start = 2

#this sets the builder unoccupied at the start of the game because on cycle = 0 doesn't trigger until the first cycle completes.


The logic for the houses

On destroy
rebuild +1; scope of change: (self) #use the paintdropper to select the object you're editing. This ensures this only affects the object itself, not the other houses. This gets changed automatically when you copy the logic to another object.
houses -1

On cycle = 1 #This is the unique address of each object. Change this manually after copy pasting the code.

rebuild +2; scope of change: (self)
#I used +2 so there are different values for "on cycle, but not destroyed (rebuild = 2)" and "destroyed, but not on cycle (rebuild = 1)". Then I can forward the cycle in the first case and do nothing in the latter.

On rebuild = 2 (thumbprint for local variable)

cycle +1
rebuild = 0; scope of change: (self)

#If the house is not destroyed, simply forward the cycle to the next house and undo the change to rebuild.

On rebuild = 3 (thumbprint)
wait = 20 s #This is the time to rebuild. You can make this different for every object. Click the eye icon and choose a symbol to display the build time.
reset <<self>> #the actual rebuilding. Finally!

rebuild = 0; scope of change: (self)
cycle = 0 #this resets the cycle so the builder can start again with the most important destroyed object.

Note that if you have multiple towns, you should give the variables diffent names, i.e. houses1 etc.

That's it! Thanks for reading, if you found it helpful leave a like and I might write more tutorials.

Edit: I noticed that resetting houses like to collide with debris, causing them to explode again or catapulting the debris into other houses. I'd have to deactivate destroyed houses, but that means they won't be able perform any logic by themselves. For now that means the player'll have to manually clear the area of debris. I'm also annoyed that I have to have every number of the cycle exactly once or else I start a second builder orstop the cycle entirely. I'll have to reprogram this and move the house logic to the builder. But this guide might still be useful to you.

Edit 2: If you want to respawn multiple objects simultaneously (such as a complex building) you have to move the logic to a parent object and trigger it by a new "destroyed" variable that works similarly to the houses -1 thing on the builder, with the same ambiguity workaround. I'll write it down if someone cares.
 
Last edited:
Top