Signal Scripts Causes Crashes After Recent Updates

Discussion in 'Technical Reports' started by Hgv, Jun 22, 2024.

  1. Hgv

    Hgv New Member

    Joined:
    Sep 6, 2020
    Messages:
    11
    Likes Received:
    2
    For many years I have been working on several Swedish routes including Jönköpingsbanan (which despite its name includes Stockholm, including the central station and its surroundings - download link and Swedish forum thread), and refurbishing of the Kiruna-Narvik route by newS (download link and forum thread).

    Unfortuantely, since around a year, the Jönköpingsbanan route freezes the sim when the route is loading. I found out that disabling certain signal scripts will allow the route to load. Even then, the route frequently crashes when certain signal links are crossed by trains (mostly linked to level crossings).

    I have all but given up on being able to continue building on and enjoy my routes, as I don't see removing possibly hundreds of signal objects/links as an option. It would be a shame as it essentially throws away 10+ years of work.

    I would appreciate any help in finding out what the root cause is and if anything can be done. I can think of a few possible ways forward:
    1. Finding out what has changed in the handling of signal scripts since the last few sim updates. With this information it might be possible to find the "offending" scripts/signals and adjust them.
    2. Reverting to an older version of TS. Is this possible?
    3. Doing a complete overhaul of the Swedish signal scripts to ensure that they don't crash the sim. They are LUA scripts that have been around, although modified many times, since the first version or Railsimulator around 2008. I have done several modifications myself, through trial and error, to be able to change signal functionality, add links to support more tracks etc.
    Below I have included an example of an "offending" script. Ths script is for a stop light used at the end of sidings, but also as a kind of stop repeater signal displaying a stop aspect if the next main signal is at danger; otherwise the stop light is extinguished (pictures). With this script enabled, the route crashes on loading. If I disable this script (by moving or changing the name of the LUA file), the route loads (but crashes when trains cross certain links at level crossings). I'm not sure of course if the problem is with the script itself, or rather how it interacts with other signals. In any case, ideally no script should crash the sim even if signals are placed in a "forbidden" way, so any help as to how these scripts can be improved would be much appreciated.

    Code:
    --------------------------------------------------------------------------------------
    -- KMW / Anders Eriksson
    -- 090108 First version
    -- 201006 Uppdaterad funktion för skyddsstopplykta
    --------------------------------------------------------------------------------------
    
    --include=SE CommonScript.lua
    --include=Signal CommonScript.lua
    
    --------------------------------------------------------------------------------------
    -- INITIALISE
    -- Signal specific initialise function
    function Initialise()
        -- Set our light node names
        LIGHT_NODE_RED            = "R1"
        BaseInitialise()
    end
    
    --------------------------------------------------------------------------------------
    -- ANIMATE
    -- Any animation that needs doing
    function Animate()
        -- use standard Animation
        DefaultAnimate()
    end
    
    --------------------------------------------------------------------------------------
    -- SET LIGHTS
    -- Set lights according to new signal state
    function SetLights()
        -- use standard SetLights
        DefaultSetLights()
    end
    
    -------------------------------------------------------------------------------------
    -- Swedish CommonScript to switch lights on/off
    -- KMW / Anders Eriksson
    -- 090108 First version.
    --------------------------------------------------------------------------------------
    --include=Signal CommonScript.lua
    
    --------------------------------------------------------------------------------------
    -- Animate Swedish distance signals
    -- switch on/off the appropriate lights
    function DefaultAnimate()
        if gHomeSignal and (gSignalState ~= STATE_GO) then
            return
        end
        if (gExpectState == STATE_GO) then
            SwitchLight( LIGHT_NODE_GREEN2, 0 )
            SwitchLight( LIGHT_NODE_WHITE, gLightFlashOn )
            SwitchLight( LIGHT_NODE_GREEN3, 0 )
        elseif (gExpectState == STATE_SLOW) then
            SwitchLight( LIGHT_NODE_GREEN2, gLightFlashOn )
            SwitchLight( LIGHT_NODE_WHITE, 0 )
            SwitchLight( LIGHT_NODE_GREEN3, gLightFlashOn )
        else    -- stop or blocked
            SwitchLight( LIGHT_NODE_GREEN2, gLightFlashOn )
            SwitchLight( LIGHT_NODE_WHITE, 0 )
            SwitchLight( LIGHT_NODE_GREEN3, 0 )
        end
    end
    
    --------------------------------------------------------------------------------------
    -- Swedish home signals SetLights
    -- Switch the appropriate lights on and off based on our new state
    function DefaultSetLights()
    --    DebugPrint("DefaultSetLights()")
        if (gSignalState == STATE_GO) then
            SwitchLight( LIGHT_NODE_RED,            0 )
        elseif (gSignalState == STATE_SLOW) then
            SwitchLight( LIGHT_NODE_RED,            0 )
        else    -- stop or blocked
            SwitchLight( LIGHT_NODE_RED,            1 )
        end
    end
    
    
    --------------------------------------------------------------------------------------
    -- Required signal functions
    --------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------
    -- ON CONSIST PASS
    -- Called when a train passes one of the signal's links
    function OnConsistPass ( prevFrontDist, prevBackDist, frontDist, backDist, linkIndex )
        BaseOnConsistPass ( prevFrontDist, prevBackDist, frontDist, backDist, linkIndex )
    end
    
    --------------------------------------------------------------------------------------
    -- ON SIGNAL MESSAGE
    -- Handles messages from other signals
    function OnSignalMessage( message, parameter, direction, linkIndex )
        BaseOnSignalMessage( message, parameter, direction, linkIndex )
    end
    
    --------------------------------------------------------------------------------------
    -- UPDATE
    -- Handles moving things and flashing ligths
    function Update( time )
        BaseUpdate( time )
    end
    
    --------------------------------------------------------------------------------------
    -- Signal CommonScript
    -- KMW / Anders Eriksson
    -- Based on KUJU / Rail Simulator Signal Scripts
    -- 090108 First version.
    -- 091220 Corrected distance signal and handling of crossings.
    --------------------------------------------------------------------------------------
    
    --------------------------------------------------------------------------------------
    -- GLOBALS
    -- States
    STATE_GO                                            = 0
    STATE_SLOW                                        = 1
    STATE_STOP                                        = 2
    STATE_BLOCKED                                    = 3
    STATE2GO                                            = 4
    STATE2STOP                                        = 5
    STATE_UNDEFINED                                = 8
    STATE_RESET                                        = 9
    
    -- How long to stay off/on in each flash cycle
    LIGHT_FLASH_SECS    = 0.75        -- 40 flashs/min
    QUICK_FLASH_SECS    = 0.375        -- 80 flashs/min
    
    -- Signal Messages (0-9 are reserved by code)
    RESET_SIGNAL_STATE                            = 0
    INITIALISE_SIGNAL_TO_BLOCKED                 = 1
    JUNCTION_STATE_CHANGE                        = 2
    INITIALISE_TO_PREPARED                        = 3
    
    -- Locally defined signal mesages
    SIGNAL_GO                                        = 10
    SIGNAL_SLOW                                        = 11
    SIGNAL_STOP                                        = 12
    SIGNAL_BLOCKED                                    = 13
    OCCUPATION_INCREMENT                            = 14
    OCCUPATION_DECREMENT                            = 15
    DISTANCE_INCREMENT                            = 16
    DISTANCE_DECREMENT                            = 17
    LAST_SIGNAL_MESSAGE                            = 17
    
    -- Crossings
    CROSSING_GO                                        = 20
    CROSSING_INCREMENT                            = 21
    CROSSING_STOP                                    = 22
    CROSSING_DECREMENT                            = 23
    CROSSING2GO                                        = 24
    CROSSING2STOP                                    = 25
    CROSSING_GATE                                    = 26
    LAST_CROSSING_MESSAGE                        = 26
    
    -- What you need to add to a signal message number to turn it into the equivalent PASS message
    PASS_OFFSET                                        = 50
    
    -- Pass on messages to handle overlapping links (eg for converging junctions / crossovers)
    -- Populated by BaseInitialise()
    PASS = { }
    
    -- SPAD and warning system messages to pass to consist
    AWS_MESSAGE                                        = 11
    TPWS_MESSAGE                                    = 12
    SPAD_MESSAGE                                     = 14
    
    -- Initialise global variables
    gGoingForward    = true
    gInitialised    = false                    -- has the route finished loading yet?
    gSignalState    = STATE_RESET            -- state of this block/signal
    gExpectState    = STATE_RESET            -- state of next block/signal
    gHomeSignal     = true
    gDistanceSignal = false
    gBlockSignal    = false                     -- is this an intermediate block signal?
    gConnectedLink    = 0                        -- which link is connected?
    
    -- State of flashing light
    gLightFlashOn            = 0
    gTimeSinceLastFlash    = 0
    
    -- debugging stuff
    --math.randomseed(os.time())
    gDebugId            = math.random(1, 100)
    function DebugPrint( message )
        if gDebugId ~= nil then
            Print( "[" .. gDebugId .. "] " .. message )
        end
    end
    
    --------------------------------------------------------------------------------------
    -- BASE INITIALISE
    -- initialise function used by all signal scripts
    function BaseInitialise()
        DebugPrint("BaseInitialise()")
        gInitialised = false
        -- Initialise PASS constants
        for i = 0, PASS_OFFSET do
            PASS[i] = i + PASS_OFFSET
        end
    
        -- Initialise global variables
        gLinkCount = Call( "GetLinkCount" )        -- number of links this signal has
        gLinkState = {}                                -- state of line beyond this link
        gYardEntry = {}                                -- is this link going inside a yard?
        gDissabled = {}                                -- is this link dissabled?
        gOccupationTable = {}                        -- how many trains are in this part of our block?
        for link = 0, gLinkCount - 1 do
            gLinkState[link] = STATE_GO
            gYardEntry[link] = (link > 6)            -- links without numbers (>6) are yard entry
            gDissabled[link] = false
            gOccupationTable[link] = 0
        end
        Call("BeginUpdate")
    end
    
    --------------------------------------------------------------------------------------
    -- ON CONSIST PASS
    -- Called when a train passes one of the signal's links
    function BaseOnConsistPass ( prevFrontDist, prevBackDist, frontDist, backDist, linkIndex )
        -- in which direction is the consist going?
        gGoingForward = (prevFrontDist > frontDist)
        -- only handle consist pass on active home signal links
        if linkIndex >= 0 and not gDissabled[linkIndex] then
            if (frontDist > 0 and backDist < 0) or (frontDist < 0 and backDist > 0) then
                if (prevFrontDist < 0 and prevBackDist < 0) or (prevFrontDist > 0 and prevBackDist > 0) then
                    DebugPrint("OnConsistPass: Crossing started... linkIndex = " .. linkIndex .. ", gConnectedLink = " .. gConnectedLink)
                    if gGoingForward then
                        if not gYardEntry[linkIndex] then
                            gOccupationTable[linkIndex] = gOccupationTable[linkIndex] + 1
                            DebugPrint("OnConsistPass: Forward INCREMENT... gOccupationTable[linkIndex]: " .. gOccupationTable[linkIndex])
                        end
                    elseif linkIndex == 0 then
                        DebugPrint("OnConsistPass: A train starts passing link 0 in the opposite direction. Send OCCUPATION_INCREMENT.")
                        if gHomeSignal then
                            Call( "SendSignalMessage", OCCUPATION_INCREMENT, "", -1, 1, 0 )
                        end
                        Call( "SendSignalMessage", DISTANCE_INCREMENT, "DoNotForward", -1, 1, 0 )
                    elseif (gConnectedLink == linkIndex) then
                        gOccupationTable[0] = gOccupationTable[0] + 1
                        DebugPrint("OnConsistPass: Backward INCREMENT... gOccupationTable[0]: " .. gOccupationTable[0])
                    end
                    SetSignalState()
                end
            else
                if (prevFrontDist < 0 and prevBackDist > 0) or (prevFrontDist > 0 and prevBackDist < 0) then
                    DebugPrint("OnConsistPass: Crossing cleared... linkIndex = " .. linkIndex .. ", gConnectedLink = " .. gConnectedLink)
                    if not gGoingForward then
                        if not gYardEntry[linkIndex] and gOccupationTable[linkIndex] > 0 then
                            gOccupationTable[linkIndex] = gOccupationTable[linkIndex] - 1
                            DebugPrint("OnConsistPass: Backward DECREMENT... gOccupationTable[" .. linkIndex .. "]: " .. gOccupationTable[linkIndex])
                        end
                    elseif linkIndex == 0 then
                        DebugPrint("OnConsistPass: A train finishes passing link 0 in the normal direction, send OCCUPATION_DECREMENT.")
                        if gHomeSignal then
                            Call( "SendSignalMessage", OCCUPATION_DECREMENT, "", -1, 1, 0 )
                        end
                        Call( "SendSignalMessage", DISTANCE_DECREMENT, "DoNotForward", -1, 1, 0 )
                    elseif (gConnectedLink == linkIndex) and (gOccupationTable[0] > 0) then
                        gOccupationTable[0] = gOccupationTable[0] - 1
                        DebugPrint("OnConsistPass: Forward DECREMENT... gOccupationTable[0]: " .. gOccupationTable[0])
                    end
                    SetSignalState()           
                end
            end
        end
    end
    
    --------------------------------------------------------------------------------------
    -- ON SIGNAL MESSAGE
    -- Handles messages from other signals
    function BaseOnSignalMessage( message, parameter, direction, linkIndex )
        DebugPrint("OnSignalMessage(" .. message .. ", " .. parameter .. ", " .. direction .. ", " .. linkIndex .. ")")
        -- This message is to reset the signals after a scenario / route is reset
        if (message == RESET_SIGNAL_STATE) then
            Initialise()
            return
        elseif not gInitialised then
            InitialiseSignal()
        end
    
        -- forward crossing messages
        if (message >= CROSSING_GO and LAST_CROSSING_MESSAGE >= message) or
            (message >= CROSSING_GO+PASS_OFFSET and LAST_CROSSING_MESSAGE+PASS_OFFSET >= message) then
            Call( "SendSignalMessage", message, parameter, -direction, 1, linkIndex )
            return
        end
        
        -- Check for signal receiving a message it might need to forward,
        -- in case there are two overlapping signal blocks (eg for a converging junction or crossover)
        -- ignore messages that have the "DoNotForward" parameter
        if (parameter ~= "DoNotForward") then
            if gDissabled[linkIndex] or not gHomeSignal then    -- just forward it on
                Call( "SendSignalMessage", message, parameter, -direction, 1, linkIndex )
            elseif (linkIndex > 0) then
                -- We've received a PASS message, so forward it on
                if (message > PASS_OFFSET) then
                    Call( "SendSignalMessage", message, parameter, -direction, 1, linkIndex )
                    message = message - PASS_OFFSET
                -- Any message other than JUNCTION_STATE_CHANGE should be forwarded as PASS messages
                elseif message ~= JUNCTION_STATE_CHANGE then
                    Call( "SendSignalMessage", message + PASS_OFFSET, parameter, -direction, 1, linkIndex )
                end
            end
        end
    
        -- messages arriving on a yard entry or dissabled link should be ignored
        if (gYardEntry[linkIndex] or gDissabled[linkIndex]) and (message < CROSSING_GO) then
            return    -- Do nothing
        end
    
        -- BLOCK STATES
        if (message >= SIGNAL_GO) and (message <= SIGNAL_BLOCKED) then
            DebugPrint("Message: SIGNAL_STATE_CHANGE received ... gLinkState[" .. linkIndex .. "]:" .. message)
            if gBlockSignal and message == SIGNAL_STOP and parameter == "BLOCKED" then
                -- train coming our direction in an entry signal, block occupied
                gLinkState[0] = STATE_BLOCKED
            else
                gLinkState[linkIndex] = message - SIGNAL_GO
            end
            if (gConnectedLink >= 0) then
                gExpectState = gLinkState[gConnectedLink]
            else
                gExpectState = STATE_UNDEFINED
            end
            DebugPrint("Link " .. linkIndex .. " is now " .. gLinkState[linkIndex] .. ", expected state is " .. gExpectState)
            if gHomeSignal then
                SetSignalState()
            end
    
        -- INITIALISATION MESSAGES
        -- There's a train on the line ahead of us when the route first loads
        elseif (message == INITIALISE_SIGNAL_TO_BLOCKED) then
            gOccupationTable[linkIndex] = gOccupationTable[linkIndex] + 1
            DebugPrint("Message: INITIALISE_SIGNAL_TO_BLOCKED received... gOccupationTable[" .. linkIndex .. "]: " .. gOccupationTable[linkIndex])
            -- Only need to do this for block signals - anything spanning a junction will initialise later when junctions are set
            if (gBlockSignal and gOccupationTable[linkIndex] == 1) then
                SetSignalState()
            end
    
        elseif message == JUNCTION_STATE_CHANGE and gLinkCount > 1 then
            -- Only act on message if it arrived at link 0, junction_state parameter is "0",
            -- and this signal spans a junction (ie, not a block signal)
            if linkIndex == 0 and parameter == "0" then
                gConnectedLink = Call( "GetConnectedLink", "10", 1, 0 )
                if gConnectedLink >= 0 then
                    gExpectState = gLinkState[gConnectedLink]
                    DebugPrint("Expected state: " .. gExpectState)
                else
                    gExpectState = STATE_UNDEFINED
                    DebugPrint("Expected state: undefined")
                end
                DebugPrint("Message: JUNCTION_STATE_CHANGE received ... activate link: " .. gConnectedLink)
                SetSignalState()
                -- Pass on message in case junction is protected by more than one signal
                -- NB: this message is passed on when received on link 0 instead of link 1+
                -- When it reaches a link > 0 or a signal with only one link, it will be consumed
                Call( "SendSignalMessage", message, parameter, -direction, 1, linkIndex )
            end
        
            -- OCCUPANCY
        elseif (message == OCCUPATION_DECREMENT and gHomeSignal or
                  message == DISTANCE_DECREMENT and not gHomeSignal) then
            -- update the occupation table for this signal given the information that a train has just left this block and entered the next block
            if gOccupationTable[linkIndex] > 0 then
                gOccupationTable[linkIndex] = gOccupationTable[linkIndex] - 1
            end
            gGoingForward = true
            gLinkState[linkIndex] = STATE_STOP    -- train going opposite direction, block no longer occupied
            DebugPrint("Message: OCCUPATION_DECREMENT received... gOccupationTable[" .. linkIndex .. "]: " .. gOccupationTable[linkIndex])
            -- If this is the connected link and last train leaving
            if linkIndex == gConnectedLink and gOccupationTable[linkIndex] == 0 then
                SetSignalState()
            end
            
        elseif (message == OCCUPATION_INCREMENT and gHomeSignal or
                  message == DISTANCE_INCREMENT and not gHomeSignal) then
            -- update the occupation table for this signal given the information that a train has just entered this block
            gOccupationTable[linkIndex] = gOccupationTable[linkIndex] + 1
            gGoingForward = false
            DebugPrint("Message: OCCUPATION_INCREMENT received... gOccupationTable[" .. linkIndex .. "]: " .. gOccupationTable[linkIndex])
            -- If this is the connected link and first train entered the block, check the signal state
            if linkIndex == gConnectedLink and gOccupationTable[linkIndex] == 1 then
                SetSignalState()
            end
        end
    end
    
    --------------------------------------------------------------------------------------
    -- UPDATE
    -- Handles moving things and flashing ligths
    function BaseUpdate( time )
        --DebugPrint("Update(" .. time .. ")")
        if not gInitialised then
            InitialiseSignal()
        else
            gTimeSinceLastFlash = gTimeSinceLastFlash + time
            if gTimeSinceLastFlash >= LIGHT_FLASH_SECS then
                Animate()
                gLightFlashOn = 1 - gLightFlashOn
                gTimeSinceLastFlash = 0
            end
        end
    end
    
    --------------------------------------------------------------------------------------
    -- INITIALISE SIGNAL
    -- Called after route is set up and all links and junctions are known
    function InitialiseSignal()
        DebugPrint("InitialiseSignal()")
        -- Remember that we've been initialised
        gInitialised = true
    
        -- check for dissabled links (links placed before link 0)
        for link = gLinkCount - 1, 1, -1 do
            local connectedLink = Call( "GetConnectedLink", "10", 1, link )
            DebugPrint("Link " .. link .. " connected to " .. connectedLink)
            if (connectedLink ~= -1) then
                gDissabled[link] = true
                gYardEntry[link] = true
                gLinkCount = gLinkCount - 1
            end
        end
        if (gLinkCount == 1) then
            gBlockSignal = gHomeSignal
            gConnectedLink = 0
        else
            gConnectedLink = Call( "GetConnectedLink", "10", 1, 0 )
        end
        
        SetSignalState()
        if gBlockSignal then
            DebugPrint("BlockSignal[" .. gLinkCount .. "]")
        elseif gHomeSignal then
            DebugPrint("HomeSignal[" .. gLinkCount .. "]")
        end
        if gDistanceSignal then
            DebugPrint("DistanceSignal[" .. gLinkCount .. "]")
        else
            Call("EndUpdate")
        end
    end
    
    --------------------------------------------------------------------------------------
    -- SET SIGNAL STATE
    -- Figures out what state to show and messages to send
    function SetSignalState()
        local newSignalState = STATE_GO
        if gBlockSignal then
            if gOccupationTable[0] > 0 and gGoingForward then
                newSignalState = STATE_STOP
            elseif gOccupationTable[0] > 0 or gLinkState[0] == STATE_BLOCKED then
                newSignalState = STATE_BLOCKED
            elseif gExpectState == STATE_STOP then
                newSignalState = STATE_STOP
            end
        elseif gOccupationTable[0] > 0 and not gGoingForward then
            -- might be an entry signal with a consist going backwards into a block
            newSignalState = STATE_BLOCKED
        elseif gConnectedLink == -1 or gOccupationTable[0] > 0 or gOccupationTable[gConnectedLink] > 0 then
            -- no route or occupied
            newSignalState = STATE_STOP
        elseif gConnectedLink > 0 and gLinkState[gConnectedLink] == STATE_BLOCKED then
            -- exit signal facing an occupied block
            newSignalState = STATE_STOP
        elseif gExpectState == STATE_STOP then
            newSignalState = STATE_STOP
        elseif gConnectedLink > 1 then
            -- diverging route, signal slow
            newSignalState = STATE_SLOW
        end
    
        if newSignalState ~= gSignalState then
            DebugPrint("SetSignalState() - signal state changed from " .. gSignalState .. " to " .. newSignalState .. " - sending message" )
            gSignalState = newSignalState
            SetLights()
            if gHomeSignal then
                if gSignalState >= STATE_STOP then
                    Call( "Set2DMapSignalState", STATE_STOP)
                else
                    Call( "Set2DMapSignalState", gSignalState)
                end
                if gSignalState == STATE_BLOCKED and not gBlockSignal then
                    Call( "SendSignalMessage", SIGNAL_STOP, "BLOCKED", -1, 1, 0 )
                else
                    Call( "SendSignalMessage", SIGNAL_GO + gSignalState, "", -1, 1, 0 )
                end
            end
        end
    end
    
    --------------------------------------------------------------------------------------
    -- SWITCH LIGHT
    -- Turns the selected light node on (1) / off (0)
    -- if the light node exists for this signal
    function SwitchLight( lightNode, state )
        if lightNode ~= nil then
            Call ( "ActivateNode", lightNode, state )
        end
    end
    
     
  2. 749006

    749006 Well-Known Member

    Joined:
    Dec 10, 2016
    Messages:
    10,169
    Likes Received:
    3,169
    • Helpful Helpful x 1
  3. Hgv

    Hgv New Member

    Joined:
    Sep 6, 2020
    Messages:
    11
    Likes Received:
    2
    Thanks! That worked! (In 32 bit. 64 bit still crashes.)

    This confirms that the core update caused the signal scripts and/or link placement to cause the crashes. I'm wondering if it's possible to narrow down what the issue is with the signals? Any LUA experts out there?
     
  4. steve.cunningham1980

    steve.cunningham1980 Active Member

    Joined:
    Jun 19, 2020
    Messages:
    339
    Likes Received:
    232
    No idea if this has anything whatsoever to do with it, but I did notice a typo here:

    Should be lights, but I don't know if that would cause a script to fail by itself.
     
  5. triznya.andras

    triznya.andras Well-Known Member

    Joined:
    Jun 29, 2019
    Messages:
    2,353
    Likes Received:
    2,837
    Some of the include statements are now comments, which suggests it was built on top of an existing signal implementation / extension, but now it either uses some basic implementation or none at all.

    For example it's using constants like LIGHT_NODE_GREEN2 (passed into SwitchNode) but they aren't defined here.

    (Steve, typos in comments really shouldn't break anything. The only queer system I know processing comments is JavaScript for compatibility with a previous millennium and then habits and conventions.)

    Some of the methods (starting with Base) are stitched into this script, not ideal, I assume it has something to do with removing the inheritance. So the above constants might be TSC LUA globals as well.
     
    Last edited: Jun 22, 2024
    • Like Like x 1
  6. Hgv

    Hgv New Member

    Joined:
    Sep 6, 2020
    Messages:
    11
    Likes Received:
    2
    Thanks everyone. My LUA skills are rudimentary at best. The same basic script is used for all Swedish signals, with some modifications depending on the type of signal. I guess that's why there are reference to light nodes that doesn't exist in this particular signal. Could that be a cause for crashes?

    Am I right in that the script doesn't contain any obvious issues that would let it run before the core update but consistently crashes on route loading post core update? It would be interesting if DTG could provide information on what's actually changed under the hood with the latest updates (maybe this exists?).
     
    Last edited: Jun 23, 2024
  7. Spikee1975

    Spikee1975 Guest

    The problem is that apparently changes were made "in-place" instead of creating new assets. That means there is different versions of KMW and newS signals with exact same path and filename around, which makes things extremely complicated.

    It would have been a good thing to clone the assets into your own Provider folder and do changes in there - this way, they would not affect other routes relying on the original signals. (Same happened to signals from Yelland - some freeware developer issued modified versions that broke some routes).
     
    Last edited by a moderator: Jun 27, 2024
  8. Hgv

    Hgv New Member

    Joined:
    Sep 6, 2020
    Messages:
    11
    Likes Received:
    2
    I'm not sure that there are different versions with the exact same name. Sure, the signal scripts have been modified over the years but it hasn't changed the compatibility with signals already placed in routes, as far as I'm aware. The modifications to signal scripts have been mainly adding signal links to be able to use the same signal for more tracks, and we haven't noticed any issues with this over the years. Where there has been a need for a new signal with different behaviour, a new asset (with its own unique name, just referencing the same 3D object blueprints) has been created.

    I don't think multiple signal versions is the root cause of the crashes, since the routes have been running flawlessly in previous TS versions. There must have been some crucial change in how TS handles errors/exceptions in scripts which is causing the issues with the current TS version. If we could know exactly what has changed then maybe it would be possible to revise the scripts to make them work in the current and future TS version as well?
     
  9. Spikee1975

    Spikee1975 Guest

    See Bergensbanen thread. Screenshots are supplied.
     
  10. Hgv

    Hgv New Member

    Joined:
    Sep 6, 2020
    Messages:
    11
    Likes Received:
    2
    Thanks for the read, however, this just confirms that since the recent (last year) core updates, some scripts are crashing the sim. Before this, all routes were working (but in some cases crashing in 64 bit).

    I agree that ideally there should be separate signal versions for each route to avoid overwriting signals in other routes, but it's easier said than done considering that the route authors have had limited knowledge of the inner workings of the sim (speaking for myself, and I believe Totte as well), while there has been a need for improvements to the signals. Adjusting the scripts for existing signals have enhanced their functionality without causing any adverse effects - except suddenly after the recent core update, which would have been impossible to foresee years ago.

    On my route Jönköpingsbanan and Kiruna-Narvik which I refurbished for newS, I can confirm the following:
    • Pre core update both routes would run in 32 and 64 bit.
    • In 64 bit, the routes would crash in certain scenarios, where I found that the crashes occurred when a train crossed a specific link related to level crossings
    • After the core update, Jönköpingsbanan crashes on route loading (I don't think I've had a chance to check with Kiruna-Narvik and I'm not at my TS computer for a while).
    • I found that disabling the SE End Signal script allows Jönköpingsbanan to load also in the latest TS version (this signal is not used on Kiruna-Narvik as far as I can remember). I have tried with the original version of this signal script as well as the updated one; both crash the route on loading so it's not related to the updated script.
    • Even with the SE End Signal script disabled, post core update, Jönköpingsbanan crashes when crossing certain signal links.
    • Reverting to a pre core update TS version allows me to run routes without signal script related crashes, at least in 32 bit.
    It would be very interesting to get some insight from the developers as to what exactly has changed in the script handling a) between 32 and 64 bit versions, and b) after the core update.
     
  11. Hgv

    Hgv New Member

    Joined:
    Sep 6, 2020
    Messages:
    11
    Likes Received:
    2
    With some help I finally figured out the main culprit for the crashes: (certain) links turned the "wrong" way. This has been used for the above mentioned "end signal" where it should display a stop aspect continuously, and having a wrong way link ahead of the base link has achieved this previously. Wrong way links have also been used in level crossings. Apparently the newer TS versions will not accept this.

    By updating the "end signal" script and turning the associated links the "right" way, I was able to keep the function of the signal. I have also replaced level crossings with a modern version (based on the standard TS level crossing scripts).

    While I'm really happy that the route can now live on (and perhaps I'll even do some work to extend it) but this raises a few new issues:

    - The level crossing script is not as flexible as the previous setup with links to activate the level crossing at specified points. The new script simply activates the crossing at a set distance. This means that the crossing signals generally activate too early for slow moving trains and too late for fast moving trains. Is it possible to modify the script to be more flexible/realistic? Does anyone know of a good level crossing script to take inspiration from?
    - The new level crossing sounds only work occasionally. Apparently it's a known issue? Is it possible to do something about that?
    - I had previously used platform barriers with a bell sound hidden undergound to activate a bell when a train crosses certain points in yards/stations. As this persistently crashed the sim whenever the associated link was activated, I had to remove these and I have yet to find a good replacement. It seems like a simple script to have a sound activate when a train passes a crossing (possibly the "main" LC script can be modified for this?). Perhaps such a script/asset already exists?
     
    • Helpful Helpful x 1
  12. Spikee1975

    Spikee1975 Guest

    Most interesting find.

    In fact, TSC allowed much "unconventional" trickery which has been restricted to prevent crashes. You could basically feed it with anything previously, even if it not makes any logical sense like wrong direction links. But I can see in my mind what happens in the code and why they removed it.

    I am in no way an expert in signalling, I know how to place one and the links. But I do know that german Schuster SignalTeam provided a "Hp0" Red Signal Trigger that corrected some Kuju shortcomings.
     
    Last edited by a moderator: Dec 14, 2024

Share This Page