Friday, May 27, 2016

Tech Trees

"Survival" is a new genre. For a while, it was just Minecraft. But now the genre has taken on a life of its own: survival with dinosaurs, survival in space, 2D survival, 2D survival in space, Son of Revenge of the Bride of Survival, ...

The three basic elements are fending off the elements and bad guys, building a base, and climbing a tech tree. Other than sandbox (diorama-building) and achievement-hunting, both of which can go on practically forever, the "game" is over when you reach the top of the tech tree. Some games have game levels (Minecraft is one such, but generally I'm thinking of games like Portal Knights) and so the game is "over" when you reach the top level and beat the last boss.

To me, though, the "proper" gameplay in a survival world is cooperative multiplayer, with a standalone server. Some like PvP servers, and although that's not my thing, I'll grant it's valid and important.

Hence: the width and breadth of the tech tree is the game.


Breadth can have several different implementations. In some games, every character learns the entire breadth of the tech tree. In games where the limit is in resource types, and there's no research or tech tree proper -- just the raw resources themselves -- then that breadth is just providing options; everyone has access to them.

Another implementation is to require players to specialize, perhaps via a class-based mechanism. Players only climb the tree in the areas they have access to. Maybe there's variation within the class, but that's a secondary concern. Generally any class-based game follows this model, and it's not one that I've seen much. You see it in RPGs all the time, but not often in Survival. I think I've seen this once but I don't recall the game. So maybe I'm just making this up? Anyway, if unexplored, then it's a novel gameplay option!

I think the most common implementation is to give players just enough points to specialize in a portion of the tech tree; hence a well-run base is one run by several people, each with their own specialization. Often the way "around" this limitation is just by gaining levels; if you really do want everything, you'll get it, it'll just take longer.


Height, of course, varies. Minecraft is both narrow and short; you can get to the highest tech tree in a couple hours of play. Diamonds take more determination than diligence or skill to acquire; you don't need to laboriously climb your way up to them.

Empyrion has a well-staged height to its tech tree: first there's survival, then base-building, then ground-based vehicles (Hover Vehicles), then small ships, then capital ships. Each step expands the range that the player has exponentially -- which is hard to do too many times. Generically, these might be: village, state, country, planet, solar system, galaxy, universe. One might take a few steps there, eg inter-system travel might initially be limited to system-to-system (as it is in Elite) and then later progress to being able to jump across many systems (hundreds of light-years, or thousands, up to the 150 thousand light-years from one end of the Milky Way to the other). In factors-of-ten, that yields six steps between closest-neighbors to cross-galaxy. Then throw in travel to other galaxies (but man, would you want to model that?) In a game that starts with just you and a suit on a planet, managing 400 billion stars is ... out of scope. No player will visit them. No army of players will visit them. There's no way to manage it all. If I had ten million players, and they each played my game for ten years, and they each visited a new star (and never the same star twice), then they'd see them all. But then... each player will have visited 1000 stars but not left anything behind. How would you manage that? Are you making a strategy game or a survival game?

Let's go the other way; back to prehistory. Among mankind, technological progress might be: wood tools, stone tools, early iron tools, copper and bronze, late iron tools, steel and steam, automation and factories, analog circuits, digital circuits, and then dozens of generations of digital circuits, and then the video-card evolution... What's next for us?


There's another twist to height: in MC, once you've gotten diamond gear, the next step is to head to the Nether and start brewing potions and enchanting gear. Hence there's really three stages: normal crafting, enchanting, and brewing. This is kinda like human progress: we went from simple stone tools up to steel, but then the frontier of material science changed to alloy steels, other metals, plastics and polymers, and ceramics. Top-end planes and spacecraft aren't made from Plutronium or some random exotic element, but from ceramics and exotic alloys -- often of non-ferric metals.

I'm going to call this "Mode." While playing a game, you might transition from one sort of advancement (materials) to a different type (alchemy). In modern and future genres, Modal changes are a switch from resource gathering to improved production methods.

Great, so you mined iron and can produce high-purity steel (in a Space-based game), but so what? What's next? Consider what else you mix in, and why: corrosion resistance, hardness, machinability, strength, melting point. And I don't know enough about exotic ceramics to even start there. But alloys, ceramics, polymers, and plastics are easys way to add more tiers to a terrestial-based tech tree, and perhaps a useful step in extending gameplay for space-based games.

Polymers are, then, like enchanting or alchemy: you use metals for one thing, and polymers for another. (Metals often where resistance to shocks is required, and ceramics where cost is no object!)

OK, so let me come back to the point here, which is extending gameplay. What happens when you get to the top of the tech tree? Many players get bored and move on. Fun is when you're not bored; I think I wrote a blog post on that a decade ago. If there's nothing new to explore, nothing new to discover, then explorer-type players get bored. Power-based players will give up if they can't get an even more powerful weapon. (They don't care if the remaining "advancements" are just cosmetic, or simplify production.)

