SpaceMerc has been available on the Pebble App Store for almost three months now and downloaded—along with its predecessor, MazeCrawler—by well over 2,000 of my fellow Pebblers. It is also, according to my research, the first FPS game ever developed for a smartwatch!
Although this is a modest achievement at best, I can’t deny it makes me happy to think I may have made a small contribution to video game history. In addition, working on SpaceMerc has been valuable for me in terms of software engineering, game development, and game marketing experience, and I can once again attest to the joys and pains of toiling to create something original and then sharing it with the world.
In what follows, I’ll share a few experiences from my time developing SpaceMerc. If you’d prefer to see basic information about the game instead, check out the official SpaceMerc page.
Looking Back: From MazeCrawler to SpaceMerc
Having built MazeCrawler, a few fundamental challenges were already taken care of: (1) effectively portraying a first-person 3D environment on the Pebble’s small black-and-white screen, (2) handling player movement within that environment, (3) reliably saving data to persistent storage, and so forth.
Nonetheless, SpaceMerc presented several new and daunting challenges, including:
- Populating the 3D environment with non-player characters (NPCs), handling their behavior, and depicting them graphically at varying depths.
- Attempting to make the environment more varied and interesting.
- Animating the player’s attack and handling its effects on NPCs and walls.
- Designing an effective mission system.
- Providing a sense of progress over time.
- Handling an increased need for narration texts.
- Attempting to resolve a “jumpy movement” issue carried over from MazeCrawler.
- Doing all of the above within the Pebble‘s tight memory constraints.
That final challenge was the biggest of all and impacted all the others, so I’ll discuss it first.
I never ran into trouble with memory during MazeCrawler‘s development, but I hit the wall very quickly after moving on to SpaceMerc. Actually, I should say “after moving on to PebbleQuest,” for it was only after realizing my aspirations for that action-RPG were far too bold that I decided to create SpaceMerc as a simpler intermediary in the first place.
Even after settling on what I assumed were achievable design specs for SpaceMerc, I had to scale them way back in order to (a) keep the app itself small enough to fit in one of the Pebble’s eight allotted app slots and (b) prevent the app’s use of dynamic memory and persistent storage from crashing the game at runtime. Naturally, this was frustrating because it meant I couldn’t do everything I wanted to do and feared the gameplay experience might suffer as a result. On the other hand, it also felt liberating: by forcing me to lower my ambitions, it enabled me to reach a stopping point much sooner than I otherwise would have.
George Lucas once said, “A movie is never finished, only abandoned.” The same is true of games and all other creative works, but abandoning one’s work can be excruciating. As such, it’s helpful to be shoved in that direction, whether by financial need, a deadline, technological limitations, or some other consideration. In fact, aren’t we all glad George Lucas was forced to abandon some of his ideas while making the early Star Wars films, and don’t we wish he’d never returned to “improve” them? But now I’m getting off topic.
Another benefit of running into memory limitations was that it gave me an excuse to put on my “serious software engineer” hat and do something I suspected I ought to do anyway: comb through all my code again looking for each and every function, block of code, line of code, and code fragment that could be improved, trimmed down, or removed altogether. This meant cutting out superfluous error-checking, reducing my use of conditionals (“if” statements and the like), being careful about when I used integers versus floating point numbers, shortening string variables, eliminating unnecessary variables (including enumerations, which can be replaced by a series of preprocessor “#define” constants), and so forth. Sure, this may not be most people’s idea of a good time, but once you dive in, it’s surprising how much fun it can be. Well, maybe “fun” is the wrong word, but it feels good to have the power to solve problems and improve things.
Anyway, with the issue of memory limitations firmly in mind, let’s move on to the other challenges I mentioned.
Non-Player Characters (NPCs)
The addition of NPCs is one of two crucial differences between this game and MazeCrawler (the other being the player’s ability to shoot). I knew I had to nail this aspect of the game if I wanted anyone to take SpaceMerc seriously, but I also knew I was working with very limited graphical capabilities, not to mention limited memory. I did the best I could and overall I’m fairly pleased with the results.
Obviously, it would’ve been nice to provide a vast array of enemies, each with unique stats, behavior, and graphics, but that wasn’t feasible. In the end, I was satisfied to have seven different enemies, some of which share the same stats or graphical elements, and all of which exhibit the same simplistic behavior: pursue the player, then attack.
I originally wanted to incorporate more behavioral diversity, such as cowardly enemies running away when wounded, and more animations. I also took it for granted that some enemies would be ranged attackers (capable of attacking the player from a distance) and hoped to throw in a few friendly NPCs that weren’t just passive like the humans you’re sent to rescue during “Extricate” missions. In the end, however, I settled for seven simple-looking, simple-minded enemies that only attack at close range, only one of which exhibits any animation (the “Beast,” whose mouth opens and closes), and that appear randomly up to two at a time. Though less than ideal, I felt this compromise was acceptable given that SpaceMerc is, after all, a smartwatch game and simply cannot approach the level of complexity and visual appeal generally expected of a modern first-person shooter.
As a final note, soon after designing the tall, bulky, intelligent race of aliens known as the Fim, I began to feel there was a resemblance between them and the mysterious grey aliens of Éric Chahi‘s masterpiece: Another World (known as Out of This World in some of its North American incarnations).
The similarity is unintentional (my aliens are block-headed and wear sleeveless shirts simply because I was able to reduce app size by not drawing necks and sleeves), but not unwelcome. I’m an ardent admirer of Chahi’s work and count Another World among my favorite video games of all time. If you’ve never played this action-adventure classic, you’re in luck: its 20th Anniversary Edition is now available not only on PC (Amazon/Steam/GOG.com) and Mac (iTunes/Steam/GOG.com), but also on Android (Amazon/Google Play) and iOS (iTunes) devices, and according to the official website it will soon be available on all the latest gaming consoles as well.
Initially, I had big plans for the 3D game world. I wanted to introduce some new wall textures and lighting effects, perhaps even outdoor locations and an occasional river of water or lava. Sadly, those features were among the first things placed on the chopping block as I started hacking away at my design specs. Variety is the spice of games, but NPC variety seemed far more important to me than environmental variety, so I made some sacrifices in this area. The only significant addition was a “door” graphic depicting the entrance/exit of each mission location.
On a related note, I originally planned on implementing in-game items for recovery of health and ammo (among other things), but elected instead to save space by allowing both health and ammo (actually, “energy” would be a more accurate term) to automatically recover over time.
The Player’s Attack
Pressing the Pebble’s “Select” button causes the player to attack, sending out a laser beam capable of burning through any enemy or wall in its path.
Drawing a simple laser beam and animating it with help from an AppTimer actually wasn’t much of a challenge, nor was it difficult to handle dealing damage to the first enemy or wall hit by said laser, but there was, and still is, one small issue: the player’s attack speed is not constant. Sometimes the gun shoots more rapidly or sluggishly than intended. It seems to be related to the number of walls in the player’s field of view, but, unfortunately, I have yet to find a workable solution to this problem (more on this later).
By the way, as I’ve been alluding to, yes, you can destroy walls in this game. If you want, you can destroy every wall you see (except for boundary walls) just for kicks. This feature was largely inspired by The Elder Scrolls: Arena, the very first Elder Scrolls title, which includes a fun wall-destroying spell called “Passwall.”
Demonstration of “Passwall” in The Elder Scrolls: Arena.
You can also increase your attack power through upgrades, but one thing you cannot do, unfortunately, is switch between different weapons. I do plan on implementing multiple weapons (and spells) in PebbleQuest, however, so you can look forward to that!
Missions are critical to SpaceMerc as they provide context, variety, and a sense of purpose. I was able to fit six (rhyming) mission types into the game: “Excavate,” “Retaliate,” “Obliterate,” “Expropriate,” “Extricate,” and “Assassinate.” They differ enough, I hope, in their descriptions, success criteria, reward amounts, and other characteristics that they, along with the procedurally-generated locations and randomly-appearing NPCs, will keep the game feeling fresh and interesting indefinitely.
One mission type I’d really hoped to include was an “Escape” mission that would occur whenever you fell in battle. You would awaken to find yourself in a prison cell, but, since the Fim were unable to remove either your advanced suit of armor or the laser gun affixed to it, you could blast your way to freedom. In the end, this was tossed out in favor of a simple narration: “You fell in battle, but your body was found and resuscitated. Soldier on!”
A sense of progress is crucial to any video game, whether it be through points, leveling, loot-gathering, increasing difficulty, the advancement of a narrative, the opening of new vistas, or whatever else. Having abandoned in-game items, and not wanting to simply tally up points, I provided an “Upgrade” system in SpaceMerc whereby money earned from missions can be spent to improve your stats, presumably by visiting a technician, cyberneticist, doctor, or other relevant expert in your current corner of the galaxy.
SpaceMerc employs a narration system to (1) establish overall context the first time the app is run, (2) describe the goals and potential rewards of each mission, (3) detail the outcome of each mission, and (4) to present “Controls” and “About” information.
At first, I designed the narration system to be animated, revealing letters one at a time, but for the sake of trimming things down I later removed that functionality. I also shortened narration texts as much as I could, freeing up memory at the cost of making mission descriptions rather terse.
In both MazeCrawler and SpaceMerc, movement can occasionally feel a bit jumpy: if the “move forward” (or “move backward”) button is held down for a while, then released, the player will sometimes seem to immediately “jump” forward (or backward) a couple extra steps.
This may be due to a general timing issue at the heart of these games causing both this and the fast/slow shooting issue referenced above. I made various attempts to alleviate the problem, including overhauling how all events were timed and handled, but to no avail. Regardless of how I used, or didn’t use, the TickTimerService, AppTimers, and various Click subscribers, the problem either persisted or got much, much worse.
Perhaps the issue could be resolved through some fundamental change to my code, or perhaps minor timing issues like this are inevitable on a device that simply wasn’t designed with 3D gaming in mind. Either way, I reached a point where it was time to “abandon” my game, flawed though it may be, and allow other gamers to enjoy it.
Looking Forward: From SpaceMerc to PebbleQuest
I may continue tweaking and improving SpaceMerc from time to time, so please share any feedback you have about the game, especially any changes you’d like to see. Most of my time and attention, however, is now reserved for PebbleQuest: the action-RPG I’ve been working towards since the moment I bought a Pebble watch.
It may be quite a while before PebbleQuest is released because I’m combing through my code yet again looking for even more ways to save memory and squeeze in content. Once complete, my hope is that PebbleQuest will offer even more than SpaceMerc in terms of gameplay variety, character customization, and narrative.
I may also build a turn-based version of PebbleQuest, in addition to (or completely replacing?) the action-RPG version, mainly because that should allow me to include even more content while avoiding the timing issues discussed above, but also because I suspect some Pebblers would actually prefer a turn-based experience.
In addition to sharing any feedback you have about SpaceMerc, please let me know what you’d like to see in PebbleQuest. In particular, would you have a strong preference between real-time and turn-based combat? If you generally prefer action-RPGs, but a turn-based RPG could offer more content, would that change your mind in this instance? Feel free to share all your thoughts and suggestions in the comment section below. And finally, thanks for taking an interest in SpaceMerc and all my indie Pebble games!