Roguelike port?

That is awesome @wuuff!

Any chance to make some rooms be not rectangular? Like some L shape rooms etc. This would look awesome with our game, but I didn’t want to ask for it, ad we were struggling as we were :wink: and it seems you got some dungeon chops on you.

I am back home, but I pulled a muscle. I need some rest, but I will make sure we have bunch of item sprites before I will call it a night.

Waiting to see if what I implemented works in c :slight_smile:

1 Like

I think you have them flip-flopped. We’d have 2 tile high horizontal walls for a sort of 3/4 rpg view.

As for the generator; It looks so awesome so far! Depending on your tweaks for the room sizes and stuff I think this would be our best bet. Let’s wait and see what @jonne is hard at work on as well. It may be very hard to decide and have a new problem in our hands

2 Likes

I think I fixed the issue of having too-large rooms. I’m pretty happy with the generated maps now.

I think that perhaps very long walls need more than one door, but I can add that if anyone thinks this generator could be useful.

It 's easy to change map dimensions and minimum room size, too. Here’s a 32x32 map:

And here’s a 64x64 map with a larger minimum room size:

Source link is the same as in my previous post. I updated the gist.

4 Likes

By not rectangular, do you mean with irregular edges, like in the link you posted earlier in this thread (http://weblog.jamisbuck.org/2015/1/15/better-recursive-division-algorithm.html)? That will be more complex because I would have to keep track of the boundary between different regions. Right now it’s done by simply dividing a region in half recursively either horizontally or vertically. Making the rooms irregularly shaped is doable, but I don’t think I can do it soon because I have been putting off work I need to do and I can’t justify spending much more time on this for the next few days.

I agree that non-rectangular rooms would look awesome though! Maybe we could do it for a post-jam version of the game, and if people are still wanting to try participating in the jam, the jam version can use simpler map generation.

@trelemar, I was following some of the information from @adekto’s posts. I think that maybe the idea is that all walls with a blank space beneath them are automatically add a tile for the side of the wall underneath them (making all horizontal walls 2 tiles high). I was thinking of using a third tile index for showing the side of walls, but I wasn’t sure how people would want to use the generator.

This mockup by @VonBednar shows how horizontal walls are thicker:

https://talk.pokitto.com/uploads/default/original/1X/8083fc42e8824613628e9fb35ad1e0ff8a483433.png

I tried to make the maps I generate compatible with simply adding an extra brick tile below a wall if the area below is empty, which is why I made the minimum room height larger than the width. All rooms have one less tile of vertical walkable space than it appears from the text output of my generator. The output is only showing the “top” of the walls and not the sides, if that make sense.

So I said 2-tile vertical doors because the top tile of the vertical door is occupied by the brick wall tile showing the side of the wall. Sorry if my response is a bit hard to follow.

At least, that’s how I interpreted things after reading the thread. There was a lot to take in.

Edit: Re-reading your reply again, I think you were already saying that walls are 2-high, so I probably didn’t need to explain it. I think it was just a terminology mix-up. I think I get what you mean now (doors in horizontal walls are 2-high and doors in vertical walls are 1-high). So I was confused because I was thinking about it differently (ignoring the side-walls and expecting them to be added later, and therefore having the two switched). I can change the map generation to make all horizontal walls 2 tiles thick, depending on how the result is to be used.

IT WORKS OMG

Great job @wuuff!

I created a very simple function for creating the 2 tile thick horizontal walls and added it to the bottom of your file.

void mappretty(char map[][MAPSIZE],int width, int height){
    int i,j;
    for (i=0; i < height-1; i++) {
        for (j=0;j<width-1;j++){
            if (map[i][j]==1 && map[i+1][j]==0){
                map[i+1][j]=2;
            }
        }
    }
}

Seeing how you did this really gives me a new outlook on the project :slight_smile:

EDIT: Here’s the modified files to get this running so we can all compare with @VonBednar’s method using @jonne’s translation:

The main file:

#include "Pokitto.h"
#include <vector>
#include "sprites.h"
#include "mapgen.c"
Pokitto::Core game;

char dungeon[MAPSIZE][MAPSIZE];

struct entity{
    uint8_t x;
    uint8_t y;
    int8_t hp;
    uint8_t id;
};

#define ID_SKELETON_MAGE     9
#define ID_SKELETON_ARCHER   10
#define ID_SKELETON_WARIOR   11
#define ID_BLOOD_SKELETON    12
#define ID_BLOOD             13
#define ID_RAT               14
#define ID_SCROLL            15
#define ID_CHEST             16
#define ID_CHEST_OPEN        17
#define ID_MIMIC             18
#define ID_COIN              19
#define ID_COINS             20
#define ID_BAG               21

//globals
int entities_size = 2;
std::vector<entity> entities(entities_size);
char printer[40] = "";
int playerGold = 0;
int playerHP = 100;


bool colide(int id, int x, int y, bool c){
    if (entities[id].x == x && entities[id].y == y) return false;
    else return c;
}
void removeEntity(int i){

        using std::swap;
         std::swap(entities[i], entities.back());
    entities.pop_back();

}
bool entitiesLogic(int playerX, int playerY){
    bool nocolide = true;
    for(int i=0; i<entities.size(); ++i){

        switch(entities[i].id){
        case ID_CHEST:
            nocolide = colide(i,playerX,playerY,nocolide); //its wierd but works
            if(!colide(i,playerX,playerY,true)){
                    entities[i].id = ID_CHEST_OPEN;
                    sprintf(printer,"open chest, taken %i gold",  entities[i].hp);
                    playerGold += entities[i].hp;
                    entities[i].hp = 0;
            }
            break;
        case ID_CHEST_OPEN:


            break;
        case ID_MIMIC:
            nocolide = colide(i,playerX,playerY,nocolide); //its wierd but works
            if(entities[i].x > playerX && colide(i,playerX+1,playerY,true)) entities[i].x-=1;
            else if(!colide(i,playerX+1,playerY,true)) playerHP -=10;

            if(entities[i].x < playerX && colide(i,playerX-1,playerY,true)) entities[i].x+=1;
            else if(!colide(i,playerX-1,playerY,true)) playerHP -=10;

            if(entities[i].y > playerY && colide(i,playerX,playerY+1,true)) entities[i].y-=1;
            else if(!colide(i,playerX,playerY+1,true)) playerHP -=10;

            if(entities[i].y < playerY && colide(i,playerX,playerY-1,true)) entities[i].y+=1;
            else if(!colide(i,playerX,playerY-1,true)) playerHP -=10;

            if(!colide(i,playerX,playerY,true)){
                entities[i].hp -= 1;
                sprintf(printer,"hit mimic, hp: %i",  entities[i].hp);
                if(entities[i].hp == 0) removeEntity(i);
            }
            break;
        default:
            printf("unknown entety %i\n", entities[i].id);
            break;
        }
    }
    return nocolide;
}


void drawHP(int hp){
    //gui
        game.display.drawBitmap(212,0,UI1);
        game.display.drawFastVLine(219,3,158);
        game.display.drawFastVLine(211,3,158);
        game.display.drawBitmap(212,162,UI2);
        int UI_hp = hp * 0.78;

        if(hp >= 0){
            for(int i = 0; i < UI_hp; i++){
                game.display.drawBitmap(213,159-(i*2),UI4);
            }
            game.display.drawBitmap(213,160-((UI_hp+1)*2),UI3);
            game.display.drawBitmap(213,161,UI5);
        }
}
int main () {
srand(30);
mapinit(dungeon,MAPSIZE,MAPSIZE);
mapgen(dungeon,MAPSIZE,MAPSIZE,0,0,MAPSIZE-1,MAPSIZE-1);
mappretty(dungeon,MAPSIZE,MAPSIZE);
game.begin();
//mapgen(0,0,0,20,20);
game.display.loadRGBPalette(paletteCGA);
//game.display.setFont(fontAdventurer);
//game.display.persistence = true;
game.display.setInvisibleColor(0);
int playerX = 2;
int playerY = 2;


entities[0].id = ID_CHEST;
entities[0].x = 5;
entities[0].y = 3;
entities[0].hp = 100;
entities[1].id = ID_MIMIC;
entities[1].x = 15;
entities[1].y = 15;
entities[1].hp = 10;


while (game.isRunning()) {

    if (game.update()) {
        if (game.buttons.repeat(BTN_UP,4)){
            if (!dungeon[playerY-1][playerX]){
                if(entitiesLogic( playerX, playerY-1)) playerY --;
            }
        }
        if (game.buttons.repeat(BTN_DOWN,4)){
            if (!dungeon[playerY+1][playerX]){
                if(entitiesLogic( playerX, playerY+1)) playerY ++;
            }
        }
        if (game.buttons.repeat(BTN_LEFT,4)){
            if (!dungeon[playerY][playerX-1]){
                if(entitiesLogic( playerX-1, playerY)) playerX --;
            }
        }
        if (game.buttons.repeat(BTN_RIGHT,4)){
            if (!dungeon[playerY][playerX+1]){
                if(entitiesLogic( playerX+1, playerY)) playerX ++;
            }
        }
        for(int x =playerX-7; x<playerX+8; x++){ //7
            for(int y =playerY-6; y<playerY+6; y++){
                if(x >= 0 && y >= 0 && x <MAPSIZE && y < MAPSIZE){
                    game.display.drawBitmap(14*(x-playerX+7),14*(y-playerY+6),background[dungeon[y][x]]);
                }
            }
        }

        game.display.setCursor(0,168);
        game.display.color = 1;
        game.display.print(printer);



        drawHP(playerHP);

        for(int i=0; i<entities.size(); ++i){
            game.display.color = 0; //remove before release
            game.display.fillRect(14*(entities[i].x-playerX+7),14*(entities[i].y-playerY+6),14,14);//remove and fix before release
            game.display.drawBitmap(14*(entities[i].x-playerX+7),14*(entities[i].y-playerY+6),sprites[entities[i].id]);
        }

        game.display.drawBitmap(14*(7),14*(6),sprites[3]);
    }

}

return 1;
}

mapgen.c:

#include <stdio.h>
#include <stdlib.h>

#define MAPSIZE 64

void mapinit(char map[][MAPSIZE], int width, int height);
void mapgen(char map[][MAPSIZE], int mapwidth, int mapheight, int startx, int starty, int endx, int endy);
void mapprint(char map[][MAPSIZE], int width, int height);

void mapinit(char map[][MAPSIZE], int width, int height){
    int i,j;

    //Generate walls around the edges
    for( i = 0; i < width; i++ ){
        map[0][i] = 1;
        map[height-1][i] = 1;
    }
    for( j = 0; j < height; j++ ){
        map[j][0] = 1;
        map[j][width-1] = 1;
    }
}

#define HORIZONTAL 0
#define VERTICAL 1
#define MIN_WIDTH 6
#define MIN_HEIGHT 8
void mapgen(char map[][MAPSIZE], int mapwidth, int mapheight, int startx, int starty, int endx, int endy){
    int i,j,orientation,position,door,doorcount;
    int width = endx-startx;
    int height = endy-starty;

    if( width < MIN_WIDTH && height < MIN_HEIGHT ){
        return;
    }

    //Determine whether we will split the space
    //horizontally or vertically by choosing whichever
    //orientation is larger (this avoids extremely long rooms)
    if( width >= height ){
        //If there is a door (or more than one door!) into a small room,
        //we may not be able to generate a wall in any location!
        //so abort if room is min + number of horiz door tiles
        doorcount = 0;
        for( i = startx; i < endx; i++ ){
            if( map[starty][i] == 0 ) doorcount++;
            if( map[endy][i] == 0 ) doorcount++;
        }
        if( width < MIN_WIDTH + doorcount ){
            return;
        }
        orientation = VERTICAL;
        //puts("Trying vertical");
    }else{
        //If there is a door (or more than one door!) into a small room,
        //we may not be able to generate a wall in any location!
        //so abort if room is min + number of vert door tiles
        doorcount = 0;
        for( i = starty; i < endy; i++ ){
            if( map[i][startx] == 0 ) doorcount++;
            if( map[i][endx] == 0 ) doorcount++;
        }
        if( height < MIN_HEIGHT + doorcount ){
            return;
        }
        orientation = HORIZONTAL;
        //puts("Trying horizontal");
    }
    //printf("startx %d, starty %d\n",startx,starty);
    //mapprint(map,MAPSIZE,MAPSIZE);
    position = -1;
    if( orientation == HORIZONTAL ){
        //Make sure the position is valid:
        //1. It must have generated at least one number
        //2. It must not be too close to existing walls
        //3. It must not be over a door
        while( position == -1 || position < starty + (MIN_HEIGHT/2) || position > endy - (MIN_HEIGHT/2) || map[position][startx] == 0 || map[position][endx] == 0 ){
            position = starty + (rand()%height);
        }
        //Generate a door at a random position
        door = startx + 1 + (rand()%(width-1));
        //printf("HORIZ %d\n",position);
        for( i = startx; i < startx + width; i++ ){
            if( i != door )
                map[position][i] = 1;
        }
        //Recursively call to fill the two new spaces we generated
        mapgen(map, mapwidth, mapheight, startx, starty, endx,position);
        mapgen(map, mapwidth, mapheight, startx, position, endx, endy);
    }else if( orientation == VERTICAL ){
        //Make sure the position is valid:
        //1. It must have generated at least one number
        //2. It must not be too close to existing walls
        //3. It must not be over a door
        while( position == -1 || position < startx + (MIN_WIDTH/2) || position > endx - (MIN_WIDTH/2) || map[starty][position] == 0 || map[endy][position] == 0 ){
            position = startx + (rand()%width);
        }
        //Generate a door at a random position
        //(allocating space for it to be 2 high)
        door = starty + 1 + (rand()%(height-2));
        //printf("VERT %d\n",position);
        for( i = starty; i < starty + height; i++ ){
            if( i != door && i != door+1 )
                map[i][position] = 1;
        }
        //Recursively call to fill the two new spaces we generated
        mapgen(map, mapwidth, mapheight, startx, starty, position,endy);
        mapgen(map, mapwidth, mapheight, position, starty, endx, endy);
    }
}

void mapprint(char map[][MAPSIZE], int width, int height){
    int i,j;

    for( i = 0; i < height; i++ ){
        for( j = 0; j < width; j++ ){
            if( map[i][j] == 0 ){
                printf("0");
            }else if( map[i][j] == 1 ){
                printf("1");
            }
        }
        puts("");
    }
}

void mappretty(char map[][MAPSIZE],int width, int height){
    int i,j;
    for (i=0; i < height-1; i++) {
        for (j=0;j<width-1;j++){
            if (map[i][j]==1 && map[i+1][j]==0){
                map[i+1][j]=2;
            }
        }
    }
}
3 Likes

Here is @VonBednar 's Lua map generato combined to @adekto demo

Now you have choice what to do :grinning:

dungeon.h:

#ifndef DUNGEON_H
#define DUNGEON_H

#include <stdint.h>

#define MAX_ROOMS 100 // 100 rooms max, I don't want to get into dynamic memory allocation here

struct Dungeon {
  uint8_t w;
  uint8_t h;
  uint8_t tiles[50*50];
}; // Dungeon structure definition

struct Room {
    int8_t w;
    int8_t h;
    int8_t x;
    int8_t y;
}; // define structure Room

extern Dungeon d;
extern void dungeon_gen();
extern void make_rooms();

#endif // DUNGEON_H

Dungeon.cpp:

#include "Pokitto.h"
#include "dungeon.h"

Dungeon d = {48, 32}; // make a Dungeon instance called "d"

uint8_t wall_h = 1; //global variable wall_h, type is unsigned char (8 bits) value 0..255
uint8_t grid_w=0, grid_h=0, room_size=4; // multiple variables of same type can be declare in 1 row

/* ---------------
mapgen starts here
----------------*/

/* this is one type of comment in C */
// this is 1 row comment in C++

// decide on max iterations

void dungeon_gen() {
  // void means function does not return anything, {} mark the beginning and end of function
  // Dungeon& is a reference to a Dungeon instance
  // blank the tile array
  for (uint8_t i=0; i<d.w; i++) {
	for (uint8_t j=0; j<d.h; j++) {
		d.tiles[i+j*d.w]=1; // all tiles set to 1 initially
		}
	}

  // add outside walls
  for (int i=0; i<d.w; i++) {d.tiles[i]=2;d.tiles[(d.h-1)*d.w+i]=2;} //horiz walls
  for (int i=0; i<d.h; i++) {d.tiles[i*d.w]=2;d.tiles[(i+1)*(d.w)-1]=2;} //ver walls
}

void make_rooms() {
  struct Room {
    int8_t w;
    int8_t h;
    int8_t x;
    int8_t y;
  }; // define structure Room

  Room rooms[MAX_ROOMS];
  for (int i=0; i<MAX_ROOMS; i++) {
	// not the cleanest way but ...
	rooms[i].x=2; rooms[i].y=2; rooms[i].w=d.w; rooms[i].h=d.h;
	}

  int ii=1;
  while (ii >= 1 ) {
	uint8_t wall_orientation = 2;
	// check room dimension and change wall orientation accordingly
	if (rooms[ii].w < rooms[ii].h) {
		if (rooms[ii].h >= 2*room_size+2) wall_orientation = 0;
	} else if (rooms[ii].w > rooms[ii].h) {
		if (rooms[ii].w >= 2*room_size+2) wall_orientation = 1;
	} else {
		if (rooms[ii].w >= 2*room_size+2) wall_orientation = random(0,2);
	}

  if (wall_orientation != 2)
  {
  	if (wall_orientation == 1)
	{
		int wx=random(1+room_size, rooms[ii].w-room_size);
		if (d.tiles[(rooms[ii].x+wx-1)+(rooms[ii].y-1)*d.w]==2 || d.tiles[(rooms[ii].x+wx-1)+(rooms[ii].y+rooms[ii].h)*d.w] == 2) {
			if (random(1,3) == 1) wx++;
			else wx--;
		}

		for (int yy=2; yy<rooms[ii].h; yy++) d.tiles[(rooms[ii].x+wx-1)+(rooms[ii].y+yy)*d.w]=2;

		d.tiles[(rooms[ii].x+wx-1)+(rooms[ii].y)*d.w]=34; //door?

		rooms[ii+1].x = rooms[ii].x+wx;
		rooms[ii+1].y = rooms[ii].y;
		rooms[ii+1].w = rooms[ii].w-wx;
		rooms[ii+1].h = rooms[ii].h;

		rooms[ii].w=wx-1;
	} else {

		int wy = random (1+room_size,rooms[ii].h-room_size);
		if (d.tiles[(rooms[ii].x-1)+(rooms[ii].y-1)*d.w] == 18 || d.tiles[(rooms[ii].x+rooms[ii].w)+(rooms[ii].y+wy-1)*d.w] == 18) {
			if (random(1,3)==1) wy++;
			else wy--;
		}

		for (int xx = 2; xx < rooms[ii].w; xx++) d.tiles[(rooms[ii].x+xx)+(rooms[ii].y+wy-1)*d.w] = 2;

		d.tiles[(rooms[ii].x)+(rooms[ii].y+wy-1)*d.w] = 18;

		rooms[ii+1].x = rooms[ii].x;
		rooms[ii+1].y = rooms[ii].y+wy;
		rooms[ii+1].w = rooms[ii].w;
		rooms[ii+1].h = rooms[ii].h-wy;

		rooms[ii].h=wy-1;
	}
	ii++;
  } else {
	ii--;
  }
  } // while ii
  for (int i=0;i<d.w*d.h;i++) if (d.tiles[i]==1) d.tiles[i]=0;
} // makerooms

And finally code that uses it:

#include "Pokitto.h"
#include <vector>
#include "sprites.h"
#include "dungeon.h"
Pokitto::Core game;


struct entity{
    uint8_t x;
    uint8_t y;
    int8_t hp;
    uint8_t id;
};

#define ID_SKELETON_MAGE     9
#define ID_SKELETON_ARCHER   10
#define ID_SKELETON_WARIOR   11
#define ID_BLOOD_SKELETON    12
#define ID_BLOOD             13
#define ID_RAT               14
#define ID_SCROLL            15
#define ID_CHEST             16
#define ID_CHEST_OPEN        17
#define ID_MIMIC             18
#define ID_COIN              19
#define ID_COINS             20
#define ID_BAG               21

int entities_size = 2;
std::vector<entity> entities(entities_size);


void entitiesLogic(int playerX, int playerY){
    for(int i=0; i<entities.size(); ++i){

        switch(entities[i].id){
        case ID_CHEST:


            break;
        case ID_CHEST_OPEN:


            break;
        case ID_MIMIC:
            if(entities[i].x > playerX) entities[i].x-=1;
            if(entities[i].x < playerX) entities[i].x+=1;
            if(entities[i].y > playerY) entities[i].y-=1;
            if(entities[i].y < playerY) entities[i].y+=1;
            break;
        default:
            printf("unknown entety %i\n", entities[i].id);
            break;
        }
    }
}

void drawHP(int hp){
    //gui
        game.display.drawBitmap(212,0,UI1);
        game.display.drawFastVLine(219,3,158);
        game.display.drawFastVLine(211,3,158);
        game.display.drawBitmap(212,162,UI2);
        int UI_hp = hp * 0.78;

        if(hp >= 0){
            for(int i = 0; i < UI_hp; i++){
                game.display.drawBitmap(213,159-(i*2),UI4);
            }
            game.display.drawBitmap(213,160-((UI_hp+1)*2),UI3);
            game.display.drawBitmap(213,161,UI5);
        }
}
int main () {

game.begin();
dungeon_gen();
make_rooms();
//mapgen(0,0,0,20,20);
game.display.loadRGBPalette(paletteCGA);
//game.display.setFont(fontAdventurer);
//game.display.persistence = true;
game.display.setInvisibleColor(0);
int playerX = 2;
int playerY = 2;
int playerHP = 100;

entities[0].id = ID_CHEST;
entities[0].x = 5;
entities[0].y = 3;
entities[1].id = ID_MIMIC;
entities[1].x = 15;
entities[1].y = 15;


while (game.isRunning()) {

    if (game.update()) {
        if (game.buttons.repeat(BTN_UP,4)){
            if (!d.tiles[(playerY-1)*d.w+(playerX)]){
                playerY --;
                entitiesLogic( playerX, playerY);
            }
        }
        if (game.buttons.repeat(BTN_DOWN,4)){
            if (!d.tiles[(playerY+1)*d.w+(playerX)]){
                playerY ++;
                entitiesLogic( playerX, playerY);
            }
        }
        if (game.buttons.repeat(BTN_LEFT,4)){
            if (!d.tiles[(playerY)*d.w+(playerX-1)]){
                playerX --;
                entitiesLogic( playerX, playerY);
            }
        }
        if (game.buttons.repeat(BTN_RIGHT,4)){
            if (!d.tiles[(playerY)*d.w+(playerX+1)]){
                playerX ++;
                entitiesLogic( playerX, playerY);
            }
        }

        for (int i=0; i<d.w; i++) {
            for (int j=0; j<d.h; j++) {
                game.display.color = d.tiles[i+j*d.w];
                game.display.drawPixel(i,j);
            }
        }


        for(int x =playerX-7; x<playerX+8; x++){ //7
            for(int y =playerY-6; y<playerY+6; y++){
                if(x >= 0 && y >= 0 && x <20 && y < 20){
                    game.display.drawBitmap(14*(x-playerX+7),14*(y-playerY+6),background[d.tiles[x+y*d.w]]);
                }
            }
        }

        game.display.setCursor(0,168);
        game.display.color = 1;
        game.display.print("OMG! this font just fits on the screen");
        game.display.drawBitmap(14*(7),14*(6),sprites[3]);


        drawHP(playerHP);

        for(int i=0; i<entities.size(); ++i){
            game.display.color = 0; //remove before release
            game.display.fillRect(14*(entities[i].x-playerX+7),14*(entities[i].y-playerY+6),14,14);//remove and fix before release
            game.display.drawBitmap(14*(entities[i].x-playerX+7),14*(entities[i].y-playerY+6),sprites[entities[i].id]);
        }

    }

}

return 1;
}

3 Likes

2 hours later we have two working mapgens

Who said we can’t do this? :wink:

2 Likes

I’m ecstatic right now. This is amazing! which one do we use everyone?

I think @wuuff 's is actually closer to working. @VonBednar 's lua thing still needs work for the doorways and stuff to be in proper places

But I gotta say translating lua to C++ is not a big thing at all

edit:

stylistic point: I think there should be some “broken down” walls and rubble. This palace is too clean. Also: big halls should have single blocks as columns in the middle. You can’t support a big roof with no colums - that isn’t goblin technology !

1 Like

Yeah I know @VonBednar Planned on doing more sprites and stuff so we can implement different walls and rubble.

I also think that we should take advantage of using classes for enemies opposed to @adektos current approach. This would save a ton of code and similar enemies wouldn’t be too hard to implement. Classes just seem to flow a lot better for a roguelike.

1 Like

I will put a bonus gift in the shipment of Pokittos to all of you involved in creating this if we get something resembling a game on time into the #cgajam. extra color case, “I survived CGAjam on Pokitto” T-shirt… who knows ? :grin:

1 Like

Awesome!

I am personally proud that I could pull off a dungeon generator at all! Even if it was translating someone else’s code. I might make a roguelike in pico-8 at some point.

With all that in mind, I vote for @wuuff’s map gen, it will obviously be much more streamlined than whatever I can come up with :wink:

@wuuff - yeah, messing about with the dungeon gen might be better for the post jam version. If you want to try something, we can always choose couple rooms (2 or 3 on the map) and delete the wall between a chosen room, and a room adjacent to make some basic L shapes.

@jonne - yeah, I will add ornaments. Rubble, columns, more wall styles (like the one with the shield) will be added. Tonight I will work on making some items to pickup and have in inventory :wink:

@trelemar - I vote for classes as well. I feel like we could benefit from having someone in charge. @jonne?

No, sorry. One of you take the lead. I am up to my ears in code & other work on Pokitto.

I can push it to twitter etc with videos of it running on hardware etc + “press release”

2 Likes

Wow, that looks awesome in the simulator!

I could add a random chance that some larger rooms won’t be subdivided and instead will be filled with columns, to give some variety. I think it would be pretty simple. Are there any other simple room types that we might want to add?

I think it would also be pretty easy to throw in random rubble in rooms when generating the map. Another choice is to populate the rooms after the map is generated. I’m not sure what everyone is thinking of for that.

1 Like

As we are going with a necropolis we can have:

  • Catacombs with bone rubble, skeletons in walls, and some tombs/coffins
  • Statues for bigger rooms?
  • I was thinking tables, chairs, shelves for those “unliving creature comforts”
  • Largish room can have some multi tile ornaments, like a pentagram.
  • We could add some moss/greenery, but without green it would be tricky

If anyone has any ideas, post them here. I will start working on items and then start cracking on the ornaments after that.

While you work on sprites I’m gunna work on a class-based approach, and implement a decent system. Off to the races boys.

EDIT:

Here’s progress for the night. Work early in the morning. I started redoing the enemy logic with classes, it’s not implemented or anything yet. Added a function to add a decent staircase and plan on getting the decent part working tomorrow. Going to relax for the rest of the night.

I’m glad we got the map figured out finally.

2 Likes

I spent a little time adding generation for large halls with columns (I probably shouldn’t have called them halls, since it can be confused with hallways…). I also added an extra door for long walls. The parameters for these can be modified in a set of defines:

#define MIN_WIDTH 6
#define MIN_HEIGHT 8
#define HALL_CHANCE 90
#define MIN_HALL_WIDTH 8
#define MIN_HALL_HEIGHT 10
#define MAX_HALL_WIDTH 18
#define MAX_HALL_HEIGHT 20
#define EXTRA_DOOR 10

For the example here, I set the chance of a hall generating to be very high. A wall needs to be at least 10 tiles to generate an extra door.

Now the source is a little messy again. Since rooms with even width can’t have evenly spaced columns, rooms of that sort sometimes have open areas with no columns. Not sure if that’s a problem, because it sometimes results in interesting spaces. Here are some rooms that have that extra space I’m talking about:

I may have to make some changes to try to force more even column spacing if that’s a problem. What’s going on right now is that the last set of columns is not placed to avoid blocking doorways.

I updated the source in the gist again, but here’s a link if you don’t want to scroll through all the previous posts:

If these changes seem ok, all I changed was the mapgen function and the #defines before it, so that’s all that would need to be replaced in the project.

Various other decorations should maybe be added after map generation. Maybe something like a detail pass, or whenever the dungeon is populated with enemies.

1 Like

Awesome! After I have finished with items (I have lost too much time on making an axe :stuck_out_tongue:) I will add few columns to the mix.

I agree, other stuff would be added as ornaments, especially that 99% of them will be passable by the characters.

BTW - I think it will be the best route if we won’t add any classes, and just go the original rogue route. I will add few mage like items (staves, books, scrolls, robes maybe?), but will let’s not concentrate on this stuff. If we can add it, cool, if not, normal “warrior” weapons will do just fine.

I decided to try pasting in my modified map generator in the project, and it worked without issues (other than generating a map in which the player started in a wall). What do you think of these rooms with pillars? I think it gives some interesting layouts. All I did was replace the original mapgen function with the updated one.

3 Likes

I think they kick ass!

I will make couple types of columns to go with it and it will make it much more interesting visually!

2 Likes