Easiest Way to Dominate Dogfighting in Starfield

Struggling with dogfighting in Starfield? Yeah, me too… until I tried a little creativity. I just started playing Starfield last Friday. I’ve got almost 8 hours in the game now and at lvl 13 (on normal) I’m taking down Galbank craft @ lvl 38. I want to tell you how =]

How I got here

It started with a spacer ship I disabled, boarded, and commandeered. I took my new second ship straight to the shipyard and decided it was time to get creative – after all, I had a pretty solid backup that had worked (mostly) for me thus far.

That’s it. That’s how I got here.

I just solo’d 6 or 7 enemies on a quest without going below 97% shields (they died before they could really get a shot at me), then took out a lvl 38 Galbank ship — but it ain’t b/c I’m amazing. This technique is early-game accessible and totally affordable. IIRC, it was only $8,000 ish in credits..? Wasn’t a lot.

The Loadout

The single biggest combat enabler that I’ve found so far are the lasers with even damage between hull and shields, and has a 3k range. The Disruptor 3300 Electron Beam. You can pick them up in the Deimos(?) dealership, floating just outside of Mars in the Sol system (heyyy neighbor!).

Ladies and Gentlemen, I present The Disruptor 3300 Electron Beam

You don’t need three weapon types. Just one. Fill 4 weapon mount points with those lasers, and put them all under your weapon 2 slot (that’s just my preference because it puts it closest to adjusting your engine power as well). This should bring the total power draw from these 4 lasers to the max (ie: 12) power slots. Perfect.

If you’re not sure how to do this, you’ll need to go into purchasing upgrades for your ship, then use the ship editor to manually delete/remove the other weapons, add one of the 3300’s, duplicate three more and place them, map them to weapon two, and rename your ship to something that sounds terrifying. Or cute and cuddly.

You know what? You do you. Or go ask ChatGPT for some suggestions – she’s quite good at it!

The Undefeated (minimally tested) Technique

Setting lasers to full power, Capt!

First: never JUMP into a fight like this – jump to a location within the solar system where your mission is and TRAVEL into the fight (it’s just like jumping except within the system and doesn’t require grav drives). BEFORE you “travel” there, set your engines to 1, then the lasers and shields to MAX (yeah baby!). NOW you’re ready to travel.

Hilarity ensues as you see a cutscene where your ship is striving to keep up with the camera pan… Screaming across the galaxy at 30 (insert interval of speed here I don’t remember). When you arrive, the bogies will almost surely see you immediately and begin their approach.

But the thing they don’t know is… these four lasers at max power are like a gatling gun of pain, misery, and space dust fabrication.

ehh that one sounded better in my head. But see the results for yourself:

LUDICROUS SPEED! GOOOOOO!!! πŸ‘€

Like I was saying – you’re truckin’ along at a comfy 29-30 (again, what measurement of velocity is this?!) something… but your lasers are putting the successes of the A-10 Warthog to shame. Your enemies are outranged and wildly outgunned… they can go faster, buuuuuut who cares when they’re actively evaporating before they have a chance to return fire.

There is one caveat though… I’ve noticed that this makes boarding ships a taaaaad more difficult, so try to disable them while you’re behind them… Or once you disable a ship, you have to be quick to turn down your lasers so you can redirect that power to your engines and get within docking range. Get ready to hold X!

Let me know in the comments if you have any techniques that you’ve tried or how this one worked for you!

Cheers,
Ryan

PS – one last pic =]

Who knew sacrificing ethics could be so profitable?!!

How to Disable the Resubscribe feature in Woocommerce Subscriptions Plugin

This brief guide is aimed at developers familiar with WordPress who are looking to disable the Resubscribe feature in WooCommerce’s very own “Woocommerce Subscriptions” plugin.

Let’s dive right in.

Outline

  1. Solution(s).
  2. Show the Work.

At the time of this writing (2023-07-03), there is no option to turn off the “Resubscribe” functionality. If you’ve come into a scenario where that is becoming problematic (not unheard of – plus, I’m also having this issue), you might be searching for a solution.

…And probably didn’t find anything that helped.

Solution(s).

Well I dug through the code and found two quick solutions that you can drop in your child or custom theme’s functions.php file, a custom plugin, or a mu-plugin drop in. The first solution is my preferred method as it effectively disables the feature:

// This simply says "nobody has the authority to resubscribe a subscription ever"
add_filter( 'wcs_can_user_resubscribe_to_subscription', '__return_false' );

The alternative just removes the button from rendering, but if a customer knew how to mock up the url to do it, or was provided a link, could still purchase the resubscription. This might be a better solution for scenarios where you want to modify or tailor how customers get to “Resubscribe”, but still leave it as a functioning feature:

// This method simply removes action buttons like "reactiveate", "resubscribe", and "cancel" from being rendered.
add_filter( 'wcs_view_subscription_actions', function($subscription_actions){
    if ( !empty($subscription_actions['resubscribe']) ) {
        unset($subscription_actions['resubscribe']);
    }
    return $subscription_actions;
});

Both will remove the “Resubscribe” button from being rendered, but only the wcs_can_user_resubscribe_to_subscription filter denies the resubscribe functionality across the site.

Show the Work.

I’d like to show my work so you can A.) follow along, B.) be more informed in your decisions, and/or C.) trust the process coming to these solutions.

Let’s start in the Subscription Details template where the “Resubscribe” button gets rendered: ./woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/templates/myaccount/subscription-details.php. Inside that file (currently line 78), there’s a function called wcs_get_all_user_actions_for_subscription() who’s job is to get all the “Actions” that are contextually available for that subscription to that user.

We then look at that function’s definition in ./woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/wcs-user-functions.php and see that upon return, it has the second solution’s filter. Here we can remove any of the available options from rendering as an available action. Mind you, this *only* removes the “Resubscribe” button from rendering in the “view subscription” template. Placing a similar button anywhere else will still work!

However, if we’re specifically looking at disabling the “Resubscribe” feature altogether, we see in the middle of the wcs_get_all_user_actions_for_subscription() function, it leverages a function called wcs_can_user_resubscribe_to() – that sound promising! Finding its definitiong in ./woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/wcs-resubscribe-functions.php, we see in its return that it provides another filter wcs_can_user_resubscribe_to_subscription — and ultimately — this is the one I prefer to use.

Using WordPress’s predefined function __return_false for the wcs_can_user_resubscribe_to_subscription filter denies anyone from resubscribing, effectively disabling the feature. Or you could implement your own logic in place of __return_false – another conversation for another time.

Hit me up with any questions, improvements, and/or thoughts you have =]

Cheers,

Ryan

Connecting to a Pervasive SQL (PSQL) v12 Database using PHP ODBC+PDO on Modern Linux

Hi friend. If this article title interests you, you – like me – have probably scoured the internet for hours trying to figure out how to fire up a db connection to an old, aging database… maybe so you can begin the process of evolving out of the 90’s.

To get all this set up, here’s what we’ll be covering:

  1. Finding the client for PSQL
  2. Extracting the contents and getting everything in place
  3. Installing a few dependencies before we run the installer
  4. Running the installation scripts
  5. Defining the LD_LIBRARY_PATH in your bash profile
  6. Writing a PHP Test script
  7. [Bonus] Ensure www-data can use it

I may be your new best friend – let’s trauma bond!

Step 1: Finding the Client

