Wednesday, May 20, 2026

Highlighted Blog Posts Over the Years

Some selected posts


A Developer's Life Stages - a taxonomy of developer growth from under-engineering to over-engineering to mature simplicity.

Underengineering Undead - a candid postmortem of an unfinished Ultima-like RPG whose lack of architecture made it unfinishable.

Some Perfect Hash - a perfect-hash optimization for Cactus Kev’s poker hand evaluator that substantially speeds up five-card evaluation.

NCAA 08's Video Highlights - a behind-the-scenes look at building in-game video highlight capture and upload under tight console constraints for EA's NCAA 08.

Times of Lore Maps - a nostalgic post sharing extracted maps from the PC version of Times of Lore.

Indigo Ocho - a brief App Store note for Indigo Ocho, an eight-ball adventure game set around a dangerous tower.

Sieve of Eratosthenes - an optimized C++ (and assembly) prime-counting sieve written for an EA programming challenge.

Poker Revisited + ESPN - a short update linking the old poker evaluator work to Coding the Wheel’s roundup and mentioning ESPN virtual play-by-play work.

Let Me Count the Ways - a dive into fast enumeration of combinations, moving from brute force to bit-level and recursive/iterative optimizations.

Let Me Count the Ways Part II - a follow-up showing that the optimized combination generator is ultimately bottlenecked by memory bandwidth.

The Relic - a launch/postmortem overview of The Relic, a solo-built 3D iOS action RPG published by Chillingo.

7 - an exploration of fast seven-card poker hand evaluation using compact indexing of 52-bit card sets.

JSON Parser for Objective C - a simple Objective-C JSON parser built on the earlier string code.

C String Library for C and Objective C - a minimal C string utility library adapted for Objective-C and C++ work.

Java-Style Properties Files in C++ - a small utility release for reading Java-style properties files from C++.

A Little 2D Map Matcher

I wrote a small 2D map pattern replacement utility.

It's simple, but solves a problem I keep running into with procedural world generation. You can generate a perfectly valid 2D tile map, but it often has that raw, algorithmic look. Water touches grass. Mountains abruptly become meadow. Rivers stop being rivers in awkward places. The data is fine, but the world needs another pass.

So this tool is that pass.

It is here on Github.  This is currently just a MacOS XCode project, but I'll eventually set it up with CMake for cross-platform building.

The input is a very simple text map format, .m2d, containing tile indices. Right now that is basically the only map format it supports, which is fine. The script file, .m2s, describes patterns to find and what to replace them with. The program reads the map, applies the rules, and writes out a transformed map, along with TypeScript output for the project that consumes it.

The example here uses Ultima V tiles. In the first image, the map is already recognizable as land and water, but the coastlines are harsh. The map is made of legal tiles, but it does not yet have that pleasing old RPG coastline logic where deep water becomes shallow water, shallow water touches a shore tile, and the edge of the land knows which direction the ocean is.

Before the replacement pass, it looks like this:


After the replacement pass, it looks like this:

Much better.

The script starts with named lists:


lists

deep         = 1

shallow      = 2

shoals       = 3

water        = deep|shallow|shoals

swamp        = 4

meadow       = 5

shrub        = 6

grasses      = swamp|meadow|shrub

land         = flatland|mounts

shore_w      = 51

shore_s      = 50

shore_e      = 49

shore_n      = 48


This is mostly to keep the rules readable. I do not want to remember that 1|2|3 means water every time I write a rule. I want to say water.

Then come the rules. A rule is just a little rectangular pattern. Each cell is find:replace. If there is no replacement, it just means find. Wildcards are supported with ? or *.

For example, one early rule turns land next to water into shoals:


water        land

water        land:shoals

water        land:shoals

water        land

There are other rules for removing one-tile islands and promontories, placing the correct directional shore tiles, fixing rivers, and cleaning up mountains. The rules are applied in order, which is important. First you make rough decisions, then later rules refine them. This is the way I tend to think about procedural generation anyway: build a crude version, then gradually make it less ugly.

The implementation goal was also modest but deliberate. I wanted to write it in modern C++, without the old habit of scattering new and delete everywhere. The map is just a small generic map2d<T> backed by std::vector. Files are read into strings. Rules are parsed into objects. Storage owns itself. The code leans on RAII instead of manual cleanup.

That sounds obvious now, but if you have written C++ long enough, you know it was not always the default style. There was a time when every little utility wanted to become a memory-management exercise. This one does not. It reads a file, transforms a map, writes a file, and exits. No ceremony.

I also like that the script format is crude in the right way. It's not JSON or XML. It's not a beautiful general-purpose language. It's a little thing for describing little grids of tile indices.

That said, it already gets surprisingly expressive. The coastline example is the obvious win. The original map has land and water in the right places, but the tile transitions are wrong. The transformed map gets shoals, beaches, shore corners, and more convincing edge behavior without needing the original generator to know about every possible local tile relationship.

That separation is useful. The world generator can think in broad strokes: continents, islands, forests, mountains, rivers. The matcher can think locally: “this water tile has land to the east, so make that land a west-facing shore.” Those are different jobs.

The next obvious improvements would be support for more map formats, better diagnostics when a script rule is malformed, and maybe some way to visualize which rules fired. I could also imagine adding probabilities, so a rule could replace a matched pattern with one of several tiles. That would make it easier to break up repeated edges and add a little controlled noise.

For now, though, it does what I need.  It takes a rough procedural map and gives it one more pass of tile-level intelligence. The result still looks like a map from an old computer RPG, which is exactly the point,

Monday, February 10, 2025

Pivots

It’s been a very long time since I posted.  It’s a different world now.

Ten years ago, I was contacted through Meetup by Matt, an entrepreneur and developer who had previously started a successful online test administration company.  He had cashed out and just secured seed funding for his next idea: an “Uber for Doctors.”  I signed on as an iOS developer, employee #1.  A few weeks later he hired Brandon, an Android dev, as #2 and we started working out of a literal garage in the Baldwin Park neighborhood of Orlando.

Over time, we made a few strategic pivots.  We became a SaaS focusing on telehealth, patient notifications and forms.  Instead of just mobile development, we built the whole stack.  Covid came in 2020 and truly tested us.  It was a tremendous amount of work but today our company is a multimillion-dollar-a-year patient engagement platform.

It’s been an interesting road for me.

The iPhone


In February 2007, I was doing console game development at Electronic Arts, and they sent some of us to the Game Developer’s Conference in San Francisco.

In a diner on Market Street, a colleague of mine pulled out his brand-new iPhone, typed in en.wikipedia.org and showed it to me. It was the full desktop version. I was transfixed.

Later I met another developer at EA who was writing games for the iPhone on the side.  Apple was not yet distributing apps from third party developers, but they had released the SDK beta and he was preparing his games for release as soon as the App Store opened in summer 2008.  They were straightforward 2D arcade games.  Once the store opened, he started pulling in huge amounts of money on a monthly basis.

The iPhone, in my mind, was the dream device for the individual game developer.  It brought back all the promise and joy of the days before and around the time of Doom and Quake and Unreal when a single developer could still make a game that would be a success on their own.

The first device I bought was an iPod Touch — which was an iPhone without the phone.  I still remember the elation of having my own full 3D game running on a device I could hold in my hand.

Indigo Ocho


I released my first iOS game, Indigo Ocho, in early 2009 to poor sales, but great reviews.   I was late, and my game landed among many others in a deluge of new entries in the store, many of them backed by sophisticated marketing.

My successful friend had chastised me for building a 3D game.  “It takes too long, you have to strike while the iron is hot.”  He was right, of course, and he had seen his sales dwindle significantly as time passed.

I was approached by another small studio to collaborate on an updated version of the game that they would market.  They helped improving the art and we produced a better looking version.  We released that to poor sales as well.  When we temporarily made it free, it was downloaded twenty times more frequently than when it was priced at $.99.

