Jump to content

How can you let things happen at certain times/places in an LUA scenario?


Recommended Posts

Posted

Hello all,

I could really use some help with making a LUA scenario. I have found out how to spawn in a train in loading sequence and set up shunting/train routes. My problem is, that I don't understand how to code for letting things happen when out reach a certain track/signal or call the dispatcher at a certain location or moment in the scenario. Does someone know, where to find g good example or explanation on how to do so?

I have provided the code I made up so far below.

-- SimRail - The Railway Simulator
-- LUA Scripting scenario
-- Version: 1.0
--
require("SimRailCore")

DeveloperMode = function()
    return true
end

-- StartPosition = {-10709.52, 282.68, 1584.34} -- spawn at perron 3
StartPosition = {-10453.90, 271.73, 1498.06} -- spawn close to Katowice dispatcher building
Sounds = {}

--Below are functions called by SimRail
--- Function called by SimRail when the loading of scenario starts - generally designed for setting up necessery data and preloading-assets
function PrepareScenario()
    
end

--- Function called by SimRail when the loading finishes - you should set scenario time in here, spawn trains etc. After calling this mission recorder is started and stuff gets registered
function StartScenario()
    StaticTrains = {}
    StartRecorder()
    --VDSetCrossingState("L1_289.317_A", true)
    DisplayMessage("LuaText", 10)
    DisplayChatText("LuaText2")
    --WaitingBeforeZabkowiceEntry = false
    SetCameraView(CameraView.FirstPersonWalkingOutside)

    PlayerTrainset = SpawnTrainsetOnSignal(Treintje, FindSignal("KO_Tm26"), 32, false, true, false, false, {
        CreateNewSpawnVehicleDescriptor(LocomotiveNames.EN57_1821, false)
    })
    PlayerTrainset.SetState(DynamicState.dsStop, TrainsetState.tsActivation, true)
    PlayerTrainset.SetRadioChannel(2, true)
    PlayerTrainset.SetTimetable(LoadTimetableFromFile("Temp/main_vehicle.xml"), false)
    --SetTestScenario()
end

--function Test()
--    PlayerTrainset.SetTimetable(LoadTimetableFromFile("Temp/main_vehicle2.xml"), true)
--end

--- Function below is called by SimRail when VD is ready to start receiving orders
function OnVirtualDispatcherReady()
    Log("Hello world!")
	DisplayChatText("Your train is located at track 22. Thats the track next close to platform number 5 and track 26.")
	VDSetRouteWithVariant("KO_Tm26", "KO_N10", VDOrderType.ManeuverRoute, {
	GetMidPointVariant("l1_ko_wk6", true),
	GetMidPointVariant("z_KO_43", false),
	GetMidPointVariant("z_KO_44", false),
	GetMidPointVariant("z_KO_46ab", true),
	GetMidPointVariant("z_KO_46cd", false),
	GetMidPointVariant("z_KO_47", true)
})
	
	DisplayChatText("Its very qwuite at the moment, I will set the shunting routo to the platform for you already. You can drive to the platform track when you are ready do to so.")
	DisplayChatText("Could you let me know when you are ready for departure from the platform?")
end

function OnPlayerRadioCall()  -- Set train routes and clear signals from KO to SPl

VDSetRouteWithVariant("KO_E18", "KO_Akps", VDOrderType.TrainRoute, { -- From KO to KZ
	GetMidPointVariant("z_KO_21cd", false),
	GetMidPointVariant("z_KO_21ab", false),
	GetMidPointVariant("z_KO_14cd", false),
	GetMidPointVariant("z_KO_14ab", false),
	GetMidPointVariant("z_KO_8cd", false),
	GetMidPointVariant("z_KO_8ab", false)
})
---

VDSetRouteWithVariant("KO_M10", "KO_E18", VDOrderType.TrainRoute, {  -- KO departure from platform
	GetMidPointVariant("z_KO_47", false),
	GetMidPointVariant("z_KO_42cd", false),
	GetMidPointVariant("z_KO_42ab", false),
	GetMidPointVariant("z_KO_41cd", false),
	GetMidPointVariant("z_KO_41ab", false),
	GetMidPointVariant("z_KO_38", false)
})

