Fleet scripts are easily the coolest part of this game. A Fleet Script is a program written in PL/pgSQL that the Tic system will run on your player's behalf each tic. Fleet scripts have the ability to do anything your player account can do, including editing and calling Fleet Script functions!
Managing Fleet Scripts is all done within the my_fleets view. All fleet scripts in the system have the following attributes.
Fleet ID Integer
This is simply a unique identifier for the fleet script. Once code is defined within the my_fleets table, a function will be created called fleet_script_#() where the # is the Fleet ID. This function can be called directly by the player for testing or just used as a macro.
Name Character Varying
Every Fleet Script can be assigned a name.
Due to performance issues, a script in the my_fleets view can only be updated once per tic.
A Fleet Script must have the enabled column set to true ('t') in order for the Tic system to run it during the Tic sequence. If a script runs longer than its runtime allows for, the system will disable the script from future runs by setting this value to false ('f'). A player can set this value to true or false as often as they like at no cost.
With 0 Runtime, a fleet script is simple a macro function a player can call. You must purchase time for the Fleet Script to have the Tic system run it. Fleet Runtime is pruchased in Minute blocks using UPGRADE(Fleet ID, 'FLET_RUNTIME',1). This costs $10,000,000 per minute of run time but the first minute purchased for any of your fleets in a round is free.
Script Declarations Text
This is where you define the variables used within your PL/pgSQL script. For more information, see the PostgreSQL manual on Declarations
This is where you define the body of your script. Anything your player can do can be written into a script such as:
- Ship Creation
- Ship Upgrades
- Ship Course Control
- Attack, Mine and Repair Actions
- Fleet Script Manipulation
- Executing Fleets with zero runtime pruchased
For more information, see the PostgreSQL manual on PL/pgSQL
Hopefully these hints will resolve any of the usual snags new players hit when working on scritps.
PostgreSQL uses a double single-quote ('') to escape a quote character. Keep this in mind when executing INSERT or UPDATE statements into the my_fleets script and script_declarations columns.
Consider this simple example of adding a single quote to a name:
INSERT INTO my_fleets(name)
VALUES('This Fleet's got a Problem with quotes'); -- Bad! Query will fail
INSERT INTO my_fleets(name)
VALUES('This Fleet Hasn''t Got a Problem with quotes'); -- Good :D
Run Your Code
Don't forget that you can always test your functions by running the associated function that is created. As mentioned above, all fleet scripts can be run by calling fleet_script_#();
--Assuming one of my fleets has an ID of 102...
Monitor Your Runtime
If you script starts to take longer and longer to run, it may be time to upgrade a fleet's RUNTIME before the Tic system starts to disable it for taking longer than it's allocated amount. You can monitor how long your fleets are taking by running a SELECT against your my_events table and looking at the FLEET_SUCCESS actions.
SELECT READ_EVENT(id) FROM my_events WHERE action='FLEET_SUCCESS';
No, you cannot run fleet scripts belonging to other players :)
Monitor Your Errors
Does it seem like something is broken? The FLEET_FAIL action is used to log any errors that your fleet script throws during it's run by the Tic system.
SELECT READ_EVENT(id) FROM my_events WHERE action='FLEET_FAIL';
In a Fleet Script, it is better to use a loop and the PERFORM statement to run Schemaverse functions like UPGRADE( ) or actions like ATTACK( ) rather than using them inline in a query.
--rather than running this:
SELECT ATTACK(ship_in_range_of, id) FROM ships_in_range;
--do something like this:
FOR attackers IN SELECT id, ship_in_range_of FROM ships_in_range LOOP
PERFORM ATTACK(attackers.ship_in_range_of, attackers.id);
Centralize your runtime costs
Only buy runtime for one fleet script and use that to call all other fleet scripts you may want to run. This should not only help save resources but also make your code easier to keep clean.
Here is a nice little example of a Controller fleet script that manages and executes all of a player's other scripts.
-- Create the Controller Fleet Script
INSERT INTO my_fleets(name) VALUES('Controller');
--Update the code segments and enable it
script_declarations= ' scripts RECORD;',
FOR scripts IN SELECT
enabled=''t'' AND name!=''Controller''
ORDER BY id ASC
EXECUTE ''SELECT fleet_script_''||scripts.id||''();'';
--Finally, buy the 1 minute of runtime for this Fleet Script
SELECT UPGRADE(id, 'FLEET_RUNTIME',1) FROM my_fleets WHERE name='Controller';