To get started, we’re gunna need the client. This will require you to sign up for Actian’s Electronic Software Distribution website. It may be confusing, but they now refer to it as “Actian Zen” but still “PSQL”. In their downloads, you can do the rpm or whatever, but I went with the tar.gz – I like pain I guess… Also, I’m running ubuntu, sooooo RPM’s don’t exactly play nice.

I’m going to pretend now that you’ve successfully found and downloaded the tarball named something like PSQL-Client-linux-12.11-033.000.x86_64.tar.gz – should be around 100mb or so. Regardless: excellent work! Well done =]

Download, extract, yadda yadda…

Step 2: Extract and place the client in position

Since you already knew how to tar -zxvf PSQL-Client-linux-12.11-033.000.x86_64.tar.gz , I’m not going to spend any time there. Suffice to say, you should be left with a folder named psql. We’re going to need to scoot that into the /usr/local folder.

It probably required a good ol’ fashion sudo to get it in place, but once there, let’s cd /usr/local/psql/etc

Step 3: Install a few dependencies (forgot about these)

Since I’m using Ubuntu, I’ll be using apt, but I’m sure yum and whatnot have similar proxies for the following (I initially did this in a docker container, so… I needed all of these things):

sudo apt install file php7.4 php7.4-cli php7.4-odbc

Of course, choose your flavor of php as necessary, but these should be pretty minimum… may even need to include vim in that list if you’re running this in a docker container πŸ‘οΈ

Step 4: Running the Client install scripts

Back to the /usr/local/psql/etc/ folder, there are two scripts that we need to run: the first one seems to just make sure you’re ready to install, and the second one does all the installing. They will require sudo, so buckle in.

The first script to run is (again, this is from /usr/local/psql/etc/):

sudo ./clientpreinstall.sh

If that reports back that all is well, it’s time for the second one. However, if it blows up, here’s probably why:

  1. You didn’t run as sudo
  2. You’ve already installed the client (or something else that’s sitting in the same path)
  3. You’re not running something in the proper architecture (64bit / x86)

The second script we’ll need to run is (still in /usr/local/psql/etc/):

sudo ./clientpostinstall.sh

THAT one does all the installing. At a glance, it appears to create the user/group for PSQL, set permissions on the psql bin stuff, symlinks some version naming pieces together, registers the so’s, aaaaand my eyes went crossed. It does things and stuff…

Step 5: Ensure your bash environment variables

We need to place the following line in our .bash_aliases file (or .profile, or .bash_profile, or .bashrc – whatever!)

export LD_LIBRARY_PATH=/usr/local/psql/lib64

^^ If you don’t place that in one of your sourced files and slurp it back in, it’s going to say something like: Can't open lib '/usr/local/psql/lib64/libodbcci.so.12.11.033.000' : file not found — even though that file is VERY F!@#ING MUCH THERE, BRO! (sorry) and you’ve even tried temporarily chmod 0777 libodbcci.blahblah to see if it’s a simple permissions issue – it’s not.

It’s because you haven’t exported the LD_LIBRARY_PATH variable. There. I just saved you a little insanity from an error message that isn’t lying, it’s just not clear =]

Now I do see where psql adds its bin folder to your $PATH – however, I’m not sure that’s entirely necessary for our purposes alone. If you’re considering using tools like isql or odbcinst (both under unixODBC), then I would consider it. For that, I would also expect to be setting configuration files in /etc/odbc.ini, /etc/odbcinst.ini and maybe even ~/.odbc.ini — none of this is required for ***our specific use-case***, but it might be handy if you need a cli option to explore the data. Here are the docs for unixODBC if you’d like to get started with that. For now, I’m going to assume we don’t need them.

Step 6: Test Script – make it count!

This is the big one! I wish you all the luck; let’s put down a quick test connection script and see how we do:

<?php

// Of course, you'll need to fill in your server and db name.
$dsn = 'odbc:Driver={Pervasive ODBC Interface};ServerName=localhost;dbq=DBNAME';

// So secure... Of course, if this is running on a Windows server (from 1998),
// there's a good chance these are your windows credentials
$username = 'myusername';
$userpass = 'securepass';

try {
    $db = new PDO( $dsn, $username, $userpass );
    // I promise I'm not shouting any of this - at you or the db...
    $results = $db->query('SELECT TOP 10 * FROM TABLENAME', PDO::FETCH_OBJ);

    foreach ( $results as $k => $row ) {
        echo "$k => ";
        var_dump( $row );
    }
} catch (PDOException $e) {
    echo "\n\nHELP! THERE'S FIRE EVERYWHERE AND GARY'S STILL IN THE SERVER ROOM!!!\n" . $e->getMessage() . "\n\n";
    // You would absolutely hate working with me, amiright? o.O
}

Copy that code and edit in your details quick… I’ll give you a keyboard replay of what happens next:

> vim test.php
> :set paste
> i, [ctrl] + [shift] + v
> :x
> php test.php && echo 'TADA!!! =D'

Did it work?!! If not, hopefully Gary made it out alright.

Step 7: [Bonus] Ensure www-data can use it

Ok – so our script works perfectly when we run it against the CLI, but when we hit it via the web (nginx or apache2 -> php) we maaaaay see that we’re back to not being able to find the file. [envision a slow-mo eyeroll and a sigh that blows all the paper off the table].

If you’re using the default www-data user for your web services, you may notice that adding something to its environment is……. problematic. Shoving the value in the nginx conf doesn’t work, adding it into a php.ini doesn’t work – there are no confs in the web services than can help you – believe me, I tried.

Then I found this solution https://stackoverflow.com/a/13428971/1238804 – basically, there should be a folder at /etc/ld.so.conf.d/ . In there, we’re going to create a new file (it appears everything in the folder with a .conf suffix is getting slurped in) and add our path to it.

cd /etc/ld.so.conf.d
sudo vim pervasive-sql.conf

# In our pervasive-sql.conf file, we'll just add the following:
/usr/local/psql/lib64

Save, close, and finish the job with a hearty sudo ldconfig

Seriously, don’t forget the sudo ldconfig. I suppose restarting the machine would do the trick too, so… YA GOT OPTIONS! Huzzah!

Now as you might imagine, if you had to go this far and add the path to the pervasive-sql.conf file, you can get rid of it from your bash profile… but of course, that’s up to you =]

Well that was graphic.

I won’t go as far as to say I had fun, but hopefully all that got you moving again. So let me know in the comments below, my fellow wayward devs… How’d you fare? Did I miss anything? Are you running into issues? Let me know in the comments below, or – and I mean this – email me at ryan@ this domain πŸ˜‰

Adding WordPress Post Metadata when using wp_insert_post

I found a little trick that I’ve overlooked so many times when writing plugins that use custom post types. Did you know that you can do this?

$args = [
    'post_type' => 'books',
    'post_title' => 'An Exciting Look at Mud',
    'post_content' => 'Things and stuff and content. Probably involving that book.',
    'meta_input' => [
        'book_author' => 'Mr. Bookwriter Dude',
        'authors_fav_quote' => "I have a belly button and HERE IT IS!"
    ]
];
$post_id = wp_insert_post($args);

How cool is that?! Now don’t laugh at me, but I looked for my postmeta in my DB because I’m always skeptical and look at this beauty:

mysql> select * from wp_postmeta where post_id=742444;
+---------+---------+-------------------+---------------------------------------+
| meta_id | post_id | meta_key          | meta_value                            |
+---------+---------+-------------------+---------------------------------------+
| 2779343 |  742444 | book_author       | Mr. Bookwriter Dude                   |
| 2779344 |  742444 | authors_fav_quote | I have a belly button and HERE IT IS! |
+---------+---------+-------------------+---------------------------------------+
2 rows in set (0.00 sec)

Nice 😎

Cheers!
Ryan

Adding a Page to your WooCommerce My Account Dashboard

So you’re writing a plugin and you want to add your own pages for your customers to use in their dashboards with its own integrated nav link. There’s just one problem: documentation for *how* to do this is…. lacking.

I just spent two hours chasing this one down; I gotchu.

There are three components (2 filters and 1 action, specifically) you’ll need to accomplish this:

  1. Add your menu item to the WooCommerce Nav (filter: woocommerce_account_menu_items )
  2. Add the Query Var to WooCommerce (filter: woocommerce_get_query_vars)
  3. Create a callback to render your content (action: woocommerce_account_{$variable_name}_endpoint)
  4. [Bonus] Detecting if the request is to your new Woocommerce Page

Step 1 puts our nav menu item into the WooCommerce nav on the left (along with dashboard, payment methods, addresses, etc). Step 2 tells Woo to register the endpoint in WordPress so that it’s a known/valid URL for our site. Lastly, step 3 tells Woo what to do when that url endpoint is requested – render stuff in the content area!

Doing it this way lets WooCommerce do the heavy lifting and should work no matter what you’ve modified your ‘my-account’ permalink to. Ultimately, it’s a pretty easy task; figuring this OUT however… Let’s just say that either I don’t know how to google, or docs are seemingly absent on this, so I’m glad you found me here =]

Honestly, this makes one wonder if it’s part of the business model for buying plugins for woo – but I digress…

For this Example

In this example, I’m going to add a page to the my-account dashboard area that allows my customers to see their spend ranking in the store. Other options might be if you want to create a wishlist feature for your e-commerce store, a shipping status monitor tab, or whatever – your reasons are your own, I’m just here to help you get there πŸ˜‰

What is your account page endpoint going to be? I’m going to call mine “spend-rank” – you’ll see how it determines a lot of things after this (including the actual hook names).

Ok – without further adieu!

Step 1: Adding your Menu item to the WooCommerce Nav

This is done through a simple filter. If my nav item is called “spend-rank”, here’s how it’ll look for me:

/**
 * Add our "Spend Rank" nav menu item as the second to last item (just above logout).
 *
 * @param   array $nav_items    Dictionary of WooCommerce Nav Items for the my-account page.
 * @return  array               The nav items with our spend-rank menu item added.
 */
function spend_rank_set_up_nav_item($nav_items)
{
    // Splice logout off the back of the list and add our spend-rank in just before it.
    $tail_items = array_merge(
        // Notice slug part => Human Readable Menu Item
        ['spend-rank' => 'Spend Rank'],
        array_splice( $nav_items, -1, 1 ) // last item should be logout o.O
    );

    // Smash them back together and return the results
    return array_merge($nav_items, $tail_items);
}
add_filter( 'woocommerce_account_menu_items', 'spend_rank_set_up_nav_item' );

Fire up the my-account dashboard on your WooCommerce site and you should see your menu item there. If you don’t, double check that you’ve lined up your filter callback to the function name and hopefully that gets you squared away.

If you’re wondering about all the array_splice‘ing and array_merge‘ing going on, it’s to keep the keys in place. Dictionaries in PHP are ordered, so it matters!

Step 2: Add the Query Var to WooCommerce

Not to just WordPress… to WooCommerce. This is specific to WooCommerce, so we’re hotwiring it using default Woo filters. Here’s where we tell WooCommerce (and therefore WordPress) about our url path /my-account/spend-rank/ – check this out:

/**
 * Adds our spend-rank query var directly into WooCommerce so it can do all the heavy lifting for us.
 *
 * @param   array   $query_vars Dictionary of WooCommerce query vars.
 * @return  array               Same dictionary with our spend-rank endpoint added in.
 */
function spend_rank_add_query_var($query_vars)
{
    // The key should correlate to your endpoint and be unique(!!!), but ultimately...
    // it's unused AFAIK.
    $query_vars['spend-rank'] = 'spend-rank';
    return $query_vars;
}
add_filter( 'woocommerce_get_query_vars', 'spend_rank_add_query_var' );

In order for this to take effect, we’ll need to re-save our permalinks, but let’s hold off on that for now since WooCommerce won’t know what to do for this yet. Now let’s wire up the render callback.

Step 3: Create a callback to render your content

WooCommerce has done all the heavy lifting for us, and now that we’re done describing that “spend-rank” is a thing to WooCommerce, we just need to tell it what to do in that context. So let’s give it a callback to render our content!

function spend_rank_render_content()
{
    echo "<h1>GO SPEND RANK, GOOOO!</h1>"; // whatever that means to you ;)
}
// Notice how we've added a magical action with "spend-rank" in the action name:
add_action( 'woocommerce_account_spend-rank_endpoint', 'spend_rank_render_content' );

Still doesn’t work? Oh yeah – don’t forget to re-save your permalinks! From the /wp-admin/ area: Settings -> Permalinks -> Save (no edits) OR perhaps on plugin/feature activation, you could try a flush_rewrite_rules() so your customers don’t have to do that manually.

Bonus: Contextually detecting your new WooCommerce Page

Here’s a quick bonus: what if you need to enqueue a special script or style but you’d rather it only be for your new page. You can use the is_wc_endpoint_url function that comes out of the box with WooCommerce. Check it out:

// Can only be run during hook `parse_request` @ $prio > 10 or after
if ( is_wc_endpoint_url( 'spend-rank' ) ) {
    // enqueue a script? wp_die()? You decide! =D
}

That’s pretty much it, y’all! Integrating your plugin’s functionality into WooCommerce should be the easy part. Hopefully this gets you a little closer. Now go write the hard part πŸ˜‰

Cheers,
Ryan

How to Easily Setup PHPUnit Tests for Codeigniter 3

This tutorial will show you how to take a new or existing Codeigniter 3 project, and add PHPunit test capabilities to it. While Codeigniter 3 shipped with its very own unit test suite, some of us still prefer PHPUnit. I’ve read many methods online, but wasn’t 100% able to do everything I needed for one reason or another. This method aims to fix that.

In essence, we’re going to create a phpunit config file, tell Codeigniter when to use our test configurations, create a custom test route, and write an inert test controller to get the app in scope for our tests. Once those pieces are in place – just add tests! Although this is a longer post, I promise it’s pretty easy. I’m just a verbose kinda guy – apologies if you’re in a hurry. Here’s the gist:

  1. Defining our Testing Environment
  2. Create a PHPUNIT Config File
  3. Configure Routes for Testing
  4. Creating Our Inert Test Controller
  5. Writing Your First Test
  6. Bonus: Writing an Actual Test for a Pretend Library

Let’s get started!

Step 1: Defining our Testing ENVIRONMENT

In the Codeigniter 3 index.php file, you’ll see a bunch of logic that tries to determine and define the ENVIRONMENT. Here’s where we’re going to modify some of this logic to tell the app when we’re running tests so it knows to load the testing set of configs.

To do this, we’ll look in the index.php file around line 53 for something like this:

define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');

And replace it entirely with this:

if ( defined("PHPUNIT_TEST") ) {
    define('ENVIRONMENT', 'testing');
} else {
    define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
}

Effectively, when PHPUNIT_TEST is defined, we’ll set the ENVIRONMENT constant to “testing”. This will tell Codeigniter to overwrite any production configs with what’s in the “testing” folder. I’ll show you how to create that to modify certain CI configurations for our tests shortly.

(Optional step) I’ve left the default environment determination (set as development) in there, but if you want, it might be wise to assume the app should run as production, JIC it gets deployed somewhere the CI_ENV isn’t defined properly and you don’t want errors to spew all over the front page after a deploy has gone sideways. Just replace the second define with this:

define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'production');

Just a thought though πŸ˜‰

Step 2: Create a PHPUNIT Config File

Let’s assume that the Codeigniter 3 framework is installed in the root of your project. In this case, the index.php file, /application folder, /system folder, and maybe the /user_guide folder are all here. If this isn’t your setup, just know that the point here is to specify the Codigniter’s index.php file as the PHPUnit “bootstrap” file. For this tutorial, we’ll place our phpunit.xml file right here beside the index.php file and run our tests from that directory.

The contents of your phpunit.xml file should look something like this:

<?xml version="1.0" encoding="UTF-8" ?>
<phpunit bootstrap="index.php">
    <testsuites>
        <testsuite name="UnitTests">
            <directory>application/tests/unit</directory>
        </testsuite>
    </testsuites>
    <php>
        <ini name="display_errors" value="true"/>
        <const name="PHPUNIT_TEST" value="1" />
    </php>
</phpunit>

Here I’m making a few additional assumptions – all of which you can feel free to adjust to taste:

  1. We’re writing a unit test suite in this example
  2. We’ve placed our unit tests in the /application/tests/unit/ folder
  3. We want to display errors as they occur

If those 3 pieces are good with you, they’re good with me =]

You’ll also notice that there is a line that says <const name="PHPUNIT_TEST" value="1" /> in there – that’ll be defined when we use PHPUnit to invoke Codeigniter for our tests now!

Step 3: Configure Routes for Testing

Somehow we need to get the Codeigniter framework running and in scope for our tests. To do that, we’re going to create our “testing” environment’s routes.php config so we can tell Codeigniter where to route our testing requests (we’ll write the test controller in step 4).

Create a folder called “testing” inside the /application/config/ folder. Inside there, we’re going to overwrite the production routes.php by creating our own in /application/config/testing/routes.php. The inside of that file should look like this:

<?php

$route['default_controller'] = 'test/index';
$route['404_override'] = 'test/index'; // when in doubt, use the hammer
$route['translate_uri_dashes'] = FALSE;

At this point, feel free to create any other testing config files you need to overwrite any production values. Ensuring your tests aren’t running/accessing anything that could potentially *do things* should be paramount! Things you might want to consider are the /application/config/config.php values, the /application/config/database.php settings… etc.

Now we’re going to go create an empty Test controller to ensure our test request is inert.

Step 4: Creating Our Inert Test Controller

We want an empty controller for our tests. This does two things for us: 1) it gets the app within the scope of our tests so we can use the Codeigniter instance, and 2) it ensures that the controller doesn’t start doing actionable things to our data/system. In the case of our UnitTests suite, we only want to exercise the parts of the code we intend to.

Let’s create the test controller here: /application/controllers/Test.php and put the following code in it:

<?php

if ( !defined("PHPUNIT_TEST") ) {
    show_404();
}

class Test extends CI_Controller
{
    public function index()
    {
        // Yep... This is all we need. Like I said... Inert.
    }
}

Notice that we’ve placed a caveat at the top of this file. If PHPUNIT_TEST isn’t defined and /test is requested it’ll 404, or if this file is directly accessed, it’ll fatal with a “Undefined function: show_404()” message. Hopefully in production, that’s just a simple WSOD (white screen of death), but if someone’s pokin’ around here, a WSOD is totally acceptable… Of course, you are free to handle those situations as you see fit #GzipBomb =]

Also, I realize that maybe you have a MY_Controller class that you normally extend. Sometimes, it’s viable to skip extending that (and go straight to the CI_Controller) for your tests, and other times you might *need* to extend it. I’ve been in scenarios where I’ve had to extend the MY_Controller and overwrite methods and properties that do actionable things here in my Test controller (like user auth stuff, etc). Adjust to taste, but for this tutorial, we’ll stick with extending the CI_Controller.

Step 5: Writing Your First Test

Let’s create our first test by asserting that true is in fact true after we’ve pulled in the Codeigniter instance. Though trivial, this will help us ensure that our tests are running and we’ve got the framework at our fingertips. Create a test file here: /application/tests/unit/myFirstTest.php and we’ll put the following code inside:

<?php

use PHPUnit\Framework\TestCase;

class MyFirstTest extends TestCase
{
    private static $CI;

    public static function setUpBeforeClass(): void
    {
        self::$CI =& get_instance();
    }

    public function test_true(): void
    {
        $this->assertTrue(true);
    }
}

I’m using PHPUnit version 6.5.5 at the time of this writing, which requires that the methods specify their return data types. Also, this might not be backwards compatible if your PHPUnit version predates php 5.6 (IIRC), but you get the idea of what we’re trying to accomplish. Hit up your version of PHPUnit’s docs if you’re getting fatal errors extending the PHPUnit TestCase class like this.

Once this test file is in place, save it and lets run our tests from the CLI in the directory our phpunit.xml file is in:

>phpunit
PHPUnit 6.5.5 by Sebastian Bergmann and contributors.

.                                              1 / 1 (100%)

Time: 55 ms, Memory: 4.00MB

OK (1 test, 1 assertion)
>_

Heyyyyy! As it turns out, true is true – and running unit tests inside the context of CI is easy now too! You can use the CI instance to load your helpers/libraries/etc and exercise that code.

Sidenote: if you’ve been using PHPUnit for a while, you’re probably already familiar with the conventions, but JIC here they are:

  • file names of your tests end with “Test.php” (fooTest.php)
  • class names end with “Test” (class FooTest)
  • test methods START with “test” (public function testFoo(): void {})

If you’re getting a warning that no tests were found, make sure you have the conventions lined up and your test files are inside the folder you specified in the phpunit.xml file. In the example phpunit.xml file I gave, that folder is specified in the “UnitTests” TestSuite as /application/tests/unit and it *can* be inside a subfolder of that.

Bonus: Writing an Actual Test for a Pretend Library =]

Let’s look at what a real test for our app might look like. Let’s say we have a Hello library with a “hello world” method called who that we want to test. The library is appropriately placed in /application/libraries/Hello.php and our test file to exercise this code is in /application/tests/unit/libraries/helloTest.php. The code for our test could go something like this:

<?php

use PHPUnit\Framework\TestCase;

class HelloTest extends TestCase
{
    private static $CI;

    public static function setUpBeforeClass(): void
    {
        self::$CI =& get_instance();
        self::$CI->load->library('hello');
    }

    public function test_hello_world(): void
    {
        $expected = 'Hello World';
        $argument = 'World';
        // Here we test the Hello library's who method...
        $actual = self::$CI->hello->who($argument);
        $this->assertEquals($expected, $actual);
    }
}

This of course could exercise helper classes/functions that aren’t placed inside the CI instance class, or the tests could use a dataProvider – however you normally write your PHPUnit tests. Suffice to say, you still have access to using the framework almost exactly how you normally would inside your controllers.

Wrapping this up

So what all have we accomplished? We’ve created a way to flag Codeigniter to recognize we’re running tests, created a custom route config for our tests, built an inert controller to give PHPUnit access to our app, and wrote some tests!