VDSetRoute("KZ_P", "KZ_E", VDOrderType.TrainRoute)  -- KZ entry

VDSetRoute("KZ_E", "KZ_B2kps", VDOrderType.TrainRoute)  -- KZ departure

VDSetRoute("SG_Y", "SG_Skps", VDOrderType.TrainRoute) -- SG R52

VDSetRoute("SPł1_T", "SPł1_C", VDOrderType.TrainRoute) -- SPl entry
end




I hope that there is example with detail comments or instructions on how to do it, the ScenarioTemplate in the game files and the wiki from the developers in its current state do not provide enough information for me to be able to continue tinkering.

Posted (edited)

You have to create a signal trigger or tack trigger for that.
In your case it could look this:
 

CreateSignalTrigger(FindSignal("KO_M10"), 350, {
    check = UnconditialCheck,
    result = function(e)
        CreateCoroutine(function()
            coroutine.yield(CoroutineYields.WaitForTrainsetPassengerExchangeFinished, RailstockGetPlayerTrainset(),
                TimeSpanCreate(0, 0, 0, 30, 0))
            VDSetRouteWithVariant("KO_M10", "KO_E18", VDOrderType.TrainRoute, {  -- KO departure from platform
	        GetMidPointVariant("z_KO_47", false),
	        GetMidPointVariant("z_KO_42cd", false),
	        GetMidPointVariant("z_KO_42ab", false),
	        GetMidPointVariant("z_KO_41cd", false),
	        GetMidPointVariant("z_KO_41ab", false),
	        GetMidPointVariant("z_KO_38", false)
        end)
    end
})

The trigger checks for a train approching the signal KO_M10. When the train is less then 350m from the signal it activates and executes the code within it.
The coroutine within the trigger waits for 30 seconds before the departure time is due and then sets the route. (The setting of routes will take some time so the signal will not change its aspect immediately)

Edited by Friedjof
Posted
1 hour ago, Friedjof said:

You have to create a signal trigger or tack trigger for that.
In your case it could look this:
 

CreateSignalTrigger(FindSignal("KO_M10"), 350, {
    check = UnconditialCheck,
    result = function(e)
        CreateCoroutine(function()
            coroutine.yield(CoroutineYields.WaitForTrainsetPassengerExchangeFinished, RailstockGetPlayerTrainset(),
                TimeSpanCreate(0, 0, 0, 30, 0))
            VDSetRouteWithVariant("KO_M10", "KO_E18", VDOrderType.TrainRoute, {  -- KO departure from platform
	        GetMidPointVariant("z_KO_47", false),
	        GetMidPointVariant("z_KO_42cd", false),
	        GetMidPointVariant("z_KO_42ab", false),
	        GetMidPointVariant("z_KO_41cd", false),
	        GetMidPointVariant("z_KO_41ab", false),
	        GetMidPointVariant("z_KO_38", false)
        end)
    end
})

The trigger checks for a train approching the signal KO_M10. When the train is less then 350m from the signal it activates and executes the code within it.
The coroutine within the trigger waits for 30 seconds before the departure time is due and then sets the route. (The setting of routes will take some time so the signal will not change its aspect immediately)

Thanks, that is the kind of information I was looking for. I will give implementing a try tomorrow.

Posted

Unfortunately I was not able to get your code to do anything.

I am fully aware of the wiki made by the developers and the example scenario template by them, but they don't provide enough information/explanation of the code to made them understandable for someone hoe does not know how to code with lua already.

Posted
52 minuty temu, jeroezie napisał(a):

Unfortunately I was not able to get your code to do anything.

I am fully aware of the wiki made by the developers and the example scenario template by them, but they don't provide enough information/explanation of the code to made them understandable for someone hoe does not know how to code with lua already.

 

Copy the code from the scenarios already available on the forum. Play with them. Change something and see what happens. If you don't know, ask a question on the forum. Maybe someone will help. Do something simple. For example, go from a semaphore to another station. And so slowly, slowly combine more and more difficult elements. After a month you will have a small script. But what a satisfaction 🙂 This is how I learn LUA. For now, I'm happy with the results. 
Good luck 🙂 You can do it.

 

 

  • Like 1
  • I agree 1
Posted

I tried some more today and I keep getting stuck with the signal triggers:

Code I have tried:

-- SimRail - The Railway Simulator
-- LUA Scripting scenario
-- Version: 1.0
--
require("SimRailCore")

DeveloperMode = function()
    return true
end

StartPosition = {-10709.52, 282.68, 1584.34} -- spawn at KO perron 3
--StartPosition = {-10453.90, 271.73, 1498.06} -- spawn close to Katowice dispatcher building
--StartPosition = {-8002.45, 265.52, 1563.43} -- spawn at Katowice Zawodzie for testing purposes
Sounds = {}

--Below are functions called by SimRail
--- Function called by SimRail when the loading of scenario starts - generally designed for setting up necessery data and preloading-assets
function PrepareScenario()
    
end

--- Function called by SimRail when the loading finishes - you should set scenario time in here, spawn trains etc. After calling this mission recorder is started and stuff gets registered
function StartScenario()
    StaticTrains = {}
    StartRecorder()
    DisplayMessage("LuaText", 10)
    DisplayChatText("LuaText2")
    SetCameraView(CameraView.FirstPersonWalkingOutside)
    
	-- Spawn the players train
    PlayerTrainset = SpawnTrainsetOnSignal("trainset", FindSignal("KO_T"), 64, false, true, false, true, {
        CreateNewSpawnVehicleDescriptor(LocomotiveNames.EN71_011, false)
    })
    PlayerTrainset.SetState(DynamicState.dsStop, TrainsetState.tsActivation, true)
    PlayerTrainset.SetRadioChannel(2, true)
    PlayerTrainset.SetTimetable(LoadTimetableFromFile("Temp/main_vehicle.xml"), false)
	
	-- Spawn a scenery train at Katowice Zawodzie
	SpawnTrainsetOnSignalAsync("static_train_KZ", FindSignal("KZ_N8"), 64, false, false, true, {
            CreateNewSpawnVehicleDescriptor(LocomotiveNames.ET22_836, false),			
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames._441V_31516635283_3, false, FreightLoads_412W_v4.Sand, 20, BrakeRegime.P),
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames._441V_31516635512_5, true, FreightLoads_412W_v4.Sand, 20, BrakeRegime.P),
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames.SGS_3151_3944_773_6, false, "", 0, BrakeRegime.P),
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames.EAOS_3356_5300_177_6, false, FreightLoads_412W.Tree_trunk, 5000, BrakeRegime.P),
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames.SGS_3151_3947_512_5, false, FreightLoads_412W.RandomContainerAll, 10, BrakeRegime.P),
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames.SGS_3151_3944_773_6, false, FreightLoads_412W.RandomContainer2040, 10, BrakeRegime.P),
            CreateNewSpawnVehicleDescriptor(FreightWagonNames.Zas_8451_7862_699_8, false),
            CreateNewSpawnVehicleDescriptor(FreightWagonNames.Zaes_3351_7980_031_3, true),
            CreateNewSpawnVehicleDescriptor(FreightWagonNames.UACS_3351_9307_587_6, false),
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames.EAOS_3151_5349_475_9, false, FreightLoads_412W.Coal, 10000, BrakeRegime.P),
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames.EAOS_3151_5351_989_9, false, FreightLoads_412W.Coal, 10000, BrakeRegime.P),
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames.EAOS_3356_5300_118_0, false, FreightLoads_412W.Coal, 10000, BrakeRegime.P),			
            CreateNewSpawnFullVehicleDescriptor(FreightWagonNames.EAOS_3351_5356_394_5, false, FreightLoads_412W.Coal, 10000, BrakeRegime.P),
            CreateNewSpawnVehicleDescriptor(FreightWagonNames.Zaes_3351_0079_375_1, true),
    })
	
