The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Games::Lacuna::Client::Governor - A rudimentary configurable module for automation of colony maintenance

SYNOPSIS

    my $client   = Games::Lacuna::Client->new( cfg_file => $client_config );
    my $governor = Games::Lacuna::Client::Governor->new( $client, $governor_config );
    $governor->run();

DESCRIPTION

This module implements a rudimentary configurable automaton for maintaining your colonies. Currently, this means automation of upgrade and recycling tasks, but more is planned. The intent is that the automation should be highly configurable, which of course has a cost of a complex configuration file.

This script makes an effort to do its own crude caching of building data in order to minimize the number of RPC calls per invocation. In order to build its cache on first run, this script will call ->view() on every building in your empire. This is expensive. However, after the first run, you can expect the script to run between 1-5 calls per colony. In my tests the script currently makes about 10-20 calls per invocation for an empire with 4 colonies. Running on an hourly cron job, this is acceptable for me.

The building data for any particular building does get refreshed from the server if the script thinks it looks fishy, for example, if it doesn't have any data for it, or if the building's level has changed from what is in the cache.

This module has absolutely no tests associated with it. Use at your own risk. I'm only trying to be helpful. Be kind, please rewind. Etc. Etc.

DEPENDENCIES

I depend on Hash::Merge and List::MoreUtils to make the magic happen. Please provide them. I also depend on Games::Lacuna::Client (of course), and Games::Lacuna::Client::PrettyPrint, which was published to this distribution at the same time as me.

Methods

new

Takes exactly 2 arguments, the client object built by Games::Lacuna::Client->new, and a path to a YAML configuration file, described in the "CONFIGURATION FILE" section below.

run

Runs the governor script according to configuration. Note: old behavior which permitted an argument to force a scan of all buildings has been removed as superfluous and wasteful.

CONFIGURATION FILE

It's a multi-level data structure. See examples/governor.yml.

cache_dir

This is a directory which must be writeable to you. I will write my building cache data here.

cache_duration

This is the maximum permitted age of the cache file, in seconds, before a refresh is required. Note the age of the cache file is updated with each run, so this value may be set high enough that a refresh is never forced. Refreshes are pulled on a per-building basis.

dry_run

If this is true, Governor goes through the motions but does not actually trigger any actions (such as upgrades, recycling jobs, or pushes). The output shows the actions as they would have taken place. Enabling dry_run disables keepalive behavior.

keepalive

This is the window of time, in seconds, to try to keep the governor alive if more actions are possible. Basically, if any governed colony's build queue will be empty before the keepalive window expires, the script will not terminate, but will instead sleep and wait for that build queue to empty before once again governing that colony. Setting this to 0 will effectively disable this behavior.

push_max_travel_time

This is the maximum time, in hours, that a push should take (one-way) to be considered a valid candidate. This can be used to prevent pushes between very distant colonies. If not defined, there is no restriction.

push_minimum_load

This is a proportion, i.e. 0.5 for 50%. It indicates the minimum amount of used cargo space to require before a ship will be sent on a push. E.g., if set to 0.25, a ship must be at least 25% full of its maximum cargo capacity or it will not be considered eligible for a push.

push_ships_named

If defined, ship names must match this substring (case-insensitive) to be eligible to be used for pushes. This is an easy to to tell the governor which ships it can utilize.

verbosity

Not all of the 'verbosity' keys are currently implemented. If any are true, messages of that type are output to standard output.

action

Messages notifying you that some action has taken place.

construction

Outputs a construction report for each colony (not yet implemented)

message

Messages which are informational in nature. One level above trace.

production

Outputs a production report for each colony (not yet implemented)

pushes

Outputs a colony resource push analysis (not yet implemented)

storage

Outputs a storage report for each colony (not yet implemented)

summary

Outputs a resource summary for each colony

surface_map

Too much time on my hands. Outputs an ASCII version of the planet surface map.

trace

Outputs detailed information during various activities.

upgrades

Outputs an available upgrade report when analyzing upgrades.

warning

Messages that an exceptional condition has been detected.

colony

See "COLONY-SPECIFIC CONFIGURATION". Yes, a 'colony' key should literally exist and contain further hashes.

COLONY-SPECIFIC CONFIGURATION

The next level beneath the 'colony' key should name (by name!) each colony on which the governor should operate, and provide configuration for it. If a _default_ key exists (underscores before and after), this will be applied to all existent colonies unless overridden by colony-specific settings.

allow_downgrades

(Not yet implemented). Allow downgrading buildings if negative production levels are causing problems. True or false.

crisis_threshhold_hours

A number of hours, decimals allowed.

If the script detects that you will exceed your storage capacity for any given resource in less than this amount of time, a "storage crisis" condition is triggered which forces storage upgrades for your resources.

If the script detects that your amount of this resource will drop to zero in less than this amount of time, a "production crisis" condition is triggered which forces production upgrades for those resources.

exclude

If this is true for any particular colony which would otherwise be governed, the governor will skip this colony and perform no actions.

never_upgrade

If defined, buildings whose class name appear in this list will never be upgraded by the governor. Classnames are, for example, "MiningMinistry" or "Fusion".

pcc_is_storage

If true, the Planetary Command Center is considered a regular storage building and will be upgraded along with others if storage is needed. Otherwise, it will be ignored for purposes of storage upgrades.

priorities