I hope this tutorial was clear, helpful, and worked for you! Feel free to leave me any comments, questions, and/or feedback below.

Cheers!
Ryan

PS – sorry for waiting so long to write this. I hope it’s not too late.

Rebel Galaxy Outlaw: Best Guide Yet

First: I. LOVE. DOUBLE. DAMAGE. GAMES. Small crew of incredible folks making games we’ve all been dying to play and maybe even didn’t know it. Yeah, I’ve sunk a ton of time in the original Rebel Galaxy, so you know I was PUMPED to play the new one.

That’s right… I played and played and PLAYED the original. Loved it. Rebel Galaxy Outlaw is the prequel sequel (hah!) to the original, playing as Juno Markev (the Aunt of the character you play in the original) with a sordid past – here we see why/how. Lore/script/story aside, I’m here to talk about Rebel Galaxy Outlaw and how to get gud, son.

Let’s dive in – most guides thusfar kinda suck and don’t get you what you need to know other than what you might already grasp having played the original – this is NOT the original. I’m going to try and explore some decent ways to ACTUALLY be successful. First, let’s talk about dogfighting.

Dogfighting

Dogfighting is all about energy management. Energy controls many different aspects of your ship’s abilities and it’s split up into 3 parts: shields, engines, and weapons. Increasing one decreases the others.

Not sure what your capacity and/or recharge is and feel like you’re always out of energy? Hit start (go to the PDA) and tab over to the SHIP tab. There you’ll see at the bottom “POWER CAPACITY” and “POWER RECHARGE”.

Coyote’s specs with a lvl 4 powerplant

It’s not necessarily the best to have the biggest guns/shields/etc as it can leave you with little energy to spare. I’ve racked up enough credits to fly the Coyote equipped with a repair droid, power plant lvl 4, duratanium armor (big duh – get it now! ZERO DRAW!), and the shield generator lvl 4.

However, despite having 60GJ (is that a GigaJoule?) of power recharge, those pieces alone take up a HUGE draw which doesn’t leave much left for recouping energy or for sustained weapon fire!

This doesn’t matter when you start to add up the weapons that don’t draw energy. That’s right friends! I like to roll with 1 or 2 Photon Cannons (which DO take energy draw) – generally I only roll 1… The rest should be AUTO CANNONS!!! These things are amazing. While they do have a delay while the reload (why can’t I reload with a button press between fights?!!!), when they come back around, DAMN! Be ready. Those Jackrabbits never stood a chance.

Auto cannons don’t take draw, don’t cost anything in ordinance, and do SERIOUS hull damage (94 DPS + 200% against hulls = 188 DPS). I pair those with the Photon Cannon, because that does 200% damage to Shields and has relatively low draw.

Why Worry About Energy Draw?

Here’s why – you can double down on energy weapons and run out of energy all day OR…. you could rock those auto cannons and set your energy management for weapons all the way down, leaving the rest of your energy management to shields and engines. This means you can run to recoup, run to get your next target in range, or take some serious punishment and not GAF. Meanwhile, not having a shortage of ability to return fire.

THEN, in scenarios where your shields are getting roughed up, hit the flight menu and dump excess energy into shields.

Since your weapons aren’t using much energy, you should regularly have full energy unless you’re firing your guns and hitting the afterburners. Dump your energy into your shields whenever you need and your Duratanium Armor will never know you were in the scrap from hell! Neither will your repair bill =]

Targeting Mode

If you don’t know what this is, you’re not doing it right.

Mid dogfight, I’m always referring to this. I’ve had half a mind to hotkey it to my right shoulder button (xbox controller) because I use it so much. This gives you CRITICAL information about what’s going on in the heat of a battle and helps you prioritize your next target. Select your target and hold L to guide you towards them and fire! Scratch one! Not only does it show you each bandit (not bogey – those are unidentified opponents – targeting mode tells all!), but it shows you who they have targeted.

When you’re trying to protect a group of freighters, fire this puppy up and go for the bandits targeting the freighters first and ignore the ones focusing you. You can even taunt them to get them off their targets and either run or come at you.

Here’s why you WANT to do that: You already got the LVL 4 shields, right? Those can absorb 700 damage and if you’re rockin’ the Duratanium armor, your hull can take another 750; You can take the punishment of 3, 4, 5+ bandits… the freighters succumb to 2 or 3 QUICKLY! They’ll even go so far as to tell you they’re getting “torn apart” – help those guys out first! Take the punishment, dump your excess energy into shields (because you have auto cannons and can afford it energy-wise) when needed, and keep on firing till they’re dust!

Last thing I’ll say about dogfighting is regarding technique… Holding the follow button (“L” trigger?) gets you most of the way there, even in ships that aren’t agile at all – like the Durston. Here’s a quick technique that might help though: when a ship approaches within close proximity or is going really slow (like a bomber), hold down the brake button and drift a bit. You can still hold L while you do this, allowing them to zig and zag their way through coming straight back into your sights. Sometimes they’ll even parallel your course and shooting them is like shooting fish in a barrel! Easy peasy =]

Taking Out Large Targets

In some engagements, you’ll encounter bigger ships like Destroyers, Cruisers, etc… In the original Rebel Galaxy, you could normally find a little nook in their afterburner wake to chill and fire with minimal incoming damage. In Rebel Galaxy Outlaw, you may find that even in finding that sweet spot, you’re still getting some guns or maybe got too close to their engines (ow) and it drains your front end shields — if you have mostly auto cannons (beating this one to a pulp because it’s that important), you could dump all that full energy back into shields and go about your day.

No turrets? No problems! Also, pretty sure this one is invulnerable – hell if I didn’t try though! That’s 30 minutes I’m never getting back ={

OTHERWISE, the one huge combat difference in this game is that you have the opportunity to completely shut down the offense of the larger ships. Thusfar, I’ve only encountered giant turret boats – so this is a great way to disable their ability to shell out any damage. Getting the Ranger LS Infinity targeting system will allow you to specifically target and shoot out the cannons sitting on the sides, tops, bottoms, etc… Once their turrets are out, they’re quite easy pickins’!

Lastly, one of my favorite weapons for these larger ships are the Dumbfire Rockets. The Swarm Rockets are fine – they do the most damage, but they can also be avoided with an EMP. Sit behind the large ships and chip away at them with your guns and dumbfire rockets – they’re cheap, have decent reload, and still pack a wallop! If you have the equipment bay in Bountiful Vista (more on that later), you can get an upgraded version that has a few extra capacity =]

Making Money

Who cares about this? Play the damn game already! Do quests, answer distress calls, buy new gear so you can handle bigger, more bountiful quests, and before you know it, credits don’t really matter.

Just playin’! Unlike the first one, you only get a fraction of your cash back when you sell your gear off (except for ships!), so don’t SELL your gear back. Leave it in surplus if you’re trying something out and come back to it when it’s useful again – especially mining turrets and rockets when your new ship has a downgraded turret or missile point counts.

One thing I highly recommend early on is to buy a repair droid. This guy will save you TONS of cash in the long run. Don’t shy away from spending that 30k =]

Rockfarming for the black market, Eureka for Bountiful Vista.

Oh, and before I forget, if you start accumulating less than legal goods in your hold, you can sell them at any station that has a “black market” rather than the typical “commodities” trade hub.