end

--function Test()
--    PlayerTrainset.SetTimetable(LoadTimetableFromFile("Temp/main_vehicle2.xml"), true)
--end

PlayerTrainset = nil

--- Function below is called by SimRail when VD is ready to start receiving orders
function OnVirtualDispatcherReady()
    Log("Hello world!")
	DisplayChatText("Het sein wordt zometeen bedient.")
	VDSetRoute("KO_T", "KO_M1", VDOrderType.TrainRoute)	
	end

CreateSignalTrigger(FindSignal("KO_M1"), 360, 
{
	check = function(trainset)
                return trainset == PlayerTrainset
	end,
	result = function(trainset)
	VDSetRoute("KO_M1", "KO_E13", VDOrderType.TrainRoute)
	end
})

--CreateSignalTrigger(FindSignal("KO_M1"), 150, 
--{
--	check = function (trainset)
--		return true
--	end,
--	result = function(trainset)
--	VDSetRouteWithVariant("KO_E13", "KO_Ckps", VDOrderType.TrainRoute, {
--	GetMidPointVariant("z_KO_24cd", false),
--	GetMidPointVariant("z_KO_24ab", false),
--	GetMidPointVariant("z_KO_13cd", false),
--	GetMidPointVariant("z_KO_13ab", false),
--	GetMidPointVariant("z_KO_6cd", false),
--	GetMidPointVariant("z_KO_6ab", false)
--})
--
--	end
--})






