Talking to Yourself, Sending Messages.
Apart from sitting around waiting for the game engine to call your methods, there is another way of making your script wake up and do something useful, and that is to send it a message. Messages are an important part of Trainz and are constantly being exchanged in the background between the game and its constituent objects.
You can find more details of how the system works in the TrainzScript Message Reference or (if you have logging enabled) you can open jetlog.txt in your \Program Files\Auran\TRS####\ folder and see a record of the messages that were sent in your last game session. For now we will just send a message to ourself to do something at a future time.
One of the problems with the way that TRS calls the Init() method is that there is no guarantee that every object in the map is initialised at exactly the same moment. As a result it is unsafe to carry out tasks in Init() which depend on information being available about other objects. It can therefore be quite useful to delay some of our initialisation until later, when we can be sure that all of the data we might need will be available.
In practice no delay is necessary to accomplish this because TRS does not start to process messages until all object initialisation is complete but we will use a five second pause so that we can be sure of what is going on.
Here is a modification to the script:
include "MapObject.gs" class Tutorial isclass MapObject { string GetTime(float GameTime) { string result = "Good Afternoon"; if (GameTime >= 0.25) result = "Good Evening"; if (GameTime >= 0.5) result = "Good Morning"; return result; } public void Init(void) { inherited(); string Now = GetTime(World.GetGameTime()); AddHandler(me,"Reminder","","ReminderHandler"); PostMessage(me,"Reminder",Now,5.0); } void ReminderHandler(Message msg) { Interface.ShowPopupHelp("Hello World, " + msg.minor,GetAsset(),Interface.GetTimeStamp()) //Exception("Hello World, " + msg.minor + "\n\n");// use this instead of ShowPopupHelp in old versions } };
AddHandler(me,"Reminder","","ReminderHandler");
- AddHandler sets up a mechanism to listen for messages.
- Messages usually consist of two text strings separated by a comma, known as the Major and the Minor of the message.
- The second and third parameters specify the major and minor.
- Since the third parameter is an empty string this handler will ignore it, in this case we are listening for any message which starts with the word Reminder
- The last parameter specifies the method to which the message will be sent for processing, in this case ReminderHandler.
PostMessage(me,"Reminder",Now,5.0);
- PostMessage sends a message
- me is the message destination, in this case we are sending a message to ourself.
- Reminder is the message major
- Now, the result of our call to GetTime() is the message minor.
- 5.0 is the number of seconds that the game should delay before actually dispatching the message.
void ReminderHandler(Message msg) {
- ReminderHandler is the method name that we specified in our call to AddHandler and is the function that will process our message.
- Message handlers always take one parameter of the predefined Message type.
- The ShowPopupHelp or Exception call is the same as before, it has simply been moved from Init() to ReminderHandler
Modify the script as before and load your asset into Trainz. The result should be exactly the same as last time except that there will be a five second delay between placing the object and receiving the message.
In practice you can send messages to other objects and you can listen for, and react to, messages from other objects. Sending a message to yourself can be a very useful device though and it should be helpful to see the whole of the process in one object script.
- Previous Tutorial: Getting Information From the Game, Writing Your Own Methods.
- Next Tutorial: Saving and Restoring Data, Using Properties.
- Back to Getting Started in TrainzScript