Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411487 Posts in 69371 Topics- by 58427 Members - Latest Member: shelton786

April 24, 2024, 12:40:14 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)I need help with organizing this auto-tiler.
Pages: [1]
Print
Author Topic: I need help with organizing this auto-tiler.  (Read 1092 times)
Giik
Level 0
*


View Profile
« on: July 19, 2015, 06:51:18 PM »

So I've been trying to get tilesetting down on and off while working on my project for a long time now. 47 tiles, inner corners, all that jazz. I think I've got something good going on but it's currently really messy.

Here's my plan so far:


Basically the inner corners (diagonals-only) would move the tile selection down along the Y axis, while the cardinals would move it along the X axis. The darkened tiles are the ones that will never appear, but are still there for reference's sake.

That would (probably) work fine, but the problem is the tilemap I'd have is huge and messy. I wouldn't mind the empty space (I still need to add over 4x the amount of tiles already in there for different transition types against walls, other floors and dropoffs) if it weren't for how cluttered the parts closer to the upper left corner are. So I'm trying to find a way to make the tiles not so spread out, and more uniform.

My question is, is there an efficient solution for this that's already figured out? I've seen other games have the sort of 47-tile tilemaps and those work fine, and I've googled it and asked everywhere, but haven't been able to find a good algorithm/tilemap for optimizing this kind of thing.
I'd be fine with using a script that's more complex than just this bitwise method. Rules, whatever you call them. Just as long as it's not a crazy stack of "if" statements or something, I'm trying to keep it light. Tongue

Ninja edit: I guess the icon isn't all that relevant, but I guess i'll keep it up so you guys know what I'm working with. Man, that icon is outdated as hell.
Logged
Fallsburg
Level 10
*****


Fear the CircleCat


View Profile
« Reply #1 on: July 19, 2015, 08:26:07 PM »

Well, there are 256 distinct possibilities, but in practice it works out to the 47.  If you think of it as:

[1][2][4]
[8][-][16]
[32][64][128]

