Building a Universe with Open Source Code

Tau Station relies heavily on open source code. Our database is PostgreSQL, with database deployment management handled by sqitch. Our main programming language is Perl 5, we use Redis heavily as a fast cache for non-critical data, and so on. Lots and lots of open source code.

For our developers who want to share some of our code with the open source community, we simply ask that the code not have “Tau Station-specific” code in it. In other words, part of the fun of Tau Station is discovering its secrets by exploring the universe, not reading them in source code.

So we’ve released two more modules which, we hope, others might find useful.

Method::Delegation

The first is Method::Delegation (github link). While there are a number of other method delegation modules on the CPAN, we didn’t feel comfortable with their syntax, and we had very specific needs, such as the case of trying to delegate to an object that might not exist:

delegate(
    methods => {
        is_repairing_in_shipyard  => 'is_active',
        repairing_in_shipyard_end => 'expiry',
    },
    maybe_to => 'ship_repair_cooldown',
);

delegate(
    methods => {
        is_refueling  => 'is_active',
        refueling_end => 'expiry',
    },
    maybe_to => 'ship_refuel_cooldown',
);

delegate(
    methods => {
        is_refurbishing  => 'is_active',
        refurbishing_end => 'expiry',
    },
    maybe_to => 'ship_refurbish_cooldown',
);

That removes a lot of repetitive, error-prone code and the declarative nature makes it easier to read.

Role::Random::PerInstance

The Role::Random::PerInstance (github link) module is a bit different. Due to the nature of the Tau Station universe, we found ourselves needing our own random number generator. Using Perl’s rand() function didn’t work because we needed separate, repeatable, random numbers per object instance.

The Role::Random::PerInstance module is, unsurprisingly, a role (if you’re not familiar with roles, they’re similar to Java interfaces with default methods). Once composed into a class, its use is very simple:

my $object = ObjectWithRandom->new( random_seed => 1234 );

if ( $object->random < .65 ) {
    # do something
}

In the above example, because we passed the optional random_seed to the constructor, every time we call random() we’ll get the same sequence of “random” numbers. The space station, Tau Station, might use the seed 15147040, while the space station KĂžbenhavn might use 9342238. Every object in Tau Station which needs “deterministic” random numbers has a unique integer seed.

The actual randomness is provided by a Linear Congruential Generator and we’ve been quite pleased with it, but the version we’ve made public is a slimmed down version of what we use internally: we have heavy logging of the “random” numbers, broken down by game action, so we can tell how often people succeed at various game actions.

We don’t know if Perl 5 developers will find these modules useful, but we certainly hope so. We also hope to open source more code in the future (we have a string munging library we’re particularly keen to inflict on the world). Enjoy!