Desynced

Desynced

Not enough ratings
Behaviors explained
By Landlocked
A guide to the behaviors programming system
   
Award
Favorite
Favorited
Unfavorite
Programming Setup and Basics
Welcome

I saw a complaint in the discussions that there wasn't much in the way of good resources for learning how to program behaviors. Boy, were they ever right. You might find people sharing copy/paste text strings of behaviors they made (some work, some don't). You might see at most 5 different youtubers making videos that sometimes involve behaviors. The wiki? Not really. So here's some of the stuff I've figured out. Reading the whole thing straight through might be too much, so come back and read or re-read stuff as you build familiarity.

Using Behaviors

There is an early research you can do in game called 'Behaviors'. This will unlock an internal component called the 'Behavior Controller'. If you make one and drag it to a building or mobile unit, it'll equip itself and then a new window will appear to the right of the interface on the bottom. You can open the behavior programming screen by pressing the 3 lines button in that window. Once you create a behavior there, you can exit the screen and press the play arrow to start running the behavior for that unit. You can also press the stop square to stop it. If you edit a behavior that's running, it'll automatically stop.

Using Behaviors Shared By People

In the lower-right of the behavior screen is a computer hard drives button that will take you to a behaviors library screen. You can save and load your behaviors here. You can also take a behavior and load it into your clipboard as a text string for sharing. You can paste it outside of Desynced like you would any text with ctrl-v. If you've already copied one and then you go back to the library screen, you will have an option to overwrite the current behavior with the one you copied. I've copied a few where I didn't get the option to do that. I'm assuming they were made on an older version and don't work anymore. Here's a copy of the result of the first step-by-step example if you want to try it out.

DSCV02qGO21CVyh0289lCC1z4boV23ezW202J81Q000gci29Kh6p1CVyij22TJNd21MTvB1rBOTd28Dbzr22kZID01oU

Nodes

The behavior programming system is a form of visual programming based on nodes. As you drag different nodes from the options on the left, they will appear as boxes in the main programming area. These boxes will have squares where values can go, labels with teeny explanations, and circles on the outside edge of the boxes. Each one does something different. The node options on the left are grouped into somewhat confusing dropdown categories. I find the easiest way to find a node is to remember a couple letters from the name of the node and type those into the search above the list of nodes so it shows just the ones with those letters.

Program Flow

Behaviors will start at the 'Program Start' node. There's always automatically one in the programming area. From there, it will go to the next node that is connected by a line. When you drag a node from the left into the programming area, it will automatically form a connection from the last node to the new node. This will form a chain of nodes that the behavior will step through. The circle on the left is how you get into a node and the circle(s) on the right is where the program goes next. Once it gets to the last node with no connection on the right of it, it will start again from the beginning.

Example Program

Here's how to make an example program.
  1. Start with a clear programming screen, and then find the 'Get Self' node under 'Math'. Drag it into the programming area.
  2. Click the square labelled 'Result' in that node. Select the purple diamond labelled 'A' in the selection screen. What this will do is make a value out of the thing that has the 'Behavior Controller' in it and then store that value in variable 'A'.
  3. Find the 'Combine Register' node under math and drag it into the programming area.
  4. Click on the 'Num' square and enter a random number. You can do this at the bottom of the selection screen with the +/- number buttons, or by typing a value into the text box. I'm using 3.
  5. Click on the 'Entity' square. Select variable 'A' near the top.
  6. Click on the 'Register' square. Select the 'Visual' register (looks like a portal icon).
  7. Click the confirm check mark in the bottom-right of the behavior screen.
  8. Press the play button for the behavior.

What this program does is get the icon for whatever unit has the behavior, adds a number to that icon, and then makes the icon appear on top of the unit. If you did this with a mobile unit, you can move it around and see the number icon follow along. You will see the program repeating over and over in the behavior window, but since the visual register is already set, repeated runs have no effect.

Bending Nodes To Your Will

