Showing posts with label metroidvania. Show all posts
Showing posts with label metroidvania. Show all posts

Sunday, December 4, 2011

Randomized metroidvania update: simple fix

I decided to take a break from skeletal animation and focus more on the room generation for the Metroidvania game. While implementing architecture and art for underground caves, I think I found out how to fix the problem where transitioning into a new room would "bump" you to an unexpected place. I say that I "found out" instead of "figured out" because it was really just a lucky observation and a lot of trial and error.

Why did it take me so long to figure that out? Well, the problem seemed to only happen when transitioning from one room to another room, while on the floor (i.e. not jumping), where the new room's ceiling was lower on the world map than the room you were transitioning from. Confusing enough? Even then, it only happened some of the time. After a lot of logging, I noticed an odd pattern: the player's new y coordinate would be slightly higher than expected (by less than a single pixel). After all that, here's the fix:

private function checkBounds():void
{
    /* code to figure out the new room and new player.x and player.y values */

    if (toRoom.mapY > currentRoom.mapY)
        player.y -= 1; // gravity causes weird things sometimes....   
}

Although I'm glad to finally have this fixed, as far as I can tell at least, I'm still annoyed by it. What annoys me most is that I have no idea how I could have prevented this and no idea how to even figure out this fix. It was a lot of observation and trial and error. There were at least a dozen previous attempted fixes that didn't fix anything. I still don't fully understand why having a y coordinate of 144 is ok but one of 144.00115 causes you to fall to the room below and have a different x coordinate. I don't even know how to write a unit test for this: it involves Flixel physics, Flixel collision detection, and the constantly changing algorithms that I use to create rooms. Could TDD have prevented this? Is there a unit test that reliably shows what the bug was?

Monday, November 7, 2011

Randomized metroidvania 09: slightly better architecture

It took a few days longer than I'd like but I was able to implement some new stuff:
    Slopes and stairs based off of https://github.com/krix/SlopesTest/blob/master/src/FlxTilemapExt.as
    Different background colors, patterns, and decorations (just columns for now)
    Different art and architecture preferences for each region




Each region gets a few architecture and art preferences. The architecture preferences are used to determine the room generation: what tiles are empty, solid, or stairs. The art preferences are used to determine the graphics: what do the background, stairs, walls, and floors look like. There's still not much content but I have a simple system set up and I can add more and better art or architecture styles later. Alpha content will suffice for now.

There's still a bug where moving into another room sometimes bumps you to a different space. I can't pinpoint where or why though. It seems to only bump you towards the bottom of the map and never the top. It also seems to bump to the left and never the right. So it bumps up the Y axis and down the X axis.... weird.

I think it's time to focus on player graphics for a while. Since I'm better at programming than art, I think I'll try my hand at skeletal animation. Flixel doesn't have anything like this as far as I can tell but forward and inverse kinematics should be fun and make a lot of the art stuff easier too. I estimate about a week until I have something useful.

Friday, November 4, 2011

Randomized metroidvania 08: initial architecture

I've got some initial architecture. It should now be possible to move from any room to any room. It certainly ain't pretty and is sometimes frustrating to get the jumps but it does allow you to get from one room to the next. I also added restricted regions to the world generation so the resulting map won't be as dense.