It caught the attention of a company called Chillingo.  They were not interested in trying to remarket Indigo Ocho but they were impressed by it and wanted to collaborate on a multiplayer Gauntlet/Diablo style game.  That initial idea would eventually become The Relic.  My relationship with Chillingo became a little tricky because at the time they were acquired by EA, I was still working at EA, and I wasn't supposed to be moonlighting...

Eventually I struck out on my own and started Axolotl Studios for my games and other contract apps.  During that time I built a couple other games for clients.  I also built white-label banking apps, sports apps and apps for security checks. I even built a few for Android and BlackBerry.

It was at the end of this time that I saw Matt’s message in the Orlando iOS Developer’s Meetup board and my life moved away from games and apps.

Sunday, January 10, 2016

LPT: How to Convert °C to °F in Your Head

These are quick math tricks to make certain day-to-day calculations much easier.  Sometimes you need to convert temperatures in Celsius (centigrade) into Fahrenheit.

The formula I learned in elementary school was °C * 9/5 + 32, which is not particularly amenable to calculating in your head.  Here's how to figure that in your head without multiplying.

Let's say the temperature is 7°C.

  • Calculate 1/10th (10%) of that.  Ten percent of a number is simply that number with the decimal place shifted left one spot.  So ten percent of 7 is 0.7
  • Subtract 0.7 (1/10th) from 7 = 6.3
  • Double 6.3 = 12.6
  • Add 32 = 44.6
  • 7°C is 44.6°F


How does this work?


In the original formula 9/5 = 1.8.  Half of 1.8 is 0.9

If you subtract 1/10th of the original number from itself, you get 0.9 * °C.  Then when you double that, you get 1.8 * °C.

After that, you merely need to add 32 to get the Fahrenheit equivalent.  Going the other way (°F to °C) is a little more complicated, and I will get to that in a subsequent post.

LPT: How to Calculate a Tip in Your Head

These are quick math tricks to make certain day-to-day calculations much easier.  When you eat at a restaurant, you'll typically tip your server.  Here's how to figure that in your head without multiplying.

Let's say the bill is $12.34.


Calculating an Exact Tip


  • Calculate 10% of the bill.  Ten percent of a number is simply that number with the decimal place shifted left one spot.  So ten percent of 12.34 is just 1.234 (round to 1.23).

10% tip:

  • Tip is $1.23

15% tip:

  • Start with the 10% of $12.34: 1.23.
  • Now cut that number in half to make 0.615 (rounded to 0.62).  This is 5% of the bill.
  • Add 1.23 and 0.62 together to make 15%:
  • Tip is $1.85

20% tip:

  • Double the ten percent: 1.23 * 2
  • Tip is $2.46



Easier Approximate Tip


That said, I typically approximate using only the dollar value, because it's easier.
  • Round up to $13.  Calculate 10% of 13.  Ten percent of a number is simply that number with the decimal place shifted left one spot.  10% of 13 is 1.30

10% tip:

  • Tip is $1.30

15% tip:

  • Cut 1.30 in half to make 0.65.  This makes 5% of the bill.
  • Add 1.30 and 0.65 together to make 15%: (1.30 + 0.65)
  • Tip is $1.95

20% tip:
  • Double the ten percent: 1.30 * 2
  • Tip is $2.60

Saturday, May 30, 2015

Fibonacci Code Golf

The other day, one of my colleagues said he'd once been asked to code a function to produce the nth fibonacci number for a job interview.  We got talking about the shortest possible function to do this.


A fibonacci number is the sum of the two previous fibonacci numbers.  The first and second fibonacci numbers are defined to be 1.  That makes the third 2 (1 + 1), the fourth, 3 (2 + 1) and the fifth, 5 (3 + 2).  Cake.

1, 1, 2, 3, 5, 8, 13, 21, ..

Beautiful, Recursive and Horribly Inefficient


