Hello, I am trying to make an advanced Vehicle management system based on the UK railway signalling system.
This system utilises a 'block' style system which separates the vehicles into their own block. No block should have 2 vehicles in at a time, unless permitted by someone with authority.
The system I have scripted allows for multiple vehicles in a block using 'string.split', as it allows me to remove vehicles from the block, but keep others.
The problem I currently face is that when sending the string for the block to a module script, it returns nil.
The current system makes sure the train is in a block but using string.find. This is currently failing for the reason attempt to concatenate nil with string. This confuses me, as the part it is referencing is sent as a string.
This is the code in the module script.
signal_manager.network = {}
function signal_manager.addblock(block)
signal_manager.network[block] = 'unoccupied'
end
function signal_manager:exitblock(block,train)
wait(2)
local find = string.find(signal_manager.network[block], ' '..train..' ')
if find ~= nil then
workspace.signals.update.Value = not workspace.signals.update.Value
if signal_manager.network[block] == ' '..train..' ' then
signal_manager.network[block] = 'unoccupied'
else
local outcomes = string.split(signal_manager.network[block], ' '..train..' ')
signal_manager.network[block] = outcomes[1]..outcomes[2]
end
end
end
At the start of the server, signals add their required blocks to the table, setting it as 'unoccupied'
function signal_manager.addblock(block)
signal_manager.network[block] = 'unoccupied'
end
When a train leaves a block, it searches in the listed block, and if it finds it, it removes it.
function signal_manager:exitblock(block,train)
wait(2)
local find = string.find(signal_manager.network[block], ' '..train..' ')
if find ~= nil then
workspace.signals.update.Value = not workspace.signals.update.Value
if signal_manager.network[block] == ' '..train..' ' then
signal_manager.network[block] = 'unoccupied'
else
local outcomes = string.split(signal_manager.network[block], ' '..train..' ')
signal_manager.network[block] = outcomes[1]..outcomes[2]
end
end
end
The part that triggers leaving the block is here.
TPWS.Touched:Connect(function(trigger)
if trigger.Name == 'trigger' and trigger.active.Value == true then
if debounce == true then
debounce = false
local unit = trigger.Parent.Parent.Parent
if unit.unitinfo.block.Value ~= '' then
local block = unit.unitinfo.block.Value
signal_manager.exitblock(block,unit.Name)
end
end
end
end
The part unit.unitinfo.block.Value is a string value.
When I add print(block) into the module script, inside the exitblock function, it prints nil.
Could someone please help, this is causing me a lot of confusion.
Thanks.

2 comments
More importantly, the module doesnt actually return the functions.
If a function is expecting 'self', whether because it is defined with a ':' or because its first argument is explicitly 'self', don't call it with "nil", just call it with
:(ie dosignal_manager:exitblock(block, unit.Name)instead ofsignal_manager.exitblock(nil, block, unit.Name). Though passing 'nil' is okay at the moment, if the function ever needed to use 'self', you'd get strange bugs!