The Search continues... slowly.

Posted by Astryl on March 16, 2012, 6:16 p.m.

I'm now entering the fourth day of development for this competition, and I've hardly gotten anywhere besides a lot of ideas, some code and some artwork (OK, and some music as well).

This does not bother me in the least, since that's the way it usually goes.

This blog is going to contain a lot of programming related information, and not much else, since it's a devlog and I've spent most of my time on the dungeon level generator. I won't discuss too much actual code, but more on the concepts (Which should be easily implementable in any language).

#01: The Dungeon Generator

I spent two/three days (Lost count. Only got four hours of sleep between them) on this, and it works pretty well with only a few flaws I can't be bothered to fix (I'm running on a tight schedule here).

My goal was to have the game generate dungeon levels that resembled closely the random layouts generated in Lufia: The Legend Returns (AKA Lufia 3, GBC). So after much thought, I did something like this:

> Define a multi-dimensional array that holds the tile-data for the

current level (In my case, this is a 1280x960 array. Which is about

4mb of data in GM (If GM uses 32-bit ints, which I'm almost positive

it does).

In C# I'm using the char datatype, which means that the amount of

memory for a single frame of tiles is 1mb.

> Define a set of enums/constants which relate to the tile indices

in the tileset file (TL_WALL, TL_WALL_B, TL_FLOOR_A, etc).

> Determine a random number that will be the number of 'rooms' to make.

> Define another multi-dimensional array (nodes[numberOfRooms, 4])

to store the data for individual rooms in. It holds X, Y, Width

and Height.

> Loop through the nodes[] array, and create the rooms by setting

the relevant positions in the map[] array to one of the FLOOR enums/

constants.

I use a typical iteration loop for this:

for(iy = 0; iy < nodes[i,3]; iy+=1)
   for(ix = 0; ix < nodes[i,2]; ix+=1)
{
   // Code here
}
   

> Now loop again through nodes[], this time drawing approximate paths

from a random starting point in node[i,] to another random point in

node[i+1,]. To do this, it uses another multi for-loop like the one

above. Something like this:

// sx,sy is the start point in tile coordinates
// ex,ey is the end point in tile coordinates
iy = sy;
for(ix = sx; ix < ex; ix += 1)
{
    map[ix,iy] = SetToRandomFloor();
    sx = ix;
}
for(iy = sy; iy < ey; iy += 1)
{
    map[sx,iy] = SetToRandomFloor();
}

(Not quite the same, because checks for negative/lesser values should

be added, as well as bounds checking (I use max(0, value) and min(room_width_tiles, value) for that).

That's just for the floors. Then the fun part starts [/sarcasm].

Creating the walls and borders. This requires a few passes over the map[] array, but it's still pretty effective (And fast).

Here's what the beginning of my generation loop looks like:

for(iy = 0; iy < room_height_tiles; iy+=1)
for(ix = 0; ix < room_width_tiles; ix+=1)
{
    this = map[ix,iy];
    left = map[max(0,ix-1),iy];
    right = map[min(room_width_tiles-1,ix+1), iy];
    up = map[ix,max(0,iy-1)];
    down = map[ix,min(room_height_tiles-1,iy+1)];

    if(IsFloor(this))
    {
        up = WALL_A; // WALL_A is the bottom border of the wall.
        if(iy == 0 || iy == 1) continue;
        map[ix,max(0,iy-2)] = WALL_B;
        if(iy <= 2) continue;
	map[ix,max(0,iy-3)] = WALL_B;
    }

    // ... 
    
    // At end of loop
    map[ix,iy] = this;
    map[max(0,ix-1),iy] = left;
    map[min(room_width_tiles-1,ix+1), iy] = right;
    map[ix,max(0,iy-1)] = up;
    map[ix,min(room_height_tiles-1,iy+1)] = down;
}

And let me just say it gets a bit more… complicated after that. I have to detect the correct locations to place a literal dozen different types of border: Corners, Straight pieces and inverted-corners (The little ones on the inside edges).

That requires a bit of hocus-pocus. Oh, and there's the 'double' edge pieces and 'cap' pieces for walls that are only 1 tile wide/high. AND there's the 'quad cap' piece for pillars. Wonderful fun.

But even so, my generation code is still only 136 lines long. Nowhere near as bad as I was expecting.

It still lacks a lot of obvious things, like decorations, wall variations (Occasionally placing a cracked wall, or maybe a random sign on the wall), treasures, down-stairways (Which will require a simple implementation of path-finding in order to make sure that the stairwell is reachable by the player before putting it there, yet keeping it away from the players starting room).

Now, if I was using GM for the whole of the project, I'd have to place those despicable bounding objects all over the place, which might be very costly processing-wise. Fortunately, I'm making the final game in C#, meaning that I can use my extremely fast grid-based collision algorithms.

#02: What I'm planning

Admittedly, the game has to be kept simple, which is why I chose to use the random level generator instead of designing them myself. I especially want to focus on gameplay for this, so… yeah. I'm doing that. The story at the moment naturally involves our usual player-named protagonist and his party of hired thugs furries soldiers/wizards/bards attempting to stop the invasion by the Army of Transvestites (not much to work with). To do this, they must set off in search of the Ball of Change (The transvestites source of power), which lies in the fabled 'Dungeon of the Transvestites'. Yay generic story!

You'll start off in a village, where you'll be able to buy supplies, magic items, scrolls, etc. And rest, of course, without fear of being raped attacked by the site admins transvestite army.

The dungeon in question will probably be between 100 and 200 levels deep, depending on what I feel will fit the game better. Every 20 levels you will find a warp point that can transport you to the village, and from there you can head back to the most recently accessed warp.

As for the enemies, I'm going to use simple artwork for their battle displays. I was thinking of drawing Dragon Warrior style artwork, but I quickly put that idea out of my mind. I can't do that, and make a good game along with good music in the two weeks I have left to do it in.

So I'm using 16x16 images, which look similar to the player's sprites. Keeps things simpler for me.

The enemies in the game range from the usual suspects (Goblins, Skeletons, etc) to the Rob-inflicted lot that I must add (Self-made-up-men (As in Makeup), Lulwat the Wizard (In a dress, apparently), Cross-dressing zombies, furries and cosplayers, Bearded Bitches, etc).

These are going to be mostly randomly generated (Stats and names anyway. Maybe some minor color variations).

#03: Something completely unrelated

I'm busy making a Minecraft mod (1.2.3 compatible, of course). Yay.

What is it? Something I feel will be completely awesome: Scrolls. If you've played roguelikes like Dungeon Crawl Stone Soup or Nethack, you know what I mean.

And so far, I have several L1 scrolls added to the game (Healing, Minor Explosion, Harm, Slingshot). I'm still trying to figure out how to implement a Regeneration effect based on the Potions, ditto for Speed/Sluggishness/Featherfall.

So does it sound like I'm doing something that's been done already? Well there is a difference: Scrolls are unidentified until you use them or Identify them (Using XP, of course). So you can take the risk and use a scroll without identifying it, but you'd better hope it isn't a Scroll of Major Explosion or Summon Creeper IV.

Pics or it didn't happen? 'K:

The Golden Quill is used to write scrolls, along with a Blank Scroll and an Ink. The Ink used determines the quality (level) of the scroll. There are four main types of ink, made with these materials: Redstone, Gold, Glowstone, Diamond. There is also a fifth level that I'm not going to talk about :P

I'm doing what Jeb did for the Potions: Storing their information in the damage value variable. Hence the debug info about Damage value. If a scroll's damage value is less than 10000, it is 'unidentified'. When you identify it (Or use it), 10000 is added to the Damage value to determine it's name/qualities/etc. Simple, hmm?

I still haven't added in the identification system, but that won't take long. It'll cost 1 XP per scroll level (Which is fair).

If I can, I'll make this SMP compatible, which would be fun (Trolling by leaving re-sealed (and thus unidentified) scrolls of Instant Death around).

Well, back to work.

EXTRA UPDATE:

Did some work on the alternative tileset for the game. Also, I ported all of the crappy GM code to my C# workspace, and it's working so fast I don't even need the "Descending into dungeon" screen anymore. :P

Here. Screenshot:

TL;DR

Here. Have what is possibly the best chiptune I've ever made…

http://chipmusic.org/64mega/music/missile-base

http://soundcloud.com/mega1992/64mega-missile-base

EDIT: I just found out that 64digits allows the submission of a blog without a title… >_>

Comments

Moikle 12 years, 8 months ago

FYEAH at that chiptune

Rob 12 years, 8 months ago

They better have transvestite-related special abilities.

Astryl 12 years, 8 months ago

Quote:
They better have transvestite-related special abilities.

That's the problem. What exactly is a transvestites special ability?

Rob 12 years, 8 months ago

Quote:
That's the problem. What exactly is a transvestites special ability?

Do some field research and find out for us.

Astryl 12 years, 8 months ago

Fuck you, I'm on the family PC.

Alert Games 12 years, 8 months ago

>Talk about transvestites on family computer

>Cant research because of family computer

No private browsing?

also this will be an…. interesting collection of competition games.