If you mouse over a node, some option buttons appear above it.
  • Nodes are locked in place to the right of whatever node they are connected to. If you press the lock button, you will be able to move the node where you like. Nodes that are locked to that node will come along with it when moved.
  • The pencil button will let you write a comment that will appear under the node. It's nice for documenting the code.
  • The play button will highlight that node. If you run the behavior then the program will start from the highlighted node.
  • Some nodes have extra options. If so, the folder button will be available to show them. Same effect as the drop-down near the bottom of the node.
  • The X button deletes the node.
You can drag from a circle on the right of a node to another node's circle on the left to make your own connection. If you drag from the right-hand circle to nothing, then an existing connection will be removed. That can leave orphaned nodes that won't run. Right-hand circles can only connect to one node, but left-hand circles can accept incoming flow from more than one node.

Values, Registers, Parameters
Values Are Versatile

The values that go in the squares can be many different things. It can be a:
  • Number
  • Icon/Concept
  • Icon/Concept and Number
  • Unit/Building/Thing that exists in the world
  • Unit/Building/Thing that exists in the world and number
  • X/Y coordinate pair
  • Blank
If you put a value that is more than just a number in a square expecting a number, it will generally take just the number part and ignore the rest. Blanks and things without numbers are assumed to be 0.

Registers

Every unit/building has several registers. These are places where a value can be and they do different things. From left to right they are:
  • Signal - A value that can be read by other behaviors at any distance.
  • Visual - An icon that will appear and stay above the unit. When you set the recipe in a production building, it will set up the visual register to display how much of a produced product there is automatically
  • Store - Whatever this unit picks up or produces will be stored here. (If this register is set on something with a behavior, it will interfere with the behavior)
  • Goto - Mobile units try to go here. If they are going to something that moves, they will follow it. Unhelpfully, this register will be blank even if it is following something. (If this register is set on something with a behavior, it will interfere with the behavior)

You can set any of these manually. If you click on signal or visual, you can pick a value for it like you would in the behavior screen. If you click on store or goto, it will left you pick a unit to focus on. (Or you can drag from the register to the unit). You can clear any register with right-click.

Parameters

You can freely create more registers for your behavior to use. In the top-left of the behavior screen are +- buttons for adding and removing parameters. In game, these will appear as extra squares to the right of the behavior controller. You can use these as places to display information, as variables to keep track of something, or as manual configuration squares that are outside the behavior. For example, if you make a program for a mining bot, you might have a parameter where you select ore, crystal, or something else to let the bot know what its purpose in life is. Or you might use one to tell a hauler where to deliver things to. (It's tempting to use the store register for this, but that will mess with any behavior you're trying to run). You can click on the name of the parameter in the behavior screen to rename it. These names will appear as tool tips in the game.

Variables

If you need to store a value but don't need visibility for it, you can store it in a variable. Choose a purple diamond in the selection screen for the 'Result' square of a node. At first only 'A' will be available, but once A is in your program, then B will show up as a choice and so on through the alphabet. Note that if you leave the result selection blank for a node then that node won't do anything. If you want one of the inputs to change, list it again in the result as well.
Advanced program flow
Split paths

Some nodes can go to more than one place. There might be a higher/equal/lower comparison between two values that will give 3 circles on the right to continue to. Or it may just be a true/false pass/fail comparison with two paths. These will give you options to do different things depending on the situation.

Loops

Some nodes say that they are loops and have a normal right-hand exit circle as well as a 'Done' circle closer to the bottom. Normally, when a program gets to a right-hand circle that doesn't link to anything it will return to the start of the program. If you have a loop node as part of your program, it will instead return to the loop node to keep running the loop with a different value until it's gone through everything in the loop. After the last loop, it will exit from the done circle.

It's possible to have loops inside other loops. In this case, program flow will return to the last loop listed and once that is done it will return to the next last loop. From there, it can start the loop that just finished again.

Don't loop a loop back to where the loop started. It will become recursive and the behavior will stop after it gets 40 loops deep. Let loops end by having an unconnected right-hand circle when your done doing stuff.

