Sunday, August 27, 2017

Fast Marching Method pursuit



I've been experimenting to learn more about the fast marching method, which is a really nice way of generating distance fields that take into account cost fields.

First, FMM is used to compute a signed distance field to the obstacles (the dark gray boxes). This distance field is the basis for a cost field, which is then used by FMM for computing distance from the mouse cursor. The cost field smooths the paths around corners, which makes it easier for groups to avoid getting snagged.

The red shading represents the cost function, while the contour plot represents the cost-influenced distance field to the mouse cursor. The orange dots move downhill on this field to approach it.

I think this is roughly similar to the "FM2" method outlined by Alberto Valero-Gomez et al. My cost-from-obstacle-distance function is totally ad hoc though. I still need to dig up the real math for that.

Sunday, March 12, 2017

7DRL 2017: Development build history

For reference, here are all the versions of the game through the week that I released to testers:

Saturday, March 11, 2017

7DRL 2017: Day 7 and Done

In Undeath and Taxis, you are the driver in a zombie apocalypse. Ferry militia from the fort to the abandoned farm houses dotting the countryside to mount a last stand against the shambling horde. Your car is not just a taxi; it's a weapon. Hunt for other abandoned vehicles, or hidden bunkers with supplies.

This game uses the old-fashioned graph-paper race track game as the core of its movement system. Combat with zombies puts you on the offensive side of the homicidal chauffeur problem.



Today's work:
  • Reskin herbs to be bunkers
  • Add multiple vehicles and parking lots to switch between them
  • Damage/healing numbers that float over vehicle
  • Muzzle flashes from gunfire
  • Alternate control schemes
  • Zombies dodge the vehicle's path
The very last thing I did was to make the zombies be a little smarter about how they move. They try to approach the vehicle but stay out of its predicted path. This changed the game completely. Previously you could just do back-and-forth sweeps with the car and mow them down as they shuffled into the path of the car. Now you have to do curving paths without letting your speed drop low enough they can take a swipe at you, and you have to look carefully at your move placements when you're dealing with one or two.

Because the zombies are better at dodging, dealing with large crowds takes longer, so I had to re-balance the rest of the game. I'm not sure it's completely balanced but it is generally winnable. Maybe a bit on the easy side.

The other big change today was getting the multiple vehicles in. I'm not convinced they're particularly well-balanced either, but they offer some fun changes of pace. They offer another reason to explore the map, too.

Big thanks to my wife for holding down the fort while simultaneously being cookie mom for two Girl Scout troops, and to my friend Tom Elmer for lots of testing!

Friday, March 10, 2017

7DRL 2017: Day 6

I woke up early this morning with a headache. Played a couple of hours of Mad Max in a despondent funk. While I was doing that I came up with a gameplay plan to try.



In yesterday's version I had chests to collect; a leftover from the Goblin Gold game I'd started with. The monsters collected around them. It kind of reminded me of zombies collecting around defended houses. Plus, running people over with cars is pretty bad; zombies are about the only valid targets for that kind of thing. It pains me to make a zombie game, but there you go.

I thought that maybe I could replace the chests with control points, like in a Battlefield game or something. You'd drive soldiers to the abandoned farmhouses, they'd fortify them, the zombies would go after them, etc. I worked through a fair chunk of the day getting that put together. I thought I'd have something where your expanding controlled area would present a harder-to-defend front against the zombies. So I had the zombies only go after the defended houses. This was ridiculous. You'd fortify one house, and wait while all the zombies came to it. Couldn't be easier. I returned to having zombies collect around all of the houses, fortified or not. But then what's the point of fortifying them?

Eventually I resorted to the oldest trick in the book: spawning more monsters. Zombies spawn on a regular schedule. Fortifying a house ensures they don't collect as heavily around it, because the soldiers shoot the zombies. The zombie-spawning schedule ramps up as you fortify houses, too, to amplify the feeling of panic. When you get down to the last house there is usually a giant mob of zombies milling around it and they all surge toward you when you roll into view.

There was a lot of logic involved in making the soldier run out of the headquarters (once there aren't any zombies around and you're stopped within an acceptable distance), then exit your vehicle once you're stopped near an abandoned farmhouse and there aren't any zombies immediately threatening. It's kind of half-baked right now in terms of pathing and so forth, but it proves out the concept. I added a bunch of dialogue lines from the guy to help guide the player through the process as well. You can see the first one in the screenshot above.

Tomorrow is polish. I would dearly love to get multiple playable vehicles in, but haven't tried it yet to see if it holds water. I'm thinking there'd be a truck that is slow but doesn't take environmental damage; a dune buggy that is faster off-road and middling on the road; a car that is fast on the road and slower off-road; and a motorcycle that goes blisteringly fast everywhere but takes damage more readily.

Thursday, March 9, 2017

7DRL 2017: Day 5

Today was mostly devoted to getting some terrain features and monsters going again.



The monster AI I was using before was way too expensive for the size of map I have now. I replaced it with a small Dijkstra map centered on the player. If monsters are on it, they use it to approach the player. Otherwise they use a cheaper long-distance distance field that just sends them to the nearest cabin.

