Uncategorized

HamQuest Hiatus Halting? Island Interloper Interruption Initiating?

The topic of this post reminds me of the 60’s Batman narrator.

HamQuest and I have a rocky relationship.

Periodically, I look back at the code base, and see a number of areas in which I can improve things.

I get inspired to do so.

After a while, the things that I want to do to make the game more configurable or better organized or generally more engineered pile up into a insurmountable list of issues to resolve.

Inspiration wanes.

Eventually I abandon working on it for a while, and move on to other things.

I imagine the curve plotted by my desire to work on HamQuest (or really, any long range project) might look something like a graph of cos(x).

Since there are endless cycles of this, the graph is really cos(x+k*2*pi), where 0<=x<=2*pi. And k is the number of cycles that have taken place already.

So, I appear to be heading for x=2*pi, which means the cycle will reset, and I will do some work on HamQuest.

Which is actually a good thing, because my “x” value for Island Interloper is rapidly reaching “pi”, or the minima in interest level.

Is it possible to have a few projects that hit peaks and valleys in interest level in such a fashion that I simply need to switch between them?

—-

So, why a decrease in interest in Island Interloper?

A couple of things.

1) There is a reason that HamQuest is not written in JavaScript(I tried… believe me!).  What does this have to do with Island Interloper? The problem with writing something in a scripting language is that it isn’t compiled.  This is also its strength, as long as it remains at a small enough scale.  Island Interloper has achieved a scale where it has become difficult to deal with.

2) I also don’t really want to invest the time needed to learn one of the many debuggers available for JavaScript.  Generally speaking, my “debugging” of JavaScript involves the heavy use of “alert”, and the FireFox error console, and that’s about it.

3) If the end goal of Island Interloper is to operate online in a multi-player scenario, a JavaScript single player game isn’t going to cut it except for prototyping how the game should be laid out.

4) I think that the “correct” client to use is SilverLight, with a swappable back end that can either be used to store data to isolated storage or through the web, and this layer would be abstracted so that I could use the iso storage one during development, and the web one in deployment.  Plus, C# has a real debugger.

Uncategorized

Object Oriented Code Is Not Smaller In Size

I have a new version of Island Interloper up.  Dunno if it is an upgrade or downgrade from the last time I uploaded it.

It has still not reached feature parity with the previous attempt, but one can buy and sell commodities at different islands.

Really there are only three minor features to add back before parity is achieved.

One is the ability to “take note” of prices at various islands.

Two is the save and load feature, which really isn’t much of a feature at all, as it just dumps a string to a textarea.

Third is the feature that actually consumes resources as the sailing voyage goes on.  It is a key feature that adds the element of anxiety over limited resources.  It gets you asking if you have enough food to make it to the next island. It is very “Oregon Trail”-esque.

(Maybe I should add the ability to fish….)

Anyway…

If you want evidence that OO code is larger than equivalent non-OO code (and the previous version was not completely non-OO, it was part-OO), you need look no farther than the code for Island Interloper.

Previous version (not counting third party code used unmodified as libraries): 37.0 K

Current version(again not counting third party, and haven’t achieved feature parity yet): 46.1 K

No, it isn’t a huge difference, but it is over 20% bigger at this point.

Of course, my software size is measured in K, not M or G.  In JavaScript, code size is the same as software size.

Why more code?

Because the code is better organized.

Huh?

Imagine this:

Your game has a number of different things to deal with that make up the game state.  In Island Interloper, these things to deal with are primarily the avatar and the islands, at least at the moment.

In the old code, the avatar was part of the game object, and was accessed using some code like:

game.avatar

One of the properties was called “heading”, which stored an angle in which the avatar’s ship was going.

It was stored in:

game.avatar.heading

As you can see, this is not entirely OO, but not entirely not either.  There is no encapsulation.  It is simply a raw global variable for all to see.

In the new code, there is still a game object passed just about everywhere, and within it there is an avatar object, but now the avatar is an object of a class called AvatarObject.

And while “heading” is still a variable within the AvatarObject, there are also two accessor functions: getHeading and setHeading.

