Game Sandbox VI: How to Pick a Fight (with JavaScript)

This entry was originally stored in my personal blog engine, but has been imported into WordPress.

Although I had to eventually write a combat engine for my project, I gave it a low priority. As I mentioned earlier, this isn’t a fighting game. I was more concerned with dialogue and mystery-solving than the turn-based combat I’d eventually have to implement.

However, without combat – even cut-scene type fighting – I hit writer’s block. I didn’t expect it. I admit – the characters (skillfully executed by AerinBoy ) do correspond with the standard archetypes. The tall, strong guy is the fighter; the short scholar is the mage; the smart-aleck is perhaps the thief. This is something I resisted. I don’t like epic fantasy; my favorite writer here is L. E. Modesitt. Like his heroes, my characters aren’t knights or cloistered clerics. They’re blacksmiths, item shop clerks, and the like. People who fight not as a profession (which seems like a pretty banal occupation), but who get drawn into fights because they must, because they’re stuck in a frontier town about to go under siege.

attack1
I also couldn’t resist it. I recall my CompSci I course, when (in C++) we started to learn about objects. “An object can be anything,” the instructor said, “even a dragon or a sword.” I didn’t need her to tell me that. The moment I saw a 2-dimensional array, I pictured a chessboard. The same story for objects. I planned to, someday, sit down and write some code that included classes like “Fighter” and “Magic-User.” It never happened, until now.

Another factor – I needed to improve my JavaScript skills. It’s a language I learned on the fly in classrooms and the workplace, without any formal training. Nor is it my favorite language. I don’t like how it handles objects, its lack of classes (the “prototype” functionality isn’t the same). I don’t know if that popular jibe is correct – that JavaScript was created within 10 days – but it certainly lacks the feel of my staples, C++ and Java.

One of my long-term plans is to become proficient in Common Lisp, that academic language that’s become the Latin of computer science departments (I coded with its basics at university for only one semester). One comment I read was that some “functional” aspects of the language found their way into JavaScript. Eventually, I decided that if this was my goal, I might as well jump straight into JavaScript (Latin again!).

Finally, I found a book that seemed to offer both practical and formal instruction – Marijn Haverbeke’s Eloquent JavaScript. I’m used to grabbing my JS instruction from Google searches and short paragraphs between larger topics. This was the first time I found a book that taught not only how to use it practically (it covers DOM elements), but also has a conventional, computer science textbook approach. It’s not written for someone who needs to learn a few commands to finish their website; it’s written for someone who wants to learn everything the language has to offer (it’s also, I heard, used in those coding “boot camps,” which makes me shudder. I did all the chapter-end exercises. They aren’t easy).

I finished the first 6 chapters rather quickly. Since Chapter 7 was a “project” chapter (creating an ecological, cellular automaton game), I decided to substitute my game engine instead.

* * *

On the good side, I overcame most of JavaScript’s object-creation idiosyncrasies (which Haverneke euphemistically described as a “rather eccentric take” on OOP). No matter what, though, I will always miss the “Class” approach that C++ and Java supports so well.

I also expanded my usage of JS’s “higher-order functions.” Take, for instance, the following function from my code, which checks, in an array of fighters and monsters, if there’s still someone standing on each side. My original formulation was:

function bothSidesStillFighting(combantantsArray) {
  var enemyCount = 0, friendCount = 0;
  for (var i = 0; i < combantantsArray.length; i++) {
    if (combantantsArray[i].HP > 0) 
      if (combantantsArray[i].isMonster)
        enemyCount++;
      else
        friendCount++;
    }
  return ((enemyCount > 0) && (friendCount > 0));
}

Using a more functional style, I changed this to:

function bothSidesStillFighting(combantantsArray) {
    return combantantsArray.filter(function(elem) { return elem.HP > 0 && elem.isMonster === false}).length > 0
        && combantantsArray.filter(function(elem) { return elem.HP > 0 && elem.isMonster === true}).length > 0;
}

I have to admit – by using JavaScript’s higher order functions, the code is much more elegant and shorter. In fact, obsessive coder that I am, I’d say it even looks beautiful!

However, there are drawbacks to this style. The first is that not everyone is familiar with the functional style. For instance, one of my superiors at work always insists on writing his JavaScript in a purely functional style. Until I took the time to teach myself the method, his code was somewhat difficult to read. For most programmers, the first version is much easier to understand, since for-loops are one of the most basic programming structures in any language, right up there with if-else and do-while. One cannot say the same about higher-order functions.

A second concern is debugging. With the functional style, there’s a lot going on under the hood, so to speak. If the code breaks, what is the trigger? Do the elements have an attribute called “isMon” instead of “isMonster?” Is the fighter count off, or the monster count, or both? The traditional method has the problem broken down into such small pieces that debugging these problems are easy. Not as much with the higher order functions.

A final problem concerns efficiency. As Haverneke noted:


A program that processes an array is most elegantly expressed as a sequence of cleanly separated steps that each do something with the array and produce a new array. But building up all those intermediate arrays is somewhat expensive. Likewise, passing a function to forEach and letting that method handle the array iteration for us is convenient and easy to read. But function calls in JavaScript are costly compared to simple loop bodies.

So there’s the cruel tradeoff – eloquence vs. performance. In my game, the list of fighters and monsters isn’t likely to contain more than 8-10 elements, so speed isn’t a factor here. But with larger arrays? Probably not.

* * *

Because combat isn’t central to my game, I sought to make the easiest, most streamlined battle system possible. A traditional turn-based RPG combat screen has a little menu with commands like “Attack,” “Magic,” “Item,” “Special Move,” etc. Too complicated. The simpler and faster, the better.

In their books, both Moore and Burchard begin their discussion of combat rules with the game of rock-paper-scissors, apparently the simplest model possible. This was too simple (and has been done before), but it gave me an idea.

At university, I spent some time playing LARPs, or live-action role-playing games. One challenge of a LARP is finding a way to resolve normal RPG tests quickly – throwing some dice while play-acting a fistfight isn’t very realistic. The primary system did use rock-paper-scissors, albeit with a bunch of stats and unusual rules. But I did find a better system in the second edition of Robert McLaughin’s Cthulhu Live rules, and these are the ones I implemented.

Like any standard RPG characters, my players have stats – HP, Dexterity, speed, etc. In a battle, though, I adopted McLaughiln’s rules, designed to streamline quick, live-action combat. On any given turn, the player has only four options:

  1. The fist. This means you attack with all your Dexterity. Damn the torpedoes; full speed ahead.
  2. V for Victory sign. This is the “split,” where you put half your points into an attack (rounded up), and the remainder in defense.
  3. Palm forward. A full defense. All the points go towards defending.
  4. Thumbs down. Run away. You don’t attack, and only have half your defense points available. If you survive the round, you flee.

attack2

The order is simply determined by the “Speed” attribute. When anyone gets attacked , they have their defense points halved for subsequent attacks. Repeat until one side is dead or fled.

* * *

Unfortunately, the battle code I originally wrote followed a linear pattern (I tested it simply by typing numbers into alert boxes). When I moved it into the enchant.js engine, I had to tear it apart and make it asynchronous. In a real game, you’re not using the prompt command or logging the result on the console; you need to cue graphics, which in turn only stay on the screen for so long, etc. And the code that results is often far from eloquent.

Judging from these entries, I’m more interested in programming the game than finishing it. Figures.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s