Roguelike with C# tutorial series begins

Nice set of tutorials starts:

http://www.billmorefield.com/index.php/2016/03/06/roguelike-development-with-c-part-1-introduction/

 

 

Advertisements

Tutorial on Dungeon Generation in Objective-C

So I am getting a Cellular Automator (CA) generator ready for this years 7DRL and hoping to create the same game in iOS and HTML5 – I am sure I am biting too much off. However, I have a basic implementation of a Dungeon generator and detailed how to create it below in X-Code using Objective-C. It’s a very simple implementation – so feel free to comment if you think we can clean the code up!!!!

In terms of CA there are some great references to get you going:

http://pcg.wikidot.com/pcg-algorithm:cellular-automata

http://www.futuredatalab.com/proceduraldungeon/

http://csharpcodewhisperer.blogspot.com.au/2013/07/Rouge-like-dungeon-generation.html

For this tutorial the dungeon is represented by 0’s as Rock and 1’s as  Path (or moveable space).

This is the output so far:

Screen Shot 2014-02-16 at 1.19.12 AM

So its a pretty simple set of steps to get us going.

Firstly create a OSX->Application->Command LineTool->Foundation project in Xcode

Then add a class called Dungeon

The header for Dungeon should look like this

#import <Foundation/Foundation.h>
 @interface Dungeon : NSObject
{
    int map[100][100];  //max size of dungeon
    int maxRows;        //size of this dungeon
    int maxCols;        //size of this dungeon
}
- (id)initWithRows:(int)rows AndCol:(int)cols;   
-(void)printMap;
@end

The implementation for this should look like

#import "Dungeon.h"

@implementation Dungeon
- (id)initWithRows:(int)rows AndCol:(int)cols
{
    self = [super init];
    if (self) {
        [self initMap];
        maxRows = rows;
        maxCols = cols;
        [self createCellularAutomatorDungeon:maxRows ForCols:maxCols];
    }

    return self;
}

//set all the map to rock
-(void)initMap
{
    for(int i=0;i<maxRows;i++)
        for(int j=0;j<maxCols;j++)
            map[i][j] = 0;
}
 //Loop through the 2 dim array and add space (not rock) if the wall has a specific minimum neighbourCount
- (void)createCellularAutomatorCellsForNeighbourCount:(int)neighbourCount
{
    //first pass CA
    for(int i=0;i<maxRows;i++)
    {
        for(int j=0;j<maxCols;j++)
        {
            if (map[i][j] == 0 && ([self getNeighboursForRow:i ForCol:j]>=neighbourCount))
                map[i][j] = 1;
        }
    }
}

//use a classic CA algorithm 
-(void)createCellularAutomatorDungeon:(int)rows ForCols:(int)cols
{
    //randomly initialize wih a few random spaces in the rock
    for(int i=1;i<maxRows;i++)
        for(int j=1;j<maxCols;j++)
            if (arc4random()%4==1)
                map[i][j] = 1;

    [self createCellularAutomatorCellsForNeighbourCount:4];//first pass
    [self createCellularAutomatorCellsForNeighbourCount:5];//second pass
}

//Count of the number of neighbours for this point
-(int)getNeighboursForRow:(int)row ForCol:(int)col
{
    int n = 0;

    //top neighbours
    if (row>0 && col>0)
    {
        for(int i=col-1;i<col+2;i++)
        {
            if (map[row-1][i]==1)
                n++;
        }
    }

    //middle neighbour left
    if (col>0 && col<maxCols)
        if (map[row][col-1]==1)
            n++;

    //middle neighbour right
    if (col>0 && col<maxCols)
        if (map[row][col+1]==1)
            n++;

    //bottom neighbours
    if (row<maxRows && col<maxCols)
    {
        for(int i=col-1;i<col+2;i++)
        {
            if (map[row+1][i]==1)
            {
                n++;
            }
        }
    }
    return n;
}

-(BOOL)ifValidCoordinateForRow:(int)row ForCol:(int)col
{
    return (map[col][row]==0 && row>0 && col > 0 && row<maxRows && col<maxCols);
}

-(void)printMap
{
    for(int i=0;i<maxRows;i++)
    {
        for(int j=0;j<maxCols;j++)
            printf("%u", map[i][j] );
        printf("\n");
    }
}

And make sure that main.m looks like

#import <Foundation/Foundation.h>
#import "Dungeon.h"
 int main(int argc, const char * argv[])
{
    @autoreleasepool {
        // insert code here...
        NSLog(@"Basic Dungeon CA Algorithm");
        Dungeon *dungeon  =[[Dungeon alloc]initWithRows:30 AndCol:50];
        [dungeon printMap];
            }
    return 0;

}

Ok so if you look at the code above in dungeon.m you should get a pretty good idea of how we are doing the generation of the dungeon using a CA algorithm. Read the comments as I have tried to explain anything a little unusual. If anything doesn’t make sense – leave a comment and I’ll get back to you.

Happy coding.

Watching my videogame reviewed on Youtube

The Game

So you may have noticed I entered the 7drl (7 day roguelike comp) this year – a comp to write a game in 7 days. It’s actually not a lot of time to write a game and given work and home commitments – its really really not very long. Anyway I wrote a crazy game called Rogue Coder using JS, HTML5 and MVC4. The end product is here www.domssite.com/roguecoder

The Review

So uberhunter is reviewing all games in the 7drl on youtube and he just reviewed roguecoder. It’s a fair stressful experience watching your game (warts and all) get a review from such a guy.

here it is http://www.youtube.com/watch?v=eEaPH34DxxE

Lessons Learned

The value of a review like this is priceless. Its a great way to look at your game through the eyes of an independent and experienced player. It’s hard to watch at times because I keep thinking “I really wish I had fixed that bug”. It’s also hard to watch a review like this because you are not there to guide and advise, and you are not there to explain the things that you have in your head but never quite got the time to either fix or document . I think I have taken some a few important lessons:

1. Ensure core game play works (the bugs with the compiler actually stop the game from being playable).

2. Watch the way someone else plays the game and look at their actions and strategies to determine ways to make the game more playable, robust and enjoyable.

Whats next

V2 of course stay stay tuned  here in the next few weeks. Of course a big thank you to uberhunter for the review