And of course, the avatar property of the game is accessed through a function called getAvatar, so to get the heading of the avatar, we go from:

game.avatar.heading

to

game.getAvatar().getHeading()

Which is already longer, and so that is where the extra size comes from.

—-

There is a company called InnoGames.  They are German. If you have been on Facebook, they had a massive advertising campaign for their game Grepolis.

I tried out Grepolis, and their other strategy game Tribal Wars.

I didn’t much care for either of them.

However.

I also tried out their OTHER other game, The West.

It turns out to be an ideal fusion of “Errand Boy”, “Sporadic Play”, “Base Building”, and so on that I’ve found.

Takes about 5 minutes twice a day to play.  I queue up about 6 hours worth of activities for my character to do, and it calmly ticks down the timer for the character to do them.

Unlike many of the other strategic browser based MMOs I’ve played (lots of Storm8 games), the games purpose is not (as yet) easily thwarted by something like investing in passive income sources. Instead, there seems to be a pretty progressive series of errand boy missions, plus adding in contributing to building the town one belongs to.

And it accepts mailinator.com email addresses.

Uncategorized

Better Living Through JavaScript Closures, An Example

function ConfigObject(){
	var vowels = ["a","e","i","o","u"];
	var consonants = ["b","d","f","g","h","k","l","m","n","p","r","s","t","v","w","z"];
	var minimumNameLength = 3;
	var maximumNameLength = 10;
	var islandCount = 1000;
	var minimumIslandX = 0;
	var minimumIslandY = 0;
	var maximumIslandX = 1000;
	var maximumIslandY = 1000;
	var minimumIslandDistance = 10;
	var maximumDockingDistance = 2;
	var currencyCommodity = "gold";
	var unknownIslandName = "an unknown island";

	this.getVowelCount = function(){return vowels.length;};
	this.getVowel=function(index){return vowels[index];};
	this.getConsonantCount = function(){return consonants.length;};
	this.getConsonant = function(index){return consonants[index];};
	this.getMinimumNameLength = function(){return minimumNameLength;};
	this.getMaximumNameLength = function(){return maximumNameLength;};
	this.getIslandCount = function(){return islandCount;};
	this.getMinimumIslandX = function(){return minimumIslandX;};
	this.getMinimumIslandY = function(){return minimumIslandY;};
	this.getMaximumIslandX = function(){return maximumIslandX;};
	this.getMaximumIslandY = function(){return maximumIslandY;};
	this.getCenterIslandX = function(){return this.getMaximumIslandX()/2+this.getMinimumIslandX()/2;};
	this.getCenterIslandY = function(){return this.getMaximumIslandY()/2+this.getMinimumIslandY()/2;};
	this.getMinimumIslandDistance = function(){return minimumIslandDistance;};
	this.getCurrencyCommodity = function(){return currencyCommodity;};
	this.getUnknownIslandName = function(){return unknownIslandName;};
}
ConfigObject.prototype = new Unserializable();

The above is a good example of what I was talking about in my last post.  Previous to my work today, all of the items that are now preceded by “var” were preceded by “this.”, which means if I were careless, I would be able to clobber the values if I used them as raw properties.  Now I can’t, as the only way to access them is to use the various getter functions.

I’ve also found other areas where I don’t want to expose certain variables to serialization, like the following:

function AvatarCommodityObject(theCommodity){
	var commodity = theCommodity;
	this.units = Game.Commodities.getCommodity(commodity).rollInventory();

	this.getCommodity = function(){
		return commodity;
	}
	this.getUnits = function(){
		return this.units;
	};
	this.setUnits = function(units){
		this.units = units;
	};
	this.buyUnits = function(unitCount){
		this.setUnits(this.getUnits()+unitCount);
	};
	this.sellUnits = function(unitCount){
		this.setUnits(this.getUnits()-unitCount);
	};
}
AvatarCommodityObject.prototype = new Serializable();

Here I have put commodity as a var within the function, and the getter of getCommodity will retrieve it. I cannot be set after construction.  The variable this.units will still get serialized as usual.  Functions never get serialized, and so are a non-problem.