and sum the tiles, I can give you the mapping from the 256 to the 47 tiles(In the order of http://www.squidi.net/three/entry.php?id=166 blob style) [it's a bit long for the forum, but I can give it via a DM]
Logged
Giik
Level 0
*


View Profile
« Reply #2 on: July 19, 2015, 10:19:54 PM »

Well, there are 256 distinct possibilities, but in practice it works out to the 47.  If you think of it as:

[1][2][4]
[8][-][16]
[32][64][128]

and sum the tiles, I can give you the mapping from the 256 to the 47 tiles(In the order of http://www.squidi.net/three/entry.php?id=166 blob style) [it's a bit long for the forum, but I can give it via a DM]

Alright, that blog post is interesting with the ruleset instead of just adding everything together. It seems like with a 47-tile tilemap you can't just do a single equation like you can with 16 tiles ((North*1)+(East*2)+(South*4)+(West*Cool).
Logged
Zorg
Level 9
****



View Profile
« Reply #3 on: July 20, 2015, 12:16:48 AM »

I've written this, some time ago, blob in ascending order (zero equals a single wall tile, without neighbour):

Code:
var top=0, topRight=0, right=0, bottomRight=0, bottom=0, bottomLeft=0, left=0, topLeft=0;

w = sprite_width;
h = sprite_height;

top = place_meeting(x,y-h,object_index);
right = place_meeting(x+w,y,object_index);
bottom = place_meeting(x,y+h,object_index);
left = place_meeting(x-w,y,object_index);

if (top && left) topLeft = place_meeting(x-w,y-h,object_index);
if (top && right) topRight = place_meeting(x+w,y-h,object_index);
if (bottom && left) bottomLeft = place_meeting(x-w,y+h,object_index);
if (bottom && right) bottomRight = place_meeting(x+w,y+h,object_index);

blob = top + 2*topRight + 4*right + 8*bottomRight + 16*bottom + 32*bottomLeft + 64*left + 128*topLeft;

blobToIndex[0]=0;
blobToIndex[1]=1;
blobToIndex[4]=2;
blobToIndex[5]=3;
blobToIndex[7]=4;
blobToIndex[16]=5;
blobToIndex[17]=6;
blobToIndex[20]=7;
blobToIndex[21]=8;
blobToIndex[23]=9;
blobToIndex[28]=10;
blobToIndex[29]=11;
blobToIndex[31]=12;
blobToIndex[64]=13;
blobToIndex[65]=14;
blobToIndex[68]=15;
blobToIndex[69]=16;
blobToIndex[71]=17;
blobToIndex[80]=18;
blobToIndex[81]=19;
blobToIndex[84]=20;
blobToIndex[85]=21;
blobToIndex[87]=22;
blobToIndex[92]=23;
blobToIndex[93]=24;
blobToIndex[95]=25;
blobToIndex[112]=26;
blobToIndex[113]=27;
blobToIndex[116]=28;
blobToIndex[117]=29;
blobToIndex[119]=30;
blobToIndex[124]=31;
blobToIndex[125]=32;
blobToIndex[127]=33;
blobToIndex[193]=34;
blobToIndex[197]=35;
blobToIndex[199]=36;
blobToIndex[209]=37;
blobToIndex[213]=38;
blobToIndex[215]=39;
blobToIndex[221]=40;
blobToIndex[223]=41;
blobToIndex[241]=42;
blobToIndex[245]=43;
blobToIndex[247]=44;
blobToIndex[253]=45;
blobToIndex[255]=46;

return blobToIndex[blob];

Spritesheet image looked like this:


Hope it helps! Smiley

Edit: I started with top = 2^0, topRight = 2^1, right = 2^2, ... clockwise, don't ask why.
Edit2: I think i got this order from this site: http://www.cr31.co.uk/stagecast/wang/blob.html
« Last Edit: July 20, 2015, 12:55:11 AM by zorg » Logged
Giik
Level 0
*


View Profile
« Reply #4 on: July 20, 2015, 10:33:06 AM »

Alright. I think I figured something out. This works, but I might just go with zorg's method of just having the blobtoindex[] array. This is just for a single tile, so it just loops through all tiles on the screen once.

Code:
repeat(9) {
    chk[next] = tiles0[# xx+(next mod 3)-1,yy+(floor(next/3)-1)]
    next++;
}

val = ((chk[3] != til)*1)+((chk[5] != til)*2)+((chk[1] != til)*4)+((chk[7] != til)*8)
+((chk[0] != til && chk[1] == til && chk[3] == til)*16)+((chk[2] != til && chk[1] == til && chk[5] == til)*32)+
((chk[6] != til && chk[7] == til && chk[3] == til)*64)+((chk[8] != til && chk[7] == til && chk[5] == til)*128)

if val < 16 { //No corners, just cardinals.
    add = val
}
else if (val mod 16) == 0 { //No cardinals, just corners.
    add = floor(val/16) + 16
}
else { //All that weird shit.
    if ((chk[1] != til))+((chk[3] != til))+((chk[5] != til))+((chk[7] != til)) > 1 {
        add = 39 + (val mod 16)
    } else {
        add = 28+((chk[5] != til)*1)+((chk[1] != til)*2)+((chk[7] != til)*3)
        if add = 28 {
        add += ((chk[2] != til && chk[1] == til && chk[5] == til)*4) + ((chk[8] != til && chk[7] == til && chk[5] == til)*8)
    }
        if add = 29 {
        add += ((chk[0] != til && chk[1] == til && chk[3] == til)*4) + ((chk[6] != til && chk[7] == til && chk[3] == til)*8)
    }
        if add = 30 {
        add += ((chk[6] != til && chk[7] == til && chk[3] == til)*4) + ((chk[8] != til && chk[7] == til && chk[5] == til)*8)
    }
        if add = 31 {
        add += ((chk[0] != til && chk[1] == til && chk[3] == til)*4) + ((chk[2] != til && chk[1] == til && chk[5] == til)*8)
    }
    }
}

tile_add(ti_test,((add mod 4)*8),floor(add/4)*8,8,8,xx*8,yy*8,-yy*8)

The tilemap itself looks like this:

Logged
mokesmoe
Level 10
*****



View Profile WWW
« Reply #5 on: July 25, 2015, 02:32:05 AM »

The easy way to do this is to use half-sized tiles. I suppose "do something else" is kinda a cop-out answer but in most cases (including that tileset you posted) it looks the same. Basically each tile is made up of 4 mini-tiles, and then you only need the basic edge/corner/inside-corner pieces making everything a lot simpler.

Though if there are no issues with your system there's no benefit to switching to this system either.
Logged
Sqorgar
Level 0
**


View Profile
« Reply #6 on: July 25, 2015, 05:03:09 AM »

Alright, that blog post is interesting with the ruleset instead of just adding everything together. It seems like with a 47-tile tilemap you can't just do a single equation like you can with 16 tiles ((North*1)+(East*2)+(South*4)+(West*Cool).
I'm the writer of that article (also coined "blob", which I regret every time I see someone else use it), so maybe I can help. The reason there are only 47 tiles instead of 256 tiles is that you can't have a wall without any corners. So if you have an east wall, you must also have a northeast and southeast corner.

Long story short, the easiest way to do this quickly is to just eight bits for each wall/corner and have a simple mapping of the 256 possibilities to the 47 actual tiles. I'm not sure that there is a approach that allows you to optimize both for tileset layout and for tilemap memory usage. A simple 256 byte array that converts an index to another index is simple conceptually, wastes only a handful of bytes, and is quite fast to reference.

I advocate the use of rules, personally, because there are things you can do with them beyond straight up "blob" patterns. The "blob" is a specific, repeating pattern that is useful and common, but not all powerful. It's really quite powerful and useful, and I think once you have it in place, you'll find all sorts of places where it can add value to your maps. But rule lookups are very slow, so they should probably just occur once and have the result stored in a second map.

I frequently see people recommending that you break tiles into quadrants, but that's usually to save on drawing tiles. You'd still need some sort of mapping from a cell's memory representation into its visual one.
Logged
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #7 on: July 25, 2015, 08:46:38 AM »

Hmm, a challenge.

Find a "nice" equation that compresses the blob pattern to 47 consecutive values. Obviously this is a pointless challenge as the look up table works perfectly fine.

Code:
side_index = north+east*2+south*4+west*8
corner_index = north*east*northeast+north*west*northwest*2+south*east*southeast*4+south*west*southwest*8
table = [0,18,5,15,17,21,12,26,25,27,4,28,20,29,30,31]
index = side_index+table[corner_index]

It's a little shorter, I guess, but probably not worth the effort.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic