[ian-reeds-games] Re: Notes for scripters

  • From: abigail prescott <abigail.prescott@xxxxxxxxxxx>
  • To: <ian-reeds-games@xxxxxxxxxxxxx>
  • Date: Mon, 26 Aug 2013 22:37:05 +0100

That's cool, it'll be a lot easier for people to understand what to do if they just need to add some extra flags.


Can you make script flags for the map?

Abi


-----Original Message----- From: Ian Reed
Sent: Monday, August 26, 2013 11:37 AM
To: ian-reeds-games@xxxxxxxxxxxxx
Subject: [ian-reeds-games] Notes for scripters

Greetings scripters!

I've added 2 new files for you to use in your script folders.
As mentioned in a previous email the focus here is to allow you to
provide map creators with easy to use script flags rather than the old
event syntax.

Examples of the new files are located in the Data for TB\Scripts\Ian
Reed\Non script files folder.
They are called: Script Flag Definitions.txt and Event subscriptions.txt.
These file names are looked for specifically by the engine so be sure to
leave the naming the same or the engine will think it's a javascript file.
Put copies of these files in your own scripts folder and edit them as
needed.

A quick description of Script Flag Definitions.txt:
There are a couple comments in the file that I'll repeat here.
// each line has the flag name followed by the type.  Valid types are
string, bool, int, float, percent, keys, function, and enum followed by
a pipe and list of enums separated by commas.
// You can optionally have a list of file types that the flag can be
used in, separated by commas.  If left off the flag is valid in all files.

Down the road the valid files might not be optional, I recommend
specifying them as it will give map creators a friendly error when they
accidentally use a script flag in the wrong file.
Let me comment on each type:
string, used for textual data, can have spaces in it, if you want to do
completely custom flag parsing this is a good one to use.
bool, as with normal flags just specifying the name of the flag sets it
to true.
You can also do flag_name false which sets it to false, since that is
basically the default this is only helpful in inheritance scenarios.
int, whole numbers, negative numbers are supported.
float, decimal numbers, negative numbers are supported.
percent, expects this format: flag_name 52%, when you get the value the
52 will be 0.52.  Using the percent sign makes it more obvious to map
creators about what this number means.
keys, uses the same format as the Keys.config flags, such as quest_menu
control q.  There is a special javascript function that lets you check
if the specified keys were pressed.  I still need to include this in TB
but it already exists in the RPG, so remind me, smile.
function, This expects this format: flag_name function_name {}, note
that this is similar to the last part of the old event syntax. There is
also a javascript function for calling these functions that I still need
to put into TB.
enum, this works just like string except if the map creator uses any
value you did not provide as an option they receive an error.
In the definitions file it looks like this: flag_name
enum|option1,option2,option3

So you might be wondering how you access these script flags from
javascript, good question!
Each object that supports script flags has a new dictionary on it called
ScriptFlags.
Here's an example of me getting the announce_name script flag off of a
unit in my testing.js file included with the game:
function announce_message(args) {
    if (args.unit) {
        if (args.unit.ScriptFlags.get("announce_name")) {
            say(args.unit.FriendlyName);
        }
    }
    say(args.message);
}
So again that was var val = unit.ScriptFlags.get("announce_name");
Note that val would be null if the script flag was not specified, false
if it was specifically specified with a value of false, and true otherwise.
Javascript treats null and false as falsy values so it works either way
in an if statement.

Now on to Event Subscriptions.txt.
This is a simple format where you specify the name of the event followed
by the function name and any arguments you want to pass in a JSON object.
For example:
after_map_load announce_message { message: "after_map_load" }

I actually recommend doing something more like this:
after_map_load ir_handle_after_map_load {}
This gives me a single ir_handle_after_map_load function that I can use
to do anything and everything I want to do after a map is loaded.
Everything I do should really be based on what script flags are set by
the map creators, so if they did not set any script flags that should
affect this behavior then I should do nothing in the function.
Note that I prefixed the function name with my initials.
This is because all the scripts exist in the global namespace and a
second function with the same name will override the first, so it's
safer for everyone if I prefix with my initials.

So for example I might have:
function ir_handle_after_map_load(args) {
    var map = args.map;
    var placeRandomUnits = map.ScriptFlags.get("place_random_units");
    if (placeRandomUnits) {
        // use the placeRandomUnits variable to decide which units to
randomly place in which area.
    }
}

You can add the load_scripts=ian_reed flag to your map pack settings
file to load my test scripts.
They basically announce every time an event occurs so you can verify the
events are working and see when they occur.
Note that this behavior of doing something even though the map creator
didn't set a script flag is bad practice, but people should not be
loading my scripts anyway since there is nothing useful in them.
So, do as I say, not as I do, smile.

Well, I think that about covers it.
I think that the ability to hook up to all the events globally and to
create your own script flags really allows you to make a nicer
experience for the map creators.
I'm interested to hear your thoughts on the pros and cons of this method
compared with the previous way of doing things.

Thanks for all your help!
Ian Reed



Other related posts: