Coder Social home page Coder Social logo

stationeers-ic's Introduction

Stationeers IC Simulator

An implementation of the suggested Stationeers IC system. This was developed for a feature on stationeering.com, but is available for use by others if they wish.

Working on stationeers-ic

npm install
npm test

You may need to globally install eslint depending on your npm environment. Pull requests are happily taken, however all submissions must include unit tests for functionality added/altered.

Using stationeers-ic

Adding as Dependency

To use in your project, ensure you have a working node and npm environment:

npm install https://github.com/stationeering/stationeers-ic.git --save

Including and Initialising

// Require IC, legacy.
const IC = require('stationeers-ic');
// Require IC, ES6.
import IC from 'stationeers-ic';

// Create new IC.
let ourIC = new IC();

Loading Program

// Load a program, a string seperated by new line characters. "\n"
ourIC.load(myString);

// Load a program, however more visible in code.
ourIC.load([
  "move r0 99",
  "move r1 90
].join("\n"));

Validating the Program

// Get any program errors, array of objects.
var errors = ourIC.getProgramErrors();

Error object format:

{
  "line": <line number>,
  "error": <error_name>,
  "field": <(optional) field number at fault, 0 indexed after instruction>,
  "type": warning|error
}

Current Error Types:

  • INVALID_FIELD_NO_SUCH_REGISTER - The register number you have specified does not exist.
  • INVALID_FIELD_UNKNOWN_TYPE - The register is invalid, or the alias has not been created.
  • INVALID_FIELD_NOT_READABLE - Instruction requires a source which can be read from, either a register or a literal number.
  • INVALID_FIELD_NOT_REGISTER - Instruction requires the field to be a register
  • INVALID_FIELD_NOT_DEVICE - Instruction requires the field to be a device.
  • MISSING_FIELD - Instruction requires an additional field in this position.
  • UNKNOWN_INSTRUCTION - The instruction you have specified does not exist, check the spelling.
  • LINE_TOO_LONG - The line is more than 64 characters, reduce the length.
  • PROGRAM_TOO_LONG - The program is too long, only 128 instructions/lines are permitted.
  • INVALID_JUMP_TAG_DUPLICATE - A duplicate jump tag has been found.
  • INVALID_JUMP_TAG_CONTENT_AFTER - Content was found after a jump tag, this is currently ignored.

Any error objects of type "error" will prevent the program from running.

Interacting with Internal Registers

// Retrieve a copy of the internal registers, array of floating point numbers.
var registerState = ourIC.getInternalRegisters();

// Get all labels for the internal registers, only populated once label instructions have executed.
var registerLabels = ourIC.getInternalLabels();

// Set register 5 to 9.999.
ourIC.setInternalRegister(5, 9.999);

Interacting with IO Registers

// Get the device names for each register, names aligned to array orders. (d0..d5,db)
var deviceNames = ourIC.getIONames();

// Get current IO/Device registers, array of objects, [{ "field": <value> }]
var deviceRegisters = ourIC.getIORegisters();

// Get any aliases that have been set for device registers, only populated once aliases have been executed.
var deviceLabels = ourIC.getIOLabels();

