diff --git a/INSTRUCTION.MD b/INSTRUCTION.MD new file mode 100644 index 0000000..d4430c5 --- /dev/null +++ b/INSTRUCTION.MD @@ -0,0 +1,134 @@ +Это проект микропрограмм для контроллеров которые интерпретируют lua. У этих контроллеров 32 входных и 32 выходных пина. +Каждая программа занимается получением сигналов из inp[] и преедачей в вывод out[]. + +Контроллеры работают в игре barotrauma. Входы и выходы могут быть integer или string. Также есть необычный составной тип это цвет. Задаётся как rgb в строку вида 255,255,255 + +## Вот сниппеты кода с примерами программ: +```lua + +-- SPDX-FileCopyrightText: 2023 Matheus Izvekov +-- SPDX-License-Identifier: ISC + +-- Autoclosing door controller wiring instructions: +-- in1: connect to door state out. +-- in2: connect to motion sensor, detecting doorway obstruction. +-- in3..6: connect to emergency sensors +-- (ex. water and fire detectors on both sides of the door). +-- out1: door set_state input. + +local lastClosedTime + +inp = {} +function upd() + local isClosed = inp[1] ~= 1 + local isDoorwayObstructed = inp[2] ~= 0 + local hasEmergency = false + for i = 3, 6 do hasEmergency = hasEmergency or inp[i] == 1 end + table.clear(inp) + + if hasEmergency then + if isClosed then + lastClosedTime = time() + return + end + if isDoorwayObstructed then return end + if lastClosedTime == nil or time() - lastClosedTime >= 4 then + lastClosedTime = nil + out[1] = 0 + end + elseif lastClosedTime ~= nil then + lastClosedTime = nil + out[1] = 1 + end +end +``` + +```lua +-- The body of the script is executed once per component load / source code change. +-- Use it to setup the component, define functions and do any other expensive one time computations. + +-- Example: Define one state that will persist across frames. +-- These can effectively replace a memory component, but note they are not saved across rounds. +local somestate = 999 + +-- Create a new function. +local function foo(a, b) + return a + 10 ^ b +end + +-- Define how signal inputs will be handled. +-- In the below example, inputs will be simply stored in a table. +inp = {} +-- You can alternatively define 'inp' as a function that +-- takes a pin and a value as inputs. +-- Eg. function inp(pin, val) + +-- Create a function that will be called every frame. +function upd(deltaTime) + -- deltaTime is the time in seconds since the last frame. + -- If you need the absolute time, you can use the `time()` function instead. + + -- Compute a value based on inputs. + local x = inp[1] * foo(inp[2], inp[3]) + + -- Produce an output. + out[1] = inp[3] / x + -- Note that `out` is not a table, you cannot read the outputs back. + + -- Also note that `out` can be set from the `inp` callback, if defined. + -- This for example allows you to mimic the behavior of certain vanilla + -- components which produce outputs outside of frame updates, such as + -- the memory and signalcheck components. + + -- After you are done using the inputs, you can optionally + -- clear them back to nil: + table.clear(inp) + -- That allows you to detect that a pin has not received any signal + -- since the last frame. + -- For example, that can be used to detect a wire has been disconnected. + + -- Otherwise, not clearing them means it will contain the last values received, + -- which is good enough for most cases. +end + +-- ADVANCED FUNCTIONALITY +-- You can check the current game mode. +-- Possible values: 'server', 'client', 'single'. +if mode == 'client' then + -- In a multiplayer game, the server and clients will be each + -- running the scripts independently. + -- Rarely, you will need to keep the clients synchronized to the server. + -- MicroLua leaves how exactly to perform this synchronization up to you. + -- It just provides the means for the server to send a string to the clients. + + -- Define a function that will allow the clients to + -- receive a message from the server: + function recv(msg) + print('message received from server: ', msg) + end + -- A message then can be sent from the server to this callback, by using + -- the `send(msg)` function. + + -- Note: As said previously, synchronization will rarely be needed at all. + -- For example, most devices that initiate a signal, such as buttons + -- and other components that react to character action, are already + -- synchronized themselves. + -- Use synchronization for long lived state in your program, which + -- is likely to not converge in the short term. +end + +if mode == 'server' then + -- Send a message from the server to the clients. + send'hello world' + + -- `send` is only available on 'server' mode. + -- Normally you would perform this sending in the `upd` callback somehow. +end +``` + +## Также можно обрабатывать в событийном режиме, не каждый кадр +```lua +function inp(pin, val) + print("pin:" .. pin .. " value: ".. val) +end +```