Category: Programming

A Brief History of My Programming Languages

I’m not crazy about the standard resume format. A chronological list of employers is not that interesting (and sometimes depressing), and anyway, doesn’t work that well if you’re self employed.

One more interesting representation is your programming language narrative (which would also be more interesting than just listing programming languages). In my case, I can safely say I’ve forgotten more languages than many programmers know (and I’m not bragging, it’s actually kind of sad – I hope I don’t have to pick up a Perl book again).

I started programming in the 80’s. In fact, I think it was right in 1980 that I started programming in BASIC on a TRS-80 in my junior high school library. But that wasn’t really programming, it was just repeatedly typing in a magazine listing of a Star Trek game until the librarian suggested I save the program on tape (that’s cassette tape).

I did a little bit better at a summer computer class typing in yet another Star Trek program in BASIC on Commodore computers, making some minor modifications, but it wasn’t until I picked up the user manual for the Apple II in my high school library (I wonder how many programmers from my generation got their start in the school library?) that I saw the light. All of a sudden, I understood programming! I wanted to write a chess program, so I started with an reversi (Othello) game, which was good enough to be my first pirated game (I know because one of my high school friends gave me a disk of pirated games with my game on it).

During high school, I also dabbled in Pascal and 6502 machine language (there’s nothing like programming in machine language to learn exactly what a microprocessor is), but basically those were my BASIC years. And that came to an end when I went to college. I started off slow, there, with just a Fortran course and to tell you the truth, I took that famous MIT 6.001 course but didn’t understand it until I reread the textbook after graduation. So although that course introduced Scheme, it was really through my part-time work at the AI lab that I got to know Lisp, specifically Zetalisp for the Symbolics Lisp Machine. Again, a programmer-friendly machine with a great user manual (affectionaly known as the “Chine Nual” for the way the title Lisp Machine Manual was usually seen on the book). And, as in high school, I wrote a reversi program, a parallel-processing version in multilisp, for my bachelor’s thesis. Again, I originally wanted to write a chess program, but my advisor hinted that wouldn’t be a good way to graduate on time.

So my college years were Lisp years, although my Lisp years extended an additional seven years after graduation, with occasional forays into C and C++, and some fun class work in my masters program with ML. First, it was Lisp on TI Explorer Lisp machines for VLSI CAD tools, then, with Lisp machines on the endangered species list, Lisp on workstations for Hubble telescope scheduling, submarine simulation, military data analysis, and computer graphics.

My last big Lisp project involved porting from Unix workstations to Windows. After that, it was Java on PCs. Java for computer graphics, semiconductor fab scheduling (working for the same guy who did the Hubble scheduling in Lisp), and mobile web browsing. Also, a little bit of Tcl/Tk got in. That lasted until the dot com bust (so not nearly as long as the previous Lisp era).

After that, I somehow went into video games, so it was mostly C and C++, with bits of Lua, smaller bits of Python, and brief experiments with J2ME, and a nicely paying Java contract in the middle (and by nicely paying, I mean not a video game contract).

Technically, that was about a ten year stretch continuing up until a few years ago (my work on Blue Mars involved CryEngine), but I also started using Unity around 2007 (version 1.5), so there’s also been an overlapping stretch of using their JavaScript (some prefer to call it UnityScript), and a recent wholesale conversion to C#. If we broaden the discussion to platforms, you could these recent years have been my Mono years, and the latest development might be F#.

BASIC was fun as my first language, Lisp I liked as a language, Java I liked as a platform, and it’s been all downhill or plateau from there. But F# looks both fun and practical (functional programming with ML roots, but with OO and imperative support and available on Mono), and Xamarin is pushing it for mobile development. It might be enough for me to stop complaining about the lack of Lisp. Maybe I’ll start with that chess program…

CLOC

Trying out CLOC, a smart lines-of-code counter, on my HyperBowl project:

   18183 text files.
   12470 unique files.                                          
   42393 files ignored.

http://cloc.sourceforge.net v 1.60  T=116.22 s (6.3 files/s, 931.4 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C#                             440          14009          14311          56650
Javascript                     179           2570           1320           8611
MSBuild scripts                  7              7             49           3028
XML                             78             97             68           2417
Objective C                      7            702            276           1556
Objective C++                    5            413            145           1143
C/C++ Header                    13            269            225            343
Perl                             1             11              8             19
-------------------------------------------------------------------------------
SUM:                           730          18078          16402          73767
-------------------------------------------------------------------------------

Auto-Sizing GUIText

I just added a couple of my GUIText utility scripts to my FuguUnity repo on github (see the lower right of this web page). One of them is not that useful, anymore, as it provides a way to select the GUIText color in the Inspector, but that’s a built-in feature, now. The other I use everywhere: a script to scale the GUIText according to screen resolution. Remember to import the font as dynamic.