// Set a device register, set d2.Setting to 1.
ourIC.setIORegister(2, "Setting", 1) {

Running the Program

// Step the IC forward one instruction.
ourIC.step();

// Move the IC forward 128 instructions or until error/yield.
var total = 0;
var lastResult = this.step();

while(!lastResult && total < 128) {
	total++;       
	lastResult = this.step(); 
}

this.step() will return an error if the program can not continue.

  • YIELD - Yield instruction was run, halt until new power tick.
  • INVALID_REGISTER_LOCATION - Attempt to access a register which does not exist.
  • END_OF_PROGRAM - Program counter has gone beyond end of program.
  • INVALID_PROGRAM_COUNTER - Program counter is less that 0.
  • INVALID_PROGRAM - Program is not valid.

Resetting the Program Counter

// Restart program counter to 0.
ourIC.restart();

Ignoring Program Errors

// Ignore any program errors, execute as a no op.
ourIC.setIgnoreErrors(true);

stationeers-ic's People

Contributors

melair avatar eearslya avatar pwood avatar

Stargazers

Victor Azevedo avatar  avatar Werner Luiz Gottschalt avatar  avatar Diana avatar  avatar  avatar Andrea Silvestroni avatar Paudi Moriarty avatar Alexander Haiduk avatar Groda Lotsapot avatar Daan Smit avatar lejban avatar Matt Sylvia avatar David Andersen avatar Sunspots avatar

Watchers

Matthew Gallagher avatar James Cloos avatar  avatar

stationeers-ic's Issues

No warning for duplicate define

I had a program that was failing in-game due to an accidentally copy/pasted define line (for the same name/value), which errored in game but took me a while to notice because the online editor did not warn about this error.

Jump label are number too

The game allow you to use jump label instead of number but the emulator give you an (INVALID_FIELD_INVALID_TYPE) error

Unexpected behaviour from SEL instruction

The implemented behaviour in this script for the SEL instruction is:
IF (A < 1.0) THEN B, ELSE C.

Please consider changing the behaviour to that which most programmers are most familiar
IF (A !== 0) THEN B, ELSE C.

Also, consider changing the opcode from SEL to IF.

I understand that Stationeer's SELECT chip itself functions as a non-standard IF command:
IF (Select !== 0) THEN (Input 2), ELSE (Input 1).
and would be better labelled as an IF chip with behaviour
IF (Condition !== 0) THEN (Input 1), ELSE (Input 2).
I'm unsure if Stationeer's unusual implementation somehow accounts for this script's current SEL behaviour.

Simulator is case insensitive for properties, game is case sensitive

Consider the following program:

start:
alias battery0 d0
alias display d3
l r0 battery0 ratio
s display Setting r0
yield
j start

That will work perfectly fine in the simulator (even if you mark the property as "Ratio" in the d0 section), but in game it will fail stating that it is a bad variable name on line 3, due to the property of a station battery being Ratio and not ratio
A relatively low priority issue that serves as a gotcha for the unwary

Suggestion: "s db Error #" should halt execution

In game, setting the Error field on the base device isn't allowed and causes execution to halt with a line number error. It's a pretty useful way to display error codes (such as in this script)
It would be helpful if the simulator did something similar.

Batch operations unsupported

Batch operations unsupported but documented on-site.

Writing atmospherics control, using six sensors for pressure average, would be handy AF to not need to rewrite several lines of code to switch between game and simulator. Similarly, would be nice to sim for complex systems; batch write for lighting, batch read for batteries average. batch read for min tank pressure from group, etc etc.

Suggested table, Hash, Field, Set, Value, in a similar pattern to d0...d5,db values but with extra Hash parameter. Don't need to have different "groups" for different device hashes, I'm sure entering Hash/Field/Value multiple times would be an acceptable compromise.

Implement new "sleep" instruction.

Implement SLEEP instruction, takes a floating point number, register or define.

Halts the program for that number of seconds, we need to decide how to implement this, as it's somewhat meaningless in the simulator.

We could either:
a) Simulate the number of ticks required until the sleep is finished, requiring the driving program to tick many times.
b) Treat it as a yield.

"sleep":{"description":"pauses execution on the IC for a seconds","example":"<color=yellow>sleep</color> a(<color=#0080FFFF>r?</color>|<color=white>num</color>)"}

indirect referencing does not seems to work

indirect referencing does not seems to work. would be nice as a feature

rr0 -> should point to r3 in case r0 is set to 3
dr0 -> should point to d3 in case r0 is set to 3

See Example 2: Indirect Register Addressing in
https://steamcommunity.com/games/544550/announcements/detail/1700561993824812128?snr=2_groupannouncements_detail_

my code does not detect deviceOn although i did set the d1 to have On 1 in the debugger

define IdleInterval 2
define IdleMaxCycles 12

# labels
alias autolathe d1
alias hydraulics d2
alias electronics d3
alias tools d4

alias led d0 # debug


define Autolathe 1
define Hydraulics 2
define Electronics 3
define Tools 4


#r0 holds the device
alias deviceNumber r0
#references current device
alias device dr0
#reserve r1-4 for idleDeviceTicks (one per printer)
alias idleDeviceTicks rr0


alias deviceOn r5
alias deviceActive r6

begin:

processAutolathe:
# set current device
move deviceNumber Autolathe
# if device does not exit, then skip monitoring it
bdns device skipAutolathe

# begin to monitor device 
jal beginCheckActivity

s led Setting idleDeviceTicks # debug
yield
skipAutolathe:


# setup and monitor the rest of devices
# >>>
# <<<


end:
# wait for the tick to pass and jump into next tick
sleep IdleInterval
j begin



beginCheckActivity:
l deviceOn device On
# if device is off, then exit
beqz deviceOn resetIdleTicks

l deviceActive device Activate
# if device is active (e.g. printer is printing), 
# then exit
beqz deviceActive resetIdleTicks

# since device is on and idling, count the idle tick
add idleDeviceTicks idleDeviceTicks 1

# if idle ticks are not max, then exit
ble idleDeviceTicks IdleMaxCycles endCheckActivity

# idle ticks is at max so turn device off
s device On 0

j endCheckActivity


resetIdleTicks:
move idleDeviceTicks 0

endCheckActivity:
j ra # back to function call and run next line

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.