or:

CreateSignalTrigger(FindSignal("KO_M1"), 20, 
{
	check = function (trainset)
		return true
	end,
	result = function(trainset)
	VDSetRoute("KO_M1", "KO_E13", VDOrderType.TrainRoute)
	end
})

Is their anybody with I clue what I am doing wrong?

Posted

 

My problem is that when I load a script, I have to wait 5 or 6 minutes. Only after 5-6 minutes does the game respond to commands and set semaphores and course. Maybe you feel that way too.

 

 

 

-- SimRail - The Railway Simulator
-- LUA Scripting scenario
-- Version: 1.0
--
require("SimRailCore")
 
DeveloperMode = function()
    return true
end
 
StartPosition = {-10048.76, 272.27, 1486.29}
ScenarioStep = 0
Sounds = {}
 
AiTrains = {}
 
function PrepareScenario()
    SetWeather(WeatherConditionCode.ScatteredClouds, 15, 1000, 66, 2000, 275, 2, 10, false)
   
end
 
function EarlyScenarioStart()
    StartRecorder();
     DateTimeCreate(24,08,15,10,00,00)
    PlayerTrainset = SpawnTrainsetOnSignal("Player", FindSignal("KO_R"), 500, true, true, false, true, {
        CreateNewSpawnVehicleDescriptor(LocomotiveNames.EP07_135, false),
        CreateNewSpawnVehicleDescriptor(PassengerWagonNames.Adnu_5051_1908_095_8_, false),
        CreateNewSpawnVehicleDescriptor(PassengerWagonNames.B10ou_5051_2000_608_3, false),
        CreateNewSpawnVehicleDescriptor(PassengerWagonNames.B10ou_5051_2000_608_3, false),
        CreateNewSpawnVehicleDescriptor(PassengerWagonNames.B10ou_5051_2000_608_3, false),
        CreateNewSpawnVehicleDescriptor(PassengerWagonNames.B10ou_5051_2000_608_3, false),
        CreateNewSpawnVehicleDescriptor(PassengerWagonNames.B10ou_5051_2000_608_3, false),
        CreateNewSpawnVehicleDescriptor(PassengerWagonNames.B10ou_5051_2000_608_3, false),
        CreateNewSpawnVehicleDescriptor(PassengerWagonNames.Adnu_5051_1900_189_7, false),
    })
    PlayerTrainset.SetRadioChannel(2, false)
    PlayerTrainset.SetTimetable(LoadTimetableFromFile("timetable.xml"), true)
    PlayerTrainset.SetState(DynamicState.dsCold, TrainsetState.tsDeactivation, true)  