My one remaining issue is the call to Game.Commodities.getCommodity().  I should not have to rely upon a global Game object, nor its subobject Commodities.  Indeed, the Commodities object should be passed in to this constructor.  This I’ll be refactoring shortly.

I feel as though I’ve “leveled up” my JavaScript.

Uncategorized

Better Living Through JavaScript Closures

My original design for the javascript version of Island Interloper, I had a rather simplistic serialization scheme.

All of the data for the game was in a global object called “game”.

This was all just data, so that it could be made into a JSON string and then stored elsewhere, and similarly come from a JSON string and parsed into the original object.

This works pretty well, but there were some issues with it.

  1. I had some functions within the game data. Function objects are not JSON-able, and would be lost when saving, and missing when loading.
  2. I wound up with a lot of rather unwieldy expressions, like game.islands[game.avatar.island].name and so on. After first wrapping this up into functions to make it slightly easier, I attempted wrapping them into proxy objects, which made it even uglier, so I decided to do a different design.
  3. Not all parts of the game object need to be serialized. The commodity list doesn’t change ever, similarly the list of ships and crew members.  Do not serialize what you don’t need to.

So, after this minor setback, I’m well on the way to having a better design.

Except that I think that some of the functions used within the objects that now comprise the Game object should make better use of closures.

For example, the createRandomName function is only needed by Game.Islands to generate a list of random names.

Also, currently everything relies upon the global Game object to get data from other aspects of the game, like utility functions and actions.  I think that closures would be another better way to get the data.  Time will tell.

Uncategorized

A Vacation to (nearly) Everywhere

I got back from my vacation last Saturday.

My wife and I went to (or through) Illinois, Indiana, Kentucky, West Virginia, Virginia, Tennessee, North Carolina, South Carolina, Georgia, Florida, Georgia again, Alabama, Mississippi, Tennessee again, Arkansas, Missouri, Illinois again, and then finally back to Wisconsin.

Fifteen states in seven days, if you count Wisconsin.  My original plan had been to also hit Louisiana, Texas, Oklahoma, and Iowa(and never actually hit the same state twice until returning to Wisconsin), but did not for a couple of reasons.  One, Hurricane Alex made for much rain in the gulf area, so after Florida I just headed back up to Georgia rather than going along I-10 to New Orleans as planned.  Two, my wife was a little tired of the big drive each day and wanted to enjoy stuff along the way.

We stayed in Winchester KY, Columbia SC, Largo FL, Perry GA, Jonesboro AR, and Hardy AR.

I recommend the Spring River Lodge in Hardy AR.

I recommend against the Motel 6 in Columbia SC.

The rest of the places we stayed were OK.

In a week, we drove over 2200 miles, which basically means living in a car.

——–

I started refactoring Island Interloper the other day. I decided that I was still early on enough to kind of switch gears with the pattern of development, which means rather than the super slow process of revising everything piece by piece into a more organized and consistent form, I decided to reimplement.  It is still in JavaScript, but I disliked some things about the way the code was (un)structured.

Uncategorized

Core Mechanics of a Trading Game

Got a change to work on and update Island Interloper.  It is also up on google code, which is the new home of the repository (migrated it from assembla).

At this point, I have the core mechanic in place, which is trading.

Interloper, like most simulation games, is all about managing limited resources. You start out with a “raft” that you can pilot solo and allows you to haul 3 tons.  You also start out with 1000 gold(the currency of the realm – I will probably lower this amount to increase the initial stress on the player), 100 units of food (each unit of food will feed one person for a day. A unit of food weighs 4.7lbs – a value I looked up), and you are docked on an island.  You don’t know of any other islands.

At the moment, there are no other commodities besides gold and food.  Fortunately, food is cheap, and you can buy yourself enough to fill up your raft, which then allows you to travel pretty far away without starving.

The first major task is not only to find another island, but to find another island with enough of a price differential in food for you be able to make a profit buying at one and selling at the other.  Hopefully these islands will be close together, but I have occasionally found islands that are 100 days apart, which cuts a bit into the round trip food price.

