Monday, November 7, 2011

There Goes the Neighbor- I Mean, Neighbourhood

Permanent Residency

Good news, everyone! I received a letter from CIC, and it appears they've made a decision! The letter was worded as dodgily as possible so as not to tip me off as to what that decision was, but indications point towards acceptance. I have a 1-hour appointment in a few weeks, and I am required to bring my documents and two government-approved photos. Trying not to get my hopes up too high, but after 11 months of waiting in the dark, it's good to have forward movement!

What does this mean for NEO Scavenger? Well, the short version is that with permanent residency, I can officially earn money. In a couple months, I should be able to incorporate, and license/sell NEO Scavenger without violating my visa.

The down side? Shiz just got real. I was sort of comfortably hiding behind my visa issues as an excuse to keep noodling with the game. After all, I couldn't do anything with it even if I finished it. But now, that excuse has an expiration date, and it looks like mid-January. So time to hunker down, take stock, and get this thing ready for market.

Audio Work

Almost as if I subconsciously knew time was running out, I decided to tackle audio in NEO Scavenger two weeks ago. I figured that was an area that had been neglected for too long, and probably one of the biggest missing features in the game, so I went at it.

As expected, audio is hard work! I managed to get mp3s playing in Flash/Flixel without too much trouble, but getting them to play and sound right is where things got difficult. As it turns out, mp3s don't loop well. For reasons I won't go into here, mp3s always have a silent gap at the beginning. And no amount of my workarounds were, ahem, working. I even went so far as sampling an mp3 stream's bits in real time to artificially cue past the gap each loop. Still an audible gap on loops.

The solution? Oddly enough, use Flash's IDE. I had been building everything in FlashDevelop, so I hadn't been using the IDE. Flash CS3/4/X does this thing where it bundles exported mp3s with information on the gap length at the beginning of the file, for seamless looping. Simply include the mp3s in an swc file at compile time, and voila! Seamless looping mp3s!

However, this meant one big change in the way I was loading assets...

Runtime Content and Piracy

Almost everything in the game, apart from the engine itself, is loaded dynamically at run time. I load images, game variables, the map, item definitions...you name it. "Why on Earth would you do that," you ask? Good question.

Originally, I thought I would be clever and avoid piracy issues this way. I had read Andy Moore's accounts of piracy and blacklisting, and I wanted to avoid the piracy issues he ran into. (Note that "piracy" here isn't the player getting the game without paying, since it's free anyway, but rather professional pirates decompiling the game, rebranding it as their own, and selling it to Flash portals for profit.)

I figured I could cleverly have my game ask my website for its guts on start-up. If the game was at a legit site, the game would get its guts. If not, or if the game was at a portal that blocked outgoing links, the game would probably default to demo content. Content which would only serve to whet one's appetite for the real deal. It was meant to be a sort of remote kill-switch, which would allow me to deny access if sites abused the game somehow (e.g. rebranded it without permission, or blocked links back to my site).

It sounded clever at the time. But there are some major drawbacks:

  1. Portals Like Single-File Games: Having a sprawl of files and web connections for a single game is a no-no in Flash game licensing. Particularly if the sponsor wants the game to be picked up by other portals, which multi-file games make difficult.
  2. Hosting Content: Having every instance of the game in the world ask my website for guts is a huge bandwidth and uptime concern. I could find a more reliable place to host the content, but even then, no portal owner wants to rely on a game that dies if I decide to stop hosting the files.
  3. Hurting Players: There's always the chance DRM hurts the player, and this would've been no exception. What if a problem causes the player's game to fail? And even working copies are going to have to rely on a centralized host to download data from, which could mean sluggish game loads for many users.
  4. Hypocrisy: I even promised myself I wouldn't use DRM. "Hello, I'm Dan from April 2011, remember me?"

So it seems pretty clear, the way forward: simplify. Just go with the game setup everyone else uses, to make accessibility as high as possible. Expect piracy, and try to use it to my advantage. I don't know what that means, yet. But it sure does sound good!

Meanwhile, Back In Actual Game Development

Notice anything new?

Attack modes!
That's right, new attack mode UI! I've changed the way attacks work in NEO Scavenger. Previously, anything you had equipped in an appropriate slot granted combat bonuses. This worked well enough when the only three weapons were bare hands, meat cleavers, and wrenches. Equipping two weapons simultaneously meant double bonuses. But that was ok, because we all have fantasies of marauding bandits in the wastelands with dual-wielded meat cleavers, don't we?

The problem came when I started adding ranged weapons. Suddenly, having a ranged weapon meant your bonuses from any other equipped melee weapon came along for the ride. While dual-wielding a hunting rifle and long-range throwing-cleavers sounds cool, it's sort of not what I intended.

Hence, attack modes. Now, every equipped weapon (when in the correct slot) grants one or more attack modes. They work kinda like Fallout or Silent Storm, in that you can see and change which attack mode is active via the graphic on the bottom of the screen.

The trusty old .308.
I also changed the UI a bit to accommodate the new attack modes. The message window is now thicker. It's an improvement in that the player can now see a bit more message history than before, but the down side is that it had to be hidden in the inventory screen to avoid obscuring important elements there. The sleep button was moved to the right, as it is an action and not a UI screen like the others. And I finally added a "Wait" action, for passing a turn without moving. I'm still on the fence about whether to use Rogue-like or Civ-like movements/turn, but for a Rogue-like method, a "wait" option is a necessity.

I also rewrote the visibility code to be faster and more reliable. You can especially see it in the first image, above. The player's line of sight gets blocked by certain hex types, even when on an elevated tile like the hill. What I had before worked, but wasted a lot of CPU on redundant hex calculations, and still made a few errors.

Since I wanted creatures to use ranged weapons, I needed visibility calculations to be cheaper. Otherwise, the AI would take too much time during a turn. And without visibility checks, creatures might attack the player from unfair locations (e.g. through a hill).

And since creatures and players were now sharing so much code, I finally took the plunge and made them both derive from a common class. (Yes, I know, they should've from the start. Bad Dan!) As you can see in the above two screenshots, now everybody knows when Dogman is comfortable. (Still working on message filtering)

One-Click Inventory

One last big change is to the inventory system. (Yes, again.) Enough testers have complained about dragging items around that I finally made auto-moving the default click behavior. Anything you so much as touch with a mouse click or drag pops automatically into an appropriate slot, if possible. Ground items go to inventory. Inventory goes to ground. Available skills go to player skills, and vice versa.

Everything you see here took one mouse click to equip/pick-up.
If the player wants to be more specific about where an item goes, they now must shift+drag. This is also true if the player wants to Tetris-rotate an item to fit.

In hindsight, it makes more sense this way. 90% of the time, users are picking up items and dropping them, and this saves the user the trouble of tedious clicking or dragging.

Next up: figuring out how to handle ammo, and making encounters and skills more intuitive. I should probably do another content pass soon, too. The skeletal story encounters need some clean-up and fleshing-out to be worth their weight.