end
 
function StartScenario()
    CreateCoroutine(function ()
        DisplayMessage("Hello", 20)
        DisplayChatText("Hello")
    end)
    ToKO()
    KOtoKZ()
end
 
function ToKO()
    CreateSignalTrigger(FindSignal("KO_R"), 50,
    {
            check = UnconditialCheck,
            result = function (state)
                VDSetRoute("KO_R", "KO_M10", VDOrderType.TrainRoute)
                VDSetRoute("KO_M10", "KO_E20", VDOrderType.TrainRoute)
            end
    })
end
 
function KOtoKZ()
    CreateSignalTrigger(FindSignal("KO_E20"), 50,
    {
            check = UnconditialCheck,
            result = function (state)
                VDSetRoute("KO_E20", "KO_Akps", VDOrderType.TrainRoute)
                VDSetRoute("KZ_P", "KZ_F", VDOrderType.TrainRoute)
                VDSetRoute("KZ_F", "KZ_B2kps", VDOrderType.TrainRoute)
            end
    })
end
 
function UnconditialCheck(e)
    return true
end
 
function CreateRoute(startSignalName, endSignalName, OrderType)
    local request = VDSetRoute(startSignalName, endSignalName, OrderType)
    coroutine.yield(CoroutineYields.WaitForVDRouteResponded, request)
 
    if (GetCurrentVDRequestResponse(request) ~= VDReponseCode.Accepted) then
        local failCounter = 0
        repeat
            failCounter = failCounter + 1
            Log("SetRoute failed - attempt " .. failCounter)
            coroutine.yield(CoroutineYields.WaitForSeconds, 15)
            request = VDSetRoute(startSignalName, endSignalName, OrderType)
            coroutine.yield(CoroutineYields.WaitForVDRouteResponded, request)
 
            Log("Status " .. GetCurrentVDRequestResponse(request))
        until not (GetCurrentVDRequestResponse(request) ~= VDReponseCode.Accepted and failCounter < 20)
    end
end
 
function debug()
end



 

 

 

 

 

 

 

 

Posted

Setting routes will not work until VD is not ready. Call this with OnVirtualDispatcherReady(). After that you can set routes.

 

function OnVirtualDispatcherReady()
    Log("VD Initialization ready!")
end

 

  • Thanks 1
Posted

In addition to what Moooritz said you need to create the function UnconditialCheck. It does not come as a default Simrail or Lua function.

It looks like this:

function UnconditialCheck(e)
    return true
end

I´ve put this at the end of my scenarios mission.lua. 

  • SIMRAIL Team
Posted
4 minuty temu, Friedjof napisał(a):

In addition to what Moooritz said you need to create the function UnconditialCheck. It does not come as a default Simrail or Lua function.

It looks like this:

function UnconditialCheck(e)
    return true
end

I´ve put this at the end of my scenarios mission.lua. 

It is not necessary to create method like UnconditialCheck but it helps a lot, and make code little bit cleaner. I mean 
 

function UnconditialCheck(e)
    return true
end

and
 

check = function (trainset)
		return true
end

gives the same result.

 

8 godzin temu, Moooritz napisał(a):

Setting routes will not work until VD is not ready. Call this with OnVirtualDispatcherReady(). After that you can set routes.

function OnVirtualDispatcherReady()
    Log("VD Initialization ready!")
end

This is pretty much what you need, at the moment Virtual Dispatcher can take a while during game loading. All commands executed before this OnVirtualDispatcherReady call are going nowhere.

Also it is mentioned in First LUA Scenario guide 
image.png

I really recommend to read it to get more into LUA scripting in SimRail.

 

  • I agree 1
×
×
  • Create New...

Important Information

Terms of Use Privacy Policy