Unfortunately, one cannot milk such a price difference forever, because each time you buy a commodity at one location, the price goes up (fractionally, but over time noticeably), and whenever you sell, the price where you sell goes down.  Eventually the prices at ports A and B will narrow into non-profitability.  This means that eventually you will want to find a new island to trade at.  In the future, you’ll just want to find a different commodity to trade in, but once those are exhausted, it will be time to move on.

Eventually, you’ll want a bigger ship (not currently implemented). Bigger ships require hiring more crew (also not currently implemented), which brings up the overhead of moving things, which means you’ll need higher margin merchandise.  Eventually there will also be encounters will other NPC ships. It begins to sound an awful lot like the game Space Trader, which makes sense, because it was partially inspired by Space Trader.

So, at some point, I realize I’m going to need a final goal.

I’m also going to need a final delivery platform. While it currently exists as a JSHTML application, I think it may be better suited to a PHPMySQL thing that gets delivered on Facebook.  Then it could be made social and have a persistent world. I work with it in JSHTML because things are very easy to change.  Once aspects get more gelled, I think I can move it to PHP without having to mess with the tables all of the time.

If I go the route of PHP and Facebook, I’ll need to throttle how many turns people take. Likely that’ll have to take the form of Energy/Action/Mana points that allow one day of sailing.  This of course then means that there will need to be experience levels and such, because that’s how all of these games work on facebook.  Sporadic play.

Unfortunately, I’m also a sporadic developer.

Uncategorized

Island Interloper

Finally winding down with the end of spring/beginning of summer activities, and I got a chance today to work on something fun for a change. That something is a moderately ugly but at least semi-functional Island Interloper. While still in a rather rough state (and the “deleteme” folder is a guarantee of non-permanent placement), one can navigate the world, dock, trade (in food only right now, the margins are slim), and sail the ocean.

This particular incarnation of Island Interloper dates back to October of 2009 (at least, that’s what the Assembla SVN changelog tells me).  I remember at the time I was working on a C# command line version of Interloper, and decided that the unwieldiness of the console interface was just too much, and wouldn’t it just be so much easier with a GUI straight away, which will eventually always lead me to making something in JavaScript.

Speaking of SVN…. I was doing a search today for a Mac SVN client (with a nice GUI… something equivalent of Tortoise SVN for windows). While I found SmartSVN, as well as a number of others, I have not found one that is free. It looks like I may need to learn to use the command line in about 31 days, when the trial elapses. Applications like Island Interloper don’t justify the cost of paying for an SVN client that will only work on 1 of the 4 machines I develop with.  Plus it is a good thing to know the command line syntax for SVN, I just know it.

Speaking as well of JavaScript. After using NotePad++ as my IDE (really just a “DE” – no “Integrated” to speak of), the rough equivalent of which on the Mac is Text Wrangler(which is still a fine tool), I have decided to move to Aptana Studio, although at the moment, I’m using it more like NotePad++ and less like how it is intended.  Over time, I’ll gradually shift over to using more of the built-in functionality. Works the same on both PC and Mac, so I can switch-hit my development on both.  Plus I have WAMP on my windows boxes, and MAMP on my Mac, I’ve got equivalent environments.

Speaking of switch-hitting. In using the Mac, at first I was somewhat hobbled by a couple of things. the first was Windows key (I use a Windows keyboard on my Mac) was basically like the Ctrl in windows.  Switching back and forth caused a number of typing errors and task menus popping up and other bizarre things that generally made me less productive. Fortunately, the Mac gives me a way to change it to more closely match my Windows layout. The second major item was the Home/End situation. I could not get used to Ctrl + arrow to replicate the Windows functionality of Home and End. Fortunately, the Mac allows me to change those around as well. There is a global setting, and from time to time I have to switch the functionality within a particular program. I feel this is rather accommodating on the part of the Mac, really. I know that there are a number of Mac fundamentalists who sneer at those of us who remap these keys from the “one true way” that they should be, but hey… I work at a job where I develop for PC all week. Using a Mac earns me nothing at the moment.