Introduction

The SRC and OUT data in a puzzle in The Signal State is defined with simple scripts written in the Lua language. The Lua code does 3 things:

1) It specifies the number of SRC and OUT channels and total number of timesteps
2) It specifies the numerical values for each timestep at each SRC and OUT channel
3) It returns this data to the game as a Lua table

Here is a basic code example from The Signal State’s first story puzzle:


sstate.setSignalSpecs(1,2,50)
for i=0, 49
do
  sstate.setSrc(0,i,i+1)
  sstate.setOut(0,i,i+1)
  sstate.setOut(1,i,i+1)
end
return sstate.signals()
                

sstate.setSignalSpecs(1,2,50) specifies that this puzzle has 1 SRC channel, 2 OUT channels, and a total signal length of 50 timesteps. Your code must specify the number of SRC and OUT channels and the number of timesteps.

Within the for loop, sstate.setSrc(0,i,i+1) specifies that for SRC 1 (index values are zero-indexed within the code), the value at timestep i will be i+1. If there are any values at any timestep not specified by your code, the game will assume it to be 0.

At the end of the for loop, return sstate.signals() returns the data to the game. Your code must contain this line at the end.

sstate is a module included by the game’s Lua interpreter that provides several functions useful for writing your signal data code. These functions are detailed below.

Note that Lua code in the game executes in a sandbox via the Moonsharp interpreter, so you will have limited access to Lua's standard library. Basic libraries like the math library can still be accessed. Refer to https://www.lua.org/manual/5.2/ for more information about the Lua language.

sstate.setSignalSpecs(srcCount, outCount, timesteps)

Specifies the number of SRC and OUT channels and the number of timesteps. There cannot be more than 4 SRC or 4 OUT channels, and there should not be more than 5 total channels. There cannot be more than 150 timesteps.


sstate.setSrcCount(srcCount)

Specifies the number of SRC channels. There cannot be more than 4 SRC channels.


sstate.setOutCount(outCount)

Specifies the number of OUT channels. There cannot be more than 4 OUT channels.


sstate.setSignalLength(length)

Specifies the number of timesteps. There cannot be more than 150 timesteps.


sstate.getSrcCount()

Returns the number of SRC channels. The value must have been specified first.


sstate.getOutCount()

Returns the number of OUT channels. The value must have been specified first.


sstate.getSrc(srcChannel, timestep)

Returns the value from the given SRC channel at the given timestep. The value must have been specified first.


sstate.getOut(srcChannel, timestep)

Returns the value from the given OUT channel at the given timestep. The value must have been specified first.


sstate.getSignalLength()

Returns the number of timesteps. The value must have been specified first.


sstate.signals()

Returns the table that contains the specified signal data. Your code must end with return sstate.signals().


sstate.setSrc(channel, timestep, value)

Sets the value for the specified SRC channel and timestep. The value must be between -100 to 100.


sstate.setOut(channel, timestep, value)

Sets the value for the specified OUT channel and timestep. The value must be between -100 to 100.


sstate.attenuator(input, attValue)

Simulates the behaviour of an Attenuator module and returns its output. The input value should be an integer between -100 to 100. attValue should be a decimal value between -1 to 1. Note that the Attenuator module in-game only allows attenuation values with 1 decimal point.


sstate.vca(input,cv)

Simulates the behaviour of a VCA module and returns its output. The input and CV values should be integers between -100 to 100.


sstate.andGate(in1,in2)

Simulates the behaviour of an AND module and returns its output. The input values should be integers between -100 to 100.


sstate.orGate(in1,in2)

Simulates the behaviour of an OR module and returns its output. The input values should be integers between -100 to 100.


sstate.notGate(in)

Simulates the behaviour of a NOT module and returns its output. The input value should be an integer between -100 to 100.


sstate.xorGate(in1,in2)

Simulates the behaviour of an XOR module and returns its output. The input values should be integers between -100 to 100.


sstate.toBool(input)

Returns true if the input value is more than 0, else returns false.


sstate.sign(input)

Returns -1 if the input value is less than 0, 1 if its more than 0, and 0 if its 0.


Code Examples


VCA Test


sstate.setSignalSpecs(2,1,50)
for i=0, 49
do
  val = math.random(-16,16)*5
  val2 = math.random(0,5)*20
  sstate.setSrc(0,i,val)
  sstate.setSrc(1,i,val2)
  sstate.setOut(0,i,sstate.vca(val,val2))
end
return sstate.signals()
                

Drone Pathfinder


sstate.setSignalSpecs(1,1,50)
val1 = 0
val2 = 0
for i=0, 49
do  
	val3 = math.random(-30,30)
  	sstate.setSrc(0,i,val3)
	if val3 > val2 and val3 > val1 then
		sstate.setOut(0,i,val3)
	elseif val2 > val1 and val2 > val3 then
		sstate.setOut(0,i,val2)
	else
		sstate.setOut(0,i,val1)
	end
	val1 = val2
	val2 = val3
end
return sstate.signals()
                

Sampler


sstate.setSignalSpecs(1,1,50)
ctr = 0
for i=0, 49
do 
	if 7 >= i then
		sstate.setSrc(0,i,math.random(25,80))
	else
		sstate.setSrc(0,i,0)
	end
	sstate.setOut(0,i,sstate.getSrc(0,ctr))
	ctr = ctr + 1
	if ctr >= 8 then
		ctr = 0
	end
end
return sstate.signals()