This is a list of identifiers for each of the actions the governor will perform. They are performed in the order specified. Currently implemented values include:

production_crisis, storage_crisis, resource_upgrades, production_upgrades, storage_upgrades, recycling, pushes, ship_report

Note: resource_upgrades performs both a production_upgrades and storage_upgrades priority.

To be implemented are:

repairs, construction, other_upgrades

Note: See the Games::Lacuna::Governor namespace for plugins. Most plugins can be activated by simply including their names in the priority list.

Known plugins: Games::Lacuna::Governor::Astronomy, Games::Lacuna::Governor::Archaeology, Games::Lacuna::Governor::Party.

profile

See RESOURCE PROFILE CONFIGURATION below. Is this getting complicated yet? It's really not. Okay, I lie. Maybe it is. I don't know anymore, my brain is a little fried.

profile_production_tolerance

Not yet implemented. Will permit deviations from the production profile to pass without action.

profile_storage_tolerance

Not yet implemented. Will permit deviations from the storage profile to pass without action.

recycle_when_negative

If true, recycling jobs will be triggered even if net waste production on this colony is negative. The default is that this does not happen.

reserve_build_queue

If defined, the governor will reserve this many spots at the end of the build queue for human action (that's you).

upgrade_selection

This is a string identifier defining how the governor will select which upgrade to perform when an upgrade is desired. One of eight possible values:

highest_level

The candidate building with the highest building level is selected.

lowest_level

Vice-versa.

most_effective

The candidate building which is most effective and producing or storing the resource in question (i.e., does it most) is selected.

least_effective

Vice-versa.

most_expensive

The candidate building which will cost the most in terms of resources + waste produced is selected.

least_expensive.

The opposite.

slowest

The candidate building which will take the longest amount of time to upgrade is selected.

fastest

Other way around.

RESOURCE PROFILE CONFIGURATION

Okay, so this thing looks at your resource profile, as stored under the 'profile' key, to decide how your resources should be managed. If a _default_ key exists here, its settings will apply to all resources (including waste and happiness) unless overridden by more specific settings. Note that storage-related configuration is ignored for happiness. Otherwise, the keys beneath 'profile' are the names of your resources:

food, ore, water, energy, waste, happiness

build_above

Attempt to reserve this amount of this resource after any potential builds. Unless this is a crisis, we don't do any upgrades that will bring the resource below this amount in storage.

production

This is a funny one. This is compared against the 'production' profile setting for all other resources. If, proportionately, we are falling short, this resource is marked for a production upgrade. For example, if all resources were set to production:1, then it would try to make your production of everything per hour (including waste and happiness) the same. If you had all at 1 except for Ore at 3, it would try to produce 3 times more ore than everything else. And so forth.

storage

Like production (above), but for storage. If this is not present, the production value use used instead.

push_above

Resources above this level are considered eligible for pushing to more needy colonies. Also used as the amount to leave behind when pushing away due to an overload. This is a proportion between 0 and 1 interpreted as this amount times your capacity.

overload_above

Resources above this level are considered "overloaded" and will be given priority for pushes to other colonies where space is available. The amount to be shipped away is everything higher than push_above, see above. This is a proportion between 0 and 1 interpreted as this amount times your capacity.

request_below

Resources below this level trigger a push request from colonies where this resource is available. This is a proportion between 0 and 1 interpreted as this amount times your capacity.

requested_level

When a push is requested, the amount we would like to receive is calculated to be enough to bring the amount of resource up to this level. This is a proportion between 0 and 1 interpreted as this amount times your capacity.

specifics

For ore and food, you can specify additional parameters for pushing. Keys beneath this are specific types of resource, such as 'anthracite' beneath 'ore', and 'apples' beneath 'food'. You can also use the _default_ key beneath here. For example:

    food:
      specifics:
        _default_:
          push_above: 500

Would specify that you want to keep at least 500 of each individual type of food on hand.

requested_amount

If you want to accumulate a specific amount of a specific resource, you can specify that using this option. If you just want to accumulate as much as possible of a specific resource, set this to something obscenely high.

push_above

This functions like the regular push_above, but is a scalar amount, rather than a proportion of capacity. I.e., 500 means 500.

recycle_above

Only relevant for waste. If above this level, trigger a recycling job (if possible).

recycle_reserve

Only relevant for waste. When recycling, leave this amount of waste in storage. I.e., don't recycle it all.

recycle_selection

Only relevant for waste. Sets a preference for what we want to recycle waste into. Can be one of:

water, ore, or energy

Always recycle the full amount into this resource

split

Always split the amount evenly between the three types

full

Pick whichever resource will take the most time before it fills storage

empty

Pick whichever resource will take the least time before emptying

storage

Pick whichever we have the least in storage

production

Pick whichever we produce least of

SEE ALSO

Games::Lacuna::Client, by Steffen Mueller on which this module is dependent.

Of course also, the Lacuna Expanse API docs themselves at http://us1.lacunaexpanse.com/api.

The "Games::Lacuna::Client distribution" includes two files pertinent to this script. Well, three. We need Games::Lacuna::Client::PrettyPrint for output.

Also, in examples, you've got the example config file in governor.yml, and the example script in governor.pl.

AUTHOR

Adam Bellaire, <bellaire@ufl.edu>

COPYRIGHT AND LICENSE

Copyright (C) 2010 by Steffen Mueller

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.0 or, at your option, any later version of Perl 5 you may have available.