Train control for kids

This is the place to request new mods or give ideas about what could be done.
Post Reply
thelordodin
Fast Inserter
Fast Inserter
Posts: 148
Joined: Fri Jan 06, 2017 1:54 am
Contact:

Train control for kids

Post by thelordodin »

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?

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Train control for kids

Post by eradicator »

thelordodin wrote:
Sun Sep 19, 2021 9:38 pm
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?
Possible? Yes. Easy? No. I quickly hacked a proof-of-concept together but it's very crude. It'll stop single-direction forward driving manual(Edit: Oops, forgot to check for mode) trains when they get near a red signal. Doesn't work for backward driving or double-headed trains. Doesn't even check if the red signal is actually on the current rail as long as it's near enough (because at a quick glance at the api doc it couldn't spot a function that directly relates signal entities to rail entities). Feel free to dive into a modding adventure to polish it up ;).

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)
thelordodin wrote:
Sun Sep 19, 2021 9:38 pm
That is because he often can't stop the train in time.
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.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Train control for kids

Post by mrvn »

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.

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3699
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Train control for kids

Post by DaveMcW »


User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 488
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: Train control for kids

Post by Silari »

DaveMcW wrote:
Mon Sep 20, 2021 3:28 am
Here you go: https://mods.factorio.com/mod/stop-on-red
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.

SoShootMe
Filter Inserter
Filter Inserter
Posts: 472
Joined: Mon Aug 03, 2020 4:16 pm
Contact:

Re: Train control for kids

Post by SoShootMe »

Silari wrote:
Mon Sep 20, 2021 6:19 am
DaveMcW wrote:
Mon Sep 20, 2021 3:28 am
Here you go: https://mods.factorio.com/mod/stop-on-red
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.
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 ;).

User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 488
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: Train control for kids

Post by Silari »

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.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Train control for kids

Post by eradicator »

DaveMcW wrote:
Mon Sep 20, 2021 3:28 am
Here you go: https://mods.factorio.com/mod/stop-on-red
An interesting read.
DaveMcW wrote:
Mon Sep 20, 2021 3:28 am
get_rail_segment_entity
Aha! No wonder my searching for "signal" didn't find it :).
DaveMcW wrote:
Mon Sep 20, 2021 3:28 am

Code: Select all

if signal.signal_state == defines.signal_state.open then return end
Hm, the doc for signal_state says

Code: Select all

Can only be used if this is RailSignal
If you're sufficiently sure that using it on chain signals is correct would you mind requesting it on the doc thread please?
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.

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2227
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Train control for kids

Post by boskid »

eradicator wrote:
Mon Sep 20, 2021 11:50 am
Hm, the doc for signal_state says

Code: Select all

Can only be used if this is RailSignal
If you're sufficiently sure that using it on chain signals is correct would you mind requesting it on the doc thread please?
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.

mrvn
Smart Inserter
Smart Inserter
Posts: 5682
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Train control for kids

Post by mrvn »

SoShootMe wrote:
Mon Sep 20, 2021 7:58 am
Silari wrote:
Mon Sep 20, 2021 6:19 am
DaveMcW wrote:
Mon Sep 20, 2021 3:28 am
Here you go: https://mods.factorio.com/mod/stop-on-red
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.
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 ;).
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.

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?

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Train control for kids

Post by eradicator »

boskid wrote:
Mon Sep 20, 2021 12:05 pm
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.

SoShootMe
Filter Inserter
Filter Inserter
Posts: 472
Joined: Mon Aug 03, 2020 4:16 pm
Contact:

Re: Train control for kids

Post by SoShootMe »

mrvn wrote:
Mon Sep 20, 2021 2:20 pm
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 ;).
It's true yellow signals will only be ahead of an automatic train but you can approach an automatic train head on.
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 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.
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.

thelordodin
Fast Inserter
Fast Inserter
Posts: 148
Joined: Fri Jan 06, 2017 1:54 am
Contact:

Re: Train control for kids

Post by thelordodin »

DaveMcW wrote:
Mon Sep 20, 2021 3:28 am
Here you go: https://mods.factorio.com/mod/stop-on-red
Thanks so much for the mod! My kid was VERY excited when he see this working!

Post Reply

Return to “Ideas and Requests For Mods”