Importance of Symmetry

One of the many joys of roguelike development is getting your ass kicked by your own game! However, in my case some of the deaths to ranged enemies felt like cheating. All I would do is come around the corner and blammo — dead. Was this an example of my own reckless play style? Or an actual bug in the game?

Turns out the problem was with my Field Of View (FOV) algorithm. Since I am using the amazing rot.js library, I had been using the default recursive shadowcasting field of view implementation. After poking around on roguebasin and re-reading Jice’s awesome overview of FOV algorithms, I realized my problem is that my FOV was not symmetrical.

Now, depending on who you ask, symmetrical FOV may or may not matter. In a game with only 3 hit points, every shot counts. While I am loath to ever over-optimize, I felt it would be time well spent. I came across Albert Ford’s implementation of a symmetrical recursive shadowcasting and ended up coding something similar in typescript. The end result is exactly what I wanted.

Before (Non-Symmetrical): This bot can see me, but I can’t see him. Which means as soon as I step over, I’ll be in range and get shot.

After (Symmetrical): Neither of us can see each other. In this case, the bot will move closer to the spot where he last saw me – sacrificing some range and giving me a chance to see him one turn before he can attack.

Initial gameplay coming together

Have been making steady progress on the core gameplay elements of hardpointe. I do feel like the end result is even a little bit.. fun? (Shocking to me most of all)

Here’s a longer-play gif of the game in action, with slightly less-embarrassing colors.

Current feature list:

  • All six initial powers:
    • Shield
    • Heavy Axe
    • Booster/Charge Attack (was originally jet pack?)
    • Cloak
    • Phasewalk (not sure if this one will make the cut)
    • Hack (turn enemies into allies)
  • One-off weapons (take up power slots but limited/non-rechargeable ammo)
  • Various combat effects:
    • Stun
    • Knockback (concussive)
    • EMP blast (in progress)
  • Enemy behaviors:
    • Basic melee
    • Keeps distance (ranged attack)
    • Explodes on death
    • Attacks in packs
    • Uses / recharges shield (in progress)
  • Terrain:
    • Chasms (if knocked into one you or enemies drop to the next level)
  • Combat mechanics:
    • Wall-smash
    • Corpse-tossing (heave enemy remains into other enemies)
  • Items:
    • Grenades (simple damage & effects)
    • Nanotech Cores (effects like acid and health – so far)
Whew. Seems a lot longer when I type it out. Stay tuned. 

Return of Heavy Axe

A lot of the powers/abilities in hardpointe are my favorite recycled bits from previous 7-Day Roguelikes. My favorite by far was my 2015 entry: Heavy Axe.

In any event, after some only minor tweaking to the pathfinding code, I now have a ‘Heavy Axe’ ability in hardpointe that functions much the same: a unique item gets thrown across the map. Use the power again to “recall” the axe, which will travel back to you and smash into any enemies along the way.

I also put a few more gifs on this Sharing Saturday thread on /r/roguelikedev if you want to see more!

Hardpointe Development Principles

I recently ready a blog post called The Slow Application Development Methodology that got me thinking about what I enjoy about hobby roguelike development, but also some frustrating parts of dealing with my own limited productivity.

Here are some brief design development principles for my current project, in the hopes stating them publicly will help me stick to them. These principles come from experience over the course of many 7-Day Roguelike Challenges (both successes and failures) and most importantly, learning my own weaknesses.

  1. Make a game YOU want to play
  2. You are not building a roguelike engine
    (no, seriously..)
  3. Don’t reinvent the wheel (ROT.js is your friend)
  4. Work on small chunks at a time – no grandiose leaps into refactoring hell
  5. You really, really, really aren’t building a roguelike engine
  6. Aim for a solid ‘coffee break’ game worth of content.
  7. When you have something that’s not embarrassing to play, get some feedback from real users
  8. Expand core gameplay only after #6 is done
Looking to have #7 done by the end of this month.. we’ll see! In the meantime, here is some more gameplay. I have 4 working powers, and have completely rebuilt the menu system so that it is super-easy to drop in new interfaces. This is the kind of thing that is boring to code but will make future features so much easier to add.

Hardpointe Updates

Slow but steady progress on hardpointe. While trying really hard not to fall into premature optimization, I did find myself running into a common problem that I have with animation and rot.js (javascript in general). One of the comments in that thread was to use postal.js, which seemed like overkill at first but is actually working extremely well.

At this point, the entire game is event driven, which makes inserting animation or other events in between gameplay super easy.

Here’s the latest gameplay, showing one of my favorite attacks, the charge (aka rocket punch). I’m leaving aside decisions on damage aside for now, but probably they will be more lethal.

The overall idea is that the player will not have access to a lot of (direct) ranged attacks. So your best strategy will be to get up close and personal quickly, and then either (a) kill everyone in a few turns (you only have 3 hp or so), or (b) escape.