Skip to content

Keeping one unit

There is no point binding every iteration. A proper loop binds rarely — only when the previous unit will no longer do

mediumYou need: Binding by type, Loops

Walking the list is good when every unit needs the same thing. As soon as a unit gets business of its own — this one carries copper, that one guards a passage — the walk starts getting in the way: every iteration goes to a different unit, and none of them finishes the job.

The answer is not to remember a unit in a variable. It is not to bind more often than needed.

tick 0
Operation0
=
Sensor1
=
in
Jump -> 52
if
Unit Bind3
type
Operation4
=
Operation5
=
Operation6
=
Set7
=
@counter0number
loopsnullnull
gonenullnull
bindsnullnull
changednullnull
previousnullnull
swapsnullnull
op add loops loops 1
sensor gone @unit @dead
jump 5 equal gone 0
ubind @poly
op add binds binds 1

Watch the two counters: loops grows without stopping while binds stays at one. The program bound once, and after that it makes sure every iteration that the unit is still there and goes straight to work.

This rests on a simple property: @unit lives between iterations. It is an ordinary processor variable, nobody clears it, and by the next iteration it holds the same unit. No copy in a variable is needed at all.

tick 0
Operation0
=
Unit Bind1
type
Operation2
=
Operation3
=
Operation4
=
Set5
=
@counter0number
loopsnullnull
bindsnullnull
changednullnull
previousnullnull
swapsnullnull

The same program without the check. Now binds equals loops, and the swaps counter shows the point: the unit changes almost every iteration. There are three polys on the map, and the program walks them in turn instead of leading one.

There is one @unit, and there can be several units. As soon as a processor has to remember more than one, they have to be stored somewhere else — and taken back out:

tick 0
Unit Bind0
type
Set1
=
Unit Bind2
type
Unit Bind3
type
Unit Bind4
type
Operation5
=
Stop6
@counter0number
ownnullnull
sameOnenullnull
ubind @poly
set own @unit
...
ubind own

The ubind field takes not only a type but the unit itself. Then the binding does not go round the circle but comes back to exactly that one — sameOne confirms it.

That is done when:

  • there are several units, each with its own job — then they are kept in a memory cell, a slot each;
  • a unit is handed to another processor — it takes it out of a shared cell and binds;
  • the program bound to somebody else in between and has to return to its own.
tick 0
Jump -> 30
if
Unit Bind1
type
Set2
=
Sensor3
=
in
Unit Bind4
type
Operation5
=
@counter0number
ownnullnull
deadnullnull
alivenullnull

The flare stands under an enemy turret’s fire and will die in a few seconds. Watch the variables: dead becomes one, and alive shows there is nobody left to bind to.

Here is what happens:

  • the unit drops out of the walk — ubind @flare starts giving emptiness at once;
  • the binding keeps pointing at the deceased. Neither @unit nor the variable is cleared;
  • sensor dead own @dead answers with a one — and that is the way to check.

A binding gives no orders by itself, but ucontrol does, and after it the unit obeys the processor for ten seconds instead of its own mind. There is no need to wait out those ten seconds:

ucontrol unbind 0 0 0 0 0

This is not “unbind from @unit” — the variable stays as it was. It is “stop driving it”: the unit returns to its usual behaviour, and the processor can get on with the next one.

Unofficial fan project, not affiliated with Anuke. Mindustry sprites, fonts and translations © Anuke, used under GPL-3.0; Fira Code under OFL-1.1. Site code is GPL-3.0.