Game Finances: Amortization

Leave a comment Standard

What Is Amortization?

This is an accounting term for taking multiple payments over time or spreading a single payment out over a period of time.

Example 1: Taking Multiple Payments

One way you can use amortization to your benefit is to take multiple payments for something. So let’s say you have a yearly upgrade that costs $50. Amortization in this instance means you allow the player to break that payment down into multiple payments. For instance, they might make two payments instead of a single one; $25 for the first 6 months of the upgrade and then another $25 for the last 6 months. With amortization you can brake a payment down into as many smaller payment as you’d like. So instead of taking 2 payments you might decide to take 5 or 6 or 30 — however it best suits your player base and brings you good business. Generally speaking, most people tend to break payments down into no more than 12 just because it makes the accounting practices easier if you have one payment a month. If you broke this $50 upgrade into 12 payments then your players could become an upgraded member for only $4.20 a month.

Why Is Example 1 So Helpful?

Many people are more willing to make smaller payments. This means that even if you don’t get a full year’s upgrade from one member you’re still bringing in income. It also encourages people to try out your upgrade system with a much smaller risk to themselves. If they don’t like the upgrade they’ve only spent half or much less than half the money than if they’d paid for a full year. It also gives them the ability to come and go on their upgrade much more readily than if they had to pay the larger sum each year. They can buy one month and not the other, then come back for the month following that allowing them more flexibility to purchase and keep their upgrade.

What’s The Downside of Example 1?

You may not be bringing in as much money as you like. Because the payments are smaller you also have more online processing fees that are applied, however some payment services will allow you register as a micro-transaction account and will take lower fees since you will be bringing in a higher volume of payments. While payments are likely to happen more frequently they will only be in smaller amounts which may make it seem like your bank account is always struggling to stay at a more comfortable level when you have slower times.

Example 2: Taking One Payment and Spreading It Over a Period of Time

This other example is one that many of you may not know about. It applies the same kind of idea except you only take one payment and you only apply a portion of that payment to your income over a duration. For example, let’s say you got your $50 upgrade and we go back to our 2 payments example. Instead of thinking of that $50 as one payment you apply $25 to this month and then 6 months later you apply the other $25. You may still have the full amount of $50 but you’re not considering it income until a period of time has passed. This idea works best when you break a payment down into bi-annually, quarterly or monthly time periods. So in our second 12 month example, instead of getting $50 for this one payment you apply $4.20 from this payment across every month.

Why Is Example 2 So Helpful?

This is really the icing on the cake and most people don’t realize it! When you take in the one payment and spread it out amongst a period of time it gives you more solid, steady income. Instead of getting $50 one month, and nothing for the next 12 months, you now have a steady stream of income coming in all year long. Generally speaking, with games the upgrade tend to have highs and lows, where people are upgrading a lot and then not upgrading at all. You may get $4,000 in upgrades one month and then nothing or very little for the next two. With this kind of amortization that $4,000 is spread over the rest of the time period. So in our 12 month example you would be bringing in $334 a month instead of $4,000 in one lump sum. This also helps you keep a steady income for the entire year instead of getting less reliable income over the duration of the year, even if the overall total for whatever time period you’re shooting for is lower than what you bring in for a month. It’s great for budgeting and paying your bills and helping you keep your game open even in slower months.

What’s The Downside of Example 1?

This example takes discipline!! It’s a much different way of thinking about the income you’re bringing in because the balance in your bank account may reflect one thing while your calculations reflect another. It is very tempting to just look at your total balance and think I have $4,000 rather than I only have $334 to spend this month. It also requires some math to keep track of how much money you are amortizing over time whereas Example 1 is easier to keep track of because you immediately account for the money from each payment you get.

What do you think about amortization? Do or have you used it? Which type of amortization do you prefer?

I would love to hear your thoughts, comments, questions and experiences!

Advertisements

Scrum Values

Leave a comment Standard

I just did a great retrospective today where we ranked each of the scrum values into two categories, what we did well and what needed improvement. For each of the values we also commented on how or why we put the value into that category. It opened the team to some really good discussions so I thought I would share the idea and the values.

Courage – saying and doing the right thing and agreeing to work on tough problems

Respect – team members view each other to be capable independent people and encourage each others’ unique ideas and points of views

Commitment – each member in the team commits to achieving the goals for the sprint, project or team

Focus –  drilling into the work of the sprint, achieving the sprint goal and completing your assigned tickets within the sprint

Openness – clear about our work and the challenges with performing the work, able to ask for help and share what’s going on in the sprint

Share the Love! Free Programming eBooks

Leave a comment Standard

GoalKicker.com is giving away these free programming books and I thought I would share the love for anyone who hasn’t seen them yet. There are more available from their website but these are the ones I was most interested in. Enjoy!

Screen Shot 2018-01-31 at 4.26.46 PM

Screen Shot 2018-01-31 at 4.26.54 PM

Screen Shot 2018-01-31 at 4.27.01 PM

Screen Shot 2018-01-31 at 4.27.11 PM

Screen Shot 2018-01-31 at 4.27.18 PM

Screen Shot 2018-01-31 at 4.27.24 PM

Screen Shot 2018-01-31 at 4.27.37 PM

Screen Shot 2018-01-31 at 4.27.44 PM

GIT Tutorial: Fetching and Testing Pull Request Branches Locally

Leave a comment Standard

There are a lot of times when you’re using Git and BitBucket in a work environment and you want to be able to test someone’s PR branch without having to download a patch or clone it. Here’s a nifty trick that will allow you to fetch and checkout PR branches on your master repo without having to clone or patch from BitBucket.

1. Add your remote master as an upstream

git remote add upstream ssh://user@myrepo.git