[it seems that transitioning from one room to the other sometimes "bumps" the player to a different spot... worked fine on my machine. I'll look a little closer into that code.]

Part of automating the process of creating room internals was changing the screen size to 32x21 tiles. Next up is adding sloped tiles for stairs, more variety, and more randomness to the architecture.

Wednesday, November 2, 2011

Randomized metroidvania 07: a brief study of C:SOTN and vertical movement

Next up is adding stairs, lifts, and all the architecture that should go in a room. It's already possible to move to rooms to the left and right, but moving up the map isn't possible yet. I decided to turn to maps of Castevania: Symphony Of The Night to see how they did it.

First of all, Alucard seems to be two tiles wide and three tall. When he jumps his feet are 4 tiles higher than they were when he started. This means that the shortest ceiling is 3 tiles from the floor and he can jump onto a tile that has a top that's 4 tiles off the floor.


Sometimes a flight of stairs or a hole in the floor is good enough to go up. The second image has three tiles from the top of the stairs to the bottom of the next floor - just short enough to jump up.
 


Sometimes you have to make a series of jumps between sides and center blocks.
 

Jumping back and forth between side platforms is the most common. These pictures show that sometimes it's more obvious than other times.
 



Here's a short series of jump-through blocks.

 This could be either a series of jump-through blocks or jumping from side to side depending on how you look at it. This pattern shows up in a few places.

There are also a few places with moving platforms to bring you up or down.
  
And this is my favorite example: a weird mix of side to side, stairs, and just jumping up through a hole in the floor. I don't remember if it's here or another place but I think you can't get to some of the non-essential side platforms until you have double-jump. The background graphics and variety make it much more interesting. 
A simple algorithm for this might be: evenly place floors, add a flight of stairs going up each third floor,  remove the floor from the top of the stairs to the opposite wall, remove the floor form the base of the stairs to the nearest wall, and add a gap in each remaining floor. The background shadows, floors, stairs, and banisters at the top of the staircases are good examples of the attention to details found in C:SOTN.



So it seems that sometimes you just walk up some stairs or do a single jump, at other times you have to jump from side to side, or sometimes from sides to center blocks, or even have to jump through one-way blocks. The best places (in my opinion) are a crazy mix of each. This is probably much easier to automate if your screen can be split into an even number of floors like the last image; that way you could place the floors and then pick random ways to move between them. It's also good to point out that each region has it's preferred method for going up. Don't forget to carefully plan the architecture to match the height and jump hight of the main character.

This may have been pretty obvious to most of you, but I learned a lot: you can use the same action (jump to the upper left then the upper right then the upper left....) but provide slight differences in art and layout and it will still provide interesting architecture and opportunities for fun. I've also got some working code to create rooms with layouts like the last image. And lastly; after 15 years, C:SOTN is still a beautiful and intricate game.

Sunday, October 30, 2011

Randomized metroidvania 04: map keys and locks

It took a few hours and I had to rewrite the code for doors, but I've got keys and locks working. A major part of any metroidvania is exploring new areas and finding some kind of impassable barrier -  a wide pit, a wall of metal blocks, a force field, etc. It's only later when you find some new ability or item - double jump, rocket launcher, field disabler, etc - that you can go past the barrier to a new region. You can abstract this idea of obstacles and items as "locks" and matching "keys". In one game the "red locks" and "red key" might represent actual locked doors and a key, in another game they might be security cameras and a disguise, and in another game they might be tall walls and the ability to climb walls.

You can see the locks and keys in my latest update. The icons are ugly and hard to distinguish, but it's just for example and will be redone many times before the project is over. Consider this the "alpha version" artwork.



[I just noticed that sometimes the first room in a region doesn't connect to the other rooms. A bug I just fixed when I redid that code for my latest work.]

when visiting a region for locks and keys:
    place an unused key
    put the matching lock on one door to each unvisited adjacent region
    any unlocked doors to adjacent regions are added to a "to do" list
    visit each unvisited adjacent region

after visiting all regions for locks and keys:
    for each unlocked door on the "to do" list, put a random used lock

This ensures that each region has a key that you need to proceed to the neighboring regions. Although; since each region can connect with its neighboring regions multiple times, it's theoretically possible that getting the first key would be enough to explore all regions.

Saturday, October 29, 2011

Randomized metroidvania 03: map regions

Different regions! It was easier than I thought it would be - of course it has been in the back of my head for a while so I didn't jump in with my first thought.




to start a new region:
    create a list of all frontiers for all rooms
    randomly pick one to start the new region
    clear all other frontiers
    place a room as normal

The current region determines the room color and a randomly chosen maximum height and width and can easily be used to control more things like the artwork, items, bad guys, secrets, and other things. Like placing doors, this algorithm is guaranteed to connect with existing regions and could even connect multiple other regions.

Randomized metroidvania 02: map connections

The rooms are now connected! I used a very simple method that's guaranteed to connect and will even create loops to join different "branches" that happen to be near by.




to connect a room:
    after placing a room
    get a list of all adjacent cells that are in a room
    randomly pick some cells to create doors

This can create multiple opening between two rooms. That's not a problem yet but it could be tweaked later on. This should be enough to create the gameplay portion but I'd like to work on defining different regions at the world-gen level before I move on to creating a player to run around.

Friday, October 28, 2011

Randomized metroidvania 01: map rooms

So I've decided to make a randomized metroidvania game; sort of a cross between a roguelike and one of the greatest games ever, Castlevania: Symphony Of The Night. Since I want this to be a flash game, I'll use Eclipse and Flixel.

I spent a few hours getting Eclipse to work with Actionscript and playing with Flixel a bit. For my game I decided to start with generating a random world map.




Here's the basic algorithm, which took less time than setting up Eclipse and Actionscript:

to start:
    add a 1x1 "frontier" space
    add a room

to add a room:
    randomly pick a frontier space
    start a room there
    randomly grow it for a while
    remove frontiers under it
    add its empty neighboring cells to the list of frontiers