public class GUIFontSize : MonoBehaviour {
		
	public float baseHeight = 480.0f;

	void Start () {
		guiText.fontSize = (int)(guiText.fontSize * Screen.height/baseHeight);
	}
	
}

GameCenter with Prime31 Option

I started using Game Center with the Prime31 plugin and later switched to the Unity Social class, figuring the fewer plugins the better. But now I’m swinging back the other way, figuring hey, I paid for all those plugins, and besides, I want to start using features not available in Social – on the fancy pants end, there’s GameKit multiplayer, and there are some little features not exposed in Social, e.g., you can retrieve the images of your Game Center friends, but not the player? I assume that’s an oversight, but in the meantime, I augmented my Game Center wrapper script with a Prime31 option.

using UnityEngine;

using UnityEngine.SocialPlatforms.GameCenter;

namespace Fugu {
	
	sealed public class GameCenter : MonoBehaviour {

		public bool showAchievementBanners = true;
		// Use this for initialization
		void Start () {
#if UNITY_IPHONE && !P31_GC
		Social.localUser.Authenticate ( success => {
      	  if (success && showAchievementBanners) {
				GameCenterPlatform.ShowDefaultAchievementCompletionBanner(showAchievementBanners);
				Debug.Log ("Authenticated "+Social.localUser.userName);
        	}
			else {
				Debug.Log ("Failed to authenticate "+Social.localUser.userName);
			}
		}
    	);
#endif
#if UNITY_IPHONE && P31_GC
			GameCenterBinding.authenticateLocalPlayer();
			if (showAchievementBanners) {
				GameCenterBinding.showCompletionBannerForAchievements();
			}
#endif
	}
		
	static public void Achievement(string name) {
			Achievement(name,100.0f);
		}
		
	static public void Achievement(string name, float progress) {
		if (IsAuthenticated ()) {
#if UNITY_IPHONE && !P31_GC
			Social.ReportProgress(name,progress, success => {
#if FUGU_DEBUG
			if (success) {
				Debug.Log("Achievement "+name+" reported successfully");
			} else {
				Debug.Log("Failed to report achievement "+name);
			}
#endif
		});
#endif
#if UNITY_IPHONE && P31_GC
			GameCenterBinding.reportAchievement(name,progress);
#endif
		}
}

	static public void Score(string name,long score) {
			if (IsAuthenticated ()) {
#if UNITY_IPHONE && !P31_GC
			  Social.ReportScore (score, name, success => {
#if FUGU_DEBUG
			if (success) {
				Debug.Log("Posted "+score+" on leaderboard "+name);
			} else {
				Debug.Log("Failed to post "+score+" on leaderboard "+name);
			}
#endif
		});
#endif
#if UNITY_IPHONE && P31_GC
				GameCenterBinding.reportScore(score, name);
#endif
			}
}

	static public bool IsAuthenticated() {
#if !UNITY_IPHONE
			return false;
#endif
#if UNITY_IPHONE && !P31_GC
			return Social.localUser.authenticated;
#endif
#if UNITY_IPHONE && P31_GC
			return GameCenterBinding.isPlayerAuthenticated();
#endif
		}

			static public string GetName() {
			if (!IsAuthenticated ()) {
				return "Player";
			} else {
#if UNITY_IPHONE && !P31_GC
				return Social.localUser.userName;
#endif
				#if UNITY_IPHONE && P31_GC
				return GameCenterBinding.playerAlias();
				#endif
			}
		}

		static public void ShowLeaderboard() {
#if UNITY_IPHONE && !P31_GC
			Social.ShowLeaderboardUI ();
#endif
#if UNITY_IPHONE && P31_GC
			GameCenterBinding.showLeaderboardWithTimeScope (GameCenterLeaderboardTimeScope.AllTime);
#endif
		}

		static public void ShowAchievements() {
			#if UNITY_IPHONE && !P31_GC
			Social.ShowAchievementsUI ();
			#endif
			#if UNITY_IPHONE && P31_GC
			GameCenterBinding.showAchievements ();
			#endif
		}
	
}
}

Unity Social Wrapper

Here are my wrapper functions for Unity’s GameCenter API. They take care of things like logging debug info (if activated by a preprocessor definition) and smooth out the inconsistency between the leaderboard and achievement parameter order (Social.ReportProgress takes the achievement name first and progress second, while Social.ReportScore takes the score first and the name second). I wrote this when I switched from the Prime31 plugin to the Unity API, but I plan to add the Prime31 option back in like I did with my iAd script.

using UnityEngine;

using UnityEngine.SocialPlatforms.GameCenter;

namespace Fugu {
	
	sealed public class GameCenter : MonoBehaviour {

		public bool showAchievementBanners = true;
		// Use this for initialization
		void Start () {
		#if UNITY_IPHONE
		Social.localUser.Authenticate ( success => {
      	  if (success && showAchievementBanners) {
				GameCenterPlatform.ShowDefaultAchievementCompletionBanner(showAchievementBanners);
				Debug.Log ("Authenticated "+Social.localUser.userName);
        	}
			else {
				Debug.Log ("Failed to authenticate "+Social.localUser.userName);
			}
		}
    );
#endif
	}
		
	static public void Achievement(string name) {
			Achievement(name,100.0d);
		}
		
	static public void Achievement(string name,double score) {
#if UNITY_IPHONE
	if (Social.localUser.authenticated) {
		Social.ReportProgress(name,score, success => {
#if FUGU_DEBUG
			if (success) {
				Debug.Log("Achievement "+name+" reported successfully");
			} else {
				Debug.Log("Failed to report achievement "+name);
			}
#endif
		});
	}
#endif
}

	static public void Score(string name,long score) {
#if UNITY_IPHONE
	if (Social.localUser.authenticated) {
		  Social.ReportScore (score, name, success => {
#if FUGU_DEBUG
			if (success) {
				Debug.Log("Posted "+score+" on leaderboard "+name);
			} else {
				Debug.Log("Failed to post "+score+" on leaderboard "+name);
			}
#endif
		});
	}
#endif
}
	
}
}

Spinner

A long time ago when I was working on a large and ridiculously mis-threaded Java application (back then we said “application”), I removed an animated color display that did nothing. Some people complained, saying they liked it – I figured it was crashing on multicore systems and taking up screen space. But now I’m all about activity indicators that give you the possibly false impression something’s going on – every app should have one. Here’s a Unity C# script I drop into every splash screen that immediately starts an activity indicator (Android or iOS) and kills it after the next level has completed loading.

public class Spinner : MonoBehaviour {

	// Use this for initialization
	void Start () {
		GameObject.DontDestroyOnLoad(this.gameObject);
		StartCoroutine(StartActivityIndicator());
	}
		
	IEnumerator StartActivityIndicator () {
		#if UNITY_IPHONE
		Handheld.SetActivityIndicatorStyle(iOSActivityIndicatorStyle.Gray);
		#endif
		#if UNITY_ANDROID
		Handheld.SetActivityIndicatorStyle(AndroidActivityIndicatorStyle.InversedLarge);
		#endif
#if UNITY_IPHONE || UNITY_ANDROID
		Handheld.StartActivityIndicator();
#endif
		yield return null;
}

	void OnLevelWasLoaded() {
#if UNITY_IPHONE || UNITY_ANDROID
		Handheld.StopActivityIndicator();
#endif
		GameObject.Destroy(gameObject);
}
	
	
}

Still Using iAd (and AdMob)

Despite my rant a while back that I was dropping iAd because they turned off my revenue without telling me that my iAd contract was (incorrectly) terminated, I’m still using it. Sometimes it actually works to say just fix it or I’m switching to an alternative, and no, I’m not providing anymore information because I already spelled out the situation twice! (It probably doesn’t work very often, though).

Anyway, to celebrate my complacency and the status quo, here’s an updated version of my ad banner script, updated for the new (and simpler) Unity iAd API and with Prime31 iAd/AdMob options as a bonus. And hey, I’ve now got Chartboost set up (via the Prime31 plugin), so if those iAd dollars go missing agin, I’m ready to switch. I really mean it this time!

public class AdBanner : MonoBehaviour {
		
	public bool showOnTop = true;
	public string AdMobID = "";
#if UNITY_IPHONE && FUGU_ADS && P31_IAD
	void Start() {
		AdBinding.createAdBanner (!showOnTop);
	}
#endif
#if UNITY_IPHONE && FUGU_ADS && !P31_IAD
	private ADBannerView banner = null;
		
	void Start() {
		GameObject.DontDestroyOnLoad(gameObject); // keep ad alive if we load a new scene
		banner = new ADBannerView(ADBannerView.Type.Banner,showOnTop ? 
			                          ADBannerView.Layout.Top : ADBannerView.Layout.Bottom);
		ADBannerView.onBannerWasLoaded  += OnBannerLoaded;
		}

		void OnBannerLoaded()
		{
			Debug.Log("Ad banner Loaded!n");
			banner.visible = true;
		}
#endif
#if UNITY_ANDROID && FUGU_ADS
		void Start() {
				AdMobAndroid.init(AdMobID);
				AdMobAndroid.createBanner(AdMobAndroidAd.smartBanner, showOnTop ?
					AdMobAdPlacement.TopCenter : 
					AdMobAdPlacement.BottomCenter);
		}
#endif
	
}