Widening the tech tree can make it easier to get multiple players together, and to provide a valuable sense of purpose to players. This can also give players a reason to re-play the game; to start over and try a different branch of the tree.

Heightening (? lengthening?) the tech tree extends the number of hours players will put into the game. You could just add multiple different areas that provide the same high-end material that differ only cosmetically, and this does extend gameplay a bit, but it's often very resource-intensive to add those bits to a game. Adding a new tier of gear tends to be easier.

One other way to extend gameplay is to add end-game content. Yet, in RPGs, this is just a modal change: players switch from leveling their character to leveling gear: a switch from char level to ilevel. For players in a survival game, once they've gotten the biggest, most bad-ass gear, then what else is there to do? Go defeat the toughest monster -- but if you have the best gear, then that's that.

Wednesday, April 27, 2016

Now Certified

As mentioned previously, I took the Unity Certified Developer exam on Monday. Passed! Yay! I am now certified.

First, a few notes on the exam:

  • If you can schedule time to take the test, take it!
  • It's all multiple choice, matching, and hot-spot identification. No essays or written answers required.
  • After the tests in a couple days, there's two in Bogata next month, and then tests in Amsterdam in June. It'll be a while before the exam makes its rounds again.

The tricky thing is that there isn't any courseware for the exam yet. There's a 3-page sheet of Exam Objectives, but that's mostly a thin gloss. The exam difficulty, to me, felt really spotty. Some sections had two questions that, if you read one page in the manual, would be trivial to answer. Other sections had a dozen questions or more and required some very specific knowledge, down to what keys to press to do certain things and how the compiler would feel about a handful of statements.

The next certifications that they add are going to be interesting; there's the Pro Programmer, Pro Artist, and Expert certifications that they've mentioned -- although there's no guarantee that those exams will be released, and no timeline for when they'll add them. Right now, I think, having the Certified Developer certification will be a rare thing on a resume and hence pretty useful. It's proof that you know your way around Unity. If all you did was watch an hour of video or played with the app for that long, there's no way you'd pass the test. Walking through the Exam Objectives was, to me, critical, as it made sure that I looked at features that I don't use day-to-day. Cloud Build? Navigation? I understand them loosely and I looked at videos years ago (well, not for cloud build; tho I did go to a meetup that discussed it) but I don't use these things. Passing the exam meant knowing these systems in some detail.

Which means the advanced tests are gonna be brutal.

As a programmer, I thought I'd have an easy time with the Programming section. Just for this basic test you'd have to be able to write a blog post on any of the sub-topics listed in the Objectives to get questions right. What's the Pro Programmer test gonna do?!

I'm still cleaning up my notes, and I'll be posting them here. I can't give away the text of any of the questions, but I'm going through the sections making sure that I covered what the test covered.

Monday, April 25, 2016

I'm Gonna Take the Unity Certification!

Scheduled later today! Unity just started offering the certification, and for right now there's just this one certification. They suggest that they'll later offer Professional Programmer, Professional Artist, and Expert certs, but for now it's just the one. I figure it'll serve as proof that one's at least gone through a set of tutorials and has played with all of the major bits of the engine. As someone that's been a Senior Engineer for over a decade it might seem odd that I'm taking the cert, but since I haven't yet gotten paid for any of my Unity work I'm actually in the target market. (The other major cohort would be college students or new college grads.)

I've been going over review material for the past week and I took extensive notes, with the idea of sharing them here. Once I take the test, I'll go back over each of the sections and review them to make sure they're actually relevant for the test. Look for those posts over the coming weeks.

One of the weird things to note is that you're required to bring a wifi-enabled laptop to the test. I guess a Chromebook would work, but I doubt that an iPad would. Dunno. I expect to see laptops, since that's what all the kids use these days. :P

The scheduled time is two hours, but evidently the test starts a half-hour after the start of that block, so the test itself I guess is limited to 90 minutes. Prior to that is "make sure your laptop works for this," I guess. I looked at the refund/retake policy and it seemed to be "you can only take the test once," so failing it doesn't allow you to freely retake it but I have no idea if technical difficulties established prior to the start of the test would suffice.

It does cost $250. For a starving post-college or non-college student that's a good chunk of change, but, again, I think the certification itself is great proof that you actually know your way around the engine.

So, who here is thinking of taking the certification? Or has already taken it? Raise your hands!

Monday, October 13, 2014

Getting Started with Git on Windows

I'm gonna assume you have a day job and you need to get Git working on a new machine and/or a new repo, i.e. where the point of the exercise is either to (A) back up your code into the cloud, possibly for sharing; or (B) download a repo that someone else has already created (e.g. your coworkers) and start working with it. I'm writing this post because I find myself going through the following steps every 4-6 months and frustrated trying to pull together all the crap I need, especially when I get dumb errors like the ubiquitous "permission denied (publickey)". If that's you, this guide should help.

