Actions

IC10

From Unofficial Stationeers Wiki

Revision as of 05:09, 22 October 2021 by Wark (talk | contribs)

MIPS scripting language for IC10 housings / chips

# Text after a # will be ignored to the end of the line. The amount of white
# space between arguments isn't important, but new lines start a new command.

Registers

The IC contains 16 registers, numbered r0-r15. Think of these as variables in other programming languages. In fact, you can name them with the alias command (see below).

To set a register directly (such as r0=2), use the move command. To read a value from a device, use l (load). To write a value back to a device, use s (set). Note that like most machine languages, the destination goes first, so instructions always look like: action destination source.

There are two more registers. One called ra (return address) and one called sp (stack pointer). The ra is used by certain jump and branching instructions (those ending with -al) to remember which line in the script it should return to. The sp tracks the next index within the stack (a memory that can store up to 512 values) to be pushed (written) to or popped (read) from. Neither ra or sp is protected, their values can be changed by instructions like any other register.

move r0 10
Sets r0 to the value 10

move r0 r1
Copies the value of r1 to r0

l r0 d0
Reads from device 0 and places the value in r0

s d0 r0
Writes the value from register 0 out to device 0

Device Ports

ICs can interact with up to 6 other devices via d0 - d5, as well as the device it's attached to via db. To change or set a device, use a screwdriver and adjust the device in the IC housing. You can read or set any of the device's properties, so it is possible to do things like read the pressure and oxygen content of a room on the same Device port.

The l (load) and s (set) instructions let you read and set values on a device.

l r0 d0 Temperature #Reads the temperature from an atmosphere sensor into r0.

s d1 Setting r0 # Writes r0 to the device on port 1 to the Setting variable.

Labels

Lables are used to make it easier to jump between lines in the script. The label will have a numerical value that is the same as its line number. Even though it's possible to use a labels value for calculations, doing so is a bad idea since any changes to the code can change the line numbers of the labels.
main:
j main

Constants

Instead of using a register to store a fixed value, a constant can be made. Using this name will refer to the assigned value.
define pi 3.14159
move r0 pi

Indirect referencing

This is a way of accessing a register by using another register as a pointer. Adding an additional r infront of the register turns on this behaviour. The value stored in the register being used as the pointer must be between 0 to 15, this will then point to a register from r0 to r15, higher or lower values will cause an error.

move r0 5 stores the value 5 in r0
move rr0 10 is now the same as move r5 10 since r0 has the value 5, rr0 points at the register r5

Additional r's can be added to do indirect referencing multiple times in a row.
move r1 2
move r2 3
move rrr1 4 is now the same as move r3 4 since r1 points at r2 which points at r3

This also works with devices
move r0 2 stores the value 2 in r0
s dr0 On 1 is now the same as s d2 On 1, r0 has the value 2 so dr0 points at d2

Debugging advice

The value stored in a register can easily be seen by writing it to the Setting parameter of the IC housing, this has no sideeffects, too see the value just stand close and look directly at the housing (s db Setting r0).
To check if a certain block of code is executed, use the above trick but with a number that you choose, like the line number (s db Setting 137).
The configuration card can be used to manually check the data values stored in all connected devices.

What a typical program looks like

A program is usually written to be a long continuous loop, that compares values to determine what to do next, sometimes it jumps out of the main loop to do a task before returning back to it. The yield instruction will force the program to wait to the next game tick, so the rest of the game can keep running, but the game is smart enough to force programs to take breaks to prevent them from freezing the entire game if yield is missing. The beq means "branch (jump) if equal" and compares two numbers.

alias myDevice d0
alias myImportantNumber r4

main:
yield
#this is a comment, the program will ignore it, they are often used to explain something to a reader, or to turn off instructions without deleting them
...
beq myImportantNumber 42 myFunction
j main

myFunction:
...
j main



Instructions


alias
alias str r? d? # labels register or device reference with name. When alias is applied to a device, it will affect what shows on the screws in the IC base. (housing)

