Creating and storing map data

DrKane
Unregistered
 
Post: #1
I'm working on a tile-based rpg engine. Up until now I've just kept a large array within my source code to represent the map. I Now want to keep an external map file and I'm trying to figure out exacrtly how to? Do I keep a text file and read the text in through some interpretive routine? I've read that I should create my own resource using rez, well if so, how should I do this and where can I get rez? Also once I have my whole external map data set up, I want to be able to read parts of the map incrementaly so that I can have a huge world, how would I do that?
Quote this message in a reply
w_reade
Unregistered
 
Post: #2
no-one's answered yet, so herewith my two penceÖ

I'm afraid I'm not sure about the best format to store your data in; that'll depend on your engine, and what you need to store for each tile, and so on. I have normally just used text files when I've needed to store things myself. It feels a bit wrong, to me at least, butÖ whatever you're comfortable with.

When it comes to reading parts of the map incrementally, I'd break the world into map squares and store each map square separately. The world would just be a grid of map squares. You'll always have the current map square in memory, but will need up to three others at the same time (if you're standing at the corner of one map square, you'll need all four to see what's around you, but if you're in the centre of one you'll only need that one). You'll never need more than four at a time, though, unless they're smaller than a screen.

When it comes to choosing when to load them, I'd suggest you only bother when the player's within a few squares of being able to actually see them, otherwise you might have to do a lot of unnecessary loading and reloading while players do the standard TB-RPG thing of "check every wall tile for secret passages", which tends to involve a fair amount of walking back and forth in a smallish area.
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #3
Have you seen Level Creator <http://www.swarming.net/levelcreator/>? If you're not using SpriteWorld you can apparently write plugins to support your own map data format.

Binary data files would be more space-efficient than text files, but you might want to be careful that you don't make the data format inflexible. If you use a text based data format, it could be easier to extend the format at a later date, although you could equally well design a binary format that allows arbitrary data for each and any tile in the map.

I wouldn't use resources for this kind of thing, personally. It's easy to swap out separate data files while developing, whereas resources (especially source code based resources) may need to be recompiled or relinked into the game. Application bundling helps to hide the extra files this would create.

As far as incrementally loading data goes, unless you're planning to run on machines with very small amount of memory, it might be simpler to just load the whole lot all at once. I mean, how big is your map? If your map is 1000x1000 tiles overall, and you had 8 bytes per tile (for whatever reason), you'd only be using 7.6Mb of memory. You could use a look-up table to reduce the number of bytes per tile. You'd probably still want to compress it on disk, though.

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
DrKane
Unregistered
 
Post: #4
My world map is going to be much, much larger than 1000 tiles. Probably more in the neighborhood of 80-100,000 tiles. I have read about a technique where you keep 9 nodes of the map, loaded into memory at any given time. The player being in the center node at all times, so if he crosses over to any node next to him, then he just reloads the nodes so that he's centered again:

each square representing a node:
---------------
|__|___|__|
|__|_x_|__|
| | | |
---------------

If you keep all 9 nodes (including center) surrounding the playerloaded into memory at all times, what would be the best way to calculate which node should be loaded and when to load the nodes?
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #5
Quote:Originally posted by DrKane
My world map is going to be much, much larger than 1000 tiles. Probably more in the neighborhood of 80-100,000 tiles.

Really? That's massive!

I used to think I wanted to do an RPG of that kind of scale until I realised that it would take me the rest of my life to design the levels. Unless your tiles are very small relative to your rate of travel, 1000x1000 is actually quite a lot. For example, how long would it take your character to walk from one side of the map to the other? Consider also that there are things for the player to do along the way, so they'll be kept busy in particular places for a while.

That said, your proposal for nodular levels is perfectly reasonable and would allow for very large designs.

While I was thinking about my idea, I thought it might be better to generate the level designs algorithmically, a bit like NetHack (if you've ever seen that), but much more sophisticated. That would allow me to have a potentially infinitely large area, because I'd generate it as I went along.

You could of course get other people to design some of the levels Smile or supply a level editor!

Quote:If you keep all 9 nodes (including center) surrounding the playerloaded into memory at all times, what would be the best way to calculate which node should be loaded and when to load the nodes?

Basically, whenever the player crosses a node boundary, you need to load the nodes on the opposite side of the new node. You could also cache the nodes the player has been in recently in case they keep walking back and forth, as w_reade said.

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
DrKane
Unregistered
 
Post: #6
<<I used to think I wanted to do an RPG of that kind of scale until I realised that it would take me the rest of my life to design the levels. Unless your tiles are very small relative to your rate of travel, 1000x1000 is actually quite a lot. For example, how long would it take your character to walk from one side of the map to the other? Consider also that there are things for the player to do along the way, so they'll be kept busy in particular places for a while.>>

I've contemplated whether or not to split the game up into 3 smaller maps, and I would like to come up with some sort of transportation system to easily navigate the player to different parts of the map. These, however, are the least of my worries at the moment. I'm just working on getting my core engine features up and running.

<<You could of course get other people to design some of the levels or supply a level editor!>>
Quote this message in a reply
DrKane
Unregistered
 
Post: #7
Okay I am working on just a basic routine for loading a generic map. It works except that from 0,0 each diagnal tile is not read from the map file. Here's the code

Code:
// I'm not actually loading the tiles, I'm just setting there type so that they'll
//show up on screen for my tile drawing routine.

#define kArraySizeH  10
#define kArraySizeV  10


UInt32 mapIndex;
    short row, column;
    char tile;
    FILE* filePtr;
    
    filePtr = fopen( "MapFile", "r" );

    if (filePtr == NULL)
    {
        gDone = true;
        return;
    }
    
    for (row = 0; row < kArraySizeV; row++)
    {
        for (column = 0; column < kArraySizeH; column++)
        {

      tile = fgetc(filePtr);
            mapIndex = (row * kArraySizeH) + column;
            
            switch (tile)
            {
                case 'm':
                    map[mapIndex].type = empty;
                    break;
            
     default:
        map[mapIndex].type = tree
        break;
   }
            
        }
    }
    
    fclose(filePtr);

// m = emp
// 0 = tree

MapFile:

mmmmmmmmmm
mmmmmmmmmm
mmmmmmmmmm
mmmmmmmmmm
mmmmmmmmmm
mmmmmmmmmm
mmmmmmmmmm
mmmmmmmmmm
mmmmmmmmmm
mmmmmmmmmm


actual screen:

// differs sometimes
m0mmmmmmm0
mm0mmmmmm0
mmm0mmmmm0
mmmm0mmmm0
mmmmm0mmm0
mmmmmm0mm0
mmmmmmm0m0
mmmmmmmm00
mmmmmmmmm0
mmmmmmmm00

Anyone know what's wrong here?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #8
Doesn't look like you're taking into account the end-of-line characters in your file.
Quote this message in a reply
DrKane
Unregistered
 
Post: #9
What's a good way to fix this?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #10
Either take all the newlines out of your file, or (as long as your file has either Mac or Unix line endings) read a single character at the end of each row & ignore it.
Quote this message in a reply
DrKane
Unregistered
 
Post: #11
Even when I use the return character at the end of my line (\n) it still doesn't work. Can someone give me a code snippet for reading a simple 5x5
text file of chars into an array?
Quote this message in a reply
Jeff Binder
Unregistered
 
Post: #12
This reads the characters into an array, ignoring newlines. Keep in mind that with this code, a newline doesn't necessarily start a new row, it's just ignored.

Code:
#define ARRAY_WIDTH 5
#define ARRAY_HEIGHT 5

char g_array[ARRAY_WIDTH][ARRAY_HEIGHT];

/* Fills g_array with characters read from f, ignoring
   newlines. Returns 0 if not enough characters to fill
   the array were found. */
int read_array(FILE *f)
{
    char c;
    int i, j;

    i = j = 0;
    while ((c = getc(f)) != EOF) {
        if (c != '\n') {
            g_array[i++][j] = c;
            /* Start the next row. */
            if (i == ARRAY_WIDTH) {
                i = 0;
                if (++j == ARRAY_HEIGHT) {
                    /* Array is full. */
                    return 1;
                }
            }
        }
    }

    /* The arrays weren't completely filled. */
    return 0;
}
Quote this message in a reply
DrKane
Unregistered
 
Post: #13
It's not working for some reason. I'm trying just about every variation I can think of. Some of the chars are still not being loaded. Is there any resource, documentation, or open suorce file/project where I can find an in-depth explanation regarding reading text files? BTW, if my map looks like this:

mmmmm
mmmmm
mmmmm
mmmmm
mmmmm

would putting '\n' at each of the end of rows, make it automatically return to the next row? Or would I have to specify that myself?
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #14
Well you could always look at the hooptie source code it uses the exact same idea for loading maps. http://inkubator.idevgames.com/
Looks like they also changed their license to be more programmer friendly; I should probably look at it too for my next game.

Iceman
Quote this message in a reply
DrKane
Unregistered
 
Post: #15
Is it only for PB, because the larger version i downlaoded didn't even work, and then the small version only had a couple global and header files, and the rest of the files it wouldn't even let me open.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Storing data for action replays monteboyd 4 3,887 Dec 5, 2005 04:14 PM
Last Post: Frank C.