If you want to stop a loop early, link it to a 'Break' node. This node has no right-hand exit circle and the next node it goes to will be the 'Done' location of the latest loop. It will not exit any other loops than the latest one.

If you 'Break' while not in a loop, the entire behavior will stop.

Debugging loops

Loops are confusing things from the outset. The largest problem I've run into is not knowing how much stuff was actually found to loop through. When I start to program with a loop, I like to get a readout on what's happening. Here's an example program

DSC8e2biIdE1BF4bV1rH8oi1nP1nh1BIgBf0158zU3KeQMe0rHFYW0reV8r3bB7w01I47hS4OkDDb0TLTAy4EDuf50A9cdv192spA3buc1M3Wofzu3KO8Ke0ged9N1v1Yho1mKEWW1ruhHF0rNFjy1UW2LY3YfBED1Ar1Hp35kVgv0Nqu5T00TzAI0x4D8v2FmbQE3sOoWQ1e7p2N1rvzlV1D8OQ81PBi8D4F14xC3ZPiA30sFTFZ1gmlgJ4fp8Dg4ZiSnu2RMoZQ1vwAY10jL5z91MP9OA4QcmXh1xOYKg2Sn95cGs7Q


It has two parameters; one for keeping a tally of how many things it's looped through and another to display what was found in the current loop. The range is set to infinite, but this node only works for things in visual range of the unit so it won't get everything. There is no filter so if you run this in a base, be prepared to see a lot of floor tiles.

Waiting

Under the 'Program Flow' category, there is a 'Wait Ticks' node which will pause program flow until the tick has finished sucking blood. Er, no that's not right. In programs, a tick is 1/5 of a second. You may notice running programs rapidly flowing through steps, and I think every program does one more node every tick. One top of being distracting to look at, if you have a lot of behaviors running this can bog down your computer. Adding a wait node and choosing a number of ticks to wait will cause the program to pause there for a while. This can take the pressure off by letting the program rest a bit. Most behaviors don't need to run nonstop to do what you want.

Not waiting

On the other hand, some complex programs may have high-performance applications where even the time it takes to step through the nodes is too slow for what you want. In that case, add an 'Unlock' node as the first step of your program and that behavior will sprint through as many nodes as it can at all times. Add at least one wait node to the program to avoid stress-testing your CPU, and also add waits anywhere else in the program where you want it to wait.
VIP nodes
Here's some nodes that end up frequently in programs.

Count Items

It has a remaining/reserved dropdown. When some or all of a stack is ordered to be moved somewhere else or is being used in a production building, it will be 'reserved' and show up in the game as having a striped amount bar. Most of the time you'll be counting 'remaining', which is everything that isn't reserved. (Bug? 7/7/2024) I've tried counting reserved items and everything always shows up as remaining.

There is an 'Item' box which will let you choose what type of thing you want to count. If you leave it blank, you will get a total count of all types of item in the inventory.

The result box is where you want the number of the count to be stored.

There is an additional option 'unit'. If this is blank, it will count items in it's own inventory, but if you fill it in with a unit, it can count items in something else's inventory.

Drop Off Items and Pick up items

Has a destination/source input. A unit will try to move to the target and then drop off/pick up as much as it can. There are additional options for item/amount and a drop-down. If you don't leave the item blank, it will only drop off/pick up the specified item. If you don't leave the amount blank, it will drop off/pick up as much as it can of that item, up to the amount. The drop-down leads you to believe that you can choose specific amounts and not just as much as possible up to that amount, but it's bugged. (As of 7/72024). If you run the program, the drop-down will disappear and be ignored.

The unit will not attempt to move if there is nothing to pick up/drop off. The node will fail and program flow will continue from there. Program flow stops at this node while the unit is moving to the target. A building can pick up/drop off if it has a teleporter and is close enough to the target. If the target can't be reached then the operation will fail and program flow will continue. New move and pickup orders are not generated on behalf of this node, so it's likely to fail for buildings.

