Sunday, March 13, 2016

7DRL 2016: Day 5

Today was devoted to progression and polish. I tweaked the level generator so it could generate levels of increasing size and difficulty and strung them together in sequence. Then I added a help menu and tidied up some of the presentation to try and make it clearer what is going on. In the screenshot below the player is getting smacked around by the guard.


I cut a bunch of stuff but the resulting game should be good for a few minutes of fun. We have a giant wind storm and power is spotty in the neighborhood so I'm going to call it good.

Here's a link to the zip file containing the game. It runs on Windows. Enjoy!

Saturday, March 12, 2016

7DRL 2016: Day 4

The game looks pretty much the same today as yesterday, but it's actually somewhat entertaining to play now.

The guard patrols work more-or-less as expected. There are a couple of pathfinding bugs (guards occasionally move on top of each other, or double back unexpectedly) but they're relatively minor.

The other big gameplay change was to streamline and have the player implicitly open and close doors, instead of doing it explicitly. This keeps the flow going better and requires less fiddly stuff.


Not much to see in the screenshot. There is a bit of furniture you can hide under inside the house now.

Tomorrow is the wrap-up. I still need to put in a help screen, level win conditions, and a level progression. If I have time I'd like to get in a collectible key that grants access to the upper blue-floored parts of the levels, and there are a couple of other functionality changes on the list.

Friday, March 11, 2016

7DRL 2016: Day 3

I've got more-or-less passable courtyard mansion levels going.


There are still room decorations to place and some bugs to fix with the existing room decorations. I'm trying to represent the hierarchy of the space by having the upper quarter or so of the rooms be a “master suite.” Eventually there will be more of the treasure here, and I've experimented with having locks separating it from the rest of the house.


Getting guards to patrol in a reasonable fashion is proving difficult. There are many more chokepoints in these levels than in my previous test levels, so guards tend to get stuck trying to go through doorways in opposing directions.

For a bit more thinking-on-your-feet, I decided to switch from fixed patrol routes to a system where guards wander from room to room, exiting a different way than they came in. I'm still in the middle of implementing that, though. My hope is that if two guards happen to bump into each other in a room they can exchange a couple of lines of dialogue and then head their separate ways.

The one-way windows work pretty well. I want to restrict visibility to be one-way through them as well, but I don't know if I'll get to that. At the moment the player can see through them but the guards can't.

Thursday, March 10, 2016

7DRL 2016: Day 2

It's the end of my second day of work on this year's Seven-Day Roguelike entry.

The first day was devoted to fixing bugs and finishing some refactoring I'd begun a long time ago. I wanted to render objects like tables and chairs on top of the floor, with alpha, instead of having the table or chair tile completely replace the underlying floor. It is mostly aesthetic, but it is a pain to get right.

One of my main goals for this round, as I said in the last entry, is to make a random level generator that works for stealth gameplay. Darren Gray warns not to mess around with level generation in a 7DRL, but I've got gameplay that basically works and I had never managed to come up with a random level generator for it.

I grabbed the starship generator from my old SpaceRL project and have been cleaning it up and turning it into something that can generate courtyard houses.


The little wedge-shaped things in the walls are supposed to be one-way windows. The idea is that they're up higher, or latched from inside, or something like that so you can jump through them one way but not the other. This is to give the player quick escapes from inner areas toward outer areas. I don't know yet if it'll work as intended; I haven't got guard patrols into the generator yet. That'll be the first thing for tomorrow.

Hopefully the last day or two I can work on the graphics so they're not quite as hard to look at. My main priorities, though, are to get a random level generator that produces fun levels, and to try to tell a bit of story.

Saturday, March 5, 2016

7DRL 2016: Late Start

I'll be getting a late start this year due to a travel conflict; probably on Tuesday the 8th.

Because of the short time frame I'm going with some existing game mechanics. A few years back I made a prototype that attempted to adapt Thief (one of my all-time favorite games) to a turn-based game. You can play that version here.

This year's 7DRL goals are to add a random level generator and a narrative. For levels I've been buying books and reading up about Chinese courtyard houses. Here are some layouts I did by hand to try to get a feel for the things I want to generate:



For a plot I'm probably going to crib something from Barry Hughart's Bridge of Birds, so expect supernatural crime. I don't know that I can match his delirious prose style and I know almost nothing about ancient China apart from courtyard houses so it'll probably be a travesty.

Saturday, March 14, 2015

Random game design thoughts

Asymmetry


