Train control for kids
-
- Fast Inserter
- Posts: 153
- Joined: Fri Jan 06, 2017 1:54 am
- Contact:
Train control for kids
Hi there.
My kid likes driveng trains in Factoio.
But he gets very upset when his train crushes another train. That is because he often can't stop the train in time.
I'd like to know if it's possible to make a mod to stop a manually controlled train if the signal isn't green? Could anyone help with that?
My kid likes driveng trains in Factoio.
But he gets very upset when his train crushes another train. That is because he often can't stop the train in time.
I'd like to know if it's possible to make a mod to stop a manually controlled train if the signal isn't green? Could anyone help with that?
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Train control for kids
Possible? Yes. Easy? No. I quickly hacked a proof-of-concept together but it's very crude. It'll stop single-direction forward drivingthelordodin wrote: Sun Sep 19, 2021 9:38 pmI'd like to know if it's possible to make a mod to stop a manually controlled train if the signal isn't green? Could anyone help with that?
Code: Select all
/c
local function is_signal_red(entity) --[[signal or chain signal entity]]
if entity.type == 'rail-signal' then
return entity.signal_state ~= defines.signal_state.open
elseif entity.type == 'rail-chain-signal' then
return entity.chain_signal_state ~= defines.chain_signal_state.all_open
end
end
local function is_any_signal_red(signals)
for _, signal in pairs(signals or {}) do
if is_signal_red(signal) then
return true
end
end
end
--[[This is a very crude implmementation that does not properly check rail-signal relation]]
local function get_rail_signals(entity) --[[rail entity]]
return entity.surface.find_entities_filtered{
type = {'rail-chain-signal', 'rail-signal'},
force = entity.force,
position = entity.position,
radius = 2, --[[extremely imprecise!]]
}
end
local function stop_train_if_red(p)
local train = p.vehicle and p.vehicle.train or nil
if train and train.front_rail then
local front_rail = train.front_rail
if front_rail then
if is_any_signal_red(get_rail_signals(front_rail)) then
train.speed = 0
end
end
end
end
script.on_event(defines.events.on_tick, function(e)
for _, p in pairs(game.connected_players) do
stop_train_if_red(p)
end
end)
I mean technically... would it be sufficient if trains just stopped faster/instant when he wants to break? That's way easier to mod than automatic signal detection. Possibly as easy as editing infinite breaking speed research in editor mode (it is infinite, isn't it?).
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Train control for kids
It's not build in as a flag. You might be able to check the rails below the train, find the next signal, check it's state and then make the train break by scripting it in LUA. But it would be complex. Maybe it would be easier to change manually driven locomotives to an alternate that has an incredible high breaking force. That way it could stop on a dime.
On the other hand it's best not to drive the train by hand. Have you shown your kid how to set temporary train stops? You can select your train and then press ctrl and move the mouse where you want to go. It will highlight the way if its possible to go there and you can simply click to make the train drive there.
On the third hand, yeah, we aliens have 3 arms.
You could design the train system with a separate track for player driven trains and add some circuit wires to signals at any crossing so automatic trains stop when a player driven train is anywhere near.
On the other hand it's best not to drive the train by hand. Have you shown your kid how to set temporary train stops? You can select your train and then press ctrl and move the mouse where you want to go. It will highlight the way if its possible to go there and you can simply click to make the train drive there.
On the third hand, yeah, we aliens have 3 arms.

Re: Train control for kids
You should make it stop on yellow too, or else it'll still cause accidents if it enters a block before the train that has it reserved does. Pretty sure manual trains won't reserve signals, though I might be wrong.
Re: Train control for kids
A reservation is effectively exclusive permission to enter a given block by passing a particular signal. When the reservation is created, that signal turns yellow and the signals that mark other ways to enter the block (if any) turn red.Silari wrote: Mon Sep 20, 2021 6:19 amYou should make it stop on yellow too, or else it'll still cause accidents if it enters a block before the train that has it reserved does. Pretty sure manual trains won't reserve signals, though I might be wrong.
But you are correct, only automatic trains reserve blocks. Due to this and the above, I think the only way to pass a yellow signal in a manual train is to be ahead of an automatic train in the same block. That is not likely to have a good outcome in any case, but stopping is definitely a bad idea