Further, these instructions are for the Git Bash / Git GUI set of tools. At home I'm using Source Tree, so some of this stuff is similar, and if that's what you're doing there's some clues below that might help with errors you get.

BTW, another common case (let's call it C) is to use Git with an op*n-source project but there's tons of samples out there for getting involved in op*n source -- in which case you're usually forking an existing repo and doing an entirely separate code-submission thing, so I leave that to other people to explain.


1. Get GitBash and GitGUI from github. The windows command prompt is ... a dodgy thing. I much prefer using bash, party because you get cool Unix tools in the bundle.

2. Open up GitBash. Set your name and email (btw the $ is just an indicator that this should be done at the bash shell prompt).
$ git config --global "Your Name"
$ git config --global ""
3. If you have a new, unversioned project and want to create an online repo for it, eg to back it up to GitHub or Bitbucket or Codebase or wherever, you need to create a new local repo; that's the way Git works. Move (cd) into the root directory of the project's folder hierarchy, and run:
$ git init
4. If you don't have an account with the online repo, go do that. If it's your company's repo, you'll have to talk to your IT team to find out how to do this.

5A. Next you need a public/private key pair. If you're using a Windows-based gui client other than Git GUI take a look at step 5B below.

Fire up GitBash and generate a key:
  1. $ ssh-keygen -t rsa -C " Oct 2014". That last bit is a comment, put whatever you want, but I find these two bits handy for remembering which key is what. The default bit length is 2048 bits (add e.g. -b 1024 to change this), and the -t rsa is, actually, the default: RSA for use with SSH protocol version 2.
  2. You might need to start the SSH agent: $ ssh-agent -s
  3. Add your key to the agent: $ ssh-add  
  4. Copy the public key to your clipboard: $ clip < ~/.ssh/ 
  5. Go into your online repo's account settings page and add a new SSH key, pasting in the info you just copied.
NOTE: if you created a key using PuTTYgen you'll need to export it in SSH format to use with bash!

5B. If you're using a Windows-based Git client, you'll need PuTTY to be your SSH agent. (Note that Source Tree installs the putty tools; if you're using Source Tree you don't need to bother with the separate download and install; check out their FAQ) Here's the home page for PuTTy; you'll probably want the zip file or installer, as it includes puttygen and pageant. I think the installer has an option for starting pageant (the SSH agent for the PuTTY suite) when you log in, which will probably be useful. Once you've got putty downloaded, here's how to generate a key:
  1. Run PuTTYgen
  2. Enter a useful comment here. I use the date and which repo/system I plan to use the key for, eg "[workplace] Oct 2014" or " Oct 2014 2048bit rsa".
  3. Hit Generate
  4. Move the mouse around a bunch
  5. Save the private key. If you lose this... eh, you'll have to go through these steps again. However, if someone ELSE gets it, they can pretend to be you and eff up your repo. Not advised.
  6. Save the public key; chances are you're gonna have to use it several times when trying to debug a repo connection that's misbehaving.
  7. Copy the "Public key for pasting" stuff from PuTTYgen. You can probably close PuttyGen now.
  8. Go into your online repo's account settings page and add a new SSH key, pasting in the info you just copied.
Next time you reboot your machine, if you get authentication errors, it could be because you're not running pageant and/or it doesn't have your key loaded.

6. If you're going to be working from an existing repo (eg you just got hired or got a new machine and are going to start working on an existing codebase), then you need to "clone" the repo. GUIs have their own commands for this. From a Bash shell, use:
$ git clone ssh://
This will create a folder named RepoName in the current directory. That is, there's no need to create the repo folder yourself.

7. If you've got source code already and now want to upload it to a fresh repo up there in the cloud, GUIs have their own command. But let's say you did the 'git init' up above. How to add this to your Bitbucket/GitHub/etc account?

.... tbd, because I haven't done this yet. I actually did it the other way: created a repo in the cloud, cloned it local, then copied my source code in.

Monday, March 7, 2011

Creating an iPhone Ad Hoc Distribution

There's always some step here that I forget, so here's my checklist of things to do in order to get a working distribution build for your iOS project:
  1. Make sure you have Default.png and Icon.png added to project
  2. go to, create App ID (this is the "bundle ID")
  3. go to, create distribution provisioning profile
  4. download distribution profile
  5. drag profile from Finder into XCode Organizer's "Profiles" window. This is critical.
  6. optional: add profile to the project. Sometimes this helps.
  7. optional: quit xcode & restart. Sometimes this helps.
  8. app target info, properties tab: edit Identifier to match App ID
  9. target info, build tab, configurations popup: choose "Edit Configurations..."
  10. duplicate Release config, rename "MyApp adhoc"
  11. build settings for adhoc, Code Signing: choose the adhoc profile
  12. build settings, "Packaging" section: edit "Product Name" to be what you want
  13. choose Adhoc / Device as your build target
  14. build
And you're done!

To distribute this app, you'll have to mail both the app (MyApp/build/MyApp adhoc-iphoneos/ and the provisioning profile to your users. If they have macs, they can use the iPhone Configuration Utility to install onto their device. Windows people need special zips (.IPA?) which you can find detailed elsewhere.

Tuesday, July 27, 2010

libAdMob.a missing from iPhone project

Did you check out someone's iPhone project (or sample code) from SVN and get a "library not found, -lAdMob" error?

That's because some SVN clients are set up to ignore .a files, which is how the AdMob library is distributed. What you'll need to do is to contact the person who checked in the project and get them to add the .a file (it's about 2MB) to the SVN repository. Or, you can download it yourself.

To download libAdMob.a, go to, sign up, create a new App for them, and THEN it will let you download the SDK code. No, you can't just download the SDK, the AdMob developers are a bunch of stupid cunts that don't want to let you have an easy day; they'd rather force you to sign up and create an app you'll never actually ship, instead. They *want* the clutter. They *want* to hassle you, one of their developers. That's because (and I hate to repeat myself) they are a bunch of stupid cunts.

Saturday, July 24, 2010

Sharing to Facebook from an iPhone App

First, let me say that the sample code provided by Facebook and others is teh suck. Some of the top hits when you search for stuff are broken samples. Be careful out there!

Second, the documentation itself is crap.

So I'm here to go over the flow that I used to share to facebook. If you're developing an iPhone app and want a "Share on facebook!" sort of thing, then start by perusing the readme: That's nice and all, but it's not shippable.

Background #1: Facebook updates. The 'stories' that appear on your wall, and are shared to your friends' home pages, are all little text doodads with links to content stored elsewhere. Adding a story to a user's wall is the simplest thing, and it's what most of those Facebook games do. There are status updates and then there are other stories; a status update is what happens when you don't include an actionable item (a 'call to action' type link). Mostly you just pull some key/value pairs together (see Facebook's list of attachments) then make a request.

Background #2: You can't upload images to a wall, only to your photo album, for example. Developers making utilities, games, and entertainment want to add a story that contains a custom image. You might note that most facebook games don't do that; they use a generic image instead, like a picture of a cow or sheep or barn as FarmVille does. Uploading a custom image is tricky. If you want a wall story with a custom picture, you have to either (a) first upload the image to the user's photo album (the default one has a limit of 500 photos, one dedicated to your app will have a 1000-photo limit), which means that two stories will appear back-to-back on the user's wall, or (b) store the image somewhere else instead and link to that.

What you wanna do:
0) First, allow the Facebook Developer application. Go to and 'Allow' it.
1) Create an application (see the image on the right). Yes, you might need to make your application page pretty.
2) Go to XCode. Create your own facebook helper class. I called mine FacebookHelper, cuz I'm creative like that. The point of creating this class is to not mix facebook delegates and dialog handlers and all that crap into your other classes. Posting isn't just one function call (there can be three or more callbacks involved), so partitioning it all into a separate class will help.
3) Add an entry point to this class. I haven't yet refactored this out; right now, I copy-n-paste the class into a new project and edit the implementation. So my entry point isn't
- (void) Share:(NSString*)shareText;
blah blah blah, but just
- (void) Share;
4) That entry point will look roughly like this:
if (self.session==nil || !self.session.isConnected)
 [self ShowLogin];
else if (!havePermission)
 [self AskPermission];
 [self PostToWall];
5) Write the FB login code and delegates. This means creating an FBLoginDialog and show'ing it.
6) If you need extended permissions of any type, create & show an FBPermissionDialog. Note that your FBDialog delegate callbacks will need to differentiate the type of dialog shown. I did this by sticking an enum in the dialog's "tag" field, and switching on it in the dialog:didFailWithError, dialogDidSucceed:, and dialogDidCancel: callbacks.
7) Finally, post to the wall. Do this by creating an FBStreamDialog, add an attachment string with all your parameters, like so:
 "name":"My App Name","message":"User enters this text, this is placeholder","caption":"etc"
These key-value pairs will include a link to your app and a link to the image to use in the post.
7b) If you're uploading an image to one of the user's albums, you use an FBRequest instead of showing an FBStreamDialog.
 NSMutableDictionary* args = [[[NSMutableDictionary alloc]init]autorelease];
 [args setObject:@"my caption" forKey:@"caption"];
 FBRequest* request = [FBRequest requestWithDelegate:self];
 [request call:@"photos.upload" params:args dataParam:image];

Later on I'll upload the entirety of the class so that you can see it all in process. Plus I'll probably clean this post up, too... meanwhile, I've got to run.