Tuesday, December 31, 2013

The End


Well, there are bugs, and there's polish, and all of that can wait for tomorrow. I made 12 games(ish) in 12 months (more or less).

The Rat King deserves his own sprite (I think I have one from June 2012 kicking around). The chain fireball spell doesn't quite work as intended, the secondary and later targets don't take damage the way they should.

And really, the Throne Room is really lazy level design.

Still. Playable and good.

Exploding Fireball, Chain Fireball


Again, screenshots don't really capture it, but I've added two new spells, so the mage character is now totally overpowered.


  • Exploding fireball - as a normal fireball, does one point of damage to the targeted enemy. But then, it splashes additional damage to all adjacent enemies.
  • Chain fireball - inspired by chain lightning in any number of other games, the fireball does 2 points of damage, and then up to three subsidiary fireballs are spawned, forking off towards other enemies, up to 4 hexes away. This repeats for a chain of possibly 3 levels deep.
I added a single new animation class that accomplishes both of these effects, it's just a matter of seeding it with the appropriate data.

However, I'm not entirely certain that the chain fireball does the right thing - it's fiddly, and there are angles and whatnot, and maybe I'm doing something wrong. Still, it's nice when it works.

I've got a little over 10 hours to create a final level, the throne room of the Rat King, and maybe even make the Rat King a custom AI.

And I might give myself some slack and slop over into January 1st.

Sunday, December 29, 2013

Blurry, Dotted Lines


If you're reading this at any time other than 2013, the title refers to some song. Don't worry, it's not relevant.