Right at the end of the day I tried a long skinnier map instead of a square one. I think it fits with the idea of driving down a road better.

The game's still not very interesting, and I don't have a lot of time left to work on it. Oh well; we'll see what can be done. I think the driving is kind of interesting; it is a bit challenging to learn how to do. Right now you just drive over monsters to kill them; kind of a high-speed version of bump-to-attack. They will hit the car if they are next to it on their turn.

The car has an indicator that looks like a 3x3 grid of dots (with the center dot replaced by a circle):



If you don't accelerate, you'll go to the circle in the center next turn. (You do that by pressing the 5 key in the middle of the numpad.) If you press any of the other numpad keys you'll accelerate/decelerate, which will place the car at the corresponding white dot. Dots marked red mean the car can't do them; this happens when you are at the top speed for the terrain you're on, for instance, or if you ran off the road and are forced to decelerate.

Wednesday, March 8, 2017

7DRL 2017: Day 4

It's day four and I don't really have a game yet.

This morning I banged together several of my old experiments to try and get a road network that would facilitate fast driving. I started with a relative neighborhood graph from a stellar-conquest strategy game I was attempting to make once (this is supposed to be a galaxy):



On top of this graph I layered corner fillets from a racetrack game I'd worked on at one point:



The end result is something that looks reminiscent of the roads in the Mad Max game:



I added terrain-dependent top speeds, so you can't accelerate as much as you like. If you drive off the road the car is forced to decelerate down to the off-road maximum speed.

This was starting to feel fun to drive on, at least for me. When I tried it out on my wife she had an allergic reaction to it, so I spent a couple hours trying to rework how the car behaves when you're trying to accelerate past top speed. It now tries to steer so it will eventually be driving in the direction you're pressing, so if you keep pressing Left you will eventually be driving straight left. There are still some nuances to work out, though. Even with that, the acceleration was hard for her to come to grips with, so I think I may pull in the top speeds some more and shrink things.

I've got to come up with some gameplay, so that's what I've begun work on next.

Tuesday, March 7, 2017

7DRL 2017: Day 3

Not a very productive day. I fixed remaining bugs from the hex-to-square grid conversion, made the vehicle crash into stuff and mow down monsters, and started to mess around with some terrain improvements to suit driving fast. Nothing definitive has come of that yet though.

Here's how it looks at the moment:



The rocks and trees don't do anything yet. When they do I have a feeling they'll need to be arranged differently.

Something that doesn't come through in the stills is that it's animated. If you hammer the keys it plays a bit like an action game.

Oh yeah, and I got clearance from the artist who did the car sprites (Maung Thuta), so that's exciting.

Monday, March 6, 2017

7DRL 2017: Day 2

Day 1 was occupied mostly with Girl Scout cookie sales. Day 2 was also somewhat slow.

I decided to switch my starting project, from last year's (ThiefRL 2) to the year previous (Goblin Gold). The latter is closer to what I'm after. Here's what it looks like:



Next I got the basic car movement working, with an eight-way car sprite to show which direction it's driving. With a bit of animation to show the motion it works okay.

After playing with the controls on a hex grid, though, I decided it was too awkward. I kept trying to move vertically. Plus I thought maybe I'd offer diagonal movement as a car upgrade. Most people aren't used to using diagonal movement, so if you offer it as a separate thing they purchase they might consider it more carefully.

So I switched things to a square grid:



It's still super-ugly, and still has all the old stuff left over from the previous game. I'd hoped to get farther on terrain creation; I'll have to do that tomorrow.

The point of car movement is to go fast. I've been thinking about scales, to try to figure out what will push the player to go fast. Realistically the car will need to have its top speed be around four or five squares per turn, I think, so that's the rough movement speed multiplier you'd be working with. (Unless I have enemies that move at sub-one-square-per-turn speeds.) If you accelerate to four squares per turn and then decelerate, you go about 4*5 squares (two times the sum of the numbers 1 to 4). The rest of the map would be covered at top speed. So for instance if you had to go 256 squares, it'd take about 67 turns (as opposed to 256 turns to move a square at a time). So that's 189 turns saved.

I'll probably have some enemies that have to be attacked at speed (ramming), and some that require you to be at a standstill (sniping), or something like that.

Sunday, March 5, 2017

7DRL 2017: Start

Time to fire up this creaky old blog again for the annual Seven-day Roguelike Challenge.

This year I'm going to try to make a game that uses the graph-paper racetrack game as its core movement mechanic, with base-building as the secondary layer. The idea is that as the area you're defending increases, you have to drive faster to be able to cross it to reach threats on the other side. You drive faster by getting better at the driving mechanic, upgrading your car, and building roads and bridges.

It's inspired by Mad Max a bit. I played the recent Avalanche game to nearly 100%. I have been wanting to make a game using a similar mechanic inspired by the Steve Jackson board game Interplanetary, but have had trouble figuring out how to make space interesting. Hence the move to the ground.

So far I've had my initial struggle with Git to clone one of my other projects. Git is a never-ending font of obscure problems with uninformed solution suggestions on the internet. Today I've had to deal with heads not being trees, detached heads, and submodule recursion.