< Back to Contents

Guide to FloodScript

Initialization files in FloodGrapher use a particular syntax I call "FloodScript". This page is meant to document FloodScript and get people started using it when they need it.

Introduction

I designed FloodScript to help me make FloodGrapher extremely easy to extend and add plugins. I tried to make the engine powerful and reasonably useable, but many design decisions were made to make it easier to parse. Its main strength is it allows me to dynamically create objects in FloodGrapher and it allows you to add to it or play with targeting or movement ideas using FloodGrapher without having to go too far into my code. Feel free to use the FloodScript parser to customize your own robots or Robocode utilities.

Statements

Statements in FloodScript are divided by lines. lines can be blank, comments, commands or assignments. Blank lines (obviously) have only whitespace characters. Comments are lines whose first non-whitespace character is a '#'. Assignments set a variable name to a value using '='. Commands are one of two special forms, either "print" or "load", followed by a parameter. There are no control structures in FloodScript, as it is mainly meant to set options interpreted by the program using it. It also has no facility for calling functions, only for using constructors.

Types

There are a set of literal value types that may be used in FloodScript. These correspond directly to java primitive types and Strings. Because of the pickiness of types using reflection to call methods and constructors, you must often be very specific and correct when choosing the type to use. So in other words, I don't want to have to guess what the types were, so I make you tell me. The type is a one-letter identifier, for instance, for all numeric types. All literal values are enclosed in [square brackets]. Examples:

int[i1000]
short[s100]
byte[b50]
long[l2093094]
float[f34.12]
double[d56.29848]
boolean[#t] or [#f]
String["This is a String"]
char['A'], ['\n']

Creating Objects

FloodScript's main purpose is to call the constructors of objects to be used by the program. You can call a constructor using a default (parameterless) constructor by just using its fully qualified class nme:

kawigi.tools.AccelerationSegmentation

You can also use constructors with parameters by putting the parameters in parentheses delimited by commas. Examples:

kawigi.tools.LateralVelocitySegmentation([d3])
java.awt.geom.Point2D&Double([d40],[d50])

Assignments

Most of FloodScript is making assignments. You can use your own variable names if you want, but the most interesting effects come when you assign variable names that are searched for by the program using the parser. Variable names are not case-sensitive. Examples:

LocationX=[i300]
LocationY=[i200]
overwrite=[#t]
powermanagement=kawigi.tools.Power3Only

If multiple values are assigned to the same variable name, these values will be packed into a list (or actually, a java Vector):

segmentation=kawigi.tools.WallSegmentation
segmentation=kawigi.tools.AccelerationSegmentation
segmentation=kawigi.tools.LateralVelocitySegmentation([d3])
segmentation=kawigi.tools.BulletFlightTimeSegmentation([i10])

There are also two special objects that can be referenced, null and this. The use of null should be obvious, this refers to the object that created the FloodScript parser (or null if it was run independently). For instance, in a FloodScript designed to initialize a robot, this would be a reference back to the robot.

Special Commands

FloodScript has two special commands that can be used. The first is the load command. It runs another flood script and then returns to the current script. It looks like this:

load otherfile.ini

The second special command is "print", with a parameter that is a variable, value or object to print. Examples:

print ["Script complete"]
print my_var
print segmentation
print [i540]
print java.awt.Point([i40],[i70])

Using the FloodScript parser

If you would like to use the FloodScript parser to add customization options to your program, simply create a FloodScriptParser (with the object to be used for the "this" reference) and call loadSettings with the File you wish to be your entrypoint. Then use getObject to get the values initialized in the script by name. A default value can also be passed in, in case the variable was not initialized. Here is how the FloodGrapher robot uses it (thanks to gVim for the text coloring):


        FloodScriptParser parser = new FloodScriptParser(this);
        parser.loadSettings(getDataFile("robot.ini"));
        //Object values are easy to retrieve from the parser:
        movement = (Movement)parser.getObject("movement");
        pm = (PowerManagement)parser.getObject("powermanagement");
        //primitive values are a little different:
        constantwaves = ((Boolean)parser.getObject("continuous_waves", new Boolean(false))).booleanValue();
        //this is the best way to get numbers in general:
        guessfactors = ((Number)parser.getObject("guess_factors", new Integer(31))).intValue();
        savePeriod = ((Number)parser.getObject("save_period", new Integer(10))).intValue();
        loadData = ((Boolean)parser.getObject("load_data", new Boolean(true))).booleanValue();
        //remember that if only one segmentation was created, I need to put it in my own Vector:
        Object segs = parser.getObject("segmentation");
        if (segs == null)       //no segmentation
                segmentatinos = new Segmentation[0];
        else if (segs instanceof Vector)        //multiple segmentations
        {
                Vector vsegs = (Vector)segs;
                segmentations = new Segmentation[vsegs.size()];
                vsegs.toArray(segmentations);
        }
        else    //one segmentation
                segmentations = new Segmentation[]{(Segmentation)segs};

Quirks

The parser doesn't really check the syntax of the statements it runs. It is quite possible that some errors will make it crash (hopefully with a semi-useful error message) and some will let it be. In particular, any characters after a complete statement on the same line are likely to be simply ignored. However, in general, be nice to it, simply because making correct commands means your more likely to continue working in the next version. If you run into any bugs, and if you have any suggestions on how to fix them, put suggestions on the robowiki.