One feature I put in quite a while back is the ability to click far away from a character, and through pathfinding (not initially A*, but I put that in, and it's much better now), the character will move to the destination.

One somewhat confusing thing about that is that this is a turn-based game, and each character gets one hex of movement per turn, even if they have 10 moves of path queued up. This wasn't well communicated, even when I was standing over the shoulder of a player.

So. Now, there's a dotted line that helps the player understand the path that the character is currently planning to follow. With a little attention, the player can even do complex planning to have paths overlap. Good luck with that.

There's currently a bug in it where the first bit of the path is not correctly drawn while the character is animating from one hex to the next. I can fix that most easily by skipping the first segment if the character's current hex is not adjacent to the next hex.

Another thing I put in yesterday (but doesn't make a good screenshot) is the ability to complete level 0 and progress to level 1. Presumably, once I have a complete set of levels, completing the final level will show a victory screen.

Another bit of work (and another bug) that I put in is some NPC logic that will allow NPCs to attempt to navigate to remembered locations of PCs, even when the NPC can't see the PC. This is working pretty well, but occasionally, an NPC will get stuck after discovering the PCs again. I'm not sure what's going on there, but I imagine it's a thing that I can stick a breakpoint on and get some insight into.

I suspect I won't have time for real character advancement, but I've been toying with the idea of awarding one XP to each PC alive when an NPC is defeated, then use that at the end of a level for some amount of leveling up. Or, somewhat easier, on each level, give the characters stats appropriate to the level. Or, easier than that, do nothing. The second level right now is pretty difficult. So be it.

Friday, December 27, 2013

"Flyup" messages


Another thing on my "TODO" list was messages saying "HIT" or "HEAL" that rise up off characters whose HPs just got modified. You see that here (grabbing screenshots of quick animations is tricky).

The combination of the combat log and the Flyup messages seem to really help remind the player what's going on.

I had thought of having character stats maybe in the upper right hand corner of the screen, which would give you more ability to know if you need to take action to guard a particular character. I don't think that's getting in before the end of the month, though.

Combat Log


Hey, remember when I used to be updating this?

I'm winding down the One Game A Month challenge for 2013, and I think I'm going to make my December game a set of small feature improvements on the November game, in part to justify the relaxing and time spent with friends and family I've already done, and am planning on for the remainder of the year.

The feature I want to brag about here is the combat log you see on the right hand side of the screenshot above. Nothing super technically interesting; just a singleton object that collects strings into an array, which anybody can log messages into. Then, in the display loop, I pull out the last several lines, measure their height, and draw them such that the bottom of the log doesn't scroll off the bottom of the screen. Most of the time, that means that I scroll off the top of the window, which is good, but at the beginning, the text starts at the top of the log, and gets added to, until such time as I need to scroll. Maybe that's the right thing, I don't think players will have a strong opinion in any case.

Shout out to cgtextures.com for the paper texture for the background of the log. It looks sort of uniformly beige if you're not looking carefully, but there's some sort of darker smudge at the bottom, and a few speckles here and there, which you get from photographic real paper imagery.


Saturday, November 30, 2013

Enemies shoot back, Selection cursor


The guy with the sword in the screenshot above is about to take an arrow, shot by the rat archer in the far left.

There's quite a lot still to do for this version. The One Game A Month Website allows a few days of slack at the beginning of the next month to finish up a project, and I'm probably going to make use of that this time around, getting some more big features into this game.

Still on the TODO list:

  • doors that open and close - would be nice, probably won't happen for this month
  • NPCs retreating from the map - low priority, but it'd be nice to see them flee from you.
  • NPCs pathfinding to get good ranged attacks - right now, an NPC with a ranged attack will use it if there are targets within 5 hexes (or, maybe 4 hexes, depending on how my visibility code is working). If it can't find any good targets to shoot at, it'll find a path to a valid target, and follow that path. But what it should be doing is finding a path to a good shooting position, which might be behind something that blocks movement, but not visibility. Hm, the right way to do that would be to calculate visibility from the potential target, and pathfind into the target's visibility range.
  • enemies being created by a data-driven factory - all games need rat factories. Right now, I create all the NPCs with the same constructor, then for the archers, I set a flag afterwards, indicating that they have a ranged attack. Better would be to have a description saying what kind of attacks the new NPC will have, and how many hit points.
  • NPC memory - NPCs will pathfind into darkness, which is good, but when they get into darkness, they forget that they were on a path to the PCs, so they just stop.
  • Combat Log - The old Bard's Tale scrolling log thing, this would indicate that a player took damage, or dealt damage, or maybe communicate messages about the level ("you hear scratching noises ahead").
  • Effects - when an attack lands, I could have a splash of red superimposed on the target, briefly. When a character heals, I could have some other effect.
  • Fireball - the guy carrying the staff needs a separate attack
  • Proper PC attack, limited by class - the fighter should only get melee attacks, the archer should only get ranged attacks, the mage should only get magic attacks. Except that the mage should probably be able to do a melee attack, in a pinch. Maybe also the archer. But the fighter doesn't have a bow, and shouldn't be firing arrows.
  • context-sensitive cursor cues - I want to help the player know what actions are possible on each hex. I may not get that done in this version.
  • Game Over - if one side is defeated, I should show this.
  • Balance - right now, the party is way overmatched. The cautious player will make use of visibility to snipe from distance and rest up before re-engaging, which is good, but doesn't feel like really engaging the enemies.
  • More levels - the plan was to have 10 levels for this month. I'll be happy to have a single level working well.


Tuesday, November 26, 2013

NPCs attacking, projectiles in flight



I've been at work, though the screenshot above doesn't display much difference. Things that are more or less working now:
  • resting - for PCs, this heals one point of damage
  • attack (melee) - PCs and NPCs can attack neighboring hexes. Does one point of damage (for now)
  • attack (ranged) - PCs can attack distant hexes. The to hit calculation is rolling less than (or equal to?) 5-range. This will be revisited, sometime.
  • character defeat - when a character reaches 0 hp, that character is removed from the board, no longer contributing to visibility, no longer accepting movement orders.
  • character movement animating - instead of blinking from hex to hex, characters now slide from location to location.
  • arrows animating - when PCs shoot at enemies, a projectile sprite moves across the board. This wasn't terribly difficult, but it's new functionality that wasn't in The Cave of the Rat King, the game I made back in June of 2012, which I'm gradually rebuilding and extending. It's nice to have functionality beyond the original game.
TODO:
  • NPC ranged attacks - For NPCs that have ranged attacks, I need to calculate line of sight to potential PC targets. That should be easy; I've got visibility calculations already. 
  • character hopping movement - back in The Cave of the Rat King, characters had a "hopping" movement that I like. It reminds me of moving playing pieces on a boardgame. 
  • zooming interrupting camera movement - if you fiddle with the scroll wheel during a camera animation, things get messed up. Maybe I disallow that. Or maybe I let it go - it's unsightly, but it goes away.
  • PC weapons - right now, all PCs have melee weapons, all PCs have the ability to shoot arrows. This should be changed so that the fighter character has a sword to use in melee, the archer has a bow to shoot arrows at range, and the mage has a staff to cast fireballs.
  • context-sensitive cursors - it would help the player if I told them what the default action is when clicking on a hex. I'm intending to do this by placing a cursor under the mouse, or centered in the hex that the mouse is over, or something.
  • movement queue - having a dotted line indicating where the character is queued to go would help understand what's going on.
  • highlighting current character - I keep having trouble knowing what character is waiting for orders. Placing a circle underneath, to indicate the current character is easy (I've done it before).
  • combat log - I imagine having a pane on the right side of the screen reporting messages about combat and whatnot. Probably inspired most directly by Bard's Tale, this would give me a little more opportunity to tell the player what's going on.
  • retreat (flee) - there are "retreat" hexes marked on the map; PCs and NPCs ought to be able to retreat from combat. 
  • level win/loss - defeating all the NPCs ought to trigger a win condition. Retreating all your PCs or having them all defeated ought to trigger a lose condition. Currently, the game spins, getting "rest" orders from NPCs if all the PCs are gone.
  • NPCs pursuing PCs around corners - right now, NPCs forget all about any PCs that they lose line of sight with. That turns out not to be very good, especially if an NPC needs to pathfind around an obstacle that blocks line of sight.
  • more levels - creating more levels ought to be straightforward, but I probably won't have time enough to make the 10 levels I had in mind.

Tuesday, November 19, 2013

Player Character Movement Queues Interleaved


Not much to point to in the screenshot, but the party is all lined up, prepared to assault the ratmen lying in wait for them.

The game (work in progress at http://bigdicegames.com/RatTower/tower.html ) now keeps track of what character's turn it is, and on their turn, the character can issue one of many orders:

  • rest - does nothing right now, just passes the turn. Later on, PCs might recover HP when resting.
  • move (adjacent) - move into an adjacent hex. Updates visibility.
  • move (distant) - really, the same thing as above, but it uses A* to find a path to the target hex and queues the path as a series of move orders. The interesting(?) bit is that you can have all of your characters with movement queues, and they each do one move at a time. Taking turns, like mom used to tell you.
There are additional orders that I intend to hook up, someday:
  • attack(melee) - characters that have melee attacks (all characters?) will be able to engage an adjacent enemy.
  • attack(ranged) - characters with ranged attacks (the archer PC, the archer ratmen, maybe the pike ratmen) can attack from a distance
  • retreat off the board - there are special "Retreat" hexes on the board. A character that reaches these may leave the combat. Shame!
  • cast magic spell - the guy on the right in the screenshot above is supposed to be a spellcaster. He was supposed to be a spellcaster a year and a half ago, but I never got that into The Cave of the Rat King. What sorts of spells? I don't know - healing, magic missile. There are options.
  • manipulate level object - open a door, pull a lever
  • use inventory item - I don't have any of these now, but one might imagine having potions or scrolls

My TODO list keeps getting longer - I'm using it largely as a brainstorming dumping ground, without any attempts to deduplicate tasks. Some of the next few things:
  • enemy movement - could be just random movement, to begin with. Pick an empty space, move in to it.
  • enemy attacking (melee) - if an NPC has an adjacent PC, attack - roll to hit, if hit, roll damage.
  • combat log - I kind of want to split the window up into at least two panes, one for combat results and other ongoing text information, one for the main map view. Maybe also buttons for the different orders.
  • character death - this goes along with combat - after a few successful hits on a character, that character is removed from the board. 
  • better prompting of player orders - put a cursor underneath the current character, hold on the current character to see the actions.
  • last man standing - if all of the PCs are dead or removed, the player loses. If all of the NPCs are gone, the player wins.
And then there's longer term ideas, including having 10 different levels, different weapons and armor - all of the stuff an RPG really needs.

Monday, November 18, 2013

Enemies placed


I've just created special game objects for PCs and NPCs, which each derive from a base character class. There's currently no functionality, no behavior attached to these new objects, but that's coming in time.

I rearranged the code that finds spawn locations, and now I'm able to select a subset of potential spawn locations and put the PCs and NPCs in those locations.

I also adjusted the pathfinding code in the above situation; the map allows the player to go South, and then West, and then North, to get to the pikemen and archers in the Northwest of the map, but the player hasn't explored the connecting passageway, so the pathfinder shouldn't allow the player to just click into that room.

On the TODO list:

  • enemies that see player characters should approach, if they have a melee weapon, or hang back, if they have clear lines of sight and ranged weapons.
  • enemies that have a clear attack should attack on their turn
  • initiative ordering
  • display initiative
  • highlight the PC whose move it is
  • allow multiple characters to move (currently there's only just the fighter PC)
  • allow ranged attacks for PCs
  • resolve combat
  • display combat results onscreen (dialog?)
  • revoke player orders when discovering a new enemy
  • doors that open and close
Part of me thinks that's not a lot, part of me thinks it's huge.

We'll see how much gets done by the end of November.

Sunday, November 17, 2013

A* (pronounced "ay-star")


... like the lovechild of Fonzie and Ringo.

I finally got around to replacing my really bad BFS pathfinding with A*, which had only slightly more code. I did have to do some debugging to get it working, but that's still me being clumsy with JavaScript.

If you go to http://bigdicegames.com/RatTower/tower.html you can try it out for yourself. A few caveats:


  • I've already talked about some of the surprising effects of the visibility calculation. Visibility seems to be working as I designed it, with entire hexes blocking visibility or not, which doesn't look right if you're looking along walls, for instance. I have some ideas to fix it, but many of them are pretty sweeping, so I don't plan to change this right away.
  • The pathfinder doesn't know what you've explored, so if you can see a hex, the pathfinder will route you there, even if you haven't explored a path to it yourself. That's something I do intend to fix.
  • This all will probably change as the enemies (and multiple player characters?) get in to the game.
Still, you can walk from one end of the level to the other with no noticeable time spent on pathfinding. So, that's working.

Saturday, November 16, 2013

Level Loaded and Navigable


It's been a while since I've posted any visuals, and I'm happy to show the level that I had been making maps for actually running in my game engine. The path to this point had some interesting steps:

Hexographer parsing

Hexographer writes all of its data out in a pretty easy to interpret text file format. I opened it up in emacs, and saw the size of the level, terrain declarations, terrain instances - all pretty straightforward.

I started writing a Python script to take things apart, and was immediately surprised to find garbage in the strings that I wasn't expecting. Turns out, the text isn't ASCII, it's UTF-16. Whoops. So, I poked around on the internet and figured out how to use Python's "chardet" library, which got things squared away there.

I started writing a tool to take my interpreted structure of the level and dumping that to custom JavaScript, which I'd write to a file, but I quickly got annoyed by the fact that lists in JavaScript can't have a terminating comma: "[1,2,3]" is valid, but "[1,2,3,]" is not. I imagine I could have got around, but I decided, instead to use Python's json library to create the JavaScript for me.

I still think the idea is a good one, but if I had made a custom exporter, code that currently looks like this: 

  "terrain": {
    "Corner 1": {
      "blocks_mvt": true,
      "blocks_vis": true,
      "filename": "c1_0_x.png"
    },

would probably look more like this:

  "terrain": {
    "Corner 1": {
      blocks_mvt: true,
      blocks_vis: true,
      filename: "c1_0_x.png"
    },

Not a big change, but then the calling code would refer to terr.filename, instead of terr['filename'].

Coordinate Conversion

I actually expected this to be trickier than it was - switching coordinate systems can be tricky, and hex grids are weirder than most. Hexographer uses an "offset horizontal layout" in Amit's terminology, and I'm using "cube coordinates". It turns out, the conversion wasn't so bad, and inside a tool, I don't mind the math. I did it in my head, and it worked on the first try.

Transparent Tile Background

I copied my Island of the Rat King code over to my new working directory,, and brought things up, tinkered here and there to change the procedural level generation of last month to an asynchronous asset loading pattern (even with compiled in level data, the tile art is loaded at runtime). All I was seeing was green grid lines on a black background  - which was promising, but not quite right. I tinkered around, and discovered that my tiles were mostly transparent, with opaque black lines for the features, and green lines for the edges of hexes. I went back to my drawing script, and tagged most of my hexes to draw a white background, reexported the tiles, and things are showing up pretty much as I expected

Things not quite working right

Visibility

I'm not sure if I'm entirely satisfied with my visibility. For solid hexes, it's doing great, but for partial hexes, maybe it needs to be reconsidered. Or maybe I adjust some of the data. For example, walls that appear to be straight occupy jagged hexagonal regions. The entire hexagon gets tagged as blocking visibility or not, and that means that the corners, even if the pen strokes suggest otherwise, might block visibility. In a lot of cases, I could flip half-walls and corners to not block visibility, but that might have other issues.

Pathfinding

This isn't anything new - I just haven't ever got around to implementing a simple A* tool, instead, using a breadth-first search. With cubic hexagonal coordinates, I've got a good distance heuristic, which was what kept me from implementing A* back in The Cave of the Rat King.  So, if you're patient, you'll be able to click around corners. But it shouldn't take that long.

Schedule

Here it is, halfway through November, and my goal was to have a party-based tactical RPG done by the end of the month. I've got one level loading, with no enemies, with one character. I may find myself scaling back a lot. I could turn it into "explore this spooky house", which really only makes it a small improvement on The Maze of the Rat King. I think I might do a single-character turn-based tactical RPG, with really simple enemy AI, and really simple inventory (possibly none).


Saturday, November 9, 2013

Fedora 19 NVidia Multiple Monitor Achievement Unlocked



I've been running Linux at home for... 18 years now? Quite a lot. I know that early on, I used Red Hat, maybe there were a few other distributions I used in the early days as I was poking around. Slackware? There was a brief period where I was happy to run Red Hat Linux on a pair of SparcStation IPX machines, just because I could.


And then, there was Fedora Core, and then just Fedora, and most of the machines in this house now run some version of Fedora, though most of them aren't up to date.


I was on vacation a few weeks ago, and I had a netbook with me, running, of course, a version of Fedora. And, of course, I hadn't updated it in a while. Around 4am the day I was scheduled to leave, I decided it was a good time to start an update.


And the update was still going when I packed all my stuff into my rollerbag and my carryon messenger bag. (My favorite plane joke is about the flight attendant that kicked the vulture off the plane for having too many pieces of carrion.) But, in my last bits of sightseeing, I noticed that the upgrade had completed, and I had got to a login prompt, so I powered off, and returned home.


Delighted that the upgrade to F19 went smoothly, once I got home, I triggered an update on my development desktop and my fileserver/webserver machine. Neither of these went smoothly, and I decided it was time to migrate the important files off the fileserver, including the web content. I migrated all that content up to Amazon S3, and pointed the DNS records over to Amazon, and now I've got higher reliability and higher bandwidth. That's good. Getting files up to Amazon is a little bit of a different pipe than before, but in some ways it's easier.


For the desktop machine, I just installed a new hard drive and created a fresh installation of F19. That seems to have worked for the most part. I still have several directories that I need to recover from the old system, and then it'd be nice to be able to boot back into Windows now and then, which I've lost in the shuffle.


The most recent chapter of this particular saga was when I decided that I wanted to reinstall the NVidia display drivers. I've got two NVidia cards in this machine, both GeForce GTX 560 Ti, hooked to three monitors. I could conceivably do four, but I'm limited by desktop space and view angle.


I used Google to find instructions for "Fedora 19 NVidia drivers", and got some instructions that sort of helped, and the instructions had a final step that told me how to undo what I did, which I think is the best part. Also, a necessary part, because I needed to back it all out. The dead end I got to was to have the two monitors on the first card come up, sometimes as one big display, with the login prompt in the crack between the two of them, and the system "tray" stretched across both. Yeah, that's no good. Sometimes I was able to get it back where the login prompt was only on the primary (center) monitor, and the tray was only on the primary monitor, which is better, and sometimes I was able to drag windows over onto the right monitor (sometimes not, as I kept poking at /etc/X11/xorg.conf). One thing that I was having a real hard time doing was getting the left monitor, which was on the second card, to be part of the desktop. I'm sure there are technical terms here that I never have bothered to fix in my brain - I know that there are devices and screens and sessions, and these all have useful, specific, definitions within X. But X terminology has always been a little too specific for a casual user ("It's an X server, because it's serving X requests, like drawing things on the local screen. The client is the software running possibly remotely. Yes, you can run an X client on a remote server machine, talking to an X server running locally." and "It's not 'X Windows', it's a windowing system called 'X').


I went around the loop of booting, logging in as a normal user, launching the nvidia-settings panel, poking at stuff, issuing a telinit 3 and then telinit 5 command, and things not getting better. Now and then, I'd get a screen saying that something's gone wrong, that I should log out and try again. Frustratingly, I had not even logged in at this point. Also frustratingly, the mouse wasn't working, so the OK button seemed like a cruel taunt. I tried tabbing to the OK button, which also didn't have any noticeable effect, and then I realized I could just hit Enter, which made the screen blank, and froze the system.


I poked around inside /var/log, looking for a description of what had gone wrong, but I saw nothing.


Along the way, I went to NVidia's site, and downloaded their driver tools, which weren't exactly the same as the tools at the first website I stumbled across, above (hint: NVidia distributes nvidia-installer, which felt more comfortable to me), but still, at best I was getting two out of the three monitors working.


Whoops, sometimes I'd fall back to a single monitor, displaying at 1280x1024, which is stretchy and gross.


I considered that maybe hardware accelerated graphics weren't that important to me, and maybe I could uninstall and get back to the triple monitor setup I had before. Nope, that bridge seemed completely burned at this point.


I poked around inside /etc/X11/xorg.conf, trying to enable the connection between the device and the monitor at the configuration file level, but that way led to non-booting and backtracking.


I tried enabling Xinerama, but again, "something's gone wrong. Log out and reboot."


I looked up Xinerama on the web, and I was pretty sure I didn't want that, anyway.


I kept poking at stuff, finding web pages for people mirroring displays, and setting up multiple seats on a single system (woo, timesharing!), and finding an article about using four monitors and "Base Mosaic" - which had worked in previous driver versions, but was crippled in Linux to maintain parity with Windows drivers. I know that I had seen the "Base Mosaic" checkbox on the nvidia-settings control panel, but the popup help wasn't especially helpful:







"The Enable Base Mosaic checkbox enables Base Mosaic."


I'm sure it does. I'll bet there's some intern that had 4 hours left to get things checked in, and he had forgotten to make a tooltip for this item, and he couldn't come up with anything better. I would suggest, NVidia, that it's probably better to describe what "Base Mosaic" is, rather than the fact that a checkbox can be checked.


Also, it might be useful to have a name that conveys what your feature does. I'm familiar with how mosaics work; I've made mosaics, they're cool. I've used the Mosaic browser. I know that all my base are belong to someone who set us up the bomb, and I've made my time.


But, I've clicked on everything else at this point, and I've more or less been able to recover from the dead ends, so I set


Option "BaseMosaic" "on"


in the xorg.conf file for all the screens, expecting to get some sort of mirroring or something, but when I restarted, I actually had three monitors light up, and the login prompt was centered on the primary monitor.


Oh, but the left screen was on the right side of the desktop. Ok, that's probably not too bad, I'll just go into nvidia-settings and drag the screen over where it belongs. Done. Restart. Same thing.


Hm, maybe I didn't save. Again. Drag. Save. Restart. Same thing. Huh.


Based on one of the tips from an NVidia employee on one of the forum threads that I saw along the way, I tried using the Gnome-desktop settings / "Displays" control panel, and that had three displays available to position. I dragged those around, hit apply, and I'm done.




So, lessons learned:
  1. Install the official NVidia distribution - or maybe the other one, if it makes you happier. The other instructions involved akmods, which is arguably the smoother path.
  2. Enable "Base Mosaic", which doesn't seem to be documented, and may or may not show up in the nvidia-settings control panel. Good luck.
  3. Use the GNOME desktop settings "Display" control panel to arrange your displays, even though the nvidia-settings control panel also gives you a control that you think would do this.

I like NVidia, I do, and I get that supporting Linux isn't something they need to do. Also, I like Fedora, and I get that making upgrades between versions is hard. But this whole experience seems like it could have been a lot smoother every step of the way.



Thursday, November 7, 2013

Hexographer "Features"


With the scare quotes in the title, I almost expect this post to be about bugs I've found in Hexographer. I've found one, and filed a bug report, but that's not important right now.

What I have done in the above map is tidy up some bits that were annoying me, bits of walls that hook up with actual terrain pieces. It occurred to me that I can add these in as an extra graphical layer that make the map look correct, without having any change to the underlying behavior.

It turns out, Hexographer has this same notion; there's a "terrain" type that a hex can have, and then hexes can have zero, one, (or many?) features. The little connecty bits adjacent to the doors, above, are features. You may not be able to read it, but there are hexes tagged as "Retreat" and hexes tagged as "Spawn".

I started off using Hexographer as a convenient place to screw around with my hex tiles, and as I've moved along, it seems like it's going to be a workable level editor for the November game.

Towards that end, I've started looking at the .hxm file that I've been saving out, and it's plaintext and easily parseable. There's a section of the file that describes all the hex types available, and then there's a list of hexes, with what kind of terrain and features.

I'm not sure if the level I've been working with, above, is actually going to make it in to the game, or if it's just a test, but it's got most of what I need. I think the next thing to do is to work on taking the .hxm file and turn it into a format that I can use at runtime, and begin making a game in this level.

Wednesday, November 6, 2013

Doors on the map


There are going to be some number of player-interactable objects on the map, from doors to dead bodies to chests. One could imagine even more, like pools and traps, but that's probably beyond what I'll do for November.

The fundamental thing about a door is that it has two states, open and closed. When open, it blocks sight and movement. When open, it allows both. The way that my visibility and movement code works is that an entire hex is movable/immovable, transparent/opaque. Given that, it makes sense for doors to be centered in a hex.

I've added two doors in the above map, and in each case, the joining of the door to the surrounding walls is problematic. For the horizontal door (permitting movement North/South), I could create special corner pieces that meet up with the door, which wouldn't be too bad. For the vertical door (permitting movement East/West), the connecting pieces seem trickier to get right.

I've also added the vertical lines making the N/S walls seem a little smoother. That requires more adjusting, especially once I get wobbly lines in.

The text there won't be visible in-game, it's just notes for me as I sketch out this encounter.

I'm currently planning on 10 encounters of roughly this size for my November game - I may rearrange this one pretty substantially, since the fiction is that these are portions of the Tower of the Rat King, and the above layout feels like it's been carved out of solid rock, like a dungeon. Perhaps this part of the tower is set against the hillside.

Tuesday, November 5, 2013

More hatch testing


Several pieces went into the above map:

  • rewrote the "inHex" math - each of the penstrokes that you see there is actually composed out of a sequence of positions along a line, which then gets a "brush" image applied to the tile, more like a rubber stamp than an actual brush. The image is something like 20% or 30% alpha, but since the images overlap so much, eventually, you get a pretty dark section in the center of the stroke, fading out to the edges. This achieves the felt-tipped pen effect, even though that's not exactly what I had in mind. Rather than figuring out where the strokes should begin and end, I just filter out the bits that aren't in the hexagon, or not in the section I want to hatch (a corner has only one quadrant that I want hatched, for example). I had taken the JavaScript code that I was using inside my previous games for turning screen clicks into hex indices, rewrote it in Python, and using that to know if the pixel was inside the hex. I got something wrong, and things seemed rotated 90 degrees, which I couldn't understand, but it turned out I was just truncating when I should have been rounding.
  • generating twelve versions of each feature - since I'm generating these tiles in Python, it's easy to create a bunch of variations. In this case, I slope the hatches at three angles up, three angles down, and then I rotate them 90 degrees, for a total of 12 different hatch directions. I don't want anything too close to horizontal or vertical, and even 45 degrees off feels wrong, so maybe I'll regenerate things again.
  • Hexographer, from Inkwell Ideas - I don't mind plugging Hexographer - it's a Java-based map editor that does hex tiles. Not a lot of tools out there run on Linux, or do hex tiles, and this one does. I haven't used it much, but so far, it's suiting my needs. I wrote a small script to create a list of my custom tiles, imported that into Hexographer, and was able to assemble the above map in a few minutes.
Looking at that, I imagine the party coming in through the passageway in the Northeast, fighting some guards in the first room, one guard fleeing to the South, and the heavy combat forces ambushing the party from the Northwest. That sort of combat progression might be more than I'll deliver this month, but it'd be a cool place to go.

A few things I want to add:
  • wobbly pen strokes - look at how ruler-straight those lines are. If there was some variation in the line, perpendicular to the overall direction of the line, it'd look more hand drawn.
  • finished edges on some full hexes - the East/West walls all have that horizontal, smooth, line marking the surface of the wall, but the North/South walls only have an edge when it cuts the hex in half. Adding hexes that are solid, but have an edge would be easy enough. I might have to do something tricky to get the edge to sit inside the full hex. Shouldn't be hard
  • ball point pen style - the felt tipped pen style is OK, but I think I want sharper, less fuzzy strokes. Like a Uni-Ball Vision Needle pen. I can draw some lines with one of those, scan them, and experiment to reproduce the actual physical marks.
  • doors - the heroes need to knock down doors.
  • columns - block movement and visibility
  • other terrain features - some things would block movement, but not visibility (a portcullis, perhaps?)

... and the imagination runs much further than that, thinking about how lighting is going to be done, how the AI will handle retreating and engagement, if I wanted to have secret doors, how that would fit in to the above tools, and so much more.

Monday, November 4, 2013

Hex Tile Wall Test

For the next game, I'm going to tackle interior spaces, which present some obvious problems with hex grids. I've considered abandoning the hex grids and moving either to square grids (boring!) or to "natural" grids based on Voronoi regions. I think that latter has some interesting possibilities, but there are so many unanswered questions there that I'm going to defer experimenting with it until the new year.

The above tiles capture some of the hand-drawn hatching of, e.g. Dyson Logos. There's more work to be done, but when I look at the effect there, I see a felt-tipped pen stroke, which isn't quite what I'm going for, but it's not bad.

I wrote a little Python script to output 14 different hex tiles, and I assembled them (duplicating a few here and there) into a little room by hand in GIMP. The slant in the hatching makes the entire map seem rotated, but that's just an optical illusion. Will I fix that? Maybe. Perhaps I'll take a page from Dyson's maps and mix up the hatching, all different directions. That could be fun.

Sunday, November 3, 2013

The Island of the Rat King, now playable online (finally)

http://bigdicegames.com/RatIsland/island.html

I had managed to get the game to a playable state by the end of the month, but I hadn't got around to recovering my ability to serve web content. So, I went through the Amazon S3 Tutorial, which made sense up until getting to the Route 53 bit, which you apparently have to sign up for separately? For whatever reason, it took several days to get access to the DNS functionality, and then I tediously updated all of my various domains. I'm not certain that they all work, but the link above seems to.

On to November's game: The Tower of the Rat King.

Tuesday, October 29, 2013

Rat Island feature complete



Ship it!

I've got several of the outstanding (I love both senses of that word - "not yet done" and "amazing") bits done, and my TODO list looks like it's really just polish at this point.

Some stuff I got done today:
  • Credited Dominique Crouzet for the hex art. They class up the place, and the art is CC-attribution, so a) it's a good thing to do and b) it's the right thing to do.
  • Guard combat working - I had built this already; combats that don't respawn and don't let you pass. I just had to allow combats to not have a sprite.
  • Rat King special victory condition - I made a fancy dialog (see the September game for the template), and it wouldn't show up. Rather than debug that, I added special victory text (see above screenshot).
  • Reset the player to the start position if they get defeated.
  • Reset the player's hit points and experience points to the start of their current level when they get defeated.
  • Tinkered with the camera after defeat - the camera should recenter on the player, even if they teleport back to the start. This seems like it's mostly working, but there's an issue if you get into combat as part of a long move (see TODO, below)
  • Made sure that items don't spawn (or respawn) on top of the player, on top of the exit, on top of other items, or on top of the start location.
  • Rejiggered experience ramp - you basically need to kill two monsters of your current level to level up.
  • Added level up/down cheats - just to debug, it goes faster if you're at level 15, rather than actually playing the game.
  • Added absurd levels - this is a game designed for one character, levels 1 - 10. It should say that on the box. (TODO). I added levels 11-20, mostly for my own cheating purposes. But if you're having a hard time fighting the Rat King, you can grind away at some of the level 9 monsters and get an edge.
And, as always, there are some things remaining to do:
  • Deploy - either bring my web server back up (probably reinstalling Fedora 19 along the way), or push to a web host (Amazon S3?). The quick solution will be just to push the game by itself. The longer solution will push all of the bigdicegames.com website.
  • The pathfinder can route you through combat, which can lead to multiple combats in a single "move". I don't think that's a bad thing, but it's weird. A long move through combat also lets the camera get out of sync with the player movement. Perhaps just snapping the camera to the player's location on arrival would fix that.
  • The pathfinder isn't smart - it just does a flood fill to find a path to the clicked location, and can take a long time to find a path. I could add a upper limit to the amount of time the pathfinder uses, and/or implement A* to make it faster. I don't think these are crucial; just don't click far away.
  • When the player arrives in combat, it wouldn't be hard to remind the player what their level and HP are at.
  • Fancy up the title screen - it's fancyish, but I can add more homage references there, including "An adventure for one character levels 1-10". 

Monday, October 28, 2013

Development proceeding - this just in, Grinding!


When I say "grinding", you either think of taking the rough edges off of metal, or you think of tedious combats to level up. I prefer to think of the latter as a player-driven ability to select the speed of the game and the level of difficulty, at least when it's not sloppy game design.

I won't claim terrific game design, but I will point to this dialog as evidence that you can now wander the island and find three different kinds of creatures to combat. If you defeat them, you gain experience, and perhaps level up, gaining hit points. If you flee, you return to where you came from (setting the stage for "guard" combats). If you are defeated, you ought to respawn with full hit points back at the start of the map. That doesn't happen yet.

Looking at the amount of work remaining, I should be able to wrap up a "shippable" version by the end of the month. Hopefully, my web server will be up and running by that time.

Sunday, October 27, 2013

Sneakernet, 2013 Style


Back when I was a kid, the closest thing we had to "the cloud" was walking around, moving files from computer to computer by carrying floppies.

These days, that seems so antiquated - except for the times when you decide to upgrade the OS on your fileserver, causing Postgres to fail, causing YUM to fail, possibly leading to shared libraries being truncated (or is that an independent problem that just happened to fail at the same time?)

So, today, I got a USB external drive, hooked it up to my laptop where I had been doing the development for the past few weeks, walked it over to my desktop development machine, copied the files over, and have managed to verify that all of the files are there and working, as the above screenshot evidences.

I had been hoping to get a lot of work done on the game today. The fact that I've got my development machine capable of doing development, that's progress from where I was on Friday, so that's good. There's a lot of stuff that I have on drives that I haven't yet figured out how to boot, so that's work to be done, sometime. There's a lot of features I need to get in to this game by the end of the month. (1GAM permits a few days of leeway, which I haven't yet allowed myself to take advantage of. Maybe this is the time.)

I find it interesting that the hexes on the right side of the screen here look purple on this monitor, while on the netbook I was developing on, they looked dark blue. Similarly, the darkened hexes that I was using for last month's game look nearly black on my phone. So, the lesson is of course to test out your game early and often and make adjustments as appropriate. Perhaps I should have some sort of brightness feature - an option in a settings menu, perhaps, or just some constants that I play around with and ship as suitable defaults.

Oh, while we're on "lessons learned": back up your stuff. Really. And, when you think it's a good idea to upgrade your system, back up your system first. And it might even make sense not to upgrade the system so much as build a new system from scratch (new hard drive, fresh OS) and bring your data with you.

Even if the game was in a state where I felt like I wanted to share a link to a version, the webserver is one of the machines that fell prey to the upgrades that seemed like a good idea at the time. I expect to be able to sort that out, hopefully by the end of the month. Probably plus a few days.

Monday, October 21, 2013


You may notice a few things different (spot the differences! Just like those fun games in the back of Highlights magazine!) about this screenshot compared to the previous screenshot.


  • more or less working buttons on the bottom of the screen - The "Attack" button works, the "Flee" button doesn't. There are "OK" buttons elsewhere that seem to mostly be working.
  • more stats in the grayish monster card on the left - The monster stats are kept in two completely separate places, written in two separate languages. So, maybe they're mostly in sync. I went through and created a full progression for hit points and experience points for the player and for monsters. I'm not sure it's going to be balanced to be fun, but there's a progression.
  • actual dynamic output of combat events in the right hand pane - it's not really enough to fully understand what's going on, but combat events are being displayed. Now that I write this, I see that it's very similar to The Bard's Tale's display.
There's still quite a lot to cram in, particularly the way that combat gets invoked when moving around on the map. Once that's in, there's a lot of revisiting and polishing.

Also, the blue tiles should have mountain icons, and the red sector of the map shouldn't be terrifying to people who know that lava=instant death.

Sunday, October 20, 2013

Seriously.


At some point, any sufficiently advanced game toolkit will have some means for supporting text displays. It's amazing to me how much work it is to get a baseline of functionality, and it amazes me how many different times I've done it - not that I've often gone far beyond the minimal baseline.

In the screenshot above, you'll see title text, which is baked in to the yellow background image. Beneath that is an informational card, which is its own image, and created in a Python (PIL) script. The text on the right, demonstrating simple text rendering, including word wrap of long strings, that's actually done by my JavaScript code, using a "sprite sheet" that I generated with yet another Python (PIL) script.

I'm using Jaws.js, which has a "SpriteSheet" class, which seems to be designed for sprite animation frames, but can be pressed into service for character letterforms. It has options for the frames to go in a strip to the right, or in a strip going down, but there's no facility for a 2D grid of frames, which seems like it might be a good thing to have.

This isn't even what I'd call "finished", in that there's sloppy stuff in there that I want to clean up, but it's probably good enough to get this particular game working. Good enough to ship.

Which is to say that I'm not done writing character rendering code. [sigh]

Saturday, October 19, 2013

Obstacles that block movement


I've hooked the visibility back up again and added in some terrain items that block movement and/or visibility.

Still no real gameplay.


Friday, October 18, 2013

Island Regions generated


I've been slacking, like I do. But I took the maze generation and reworked it. There are now three regions, with a border region between each.

Next up: generating passages between the island regions.

Then: putting monsters in.

Wednesday, October 2, 2013

September Game "Maze of the Rat King" bug fixed, time to start on October game

So, if you've been waiting to play the September game until I'm done with it, I now give you permission to hit http://bigdicegames.com/RatMaze/maze.html as I'm not going to be updating it further.

That sounds bad, let me rephrase: "Yay, the maze game is now full up with awesome, and it's ready to go!" Which sounds a little over the top. Somewhere in the middle, though, I'll say, yes, there's stuff that didn't get done (like any of these fixed time limit games), there's stuff I'm pleased with, and I'm happy to have working pieces to carry forward to the next game.

The last bit that I just fixed was a weird loading behavior - when I would load the game the first time, or one of my friends would load the game any time, certain assets wouldn't load, and the game would just show a black screen.

Turns out, what was happening was that I had a bug where I was launching the Jaws.js game framework twice. Jaws, like most Javascript engines, gets a lot of its work done through callbacks, so what was happening was that I'd set up a list of assets, the framework would issue asynchronous calls to load those assets, and would go away. Each time an asset would be loaded, it'd tally up the loaded asset (or failed load, if that happened, which it didn't in this case).

I was loading 23 assets, I was seeing 23 callbacks, but I was only seeing 20 loaded assets. It took me a while to recognize that 3 of those assets were being loaded twice, and it took me a while to recognize that I was launching the framework (and hence the loader) twice. Once I saw that, it made sense - the tile art was much smaller than the splash screen, and loading a 100x115 PNG twice is much faster than loading a 800x450 PNG, so some of the tiles would get loaded twice, the loader would say, aha, I've loaded 23 things, that's all I need, let's start the game. And then my splash screen code would leap into action and it'd all end in tears, as the first thing that I do is try to draw my biggest piece of art. Bam.

I'm not going to badmouth Jaws.js - it's so far been a pretty good tool, and I've been able to walk through the code pretty well. There are things that I'd change, and a few places where I've stitched in debugging code and a few places where I've stitched in new functionality. I really need to get back to the original author and share my experiences - even if he's not interested in my patches, I expect he'd appreciate knowing that it's getting use.

I do think that as I continue to make games with my toolbox of code, I'll lean less and less on Jaws.js and might eventually get rid of it altogether. I think right now, I'm using the asset loading and the keyboard/mouse/touch handling, which I could probably rewrite without much effort if I needed to.

I don't need to for the moment, so I won't.

Next up: Our hero has escaped from The Maze of the Rat King, and pursues him overland through adventures in the wilderness.

Sunday, September 29, 2013

Front matter


I've updated the splash screen (which you'd only have seen if you had been playing the Android builds up until now). I've also added a main menu, a title screen, a credits screen, and going in and out of the game. Nothing exciting, but the sort of thing that makes a game feel like a package.

I struggled with getting the buttons working right on all three of the platforms at the same time: desktop web, mobile web, and mobile app, but I think they're working now.

I think there's some bug in the way I'm loading my splashscreen - the first time I load the game, it fails, but eventually it gets loaded and is cached. If you try to play the game, and just get a blank screen, hit F5 a few times. Sorry.

Maybe I'll get to fixing this today or tomorrow. If not, it's hitting the features I wanted to get done for the month.

http://bigdicegames.com/RatMaze/maze.html

Saturday, September 28, 2013

Things that don't make for good screenshots


I spent some time tinkering with the game camera, and got two pieces pretty much working: dragging and pinch/zoom.

The dragging is accomplished by taking long clicks (longer than half a second) and applying the offset from the mouse(touch) down event to the current mouse(touch) position. That's pretty good, but then I have some special case code to get rid of that offset through interpolation, and it's pretty similar to the camera movement code I have in the other branch, which focuses on a hex. Similar, but completely separate. Code redundancy is nice, if I expect one path of the code to be eaten by gamma rays, not so good if I want to maintain it.

The pinch/zoom code is relatively simple: when I detect two simultaneous touches, I capture the distance between them. As the touches update, I compare the new distance to the old distance, and scale appropriately. There's a bunch more fiddliness, and it turns out that I end up snapping the camera position back to where the character is standing, which is probably not the best solution, but it's a solution.

Maybe tomorrow, I'll put in the main menu screen. Cause I can't have a credits screen if I don't have a menu screen.

Maybe I'll update the character movement so he hops instead of blinks.

Thursday, September 26, 2013

Mobile progress


I only have a little more time to go on this one, and I haven't been putting in a bunch of time lately. However, I have sorted out some issues with handling touch events that had been keeping the game from working on mobile.

I also learned a bit about remote debugging: https://developers.google.com/chrome-developer-tools/docs/remote-debugging which proved valuable - breakpoints and data inspection are handy.

I also figured out that by passing "script" to the Closure "calcdeps.py" script, instead of "compiled", you get one big uncompiled file, suitable for debugging. I also saw that there's some hints of a source map, but I haven't dug in to that yet.

As the above screenshot evidences, you can use a single touch and move around, as if you were using a mouse to click. I really want dragging for both desktop and mobile to work, and pinch-zooming on mobile. Maybe that'll be easy, given the things I've built, the things I've learned.

There ought to be sound, there ought to be a title screen. Other than that, this is just about done.

Sunday, September 22, 2013

On Better Hiding Keys


When I first wrote the code to place the items (exit, key, gate), I used this process:

  1. pick a random location
  2. find the farthest place away from it - put the player there
  3. find the farthest place away from the player - put the exit there
  4. find a spot about 70% of the way from the player to the exit, put the gate there
  5. find a spot about 50% of the way from the player to the gate, put the key there
And this works, in the sense that the key and the exit are guaranteed to be on the correct sides of the gate. It also does a good job of forcing the player to travel the furthest, guarding against degenerate mazes.

I recognized one thing that it didn't do was to allow the player to reach the gate without first having reached the key. And, if you're guaranteed to pick up the key before you reach the gate, one or both of them isn't really fulfilling its purpose.

So, I've put a new build up here: http://bigdicegames.com/RatMaze/maze.html The big difference here is that the key is now placed differently. I've got a modified version of the "farthest place away" code that generates a table of locations indexed by distance from the start location and another table of locations indexed by distance from the gate. I then walk through one of these lists and cross reference with the other list, and I can find out the distances for each location to the start location and to the gate location. I find a hex that has the maximum sum of these two values, and that's going to be a place far away from both, and probably off in some dead end; a good place to hide a key.

One thing I'm pleased about, even though the code is a little gross, that whole thing is running in O(n) in the number of walkable spaces inside the gate. A somewhat simpler algorithm would have been O(n2)

So, the game is pretty much doing what it needs to - you get a maze, you have to find the key, the gate, and the exit, and visit them in that order.

Some things that aren't working correctly:
  • pinch to zoom on mobile - the mobile experience isn't really something I've looked at recently.
  • mobile viewers of the webpage can't click - I haven't really been optimizing for this case, but it's totally broken. May stay totally broken, depending on how excited I am about fixing it.
  • dialogs when finding an item - this may be pretty simple, and the text is going to be trivial to write, something like "You have found a key! Now find a gate to unlock!"
  • sound effects - footsteps, picking up a key, opening a gate
  • main menu, about, credits screens - I'll probably reuse much of earlier projects, that's what I'm here for. 
  • HUD? - maybe I should provide an indicator that you've picked up a key and are looking for a gate. Almost like a mini quest log thing. Or a simple inventory. Or maybe I don't need it for this game.
  • smoother movement - blinking from hex to hex isn't what I wanted. I like the Lair of the Rat King implementation where the guy would move by using a spline, hopping from location to location, like a piece on a board.








Friday, September 20, 2013

Fog of War


There's no war. And not really much fog. But that's what I'm calling this functionality - stuff you can see is bright, stuff you've previously seen is darker, stuff you've never seen is black.

This took a fair amount of work, even though it's a very small difference from the last screenshot, because I did a bunch of refactoring under the hood - now there's a "location container" class that holds "locations".

The various bits (player character, key, gate, exit) ought to be held inside locations, but that's not in yet.

Things I hope to get in this weekend:
- picking up the key
- opening the gate
- landing on the exit
- dialog boxes demonstrating all of this





Sunday, September 15, 2013

Visibility, pathfinding, new build up


http://bigdicegames.com/RatMaze/maze.html

It's starting to feel like the game I have in mind. Big bits that aren't there:

Smooth movement - in The Cave of the Rat King, character movement had a feel like physical counters on a boardgame, with "hopping" from location to location. That movement is smooth between points, rather than now, where the character blinks from tile to tile. It's not going to be very animated, but it's something.

Fog of war - the greyed out bits of the map right now are unexplored. I want to have the explored, but not currently visible, bits to be greyed out, and the unexplored bits be black. I'm in the process of rewriting the Tile class, which should make this sort of thing easy.

Picking up the key - when the player lands on the key, stuff should happen

Landing on the gate - there should be logic with the gate, keeping the player from going through without the key. Huh, I just realized, the way I generate the key position right now, there's no way to get to the gate without having the key.

Landing on the exit - trumpets, confetti.

Pathfinding with awareness of player knowledge - the pathfinder doesn't take into account if the player hasn't explored a location, so you can click on the exit even if it's greyed out.

Mobile support - I haven't made an Android build in a while. When I do, I'll want to support pinch to zoom.


It's kind of weird, shifting from making minimal implementations to building big pieces of a system that are only lightly used by the current game. The tile system I'm working on and the visibility system are examples of things that I know I'll need down the road, even if the work doesn't seem necessary this month.

Visibility Calculations


280 lines of hexagon math, 148 lines of test harness to verify the code as I was going, and now I have a visibility routine. The thing with this month's mazes is that visibility is always going to be very constrained; I could have accomplished the same effects in a lot less time, in a lot less code by doing a simple raycast in 6 directions.

I'm halfway through refactoring the tile code - my intention is to keep track of what the player has seen in the tiles, and use that to create a "fog of war" effect; stuff you currently see is bright, stuff you saw previously is darker. Stuff you've never seen is, let's say... black.

I've been wrestling with what colors to use for the various tiles. Anything that's at all colorful has been, to my mind, debugging assets. The stuff I was thinking I'd use was the greyscale (anything between black and white, inclusive) hexes. But the difficulty there was that a currently visible wall is going to be some color of grey, and a previously visible path tile will be some other color of grey, and a previously visible wall, that's yet another color of grey, and it's all too much. So, new assets for the tiles, I guess.

Saturday, September 14, 2013

Sometimes, the successes, they look like a long list of numbers.


I'm going to tag this with the "screenshot" tag, which is an abuse, since the above isn't an actual screen from the game, or running the main loop of the game. What it is is a debug harness running some of my new code. If you look carefully at it, you can get some hints where I'm going with this.

Hint: the contents two lines at the bottom of the top pane are important, and perhaps more important are the contents of the line that isn't there.

Ok, that's elliptical.

Saturday, September 7, 2013

Key, Gate, Exit


Well, I've got something working. I don't like the behavior, and I don't like the implementation. But it's "working". Including sometimes when it isn't exactly working the way I want, even then it's pretty much working.

My process here is to first pick a random spot on the map, I call that the seed. Then I find a spot as far as I can (pathfinding-wise) from the seed. That's the exit from the maze. Then I find a spot as far as I can from the exit, that's the start. I'm not entirely sure that that's the right feel for a maze - but it does give the player the maximum distance to travel in the best case.

After that, I find the path from the start to the finish, and drop the gate 70% of the way along it. This divides the maze into two sub-mazes. I want to pick a spot in the player's sub-maze, far away from the start position and far away from the gate. Instead, I just pick a spot halfway from the start to the gate. This puts all the interesting bits of the maze on a single path, and if you're extremely lucky, you won't have to backtrack at all.

I'm finding that I want to build some nicer tools for handling tile positions - right now, I'm iterating over lists more than I want, and it's gross.

Also, sometimes, the player ends up at a location that's not the furthest from the exit, so something's not right.

If/when I rewrite the tile position code, maybe that bug will get sorted out.

I'm calling this stuff good for now, with the intent to come back and rewrite it to make it pretty.

TODO:
clicks make player move
player animates from location to location
player picks up key
player can't pass through gate without key
landing on exit is a victory

That's not much, really, and I have over 3 weeks to do it. That means I'm likely to actually get around to the cleanup, I hope.


Refactoring can be painful


Since we last met, I added in some (placeholder?) icons for various things in this game - a key, a gate, and the exit. Also, I'm reusing a player character icon from my last hex game, The Lair of the Rat King. The icons are just dropped anywhere on the white tiles, so there's no guarantee that the player can reach the key in order to open the gate and then get to the exit. In fact, in the screenshot above, the player can get to the exit without mucking about with keys or gates.

I've got a plan for positioning the exit, then positioning the player, then positioning the gate to be between them, then positioning the key to be between the player and the gate. "Between" is a path-finding thing, in this case. Should be easy.

One thing you can't see here is that there's a "camera" that pans around the level to focus on the player character once all the tiles have been placed. This was working acceptably well, and so I started pulling the camera into its own class, and in so doing, got things mostly broken for most of the past 12 hours.

But things are back to functional again, and it's kind of fun just watching the mazes be generated.

I'm beginning to wonder if there's a bug in my maze generation code - I've seen some mazes that have surprisingly long, straight passages. I've seen more than once a level that's just a single straight corridor, with no turns. That seems really unlikely to happen once, much less twice.

Wednesday, September 4, 2013

Now with click detection and screen -> tile math


In which we learn that math is hard, and going to sleep is good.

Hex grids are cool, and they give me a frisson of strategy-geeky joy when I look at them. I was just chatting with my sister about hex grids, and she reminded me that an early influence on me (before the wilderness rules of Expert Dungeons and Dragons) was the game "Outdoor Survival" by Avalon Hill.

I remember playing a variety of starship battle games on the living room table with large hex maps and 1/2" cardboard counters. A buddy of mine at the time, Nathan, complained that a flat map didn't capture the full three-dimensionality of true space combat. "Oh, come on", I said, "you can stack the counters, surely that's three dimensional enough".

Those old hex maps used a numbering system where each hex had a 4 digit number printed on the map, going from 0000 to 2245, maybe. The first two digits were the column, and then the second two digits were the hex within that column. That's all fine for pencil-and-paper reference, but it becomes cumbersome for algorithmic computation of adjacent hexes. Quick! What hexes are near 1327? Well, 1326 and 1328, sure. And then 1227 and 1427. Um, 1226 and 1428? or 1228 and 1426? Could be either, depending on how the map was laid out. Bah!

Last summer, I made a hex-based RPG using this "offset coordinate" system, and I managed to make it work with a little modular arithmetic and a fair amount of special-case code. I never managed to get a distance calculation working, just adjacency. More recently, I stumbled across the Q-Bert coordinate system also known as the Cubic coordinate system, in which you put x and y 60 degrees apart, which makes the numbering really simple, but then you introduce a z coordinate such that x + y + z = 0. This doesn't seem like it adds anything, but once you have well behaved x,y,z coordinates, calculating distances on that surface is simple. Click either of the links above to see the math.

Ok, so I've got distances now. The next tricky bit is converting a position in screen space back to a tile. In my offset coordinate game last year, that was some involved math, with three different regions, a rectangle, some triangles, bleh. With the new cubic coordinates, I just reverse the code that I use to figure out the tile-to-screen positions, which wasn't all that hard, and then I use the rounding technique to clamp to a set of integer tile coordinates.

Along the way (and not terribly late last night, just later than I intended to be up), I added some debug code to my hex maze display to highlight my x, y, and z axes. I did this by checking to see if the x-coordinate was 0, and if so, color the hex red. If the y-coordinate was 0, color it blue, and if the z-coordinate was 0, yellow. It took me maybe a half hour to figure out that the y-axis was the collection of points where x was 0, and the x-axis was the collection of points where y was 0, which was why the blue hexes were a horizontal line, instead of the red hexes, like I had been expecting. Part of me knew this already, but my sleepy brain wasn't listening.

I think I've worked out the difficult bits of the math now, and I can click on tiles, and my current debug code lets you turn path tiles green by clicking on them. Hey, that's almost like gameplay. Solve a maze by drawing a path from one side of the screen to the other. Ok, it's self-directed gameplay - the computer doesn't give you any goals, or enforce any rules.

Still, if you like clicking on hexagons, it's got that.