Move Unit

Has a destination input and a synchronous/asynchronous drop-down. The unit will move to the destination. Fails and continues if it's not something that exists in the game world. Pauses behavior execution while the unit is moving. If the target is on the move, this will make it follow until it gets close enough. You can assign a number to the input on top of a destination object and it will move until it is that distance away instead of directly next to. If you set it to one, that is directly next to the destination. I don't know what sync/async does.. It doesn't seem to vary any of the things I've just described.

Loop Signal (Match)

Loops through all things that have a certain signal. That is, whichever icon is in their signal register. This loop is good for finding things that may be out of visual range of the unit running the behavior. It will consider all things that have the given signal, regardless of range.

Example program: Distribution Bot

Here is a program I use to stockpile materials from one building across multiple buildings. While it's possible to set several storage buildings as the store register in a chain, it also means that things will be moved several times to get through each building if you do so. This program repeatedly picks up items from a home base (set Parameter 1 to this) and delivers them to any building with a certain signal. (Set parameter 2 to this, and then set the signal register in each building to deliver to as that same signal). You may drag-select several things and set the signal register of them all at once. For example, I have crystals delivered to one central building and then this bot spreads the crystals out to several other crystal storage buildings. It will take one load from the main storage to each signal storage in turn. If there's either nothing to deliver or everything is full, then the pickups and drop-offs will start to fail and it will stay in place as it goes through the loop. For a few distribution locations very close to the home base, a 1-inventory worker is fine. If you start to have more drop-offs, or have them spread through the base, or have a very high throughput on the material, then using faster bots with more inventory slots will help.

DSC7X4CU9nc1q0AL21lSfaM2rWBbm3EjamF3HSKZA01h86O0LbTZj3eF4ot4RhTzn0wWdQ326egx11NF0fS2gcamo0nRYES0up3go0CpALj0WyWum34cv4B06GFGO13ygoo3F6z1Y3Jkl8S0RzslY2glqrw2iPBA92gAZzt2iQKqI1Y10Ax2gQKNe06WNzN1k1dzl3H4Akb3vghCE2SpoRe4Qzgvw0x8Qdf1C2ID40mlS2M1NNtyP2M9wMU1Nq5H0006w6K3PXWrrL


Node 1: Wait 20 ticks (4 sec). In case it gets through the loop quickly, I throttle to speed down a bit
Node 2: Loop Signal (Match). Input - Parameter 2, Output - Variable A. Loop through all things with the signal given in parameter 2
Node 3: Pick up items. Input - Parameter 1. Pick up as much as possible from the building/unit set as parameter 1.
Node 4: Drop off everything possible at destination variable A.

Combine Register

It has 'num', 'entity', and 'register' inputs. It will allow you to take the number part of the num, the icon part of the entity and combine them into a single thing. Both the num and entity inputs may have icons and numbers and it will still work. Having a blank input will count as a blank icon with 0 value. You can assign blanks/zeros to clear registers. The target can be a register, parameter, or variable.

Optionally, it also has 'x' and 'y' inputs for working with coordinates. If you enter an x and y it will overwrite the icon with coordinates, but keep the number of the num input. If you leave out either x or y, then it will use the icon instead.

It's possible to use this and completely skip using the 'Copy' node since it can do everything Copy can and more.

Game of drones?

I'm publishing what I have here but may add more later

1 Comments
hugedata 17 Sep, 2024 @ 10:32am 
Synchronous means the move command will continue until it reaches its destination before continuing the program. Asynchronous means it will continue the program as soon as the move command starts allowing the unit to run the rest of the code without waiting for the unit to reach its destination.

For example, say you have a program that tells a unit to Move to Location, Scan for Enemies, and call your combat team when it finds some. Synchronous movement will not scan for enemies until it reaches destination. Asynchronous movement will allow it to scan for enemies while it is moving and can even override the initial move command with another command before it reaches destination.