2. Change your new remote to fetch from your pull requests instead of regular branches

git config --add remote.upstream.fetch '+refs/pull-requests/*/from:refs/remotes/upstream/pr/*'

3. Now fetch the PR branches that are currently available in your repo

git fetch upstream

4. Finally, you can use the ID of the PR you want (the ID will be available in the URL of the link to the PR) and simply checkout the PR with that ID number by replacing ID with the number of the PR in the code snippet below.

git checkout upstream/pr/ID

5. Voila! You’ve now downloaded a PR branch to your local git instance and can run it like you would for any other branch.

Tutorial: Flexbox dividers with positioned labels over top

Leave a comment Standard

It’s so frustrating to make a horizontal ruler with label text positioned on top of it. There are many different ways to do it but they require a lot of custom CSS that makes it hard for you to easily move the label around to a new position if you need to. I’ve come up with a way to fix that problem using FlexBox and I wanted to share. This JsFiddle will let you select from a few different styles of horizontal rulers, whether it is a full span of fixed width and where the label should be positioned in just a few lines of code. Enjoy!

Highcharts Tutorial: Set Custom Tooltip Date Format

Leave a comment Standard
high charts custom date format in tooltip

I spent a good 4 hours trying to figure out how to get HighCharts to use a custom date in the tooltip without using the custom tooltip formatter. Geesh! Why is it so painful?? Anyways, here is a JSFiddle showing how you can add your own custom formats to HighCharts and then use them in the date formats on the tooltip. In this example I’ve added a %c and then I can use that anywhere in HighCharts that I want to use my custom date formatting.

http://jsfiddle.net/c9mm9505/4/

Jasmine Tutorial: Unit Testing Promises In Angular Services

Leave a comment Standard

So recently I’ve been doing a lot of Angular unit tests with Jasmine and Grunt. I have to say, testing promises is extremely frustrating and most of the examples I found out there either 1) didn’t work or 2) wouldn’t allow you to test content in a then block if you had multiple chained promises, or if you had a promise being called from and returned from another service. After many hours of frustrating trial and errors I found a solution I’m happy with so I want to share.

Let’s assume this is your controller:

'use strict';

angular.module('myModule').controller('myCtrl', ['$scope', 'api',
function ($scope, $api) {

  $scope.data = null;
  $scope.message = null;

  /**
  * Load some data from the API service
  * @return boolean
  **/
  $scope.loadData = function () {

    var config = {
      method: 'GET',
      url: 'http://api.domain.com/someRESTfulEndpoint',
      headers: {'Content-Type': 'application/json'},
      data: null
    };

    return $api.load(config).then(function (request) {
      if (request) {
        $scope.message = 'Your data was successfully loaded';
        $scope.data = request.response;
        return true;
      } else {
        $scope.message = 'The API service failed';
      }
      return false;
    });
  };
}]);

And here is the service making your API calls:

'use strict';

angular.module('myModule').service('api', ['$rootScope', '$http',
  function ($rootScope, $http) {

    /**
    * Makes the $http request given the proper configuration options
    * @param Object configruation for the $http request
    * @return Object $http promise that resolves to request payload or error
    **/
    this.load = function (options) {
      return $http({
        method: options.method || 'GET',
        url: options.url || 'http://api.domain.com/someDefaultEndpoint',
        headers: options.headers || null,
        data: options.data || null
      }).then(
        function (request) {
          //we got a response back, return just the API payload data
          if (request.status === 200 && request.data) {
            return request.data;
          } else {
            return {
              results: false,
              message: 'API request error',
              response: request
           };
         }
       }
     );
   };
}]);

Finally, this is your working unit tests:

'use strict';

describe('testing myModule', function () {

  beforeEach(module('myModule'));

  var $controller, $rootScope, $scope, $api, $httpBackend, $q;

  beforeEach(
    inject(function (_$controller_, _$rootScope_, api, _$httpBackend_, _$q_) {
      $controller = _$controller_;
      $rootScope = _$rootScope_;
      $httpBackend = _$httpBackend_;
      $q = _$q_;
      $api = api;
      $scope = $rootScope.$new();

      $httpBackend.when('GET').respond('test http GET call');
      $httpBackend.when('POST').respond('test http POST call');

      $controller('myCtrl', {
        $scope: $scope,
        $api: $api
      });
    })
  );

  it('has a $scope.loadData() function', function() {

    var testConfig = {
      method: 'POST',
      url: 'http://api.domain.com/endpoint',
      data: { some: 'data'}
    };

    var fakeData = { data: 'is fake' };

    //we spy on the API service and also return a fake promise call
    spyOn($api, 'load').and.callFake(
      function() {
        var deferred = $q.defer();
        deferred.resolve({result: true, response: fakeData});
        return deferred.promise;
      });
    });

    $scope.loadData(testConfig); //call the function we're testing in the controller
    $scope.$apply(); //we have to call this so Angular will try and resolve the promise
    expect($api.load.calls.count()).toEqual(1); //make sure it's called the api service
    expect($scope.message).toEqual('Your data was successfully loaded');
    expect($scope.data).toEqual(fakeData);
  });

  it('returns an error if the API fails', function() {

    var testConfig = {
      method: 'POST',
      url: 'http://api.domain.com/endpoint',
      data: { some: 'data'}
    };

    spyOn($api, 'load').and.callFake(
      function() {
        var deferred = $q.defer();
        deferred.resolve({
        result: false,
        message: 'api error'
      });
      return deferred.promise;
    });

    $scope.loadData(testConfig);
    $scope.$apply();
    expect($scope.message).toEqual('api error');
    expect($api.load.calls.count()).toEqual(1);
  });
});

Continue reading