Not sure where to find one? Head over to Granite in the Rockfarming System where all law is taken as more of a guideline. Or, if you’re not close to Rockfarming, there’s another option towards the top of the System Map in the Medicine Hat System called “Dautry Outpost”. Lastly, there’s a black market in the Hampton System (top right corner of the section map) at a little station called Cordell – the “Black Market Boutique”.

In each place, you’ll find an Independent’s station that will gladly buy those Human Transplants and explosives off you. Hey – it’s more cash than carrying it around till you get caught with it or finally find the one off station where it’s not illegal.

OH! And also before I forget, if a dodge patrol is telling you it’s performing a scan for illegal substances, feel free to jettison those goodies out before they cut radio and complete their scan. Sure, someone else might (and probably will) tractor some of those items in, but it’s better than going hostile with the patrol if you intend to stay lawful.

Honestly making serious cash fast

Ships are the one thing you can go between without losing credits! I’ll say it again later, but the Durston is for making cash, the Coyote is for winning. If you want to make cash, go for the biggest hold you can find – this is where the Durston (one ship before the Coyote) comes in. Throw a Cargo Hold Expander lvl 3 in and you can either travel the universe and pick up all the cargo from your defeated foes from missions and distress calls, or invest in a mining turret to mine your heart out. Or both.

Speaking of mining (the fastest way to make some cash with low effort)….

How to Mine in Rebel Galaxy Outlaw

Head out with an empty hold, equipped with a mining scanner (under components in any station that has an equipment bay) and a mining turret (you’ll only need one). A mining scanner and turret/weapon IS required – so don’t get out there and realize you don’t have one of those two!

Set a destination for one of the locations that a bartenders suggest when you ask about the latest news… if there are asteroids laying about, you’re almost guaranteed to strike gold – literally – plus many other high value items!

“Resources detected” – oh be still my beating heart!

Scan the area using the scanner from the flight menu to find resources. You’ll notice the onboard computer tells you “Resources found” – get set, cause you’re about to make some serious dough.

Use this scanner – maybe even multiple times to ensure you can (and continue to) see the good stuff!

Once you’ve scanned and detected resources, all you have to do is find one of the golden checkered areas on the resource asteroid of your choice! Switch to your mining turret or take aim with a mining laser and fire away! Feel free to relocate all energy to weapons to ensure you don’t run out, but honestly, mining in Rebel Galaxy Outlaw is NOT like farming Faces of Goyu (or w/e) and antimatter-specs in the original. It takes mere seconds with a mining turret to get the goodies. Each resource (as of this writing) gets you a few ore and a few other things as well. I’ve gotten antimatter, alien specimens, and a bunch of ore from each asteroid.

This is how we do it =]

Walking away from one mining trip netted me around +85k credits in about 20 minutes – even with having to figure everything out. I filled my entire cargo hold (44 tons) and could have gone back! You need cash?! You need the Durston equipped with mining tools, and you need to start mining.

Another Entertaining Prospect

I have also gone to pirate bases and just wrecked all the pirates, tractored their cargo, and sold it later. That was kinda fun. Bases – like the original – seem pretty indestructible, so feel free to waste some ammo on those. Ultimately, this didn’t net a ton of cash, but it was fun and I did walk off with about 17k worth of goodies for a 5ish minute dogfight. Be prepared to find a black market afterwards though!

Summary for making cash

At the end of the day, two ways get you the most: 1) your “buddies” (folks you can call upon to join you in battle like Richter, Satchel, Marla) will offer quests which are more lucrative than most, so don’t ignore them when they ask for assistance! And 2) scouring the universe for resources and mining. There doesn’t seem to be any single item that will get you rich like the original (faces of goyu and antimatter specs), so making money is all about the size of your cargo hold.

Wait. Hold the phone. What’s THIS?!!

Baryonic Catalyst?!! Well… it’s no Face of Goyu from the original, but that’s a nice chunk of change! Found a couple of these in the systems to the top right. What’s better even yet? They have a tendency to be in demand:

Huh… Alright then. That’s WAYYY better than hitting 777 in the slots!

At a max bet of 500, this is a $15k win. Nice! …but it’s no Baryonic Catalyst!

Anyways, like I said before, the Durston is for getting cash, the Coyote is for winning fights. Swap ’em at will, leave your excess gear in surplus, refit your weapons, and keep flyin’.

Bountiful Vista

If you don’t know what this is, you CLEARLY haven’t been listening to the ads on the radio and need to find it immediately. Nestled in the Eureka System (see sector map screenshot from above – right next to the Texas System) is a rock you can buy. A station of your own. A home in a galaxy of hostiles. Rumored to be a backwater mining central, it seemed to have fizzled out. As such, do yourself a favor and don’t take the first offer Spanner gives you. Play a little hardball and you can get it for a fraction of the cost – you didn’t hear that from me though! Spanner is my homie =]

Bit by bit, you can build it up to have an equipment bay, a mission station, a shipyard, and more — I haven’t gotten that far yet, but next piece for me seems to be a gambling hub.

All I know is Bountiful Vista gives perks. First, the perks are just more capacity for all of your launchers (ie: rockets and such). I gotta find out what’s next, because I’m hoping it’s amazeballs.

Bountiful Vista Shipyard [Update]

IT IS amazeballs. So, here’s why: once you get your shipyard up and running, it offers modified versions of the Sonora, Sandhawk, Durston, and Coyote. These modified ships have a new coat of paint, generally modify speed and maneuverability, and then have different cargo hold sizes, turret counts, etc. It’s not a landslide upgrade modification – as each has a form of trade off.

With All that being said, let’s meet the new ships!

The Sequoia

Ignore the red – I snapped this while currently owning The Beluga, so it’s comparing against that!

Slightly faster than the Sonora, it adds one missile hardpoint, 4 additional ton cargo hold, loses a turret, but then grows it’s max shield, powerplant, and cargo ranks from two to three! This feels like a pretty good upgrade for the Sonora!

The Beluga

Holy cow! Errr, whale! This is a modification to the Durston. The Beluga loses a missle hardpoint, loses 4 tons for its cargo bay, but adds a turret. It’s no more or less faster or agile (hah!) than its original, but it keeps the max ranks for shields, power plant, and cargo. Ultimately, the third turret can help you get out of scraps or have more convenient mining options if you go that route. Losing 4 tons in the cargo hold is kind of a kick in your mining operation’s pants! Between the two – I might just stick with the Durston, since the turret’s have just about as bad of aim as I do D=

The Blood Eagle

Again, we’re comparing against the Beluga – don’t mind the red stats here!

The Blood Eagle is the modified version of The Sandhawk. Not gonna lie, I went straight from the Sonora to the Durston – so my thoughts on these ships as of right now are “Hey, I need to try these ships”. However, the Sandhawk and Blood Eagle share the fastest top speeds and maneuverability in the game, so if agility is a big factor for your playstyle, you’re still in good company (maybe even better)!

The Blood Eagle adds one missle point, adds one max shield rank and TWO max powerplant ranks, but loses it’s one paultry cargo rank. Wow. You have a bogey you need to catch and kill, the Blood Eagle is your bird of choice.

The Dingo

The Dingo is of course a modified version of the Coyote. It’s slower, a bit less maneuverable, and *slightly* less armed to the teeth. Top speed dives from 430 MPS down to 400 MPS and you lose 5 DPS (degrees per second – not damage) in maneuverability; ultimately, nothing to cry about. You lose 2 weapon hardpoints (hey! I needed those auto cannons!), but gain 2 missile hardpoints. This puppy is for making small work of those cruisers that always seem to pop up at the most inopportune times (am I the only one that LOVES the dumbfire missiles, btw?).