alias vTemperature r0
alias dAutoHydro1 d0

move
d s # stores the value of s in d

move r0 42 # Store 42 in register 0

l (load)
l r# d# parameter

Reads from a device (d#) and stores the value in a register (r#)

l r0 d0 Setting
Read from the device on d0 into register 0

l r1 d5 Pressure
Read the pressure from a sensor

This also works with aliases. For example:
alias Sensor d0
l r0 Sensor Temperature

ls (load slot)
ls r# d# slotNum parameter

Reads from a slot (slotNum) of a device (d#) and stores the value in a register (r#)

ls r0 d0 2 Occupied
Read from the second slot of device on d0, stores 1 in r0 if it's occupied, 0 otherwise.

And here is the code to read the charge of an AIMeE:
alias robot d0
alias charge r0
ls charge robot 0 Charge


s (set)
s d# parameter r#

Writes a setting to a device.

s d0 Setting r0


add
d s t # calculates s + t and stores the result in d

add r0 r1 1 # add 1 to r1 and store the result as r0
add r0 r0 1 # increment r0 by one

sub
d s t # calculates s - t and stores the result in d
mul
d s t # calculates s * t and stores the result in d
div
d s t # calculates s / t and stores the result in d
mod
d s t
  1. calculates s mod t and stores the result in d. Note this
  2. doesn't behave like the % operator - the result will be
  3. positive even if the either of the operands are negative
slt
d s t # stores 1 in d if s < t, 0 otherwise
sqrt
d s # calculates sqrt(s) and stores the result in d
round
d s # finds the rounded value of s and stores the result in d
trunc
d s # finds the truncated value of s and stores the result in d
ceil
d s # calculates the ceiling of s and stores the result in d
floor
d s # calculates the floor of s and stores the result in d
max
d s t # calculates the maximum of s and t and stores the result in d
min
d s t # calculates the minimum of s and t and stores the result in d
abs
d s # calculates the absolute value of s and stores the result in d
log
d s # calculates the natural logarithm of s and stores the result
  1. in d
exp
d s # calculates the exponential of s and stores the result in d
rand
d # selects a random number uniformly at random between 0 and 1
  1. inclusive and stores the result in d
  1. boolean arithmetic uses the C convention that 0 is false and any non-zero
  2. value is true.
and
d s t # stores 1 in d if both s and t have non-zero values,
  1. 0 otherwise
or
d s t # stores 1 in d if either s or t have non-zero values,
  1. 0 otherwise
xor
d s t # stores 1 in d if exactly one of s and t are non-zero,
  1. 0 otherwise
nor
d s t # stores 1 in d if both s and t equal zero, 0 otherwise
  1. Lines are numbered starting at zero
j
a # jumps to line a.
bltz
s a # jumps to line a if s < 0
blez
s a # jumps to line a if s <= 0
bgez
s a # jumps to line a if s >= 0
bgtz
s a # jumps to line a if s > 0
beq
s t a # jumps to line a if s == t
bne
s t a # jumps to line a if s != t
bdseal
d? a(r?|num) # Jump execution to line a and store current line number if device d? is set.

bdseal d0 32 #Store line number and jump to line 32 if d0 is assigned.
bdseal dThisVictim HarvestCrop #Store line in ra and jump to sub HarvestCrop if device dThisVictim is assigned.

yield
# ceases code execution for this power tick
lb
r? typeHash var batchMode # Loads var from all output network devices with provided typeHash using provided batchMode: Average(0), Sum (1), Minimum (2), Maximum (3). Can be used word or number. Result store into r?
sb
typeHash var r? # Store register r? to var on all output network devices with provided typeHash
#
# The following text will be ignored during compiling; use this to create comments.

Other examples

Conditional functions cheatsheet

suffix description branch to line branch and store return address relative jump to line set register
prefix: b- b-al br- s-
unconditional j jal jr
-eq if a == b beq beqal breq seq
-eqz if a == 0 beqz beqzal breqz seqz
-ge if a >= b bge bgeal brge sge
-gez if a >= 0 bgez bgezal brgez sgez
-gt if a > b bgt bgtal brgt sgt
-gtz if a > 0 bgtz bgtzal brgtz sgtz
-le if a <= b ble bleal brle sle
-lez if a <= 0 blez blezal brlez slez
-lt if a < b blt bltal brlt slt
-ltz if a < 0 bltz bltzal brltz sltz
-ne if a != b bne bneal brne sne
-nez if a != 0 bnez bnezal brnez snez
-dns if device d is not set bdns bdnsal brdns sdns
-dse if device d is set bdse bdseal brdse sdse
-ap if a approximately equals b bap bapal brap sap
-apz if a approximately equals 0 bapz bapzal brapz sapz
-na if a not approximately equals b bna bnaal brna sna
-naz if a not approximately equals 0 bnaz bnazal brnaz snaz

All b- commands require target line as last argument, all s- commands require register to store result as first argument. All br- commands require number to jump relatively as last argument. e.g. breq a b 3 means if a=b then jump to 3 lines after.

All approximate functions require additional argument denoting how close two numbers need to be considered equal. E.g.: sap r0 100 101 0.01 will consider 100 and 101 almost equal (not more than 1%=0.01 different) and will set r0 to 1. The exact formula is if abs(a - b) <= max(c * max(abs(a), abs(b)), float.epsilon * 8) for -ap and is similar for other approximate functions.

Device Variables


Activate
1 if device is activated (usually means running), otherwise 0
l r0 d0 Activate # sets r0 to 1 if on or 0 if off
AirRelease
Charge
The current charge the device has.
CLearMemory
When set to 1, clears the counter memory (e.g. ExportCount). Will set itself back to 0 when triggered.
Color
0 (or lower) = Blue
1 = Grey
2 = Green
3 = Orange
4 = Red
5 = Yellow
6 = White
7 = Black
8 = Brown
9 = Khaki
10 = Pink
11 (or higher) = Purple
CompletionRatio
ElevatorLevel
ElevatorSpeed
Error
1 if device is in error state, otherwise 0
ExportCount
How many items exporfted since last ClearMemory.
Filtration
The current state of the filtration system. For example filtration = 1 for a Hardsuit when filtration is On.
Harvest
Performs the harvesting action for any plant based machinery.
s d0 Harvest 1 # Performs 1 harvest action on device d0
Horizontal
HorizontalRatio
Idle
ImportCount
Lock
Maximum
Mode
On
Open
Output
Plant
Performs the planting operation for any plant based machinery.
s d0 Plant 1 # Plants one crop in device d0
PositionX
PositionY
PositionZ
Power
PowerActual
PowerPotential
PowerRequired
Pressure
PressureExternal
PressureInteral
PressureSetting
Quantity
Total quantity in the device.
Ratio
Context specific value depending on device, 0 to 1 based ratio.
RatioCarbonDioxide
RatioNitrogen
The ratio of nitrogen in device atmosphere.
RatioOxygen
The ratio of oxygen in device atmosphere.
RatioPollutant
The ratio of pollutant in device atmosphere.
RatioVolatiles
The ratio of volatiles in device atmosphere.
RatioWater
The ratio of water in device atmosphere.
Reagents
RecipeHash
RequestHash
RequiredPower
Setting
SolarAngle
Solar angle of the device.
l r0 d0 SolarAngle # Sets r0 to the solar angle of d0.
Temperature
TemperatureSettings
TotalMoles
VelocityMagnitude
VelocityRelativeX
VelocityRelativeY
VelocityRelativeZ
Vertical
Vertical setting of the device.
VerticalRatio
Ratio of vertical setting for device.
Volume
Returns the device atmosphere volume

Slot Variables

In general (always?) slots are assigned as follows.

Slot 0: Import
Slot 1: Export
Slot 2: Inside Machine


Occupied
ls r0 d0 2 Occupied #Stores 1 in r0 if d0 has more seeds
ls vOccupied dThisVictim 2 Occupied #stores 1 in vOccupied if dThisVictim has more seeds
OccupantHash
Quantity
Damage
Efficiency
Health
Growth
ls r0 d0 0 Growth # Store the numerical growth stage of d0 in r0
Pressure
Temperature
Charge
ChargeRatio
Class
PressureWaste
PressureAir
MaxQuantity
Mature
ls r0 d0 0 Mature # Store 1 in r0 if d0 has a mature crop
ls vMature dThisVictim 0 Mature # Store 1 in vMature if dThisVictim has a mature crop

Examples

Previous examples were obsolete due to game changes, or confusing, they have been moved into the Discussions section


Harvie automation

This script uses the batch instruction sb ... to control all Harvies on the network. But only one Harvie and one Tray will be the master and have their values read, the rest of the Harvies will just repeat whatever the master unit does. Some problems with this is that different types of crops mature at different speeds, and if manually planting and giving the master unit the first seed the harvesting action will be performed too early on the other plants.

alias dHarvie d0
alias dTray d1

alias rHarvieHash r8
alias rTrayHash r9
l rHarvieHash dHarvie PrefabHash
l rTrayHash dTray PrefabHash

main:
yield
 #read plant data from the Tray
ls r0 dTray 0 Mature
 #harvestable plants return 1, young plants return 0
 #nothing planted returns -1
beq r0 -1 plantCrop
beq r0 1 harvestCrop
ls r0 dTray 0 Seeding
 #seeds available returns 1, all seeds picked returns 0
 #plants too young or old for seeds returns -1
beq r0 1 harvestCrop
j main

plantCrop:
 #stop the planting if no seeds available
 #otherwise it will plant nothing repeatedly
ls r0 dHarvie 0 Occupied
beq r0 0 ra
sb rHarvieHash Plant 1
j main

harvestCrop:
sb rHarvieHash Harvest 1
j main

### End Script ###



Solar Panel 2-axis tracking

This script was copied from the Solar_Logic_Circuits_Guide (code provided by bti, comments and readability changes by Fudd79)

# This code assumes the following:
# Daylight Sensor data-port points north
# Solar Panel data-port points east

alias sensor d0
alias v_angle r0
alias h_angle r1
alias sun_up r2

define solar_panel_hash -539224550
define heavy_solar_panel_hash -1545574413

start:
# Check to see if sun is up
l sun_up sensor Activate
# Go to reset if it's not
beqz sun_up reset

# Calculate vertical angle
l v_angle sensor Vertical
div v_angle v_angle 1.5
sub v_angle 50 v_angle

# Write vertical angle to all solar panels
sb solar_panel_hash Vertical v_angle
sb heavy_solar_panel_hash Vertical v_angle

# Obtain horizontal angle
l h_angle sensor Horizontal

# Write vertical angle to all solar panels
sb solar_panel_hash Horizontal h_angle
sb heavy_solar_panel_hash Horizontal h_angle

# Go to start again
yield
j start

reset:
# Park solar panels vertically facing sunrise
sb solar_panel_hash Vertical 0
sb heavy_solar_panel_hash Vertical 0
# Park solar panels horizontally facing sunrise
sb solar_panel_hash Horizontal -90
sb heavy_solar_panel_hash Horizontal -90
# Wait 10 seconds
sleep 10
# Go to start again
j start

### End Script ###



Links


  • [1] Stationeering.com offers a programmable circuits simulator so you can develop your code without repeatedly dying in game!
  • [2]
  • [3]
  • [4] syntax highlighting for IC10 MIPS for KDE kwrite/kate text editor
  • [5] syntax highlighting for IC10 MIPS for Notepad++
  • [6] syntax highlighting for IC10 MIPS for Notepad++ (updated: 05/05/2021)



Index


Functions


Device Variables

Slot Variables