Re: Train control for kids
Huh can't say I ever noticed that - thought all the signals leading into the reserved block were yellow, not just the one coming from the block(s) the train is coming from.
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Train control for kids
An interesting read.
Aha! No wonder my searching for "signal" didn't find it :).
Hm, the doc for signal_state saysDaveMcW wrote: Mon Sep 20, 2021 3:28 amCode: Select all
if signal.signal_state == defines.signal_state.open then return end
Code: Select all
Can only be used if this is RailSignal
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Train control for kids
LuaEntity::signal_state read checks for the RailSignalBase type which is the shared parent of both RailSignal and RailChainSignal. I can see the misunderstanding but there is no type associated with RailSignalBase to provide in the docs. Maybe Therenas will find some good alternative. There is also the chain_signal_state which is only accessible for RailChainSignal only.eradicator wrote: Mon Sep 20, 2021 11:50 am Hm, the doc for signal_state saysIf you're sufficiently sure that using it on chain signals is correct would you mind requesting it on the doc thread please?Code: Select all
Can only be used if this is RailSignal
Re: Train control for kids
What about when using 2-way tracks or when driving the wrong way? It's true yellow signals will only be ahead of an automatic train but you can approach an automatic train head on.SoShootMe wrote: Mon Sep 20, 2021 7:58 amA reservation is effectively exclusive permission to enter a given block by passing a particular signal. When the reservation is created, that signal turns yellow and the signals that mark other ways to enter the block (if any) turn red.Silari wrote: Mon Sep 20, 2021 6:19 amYou should make it stop on yellow too, or else it'll still cause accidents if it enters a block before the train that has it reserved does. Pretty sure manual trains won't reserve signals, though I might be wrong.
But you are correct, only automatic trains reserve blocks. Due to this and the above, I think the only way to pass a yellow signal in a manual train is to be ahead of an automatic train in the same block. That is not likely to have a good outcome in any case, but stopping is definitely a bad idea.
The yellow signals means the automatic train won't be able to stop in time before it crashes into you. So if you drive towards an oncoming train and don't stop for yellow signals then you will collide. This might also be a concern if you drive before an onrushing train. When you start driving and 2 tracks merge you can drive into a yellow block and the automatic train is faster than you. It can then hit you in the back. Especially if you then get stopped at the next signal because it is red.
I'm not sure about the signal state with 2-way tracks but I think when the automatic train reserves a block the entry signal on both sides of the block turn yellow while the exit signal on the remote side remains green. So you have to check for a signal on the opposite side of the track for yellow.
Going the wrong way on a 1-way track I think you have a problem because every time before you pass a signal you have to look ahead and check if the next one is yellow.
Also: Does the stop-on-red mod stop gradually or on a dime? Would be much nicer if it would apply breaks when approaching a red signal but a lot more computationally expensive. You would have to somehow follow the track. But if you can manage that then it would solve the problem of going the wrong way on a 1-way track.
Maybe there is a better hack to implement this. Maybe the script could project the path of the train forward and set a temporary stop? Then the game mechanic would reserve blocks and handle signals itself. Can lua check the keyboard state so it knows if the user steers left/right, accelerates or breaks?
- eradicator
- Smart Inserter
- Posts: 5211
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: Train control for kids
Thanks for the clarification (and Dave for posting the correction request). Being somewhat unexperienced with train related stuff I simply wasn't sure - given the doc - if the observed behavior is intentional and supported or mere coincidence.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: Train control for kids
Well, technically, signals on the left of the track mean nothing. I'm not sure stopping or not would make any practical difference when approaching head on anyway. "Going the wrong way on a 1-way track" is definitely a problem, as you mentioned.mrvn wrote: Mon Sep 20, 2021 2:20 pmIt's true yellow signals will only be ahead of an automatic train but you can approach an automatic train head on.SoShootMe wrote: Mon Sep 20, 2021 7:58 am A reservation is effectively exclusive permission to enter a given block by passing a particular signal. When the reservation is created, that signal turns yellow and the signals that mark other ways to enter the block (if any) turn red.
But you are correct, only automatic trains reserve blocks. Due to this and the above, I think the only way to pass a yellow signal in a manual train is to be ahead of an automatic train in the same block. That is not likely to have a good outcome in any case, but stopping is definitely a bad idea.
The behaviour I described before applies in both these cases. With the block containing the merge reserved by the automatic train, you would pass a red signal on entry to it. On a 2-way track, the other entry signal turns red.mrvn wrote: Mon Sep 20, 2021 2:20 pm When you start driving and 2 tracks merge you can drive into a yellow block and the automatic train is faster than you. It can then hit you in the back.
...
I'm not sure about the signal state with 2-way tracks but I think when the automatic train reserves a block the entry signal on both sides of the block turn yellow while the exit signal on the remote side remains green.
-
- Fast Inserter
- Posts: 153
- Joined: Fri Jan 06, 2017 1:54 am
- Contact:
Re: Train control for kids
Thanks so much for the mod! My kid was VERY excited when he see this working!