The big benefit to the Dingo though, is she’s got a bigger cargo hold – going from a 5 ton cargo hold to an 8, and the max cargo rank from 1 to 2. With the Cargo Extender 2, this gets the Dingo’s hold capacity up to a whopping 18 tons – that’s not too bad for a fighter – and if you’re out doing merchant guild quests, this is a huge enabler.

Bountiful Vista Spoiler D=

It appears Double Damage left us a little insight into what all we’ll be able to unlock at Bountiful Vista. See for yourself, the icons don’t lie:

Another cool thing is that there are perks you get from unlocking most of these pieces. For instance:

I haven’t paid much attention to how much and/or when this happens, but feel free to add it to the comments section below if you’ve been keeping score here. Regardless, that’s a nice perk =]

Last bits on Bountiful Vista

Bountiful Vista is your home in the galaxy, but it also gives you some of those component goodies that you can only find in some of the stations (I think just the ones with a merchant’s guild). Like for instance the Secret Stash and Smuggler’s Hold Cargo Extenders, upgrades to all the missile point weapons, and who could forget about Spanner?! That quirky, mildly timid, very helpful guy that sends you off into the galaxy with a shopping list and a bill for the next piece to build out.

Meet Spanner – Your one and only confidant in Bountiful Vista!

Ok, so maybe you don’t need to find it immediately, but it sure is fun to rock out the quests for good ol’ Spanner and liven up the atmosphere in Bountiful Vista. Hah! That Spanner. He’s a good droid =]

Critiques

Everyone has their opinions, right? Well… why not me? So, while I absolutely love the game thusfar, I do have some thoughts on how they went right, and how they went wrong.

First, I love the addition of Bountiful Vista. What a great aspect of the game the original didn’t feature. Who doesn’t want a home? Who doesn’t wanna upgrade all the things and see what goodies come next? Love this!

Next, I think the “Autopilot” was a mistake. I really loved upgrading my ship’s capability in the first Rebel Galaxy to go from putzing through a galaxy, to SCREAMING through it. Then being able to turn as you go to avoid the next asteroid belt or w/e… Autopilot in Rebel Galaxy Outlaw kinda cheapens the vastness of space in the game. Then it feels like to “liven it up”, they created interruptions like ships in close proximity, hostiles, and distress signals to make it feel less one-dimensional. These can get rather annoying when trying to get where you’re going… And I know, you’re going to say “but Ryan – hit your sublight and stop crying about it”.

And sure, you wouldn’t be wrong, but you can’t steer it, it doesn’t get faster by upgrading your ship, and it’s a terrible waste of time compared to autopilot.

Now that autopilot is a thing, is there a way to go back? Nah… Which is why it’s kinda borked the experience of space travel. Boo.

Next, I really wish they’d elaborate on the comms with other ships! Holy smokes! How fun is it to taunt an opponent right before you smoke them?!!! Then, each time I come across a trader in the area, a quick little “How y’all doing?” is definitely in order. It’s a bit skin deep though – but it seems like there is a ton of room here to build upon and grow the game. Potential quests, trades, etc… Each time getting a “The board is green and the flying is easy!” is a little monotonous, but I still check in =]

How great would it be to trade some of those components or robot modules rather than having to tell them to drop their cargo so you can keep building out Bountiful Vista? Hey, I may be lawful(-ish), but in this galaxy, sometimes these materials are few and far between!

Best Bug Ever

I found a bug (that I haven’t exactly reported yet….. wink wink) that led me through some pretty entertaining times. At first meeting Sharky, I started the mission, flew off the wrong way b/c I wasn’t paying attention, and did something else for a while. I got the ol’ “Mission Failed” text.

Not sure if that was what kicked it off, but when I went back to restart the mission, I could talk to Sharky time and time again about this mission (where she challenges you to a game of 8-ball).

Here’s where this gets awesome:

6 Instances of the same quest all at once – what fresh hell is this?! Wait. Nope – they’re stocked full of gold ore. Nevermind – nothing to see here… Move along, people!

While going through the quest line 6 times did get mildly annoying at times, it kinda paid off here. You eventually run into an Irish sounding scoundrel nicknamed “The Chaplin” (IIRC). He’s off to raid some cargo vessels for their gold.

I have to say, this was one of my favorite moments of gameplay thusfar – totally by accident. It felt like one of the star battles straight out of a Star Wars movie. TONS of action, dodging other craft, threading between cargo vessels, locking on to your next target, taking TONS of fire… holy shit that was exhilarating!!! Then to top it all off, I had to go swap out to a Durston to take everything home – still took 2 trips! I sold over 60 gold ore to a nearby station who must have been in incredibly short gold ore supply!

Do yourself a favor – talk to Sharky a shitton, fail this mission repeatedly, fight for your life and have a blast doing it!

Lastly

I’m compiling a list of all the systems, stations and what they produce vs. what they demand… I’ll go ahead and post that somewhere here soon (please visit again soon as this guide is evolving!), although it’ll lack the pirate stations since I’m all lawful(-ish) and whatnot. If you have the pirate station data, feel free to hit me up! I know Double Damage loves their RNG (random number generator), but IIRC (if I remember correctly), they shy’d away from it this time, so hopefully the stations share similar needs through each play through. [Update – they seem to evolve over time OR I goofed when I jotted the data down the first time]

If you’re wondering where the screenshots are stored, they’re in your documents folder under Documents\My Games\Double Damage Games\RebelGalaxyOutlaw\screenshots

Anyways, suffice to say I’m having a great time playing the game and hope you are as well! Maybe this guide even helped you a bit! As the mercs say “Stay frosty” =]

Seeking Happiness

Quick aside first: if this was shared with you, please know I wrote this for myself and nobody else. Ideally, this is just a thoughtful article to get folks thinking about things in their lives and is worth sharing. That’s what I’m hoping for at least!

Is it just me, or is happiness one of those elusive things… something that comes and goes, or maybe leaves you feeling like you’re coming up short? A roller coaster of highs and lows, or maybe even just something that you never can quite grasp?

I would like to make a slightly bold statement: we all have an imperative to greedily seek out the things that make us happy.

Not to the detriment of ourselves or others – in some cases, service to others is what makes us happy. Simply put, I want us to begin (or continue) the avid pursuit of achieving our own happiness. Let’s face it: nobody is going to find it for you and nobody is going to lay it in your hands.

I mean that with all kindness =]

Plotting a Course

What do we do about this? How do we approach this? The one bit of wisdom I can eke out of this concept (seeking happiness), is that if you’re not where you want to be, if you don’t have the things in life that you want, chances are high you’re going to have to do something you’ve never done before to get there. A fresh approach, taking with you all the learnings of before to achieve something closer than you’ve ever been. The great climb to a genuine smile!

I’m writing this right now because I currently find myself in a situation where I have an infinite of options in front of me, and I’m not sure what the next step is. I’m not quite terrified by this prospect though. I look at it like this: if you find yourself in the middle of the ocean and aren’t sure which way will get you to land, the best course of action is to pick a best guess direction and go.