Computers and humans aren't good at the same things; you can capitalize on that. For instance, let's say I have a game that involves flying a rocket through caves. I could try to make an AI that can also fly a rocket through caves and pit you against it, but that would be a lot of work that may or may not pay off. Instead I can put a bunch of dumb turrets in the caves to give you however much challenge you need.

Positive and negative feedback


Positive feedback is paying dividends on investments. The “rich get richer and the poor get poorer” as Jesus says (Matthew 25 and elsewhere). A lot of basic strategy game design is built around this, where you're accruing advantage over time.

The upside of positive feedback is that it drives things to a conclusion. For instance, in draughts when you get a pawn to the opposite side of the board it promotes to a king, with vastly increased mobility. In a first-person shooter each opponent you kill is one less person who can harm you, so the game gets progressively easier. If you weren't continually presented with new people to kill the game would rapidly lose its challenge.

The downside of positive feedback is that your early choices in a game are the most critical, with successive choices becoming less and less important because they're overwhelmed by the dividends from the early choices. For instance, you might have a critical sequence of things to do to get a Starcraft game started with optimal production. In a stealth game when you get discovered, a guard might call for help from other guards, who then arrive and encircle you making defeat a near-certainty. Game designs have to try to mitigate this.

Negative feedback is resistance to change. It's very useful for balancing games. For instance, you might have a set of items available for sale in a board game, and the ones that aren't bought get a little bit cheaper each turn, until they match someone's idea of their value. Another example is when you acquire territory but your troops become spread thinner and as a result it becomes harder to hold that territory. In my 7DRL the last goblin from one chest will run off to another chest; as a result chests you tackle later tend to have more defenders.

De-escalation


I like to ensure that the player can back away from situations when they get in over their head. A lot of times this means the player can run faster than anyone else, but usually you also need other ways to cool down a situation. This is a form of negative feedback, I suppose.

Designers need to spend a lot of time thinking about what happens when the player fails, and how to keep the game rolling through it. The coin-op approach was to just put up Game Over and let the next person have a turn, but with a bigger game played solo it's good to think about how to not have the game just reset when the player fails. Thief 3, for instance, gave you a jail level to bust out of if you got caught in the open-city part of the game. This served as a re-trainer for the skills you were lacking.

Mowing the lawn


This is what I call solitaire-style or match-three sorts of games, where you're not spending most of your time learning new skills; you're just trying to execute existing skills well. It's a low-intensity sort of fun.

Kill them fast


Every second an AI stays alive in a game is another chance for them to do something dumb that destroys the player's suspension of disbelief.

Friday, March 13, 2015

7DRL Day 7

Finished! The final version is on the game's website. Here's an announcement thread on Reddit.

Today was devoted to polish, and I ended up adding some animation.

Last night I ran the game past a couple of my friends, which highlighted how poor the feedback was for monster movement and attacking. After trying various things to indicate without animation who had attacked, or where they'd moved from (I tried motion-blurred icons!), I decided I really needed to bite the bullet and do some animation. It's something I have not really figured out a good solution for in my roguelike library.

The technique I opted for here is dirt-simple. You can register a callback with the library for updates, which happen every 5 milliseconds. When time advances in the game, I set a frame counter and register an update callback. (It's 12 frames, I think right now, so pretty quick.) Each update, the frame counter is decremented and the screen is invalidated so it'll get redrawn. On redraw, the frame counter is converted into a percent-done amount, and the characters use this to position themselves as some simple functions of time. Once the frame counter hits zero, the update callback is unregistered, which causes the roguelike library to go to sleep until the next Windows message. Thus it doesn't use any CPU time. (I don't have ongoing incidental animation in the game.)

Sitting still the game looks about the same as yesterday:



Adding animation exposed a nasty bug in my movement code. The pathfinder was returning a set of coordinate pairs: the guy at this position moves to that position, etc. The problem is that the pathfinding code can return a pair of moves (A --> B) and (B --> C). If you process those in that order, you end up with two people at position B after processing the first order. The lookup is indeterminate for handling the second order; you might get the guy who was originally at A, or you might get the guy who was at B. In the non-animated version it didn't matter since all monsters are interchangeable, but with animation it was glaringly obvious when someone moved from A to C in one turn.

Besides animation, I did some other chores like putting in a help and credits screen. I also did some ongoing renaming of stuff in the code, from its origins as a sci-fi extravaganza to its current theme. (The level is still called a planet, though.)

It's been a fun week, and I'm hugely relieved that I got a fun game out of it. In the middle of the week I wasn't sure I'd be able to come up with something interesting. I'll probably talk more about this tomorrow, but it really has been a miniature version of a full game cycle. The wild ideas, the drastic cuts, the race to the finish, etc.