Tuesday 3 February 2015

TS2015 - Scenario Scripting in LUA Part 1 - Getting Started

Last night on Twitch I did another tutorial about scenario creation, this time it covered the much more complex topic of using LUA scripting to add a lot of other cool things to your scenarios.

I thought i'd start this blog to allow me to put other commentary on the topic as well as provide access to various script snippets to help you reproduce the techniques in your own work.

I'm not going to go in to great step by step detail, that was covered in the show and available on YouTube.

The video from the show is here: https://www.youtube.com/watch?v=1RcO_og8q7M

Once you've got your script created and have a scary blank window in your editor of choice (I use Notepad++), the first thing you're going to want to do is drop some definitions in to make the code easier to read as we go.  Here they are - just copy and pasted to the top of your script file:

-- true/false defn
FALSE = 0
TRUE = 1

-- condition return values
CONDITION_NOT_YET_MET = 0
CONDITION_SUCCEEDED = 1
CONDITION_FAILED = 2

-- Message types
MT_INFO = 0   -- large centre screen pop up
MT_ALERT = 1  -- top right alert message

MSG_TOP = 1
MSG_VCENTRE = 2
MSG_BOTTOM = 4
MSG_LEFT = 8
MSG_CENTRE = 16
MSG_RIGHT = 32

MSG_SMALL = 0
MSG_REG = 1
MSG_LRG = 2

Next, you'll want to put in the standard function definitions that the game will call:

function OnEvent(event)
end

function TestCondition(condition)
end

Anyone who codes a lot knows the golden rule about not putting too much code in any one single function.  Unfortunately these two functions are going to inherently get very big with lots of "if this then that else if this then the other etc etc".  Fortunately LUA comes to the rescue with a neat capability that I didn't cover in the show. Modify the above two functions to read as follows:

function OnEvent(event)
   return _G["OnEvent" .. event]();
end

function TestCondition(condition)
   return _G["TestCondition" .. event]();
end

What this does is mean that every event or condition can now be placed in to its own function!

So where we might have had this before:

function OnEvent(event)
   if (event == "IntroText") then
      -- do some stuff
   end
end

Now we've got this:

function OnEventIntroText()
   -- do some stuff
end

function OnEvent(event)
   _G["OnEvent" .. event]();
end

Now any time you want to add a new event you just need to add a new function.

The same applies with conditions; using the snippet above for the modified TestCondition, the conditions will now go to their own function such as this:

function TestConditionOverspeed()
   return CONDITION_NOT_YET_MET;
end

That's the foundations of your script in place, in future articles i'll start covering specific features.

I'd love to hear your feedback on this article, not just if you like it but if there's anything you think could be improved!

 

10 comments:

  1. Done a lot of programming but first time in LUA. Thanks again for the video's and for pointing me to your blog today. Cheers Jim (PipeSgt)

    ReplyDelete
    Replies
    1. Thanks Jim - hope you enjoy the series, i've currently got about 15 or so articles planned that should cover the majority of what you can do with LUA scripting. Article 5 went up this morning :)

      Matt.

      Delete
    2. Hello Matt,
      thank you very much for the fantastic LUA Tutorials. I've learned a lot. But I have a request: could you publish the whole code of the speed control script, it is very dificult to study this script because in the video I can see only a part at he same time and not the whole stuff. Indeed yours is a great work and I hope that a many people will learn to apply LUA for making the scenarios more interesting.

      Thanks and best Regards

      Gerhard Illi

      Delete
  2. Hi Matt,

    I´m not having too much luck with this. I´m trying to set up a cinematic camera and have followed your tutorial to the letter, or at least I think I have! Problem I have is when I hit "reload" nothing at all happens. I have set up the ScenarioScript.lua folder and have filled it in as per your video but for me nothing occurs. Please can you help?

    Many thanks

    Simon Schofield

    ReplyDelete
    Replies
    1. The first thing i'd suggest is go through the second article about adding debug logging in and use LogMate - then drop some logging in to things like your event handler, go right back to the "OnEvent" function and drop some logging in there, see if it gets called, does it get called with the parameter you expect and then does it follow through your code as you hope?

      One of the quirks of a "dynamic scripted language" like LUA is that the notion of "compilation" is very basic, it will actually let a lot of errors go through and is really only checking the most basic of syntax - so one thing that you can look out for is whether you get any error's showing up in LogMate (just search for "error" in the log output and see what comes up).

      It really sounds like an error means nothing is getting executed, OR something is wrong in the script and adding debug will tell you where.

      If you continue to be stuck drop a copy of the scenario over to me via email (uktrainsim@googlemail.com) and i'll take a look :)

      Matt.

      Delete
    2. Hi Matt,

      I got nowhere nearer with this. I hope that you don´t mind but I have emailed across my scenario to see if you can pin point my troubles.

      Many thanks

      Simon

      Delete
  3. Thanks Matt. I´ll give it a go and keep you posted.

    Cheers

    Simon

    ReplyDelete
  4. Oh my gawd, 15 parts to read and learn, I might as well go to school again. :) Many thanks for this elaborate tutorial blog (and video). I certainly hope to be able to implement some of this in my scenarios. Sadly most of them will not be played by ou since they will be for the freeware routes and I know you want your install clean from those. Maybe one time you will have a seperate TS install where you will use those freeware routes, some amazing work can be found (heck.. who am I telling, you know it better than anyone lol)

    Will however dabble with some WS content as well and keep you informed if and when they will be published, maybe one might appear on your show :D

    Mava

    ReplyDelete
  5. Hey Matt! Is there a public API reference I can use, which tells me which variables are exposed to the scripting engine and how to read/write them? Many thanks!

    ReplyDelete