It's probably hard to just learn lua without an objective as I can't think of something to just write in lua for practice - unlike say C# where I could suggest 100 projects to learn the basics and beyond.
I learnt it for the 56xx by starting with an "original" very basic script (I think for the default Black 5) writing everything in pseudo code to do what I wanted, and then translated that into lua/TS function calls by googling and a few UKTS threads where people (mostly Ben Laws) talked about available lua calls.
For example, I wanted to hide a few objects so I wrote my pseudo code - just program type language that I understand but with no specific language syntax.
- Code: Select all
mylist = an array ("LeftLamp", "RightLamp", "TopLamp", "BottomLamp")
iterate each object in mylist
Hide object
So I head to google for 3 searches: lua arrays, lua iterate array, Railworks lua hide object.
Translate the pseudo code and end up with this:
- Code: Select all
local mylist = {"LeftLamp", "RightLamp", "TopLamp", "BottomLamp"}; -- create a lua array of strings
for index,value in pairs(myList) do -- iterate a lua array
Call( "*:ActivateNode", value, 0); -- TS function to hide model a node (0 is off, 1 is on)
end
Do that for a whole loco and by the end of it you've learnt loads and have your own nicely commented reference for the next one. Do 3 or 4 with scripts of 1000+ lines and you can do most of it from memory
If you look at the old scripts they are pretty self explanatory as to the default functions..
Initialise() - Called when the loco first loads, this is called before the 3d model is initiated so you can't hide model nodes here, but you can turn emitters off and set up any global variables you need. You need Call ("BeginUpdate") in here to get things started. Most people place a one time call in the Update function (code that runs once, then sets a variable to say it's done and not to run again) to handle the bits that Initialise can't.
OnControlChange(name, index, value) - Called when a loco control changes SOME of the time, certainly when a key is pressed for a control. It's often better to keep a global note of a control's value and look to see if it's changed during each update call for which there is a function
Update(time) - this function is called numerous times a second, with the parameter "time" being how long since it was last called. This is where the meat of your script is called from.
There are other functions for specific tasks (consist messages, signal messages, camera view change, etc) but those 3 are your basis for every script. You can also write your own functions (just code blocks with parameters in and out) for things you need to use frequently or just to keep your script tidy.
So a very simple example of the Update function would be:
- Code: Select all
gTotalTime = 0; -- This variable is outside of a function and is global so can be called from anywhere in the script and retains it's value
function Update(time)
gTotalTime = gTotalTime + time;
end
This will give a globally available variable that will increase with every Update function call to give the total time since the update function started repeating.
To take it a step further:
- Code: Select all
gLastSpeed = 0; -- Global variable to store the last speed query
function Update(time)
local speedNow = Call ("GetSpeed"); -- local variable as once it's used here we store the value in the a global variable. GetSpeed is a TS function call to get the current loco speed in m/s
local speedDiff = speedNow - gLastSpeed; -- Get the difference in speed from the last Update function call to now
local acceleration = speedDiff / time; -- Acceleration simply from speed difference divided by time in m/s/s or m/s(squared)
gLastSpeed = speedNow; -- Store the speed now globally so we can query it in the next Update function call
end
In truth there is a function call "GetAcceleration" that returns the same thing, but just calling that doesn't teach us anything
Hopefully that's provided enough basic framework to start doing something. Like I say, get a basic script from an old loco and start writing in pseudo code to do exactly what you want - as I say to people when I begin a web design project, don't limit yourself to what you think is possible at this point just put down what you want to do (we'll figure out later if it's possible or not). Then get started on translating it into TS lua and see how you get on. If all else fails, ask