Is that the best we can do though? Does it all boil down to a good guess, a bit of luck, and maybe even a little good ol’ fashioned gumption? A little bit every day or haymakers until we have to stop to catch our proverbial breath? This is starting to sound like the ultimate showdown of the Turtle Vs. the Hare. Perhaps there’s wisdom there (#UnawarePoet).

Necessity for Adapting

Life at times can feel like it’s nothing but curve balls and monkey wrenches… so expect that! Trials will be had, hurdles appear… the obstacles that we anticipate seem to never happen, and yet what we least expect generally occurs (speaking as a developer – hah! Damn that left field!). So let’s expect that in the course of our lives we have to roll with the punches and adapt.

So that’s it? We plot a course, make a plan, execute it, and adapt as the situation changes? I suppose so… then when we come up short (which is bound to happen – monkey wrench incoming!), we adapt. We rinse and repeat, starting back at step one – plot a new course with all of our learnings from our previous attempts, and press on.

I think the point here is: don’t let a little thing like failure slow you down. When beating your head against the wall doesn’t get you through it, try to find a way around it – or at least find a method that isn’t quite as head-trauma inducing!

What can I say? I’m a caring guy like that =]

Simple Concept, Not Simple

Ugh! You know what though?! That sounds like a lot of work. A lot of heartache. A lot of struggle and pain. A lot of bullshit. But then again, you tell me – are you where you want to be in life? Maybe there is something to be said for finding happiness without finding land — in the middle of that ocean, so to speak. Maybe…

Yet I find myself wanting… friends, family (especially one of my own), connection, a loving relationship, success, happiness, trust, and purpose! I do know where I’m wealthy – my friends and family. I’ve had success and found software development to be my craft of choice – something I’m pretty good at!

Real Talk

Hold the phone! Did I really just confess that what I’m seeking right now is the lady of my dreams? Whoops. Eh… I’m ok with being vulnerable to the entire internet. Pshhh! It’s just the internet! Joking aside – I think we could all be a little more honest with ourselves and each other.

So let’s do this! What is it that you want in life? What steps can you take to get yourself closer to realizing that dream? What’s in your way to getting there now? How can we get there?

I’d like to apply one last parting concept from software development to life. Be forewarned, this one is taken from agile (hey! don’t hate!): whenever you start any endeavor, you’re starting from nothing. Effectively, you’re at your dumbest point! Give yourself the space and a little kindness to muck things up a bit – because you will – and if it’s worth it, you might muck it up a few times before you get there.

Learn from those moments, adjust course, and press on. Rinse and repeat my friends, rinse and repeat!

Lastly…

At the end of the day, I mainly wrote this for myself. Don’t let that stop you if you’re feeling compelled – please throw some comments below! Tell me (and everyone else for that matter) if something here resonated with you! Proclaim the things you seek! Share your plan or your wisdom! Alternatively, you could just enumerate the ways I sound like a looney person or lack solid conclusions in all of this whimsy! All is welcome.

And yes, lastly, I hope you find what you’re looking for – even if it’s just the contentment of being right there in the middle of the sea =]

Helpful Hacky Skyrim Tools

Dragons fly in Skyrim's sky!

Enter the Skyrim Alchemy Sage

Skyrim Alchemists know that potent poisons come in small doses!

Welcome fellow Skyrim alchemists – interested in brewing the most potent of poisons?! The most proverbial of potions?!! The most electrifying of elixirs?!!! …perhaps with a touch of alliteration? Hrmph! I have a scroll called the Skyrim Alchemy Helper that will help you craft the finest concoctions – far beyond the skills of mere mortals… In a land where everything’s for sale, this one is free…

Back to Reality

Whew! Ok, now that the RP’er in me has had a chance, the developer in me has a question for you: have you ever been doing something where you just wished you could tie a few things together quickly? Make sense of large amounts of data in no time? Then call me Mr. Rinse & Repeat, ’cause I can’t stop! heh ok… I’ll calm down.

Anyway, as a developer, I have the advantage of being able to put data together and display it in a fashion that makes sense to me. This is a story about one such helper that I made to assist in all my alchemy endeavors in Skyrim – one that I thought I would use as an example (and advertisement) of code that’s good enough for now and why that too can be ok.

The Pain Point of Inspiration

Recently (well, recent to me), Bethesda Game Studios came out with a freshly revamped Skyrim – Special Edition – full of high res textures, bug fixes, and many improvements. Cool! I’ve sunk a few hours in that game, but it’s been a minute and I wouldn’t mind returning to Skyrim to slay some dragons once more!

I get started and it dawns on me: “Geez, I wish I could get back to crafting my alchemy stuff.” I used to have those recipes memorized! What parts for my paralysis poisons? What’s good for restoring health? What’s the other thing I used to craft for those times when I need that thing?!! Blah! It’s too much to get started all over again!

So what’s the solution you might be asking? The new hotness in web frameworks, CI/CD pipelines, and the latest, most feature rich, spanky IDE?! Huh huh huh?!! =D

Hell no! I ain’t got time for that! I made a few hacky scripts to make sure my alchemy prowess was better than ever so I could get back to the game! Pshhh.. what, is this your first rodeo with Skyrim?

Enter the Lazy Dev Sage

So why is this article under filed under “Code”? I realize the quality of the code in these is more or less not ideal… Not a great start for the Code category. Yet, if there’s one thing I know, it’s the tendency of developers (especially jr. devs) to be paralyzed by the quality of their code to the point where progress is painfully slow. This is my effort to say “Heck with it! I need this now!” and to show that even when you write mediocre, unreadable, and/or unmaintainable code… there’s a place for that too.

Going back to one of my favorite rules of the dev process: “Make it work; Make it right; Make it fast”. Right now, we’re at stage 1… I might not ever need to come back to this code, so while it works, it’s fine as it is – and now I can focus on the next task at hand way sooner than perfection would allow for.

Can improvements be made? Hell yes.
Can features be added? Sure – might have to start thinking about the overall architecture if we’re working on this a lot.
Is it fast? Probably not as fast as it could be yet not unbearably slow. Does the trick, I guess scratches head.

Resultant Results and a Few Caveats

For now – it IS… which is way better than “it is not”. I think that counts for something too. Sure: take feedback from code reviews with respect and perspective. Sure: this isn’t how you should be writing code for mission critical applications (sidenote: if your mission critical software doesn’t already have a CI/CD pipeline to prevent this – HOW ARE YOU LIVING YOUR LIFE RN?!! IS IT BROKE? ARE YOU SURE? ASK GARY AND MAKE SURE! I DON’T CARE – ASK HIM AGAIN! WELL WAKE HIM UP!!!)

heh. I’m a dork.

…and sure: is this the standard I want all my code to sink to? Nahh… but for what it is – it’s just right and that’s ok.

If Source Code Wore Underpants

As it turns out, I even went as far as to make a script that allows you to look at the files and their source code! Yeesh! What was I thinking?! Eh… I was having fun banging out something I wanted to make and not thinking twice about it.

So, without further adieu, if you’d like to see London and you’d like to see France – here’s the Skyrim Helper Scripts underpants. They’re hacky and look like hell, but it’s way better than having to relearn all the different alchemy recipes from scratch again!

I hope it helps and I hope you enjoy!

Cheers!
Ryan

How I Write Professional Code

Subtitle: and talk about it UNprofessionally

I’ve been writing code for about the last decade and a half. It really wasn’t till I started working on a team of developers that I was pushed to write better, more readable code — a very important lesson. Then, it wasn’t till I started breaking old habits and started writing in a test driven development (or TDD) fashion that I started to write professional code. Continue reading “How I Write Professional Code”

Rohjaynator::1714086241::11964899