Barotrauma

Barotrauma

Not enough ratings
MicroLua
   
Award
Favorite
Favorited
Unfavorite
File Size
Posted
Updated
21.107 KB
10 Aug, 2023 @ 11:53am
3 Dec, 2023 @ 1:36pm
4 Change Notes ( view )

Subscribe to download
MicroLua

Description
MicroLua - Scriptable Electrical Signal Component

This is a new electrical signal component that can perform any computation and store any amount of state.

This means one MicroLua component can be used to replace many vanilla components, making complex controllers much easier to write and maintain.

The accepted source script language is MoonSharp flavored Lua 5.2.

This document will assume some familiarity with this programming language.

Some resources to help get up to speed:

https://the-ravi-programming-language.readthedocs.io/en/latest/lua-introduction.html
https://www.lua.org/manual/5.2/manual.html
https://www.moonsharp.org/moonluadifferences.html
https://www.moonsharp.org/additions.html

Dependencies

This mod depends on both `Cs for barotrauma` and `Lua for Barotrauma` mods.

Make sure both the server and all clients are running it.
`Lua for Barotrauma` requires special actions for this. See it's documentation.

Example autodoor controller


-- SPDX-FileCopyrightText: 2023 Matheus Izvekov <mizvekov@gmail.com>
-- 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

Scripting walkthrough

Just paste the lua code in the source field of the placed MicroLua component.

It can be pasted verbatim, or it can be base64 encoded. See the MoonSharp documentation for the format.
Note: When pasting verbatim code with multiple lines, the game textbox UI will look bugged, but this otherwise works fine.

Any errors, and also output from any `print` calls, will be available in the game console (press `F3` to open it).

Syntax errors, and also any runtime errors in the script body, will be available immediately as the script is loaded into the source textbox.


-- 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

Also see https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?edit=true&id=3347044949 for a submarine which showcases this component.
59 Comments
whosyourdaddy 24 Apr @ 7:59am 
Hi, I've made some performance optimizations to your Micro Lua (primarily focusing on caching techniques and stack access), and also added a few other features.

RuyiLuaComponent
Matheus  [author] 28 Nov, 2024 @ 4:24pm 
Of course, it is my intention to not break existing setups with any updates, going forward.
1465114862 28 Nov, 2024 @ 11:38am 
Just a suggestion.
For compatibility, please keep the 32 nodes version existing.
So that I don't need to refactor my code. :steamsad:
Matheus  [author] 27 Nov, 2024 @ 2:50pm 
Nick I agree the mod isnt well balanced. Though Id rather fix this mod, than create an alternate one.

I will take this into consideration to the next update. I think it needs to be way harder to craft than a circuit box.
Nick Molliger 26 Nov, 2024 @ 1:48pm 
How about second (alternative) mod with a some of these balancing features?
1. Input and output nodes are limited to 8/16
2. Can't be used in Circuit Boxes
3. A bit harder to craft. May be the same recipie as vanilla Circuit Box
4. Crafting depends on one of the top engineer's perks
5. Rare and expensive to buy in outposts

I mean, with this thing everyone can handle whole submarine's automatization (even by copying code from internet), save many copper and tin and collect great bunch of FPGAs by disassembling old components. This ability should be deserved by making decisions and having a real engineer game experience
Nick Molliger 26 Nov, 2024 @ 1:48pm 
This mod is a game-changer! You're damn genious! 🔥👏
Matheus  [author] 11 Oct, 2024 @ 2:39pm 
FYI I have published a submarine which showcases MicroLua: https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?edit=true&id=3347044949
Matheus  [author] 9 Oct, 2024 @ 11:37pm 
I meant to give an example of table indexing: foo\[i\]
Matheus  [author] 9 Oct, 2024 @ 11:36pm 
The error about indexing method not implemented is important.
It means somewhere in the code, we are applying table indexing, for example foo , to an object which does not support it.

The console error should say which line and column have a problem.
Can you double check and paste here?
dhdoctor 9 Oct, 2024 @ 5:04pm 
polarity is correct going into the componet 1 for presence 0 for none. input 1 is door state out 2 is motion sensor 3-6 room state inputs out 1 door set state. tried it with both polarities and rewiring a new door. console is saying index method is not implemented. no output at all