Skip to main content
Illustration.
Source Link
Tapio
  • 2.6k
  • 1
  • 18
  • 18

One wild idea I just came up would be to create a small hand-made prototype map which would have all the bosses and treasures in their relative positions, but during the map generation you would multiply all their positions with the actual map dimensions (i.e. you kind of magnify the map, but keep the preset features as one tile. With some constraints, this could be expanded to walls too (if the proto map has adjacent wall tiles, the gaps are filled during expansion in that dimension, but not in the dimension where there is no neighbouring wall). Below is an illustration with only horizontal expansion (S and E are just some preset tiles you want to place relatively but don't want to use explicit function calls).

#####         #############
#S# #         #  S  #     #
# # #   ==>   #     #     #  
# #E#         #     #  E  #
#####         #############

One wild idea I just came up would be to create a small hand-made prototype map which would have all the bosses and treasures in their relative positions, but during the map generation you would multiply all their positions with the actual map dimensions (i.e. you kind of magnify the map, but keep the preset features as one tile. With some constraints, this could be expanded to walls too (if the proto map has adjacent wall tiles, the gaps are filled during expansion in that dimension, but not in the dimension where there is no neighbouring wall).

One wild idea I just came up would be to create a small hand-made prototype map which would have all the bosses and treasures in their relative positions, but during the map generation you would multiply all their positions with the actual map dimensions (i.e. you kind of magnify the map, but keep the preset features as one tile. With some constraints, this could be expanded to walls too (if the proto map has adjacent wall tiles, the gaps are filled during expansion in that dimension, but not in the dimension where there is no neighbouring wall). Below is an illustration with only horizontal expansion (S and E are just some preset tiles you want to place relatively but don't want to use explicit function calls).

#####         #############
#S# #         #  S  #     #
# # #   ==>   #     #     #  
# #E#         #     #  E  #
#####         #############
More stuff.
Source Link
Tapio
  • 2.6k
  • 1
  • 18
  • 18

EDIT:

I seem to have thought this a bit too high level (as in preset rooms instead of preset walls as you mentioned). However, you could change the preset x and y to be relative to the map size, e.g. x=0.333 would be 1/3 of map width (the loop would multiply x by the width). Null could mean "repeat the pattern through the dimension". Thus the preset for your lava-column example in the comment would be { x:0.333, y:null, map:"L" }.

However, this is rather limited and getting a little complex. For such components as straight, varying size wall sections you are eventually going to have a loop that creates it. The easiest way is to call a function as you did, but if that looks ugly, you can use data-oriented approach as I outlined.

One wild idea I just came up would be to create a small hand-made prototype map which would have all the bosses and treasures in their relative positions, but during the map generation you would multiply all their positions with the actual map dimensions (i.e. you kind of magnify the map, but keep the preset features as one tile. With some constraints, this could be expanded to walls too (if the proto map has adjacent wall tiles, the gaps are filled during expansion in that dimension, but not in the dimension where there is no neighbouring wall).

In the end I think the best way to make the generator feel nice, is to structure it with high-level functions as ashes999 suggested.

EDIT:

I seem to have thought this a bit too high level (as in preset rooms instead of preset walls as you mentioned). However, you could change the preset x and y to be relative to the map size, e.g. x=0.333 would be 1/3 of map width (the loop would multiply x by the width). Null could mean "repeat the pattern through the dimension". Thus the preset for your lava-column example in the comment would be { x:0.333, y:null, map:"L" }.

However, this is rather limited and getting a little complex. For such components as straight, varying size wall sections you are eventually going to have a loop that creates it. The easiest way is to call a function as you did, but if that looks ugly, you can use data-oriented approach as I outlined.

One wild idea I just came up would be to create a small hand-made prototype map which would have all the bosses and treasures in their relative positions, but during the map generation you would multiply all their positions with the actual map dimensions (i.e. you kind of magnify the map, but keep the preset features as one tile. With some constraints, this could be expanded to walls too (if the proto map has adjacent wall tiles, the gaps are filled during expansion in that dimension, but not in the dimension where there is no neighbouring wall).

In the end I think the best way to make the generator feel nice, is to structure it with high-level functions as ashes999 suggested.

I've created several similar dungeon-based games and I've always used a string-based representation for the map, where a different character represents each tile, e.g:

var map = [
    "##########",
    "#........#",
    "#..>.....#",
    "#........+",
    "#........#",
    "##########"
];

In my opinion, this gives a great visual representation and allows you to use a regular text editor as "tile editor". This character representation is used for generating the actual level data, if you e.g. need coloring, graphical tiles or as I've done, a 3D dungeon mesh.

As for the handling of preset sections, just create similar character representations for each of them and in your generator, loop through them and put them into correct locations in the big dungeon map. Here's some pseudo JavaScript for one possible approach:

var map = /* stuff */ // Here's the dungeon map without preset stuff
var presets = [
    { x: 2, y: 5, map: [ "()]" ] },
    /* More map fragments with positions */
];
for (var i = 0; i < presets.length; ++i) {
    for (var j = 0; j < presets[i].map.length; ++j) {
        var x = , y = ; /* Figure out coordinates based on presets[i].x/y and j */
        var x = , y = ; 
        map[y][x] = presets[i].map[j];
    }
}
/* Now the presets are part of the main map 
   and you can process the map into final representation if needed */

I've created several similar dungeon-based games and I've always used a string-based representation for the map, where a different character represents each tile, e.g:

var map = [
    "##########",
    "#........#",
    "#..>.....#",
    "#........+",
    "#........#",
    "##########"
];

In my opinion, this gives a great visual representation and allows you to use a regular text editor as "tile editor". This character representation is used for generating the actual level data, if you e.g. need coloring, graphical tiles or as I've done, a 3D dungeon mesh.

As for the handling of preset sections, just create similar character representations for each of them and in your generator, loop through them and put them into correct locations in the big dungeon map. Here's some pseudo JavaScript for one possible approach:

var map = /* stuff */ // Here's the dungeon map without preset stuff
var presets = [
    { x: 2, y: 5, map: [ "()]" ] },
    /* More map fragments with positions */
];
for (var i = 0; i < presets.length; ++i) {
    for (var j = 0; j < presets[i].map.length; ++j) {
        var x = , y = ; /* Figure out coordinates based on presets[i].x/y and j */
        map[y][x] = presets[i].map[j];
    }
}
/* Now the presets are part of the main map and you can process the map into final representation if needed */

I've created several similar dungeon-based games and I've always used a string-based representation for the map, where a different character represents each tile, e.g:

var map = [
    "##########",
    "#........#",
    "#..>.....#",
    "#........+",
    "#........#",
    "##########"
];

In my opinion, this gives a great visual representation and allows you to use a regular text editor as "tile editor". This character representation is used for generating the actual level data, if you e.g. need coloring, graphical tiles or as I've done, a 3D dungeon mesh.

As for the handling of preset sections, just create similar character representations for each of them and in your generator, loop through them and put them into correct locations in the big dungeon map. Here's some pseudo JavaScript for one possible approach:

var map = /* stuff */ // Here's the dungeon map without preset stuff
var presets = [
    { x: 2, y: 5, map: [ "()]" ] },
    /* More map fragments with positions */
];
for (var i = 0; i < presets.length; ++i) {
    for (var j = 0; j < presets[i].map.length; ++j) {
        /* Figure out coordinates based on presets[i].x/y and j */
        var x = , y = ; 
        map[y][x] = presets[i].map[j];
    }
}
/* Now the presets are part of the main map 
   and you can process the map into final representation if needed */
Source Link
Tapio
  • 2.6k
  • 1
  • 18
  • 18
Loading