A clean and simple implementation in C might look like this:

int fibonacci(int n)
{
    if (n == 0) 
        return 0;
    else if (n == 1 || n == 2) 
        return 1;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

Since I'm not a golfer, and code golf and mini golf are the only kinds of golf I play, I came up with the following in (bad) C.

f(n){return n<3?1:f(n-1)+f(n-2);}

Now, this one isn't correct for 0, which should return 0, so let's revise it at the expense of four more characters.

f(n){return n<3?n?1:0:f(n-1)+f(n-2);}

That works.  Kind of.  The highest n you can pass it is 46 (returning 1,836,311,903), because after that it overflows the 32 bit signed int (which holds a maximum value of 231-1 = 2,147,483,647).

Okay, but the real problem with these functions is how phenomenally slow they are.  You wouldn't be able to get much past 46 anyway without rendering your machine absolutely useless.  This is a classic recursive function, that is, a function that calls itself.  This fibonacci function itself is often used to demonstrate the elegance of many functional languages.  For example, here it is in OCaml:

let rec fib = function
  | 0 -> 0
  | 1 -> 1
  | n -> fib (n-1) + fib (n-2)

As it turns out, to calculate f(46), you end up calling f() 3,672,623,805 times!  f(47) makes 5.9 billion and f(50) makes nearly 20 billion calls.  The recursive fibonacci sequence grows in number of calls on the order of 2n, which makes it roughly equivalent to the rice and chessboard puzzle.

Ugly Lookup Table


So we need to rework it and make the shortest version that isn't super inefficient.  Since 46 in the maximum n that fits in a signed 32-bit int (and 47 unsigned), we could just make a precomputed look-up table.

int fib(int n)
{
    static int fibs[] =
      { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 
        610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 
        46368, 75025, 121393, 196418, 317811, 514229, 832040, 
        1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 
        24157817, 39088169, 63245986, 102334155, 165580141, 
        267914296, 433494437, 701408733, 1134903170, 1836311903 };
    return fibs[n];
}


That's as fast as you're probably going to get, but it's ugly and not particularly short.

Iterative and Fast


You can also do it iteratively, without any recursion at all:

int fib(int n)
{
    if (!n) return 0;
    int p = 0, q = 1;
    for (int i = 2; i < n; i++)
      { int t = p; p = q; q = t + p; }
    return p + q;
}


It's starting to get a little longer, though, so I don't bother to shove it on one line or abbreviate int fib(int n) into f(n) like with the shortest ones above.  This function can be literally billions of times faster that the first ones.

Returning to Recursion, with Memoization


But..  I've got a short recursive version that outperforms this one on the whole, especially when called more than once, because it builds up a look-up table dynamically, with a simple technique broadly called memoization.

f(n){static int m[64]={0,1,1,0};return !n||m[n]?m[n]:(m[n]=f(n-1)+f(n-2));}


Fast and short.

No Recursion, No Iteration, Just a Formula


Let's do one more.

There is a closed form calculation of the fibonacci number that requires neither iteration nor recursion.  You just calculate it and there you go.  Here is my shortest implementation of that:

f(n){double A=sqrt(5),B=A/2;return(pow(0.5+B,n)-pow(0.5-B,n))/A;}


Short.  No iteration, no recursion.  Over several calls, I figure this will be slower than the previous function, but it's way slicker.

Saturday, January 31, 2015

The Book of Sand

Argentine literary genius Jorge Luis Borges ('magic realist') is one of my favorite writers. Borges unravels the many human uses of information within a universe that is mystical and mathematical at once. His work illuminates the way we, as human beings, struggle to capture meaning - any meaning - from infinite quanities of data. Borges explores ideas such as the recursivity of mirrors, points in space containing all the universe (The Aleph) and man's struggle to find meaning in endless information (The Library of Babel & The Book of Sand).

For many software developers, creation of software, while frequently mundane, is still very much an aesthetic pursuit - an art. When a piece of software is 'beautiful' it is so in the same way that a Borges short story is beautiful, and in a very different way than a Dostoevsky short story is beautiful (which is the gut-wrenching, depth-of-human-suffering-and-existential-torment sort of way) or in the way a Hemingway story (the depth-of-human-suffering-but-don't-actually-ever-say-it sort of way) is.

A Prediction from 2007

In 2007, I wrote a post called --

Xbox 360, PS3 Games Unplayable on Future Hardware?

Where I concluded that, due to technical reasons detailed in that post --

.. I suspect that far more Xbox 360 and PlayStation 3 games will be unplayable on future hardware than Xbox and PS2 games on the 360 and PS3.

Unfortunately, I was right, as we've known since before the new hardware was released nearly a year and a half ago.  The Xbox One and PS4 are capable of playing exactly zero binaries built for their predecessors.

But just because we saw it coming doesn't make it any less painful.  Once our older machines die, how will we play those games we love?

Java-Style Properties Files in C++

(Originally posted Feb 28, 2008)

Need to handle Java-style properties files in C++? I've decided to post some of my own personal library of code on this blog. This is one of those occasionally useful things.

javaproperties on github

If you fix any bugs, extend the code or anything else, send back your changes if you don't mind. ;)

Tuesday, January 13, 2015

Monday, January 05, 2015

Surge of Video Game Nostalgia


When I was a wee lad in the mid 1980s, Compute! magazine would run ads like this.  Box cover art is what sold it back then, I'm telling you.

Saturday, January 03, 2015

Friday, January 02, 2015

Ideas Are Cheap




This has been on my mind lately regarding mobile app ideas.  Or as Thomas Edison most famously put it,

"Genius is one percent inspiration, ninety-nine percent perspiration."  

These days it seems like 99.999% perspiration.

Friday, August 22, 2014

Rapunzel's Tower

 Made a game for my kids, based on Indigo Ocho.  It's called Rapunzel's Tower.  It's basically a reskin. 





Friday, January 31, 2014

I Was An Atomic Mutant

(Originally posted 2006)

I bought this PC game a few years ago at a Wal-Mart in Lee's Summit, Missouri for $3. The gameplay is repetitive and the in-game graphics are unimpressive - but it hooks me. It's a ValuSoft title developed on a shoe-string. A single developer is credited for the engine. Its redeeming strength is that its atmosphere totally captures the 50's and 60's era sci-fi and monster movies it imitates.

Thematically the game resembles Destroy All Humans! and Destroy All Humans! 2, which are far better games but don't quite nail the atmosphere of old sci-fi flicks like this does. The Destroy All Humans! are too self aware to fully capture those movies. Another game with a similar feel is Godzilla: Save the Earth which, while clearly much more polished, scores one point below Atomic Mutant on Metacritic (64 vs. 63). And I Was An Atomic Mutant scores a full thirteen points above our own vastly ambitious but ultimately underwheming Superman Returns.

So what does this mean? It would be irresponsible to draw any conclusions from this example, but it is interesting.

Saturday, July 14, 2012

JSON Parser for Objective-C

Building on the string code in the previous post, here is a simple Objective-C JSON parser that I use a lot.

Json.h, Json.m at GitHub.

Friday, July 13, 2012

C String Library for C++ and Objective-C

In the last couple of years I've shifted professionally to iOS development.  In doing so, I adapted some of my previous code for use with Objective-C.

I converted my super minimal C++ string library, consisting of basic string manipulation and parsing functions, back into pure C so that I could use it more conveniently with Objective-C as well as C++.

You can find strs_c.c, strs_c.h at GitHub.

It is intended to be very basic and small, so there's no regex or anything like that.  There are string splitting and list handling functions, searching functions, trimming, parsing, etc.  I have further libraries building on top of this for more sophisticated tasks.  For example, an Objective-C JSON parsing library that I'll post right after this.

Tuesday, May 24, 2011

Cholera

People talked of the days of cholera, of Xochitlán's baptism in a great flood of diarrhea and vomit.  In those days there were wives and husbands, children, mothers and fathers just gone.  The water was unclean and there is no deliverance from water. 

They said one-in-four perished.  I didn't believe in the 1990s a medieval epidemic wiped out a town like this with no peep heard elsewhere.  The government underreports outbreaks and it was an unbearable tragedy here whether one in four or one in forty.  Xochitlán's torment was in the still dirt streets, the ramshackle homes at the periphery, the dust-blown open market and in the church of broken walls that stood as the headpiece of the town square called the zócalo.

It was three years after the epidemic.  Sweat soaked our shirts as we raced again in the sun past men with straw hats plowing and harrowing new milpas and breaking up dark soil beneath the pale dust.  We slowed to saunter at a reverent pace as we walked those streets near the graveyards where from time to time other men with straw hats, muscled from years of labor, would stand quietly with calloused hands and infected nails clutching their deep-lined faces or kneel at wooden crosses and weep.

Wednesday, March 16, 2011

The Relic

In the App Store April 14, 2011!

The Relic is a 3D Gauntlet- or Diablo-style arcade RPG developed by Axolotl Studios (aka me) and published by Chillingo. It runs on iPhone and iPad. It's taken too long to develop but it is currently in submission with Apple and will be released within the next few weeks. I'm proud of it. There are those projects that you create that turn out far better that you had hoped and this is one of them - for the most part. Like all your creations that you know intimately, you know its flaws. One big disappointment was having to cut multiplayer.

Multiplayer is not in this release. I spent months working on it and got it working reasonably well but the architecture was a mess and it was hard to fit the rest of the game around it at that time and it was getting later and later. I was starting to believe myself that the game would never be released, so I cut it. I intend to get it in in a future update. 

And Death Shall Have No Dominion

Life is about attachment and detachment.  We're born; we love; we die.  Yet science in our age hints that even death itself may yield to the relentless advance of technology. The Relic explores the concept of immortality and of mastery of the biological in an unexpected, though admittedly minimalistic way. I'd like to add more depth and nuance to the story in future updates.

The Art of The Relic

Mark Jones created the character art and most of the animations. Some of the environment art (the tents and market area) was stock 3D art and well worth what I paid for it.  In the future I will use stock art more, it's more cost effective that creating my own art or paying for custom art.  I created the dungeons themselves and props such as the crates and barrels and the items that can be dropped, some of the animations, the UI art and the logos. Much of the scene art, the intro, etc. uses art adapted from public domain art sources - that is, famous, old works of art.  I used Blender for the 3D art.

The Music of The Relic

Most of the music in The Relic is stock music, however, The Relic includes two songs by indie songwriter and musician Andy Livingston, "Indigo Winter" and "Heavy."

The Code of The Relic

One of the most successful parts of The Relic's engine is the sheer number of animated 3D enemies that it can handle. The Relic engine uses Lua heavily for game-side scripting, but it is organized in a way that does not interfere with The Relic's ability to manage so many enemies.

I'll write more about coding concerns later, but with 438 source files (not including the Lua files), this is certainly the largest software project I've written entirely by myself. It's written primarily in C++ and I did most of the development on Windows PC with Visual Studio and occasionally testing with the iPhone with platform-specific pieces written in C++ on the Windows side and Objective-C on the iPhone/iPad side. As with Indigo Ocho, near the final stages of development, development shifted completely over to the Mac/iPhone.

The Relic (iPhone 4 screens) [on facebook]






Friday, March 11, 2011

Indigo Ocho

Indigo Ocho has been out of the App Store for some time now, and now that The Relic is done, I'll try to get Indigo Ocho back up there.

Indigo Ocho on the App Store.

Join in the adventures of Indigo Ocho, the eight ball on a quest to destroy a labyrinthine tower threatening to wreak havoc on the human world.

I'd like to write more about Indigo Ocho, and hope to get around to it in some future post.

Indigo Ocho [facebook]