Friday, July 8, 2011

Inventory and Maps

Well, our trip to Eureka was a success. We had a good number of nights by the fire, a few days out on the boat at the lake, and tons of fireworks! I was a dork for not bringing my audio recorder, as the wilderness noises out there would've been handy to have. The crickets sound different, there were crackling campfires, and even distant elk grunts. And the semicircle of campers were a bit of inspiration for post-apocalyptic makeshift communities (though way more luxurious).

Back on the homefront, I managed to squeeze quite a bit of work into NEO Scavenger in the limited workdays since the 30th.

Inventory Screen
When we last left the inventory screen, one could see equipped items in the various slots by pressing "I" on the keyboard. Clicking on the arrows at the center of the screen allowed the player to toggle which equipment slot was displayed on each half of the screen.

Fast forward a few workdays, and here's what we have:
Inventory screen showing local hex items and a plastic bag in the player's right hand.
One of the new features in the inventory screen is a category for showing the items on the ground in this hex. This is probably going to expand to include items the player scavenges for, but for now, it shows randomly generated loot. Each hex has a probability for finding certain items, and in this case, we found a few cans of soup. I noticed I was constantly opening the ground contents as I moved around the map, so I made that category open by default when the screen opens.

The right side of the screen is showing the player's right hand slot, which currently has a plastic shopping bag equipped. Equipping an item is just a matter of dragging the item over an empty slot graphic for a category, like so:

Equipping a plastic bag in the right hand.

If an equipped item can act as a container, they will have a dark box below them, representing their storage space. The ground always has available storage space, and the bag has room for about 6 cans of soup.

The idea is that items will have differing sizes, and differing storage box sizes, to limit to how many items one can fit in a container. Items cannot overlap in a container, so the player must arrange the items via drag and drop to fit if they want to maximize carrying capacity.

Containers that are moved around maintain their contents, and can contain other containers. To avoid infinite nested containers, I want to make containers use at least as much storage space as they provide.


To make life a bit easier for the user, I added a few helpers to the inventory screen. First of all, the drag and drop highlights the object to let the user know if it will fit here or not. Red means it won't fit in it's current position, blue means it will. I also added a snapping/padding algorithm to be a bit more forgiving on the player, so placement doesn't have to be pixel perfect. The game will just snap an item to the nearest space where it will fit, within a certain threshold.


Dragging the can to a location it won't fit (left) vs. a place it will (right).
I also added doubleclick support to the items, so the user can just doubleclick an item to move it. The behavior right now tries to move the item from it's current side of the screen to the opposite side's slot or container, if available. If it can fit, it finds the first available space and puts it there (preferring the equipment slot if empty, otherwise the storage space). If it cannot fit, it does nothing. I thought this would be important because constant mousing across the screen can be tiring, and I always appreciated it when games like Fallout allowed for doubleclick transfers of items. I will likely add a "transfer all" mechanism in there too.
I'm still not sold on the UI for the categories, but I haven't figured out an improvement yet. I did toy with the idea of a human body as a category selector, but haven't hooked it up yet.

Human silhouette as selector for equipment slots.
I'm not sure this makes it much easier to use, though it might slightly improve user recognition of slots. It'll require more testing and experimenting.

Eating and Time Passage
I also made a slight change to the game after trying out the scavenging of soup cans. Originally, a turn lasted 4 hours, and the player could move 4 spaces per turn (barring hills or forests). With this timescale, I was getting hot/cold/hungry very quickly, and hardly had time to deal with it. Also, the player character ate whatever he had on hand automatically when he became hungry. Overall, this left me feeling a bit overwhelmed by the amount of "surviving" I had to do each turn, not to mention the rapid day/night/weather changes.

So I decided to change the turn length to 1 hour, and make eating a manual task. Now, weather changes less drastically per-turn, and the player can choose when to eat vs. ration. And health conditions take longer to set in, allowing for more exploration time between crises.

So far, I like the new pacing. After tinkering around with it a bit, it felt more like a game than before. One thing which did seem to work as-designed was the overheating mechanic. My character was starting to suffer from heat exhaustion, and it started raining. Immediately, the player returned to normal. And on another occasion, I was able to postpone heat exhaustion by taking off his t-shirt. A few times, I died of heat exhaustion as well, in sustained 105F+ temperatures.



Maps!
Up until now, the game has used perlin noise to generate smallish (36x72) hex maps. Anything larger tended to bog down the game and ultimately crash due to timeout. Since I wanted to stage my game in a post-apocalyptic Michigan, I needed a way to edit maps. So I decided to repurpose my random-image code to support loading a hand-painted map of Michigan.

Michigan, in 422x489 pixel, 6-color glory.
The map is 422x489 pixels, with one pixel corresponding to a hex. Each color is a different terrain type. It lacks a lot of the features I would like to add, but has enough to equal the random maps I've been using.

But first, some optimization was in order. As said before, I was having trouble much above the realm of 70x30 pixels. There was no way 400x500 would fly as-is. So I broke up my map-parsing into manageable chunks, and called a chunk each game cycle until it was done. Then, I dispatched an event to signal the game-start code. This, along with a few bug fixes it revealed, allowed me to load much larger maps.

Second, my map needed some special treatment. Careful readers will note that hex maps have every other row offset by half a column width, so using a square-grid bitmap to define a hex map may cause weirdness. Well, it did. My rivers looked like stitches in-game, with land bridges every other column. Turns out, I had to paint my rivers using a 1x2 pixel brush, rather than 1x1, to avoid broken rivers in-game.

The outcome was actually kinda fun to play with. For the first time, I could pick out where I was in the world by features, and sort of knew my way around. And the vast distances allowed me to tinker with the eating and overheating mechanics a bit more.

Still to come, per-hex shelter from the heat, additional types of items to pick-up, new hex features like ruins. This next week may be a nice artistic breather from the code work I've been up to lately. Till next time!