Large-scale 2D city - good design approaches?

Started by
16 comments, last by ArchangelMorph 18 years, 7 months ago
Hi! I'm in the process of designing a game which I hope is going to be a sci-fi 2D stealth action title where the main character will be able to move around the world in a similar way to spiderman in the Xbox game (Spiderman 2), but in only 2 dimensions of course (side-scroller like view).. I'm planning on building a VERY large city but to do so would require areas with dimensions that span into the 10s of 1000s of pixels.. So i'm wondering.. Considering I plan on using DirectX 8.1 (or higher) for the required performance of a 2D game of the kind of scale i'm hoping for, what would be the best approach of designing an engine suitable of coping with such a huge 2D worldspace, running at a reasonable framerate AND allowing the player/avatar to move around the map in a seamless fashion (similar to the kind of seamlessness we see in games like GTA for example)..? I have alot of (artistic) ideas that should allow me to create the volume of artwork/2D content necessary to accomodate such a vast environment which include re-usability and a simplified artistic style so thats not a problem.. My real concern is figuring out how best to design an engine capable of giving me the kind of performance I would need for this kind of game..? Any ideas would be most appreciated..
Advertisement
I would try breaking the world down into tiles, and only rendering the tiles which are visible to the camera at the moment. In a 2D game, that's not very hard to do. The bigger problem that I've run into when I've tried anything with huge worlds is memory consumption. Your tiles need to be small enough that you can create small alleys, etc, but yet large enough that you don't need 10's of billions of them. ~4.5 billion would be the max for a game, IMHO, otherwise your indexes and counters would have to be 64 bit, which is a fairly large performance hit. Also, you may (or may not) want to implement your own method for pulling map data off the disk as the player moves around. Having the entire city in memory at one time isn't feasible, and I wouldn't want to rely on the OS swapping.

Good luck. I'd love to see your game when it's done. I have a special place in my heart for 2D stuff.
Well....

Some form of dynamic loading? Surley you could open up a file, and read from it when you need, aka as your scrolling around the world, load the bits you need. Like instead of loading it all into memory at once, load it up as you need it.

Not sure how this would be achieved though, but you can always try it :)

Gu'luck :)

Cyas.
Asheh's suggestion is part of what I was trying to say earlier, but couldn't fit into words.

It actually isn't very hard, on a conceptual level. The width and height of the map are known, and the size of tile structures on disk is known, so it'd be simple to calculate the offset into your data file of any given tile. The steps I would use are:

1) Calculate the tile the player is on

2) Calculate which tiles are in view

3) Allocate room in memory for the tiles which are in view (freeing the memory allocated on the cycle before this one)

4) Calculate the offsets into the file of the tiles in view

5) Load the tiles

6) Render

A note about #3 is that if your camera height and field of view are constrained to a certain range (say, 100 meters above the ground and 80 degree FoV), then it would be easy to figure out the maximum number of tiles that can be in view at any given time, and allocate enough room at program initialization, rather than allocating/freeing every frame. I would STRONGLY suggest doing this, as it should provide a fairly large speedup.

There are also a few optimizations, such as only fetching (from disk) the tiles that have just come into view, and just shuffling the ones that were already in view into their new locations.

On a conceptual level, it's pretty simple, and should work fairly well... How it works once you really start coding it... I dunno.
Well all that loading of the tiles from disk is very time consuming. You'd need a really small form of map files and some quick loading procedures.

How big exactly is this world going to be and how many different tiles will you have along with sprites?

You could divide the world up into smaller sets of tiles. The tile images would be loaded into memory upon startup. And your array for the map section loaded would be just a quick number pointing to your table of tile images. For instance,

1 Grass.png
2 Road.png
3 Sidewalk.png
4 tree.png
5 car.png
6 dog.png
7 cat.png
8 beerbottle.png

you might want to consider compressing the map array so instead of allocating 16bits for every integer you would only use 3bits in this case since there are only 8 different tile types. You could make yourself a bit stream instead of using an array. It doesn't seem like much but when you have thousands of tiles that have no pattern of values it will come in handy.

The sections of tiles you divide your world up into has to do with how much memory you actually use and how well it performs. So if your holding 65025 tiles in memory or a map thats only about 255x255 and your game runs pretty quick then you could risk loading a larger amount of memory. But say your character gets closer to the edge of the region in memory you could open another thread that will start loading the region he's closest to into memory. I dunno if any of this will help or if I'm just confusing you.

sure you could do that. But it'd limit you to 8 types of tiles, and it'd be perfectly flat. No hills, no curbs. No nothing. I wouldn't play that. And the penalty for reading off the disk isn't as much as you'd think. You're only reading when new tiles come into view (assuming you optimize it that way). That's not a very large problem.
Well, that was just an example of course you wouldn't limit yourself to only 8 tile types. But to not waste that much space on storing numbers as just one means of compressing the data and reading from disk is not as expensive and operation as it once was but it still can eat up some time so if you find that you need to optimize that those operations compressing your data in memory and loading the map file by sectors would certain do that.

Another option that would be quiet involved would be to time how long it takes to do the reading from disk of a bunch of tiles and then scale how many tiles are loaded in memory by both the available memory and how much processor time you take up while loading.
ehh... that's getting a bit elaborate, imho. It's not like a 2D game is going to have mega-problems with FPS anyways.
Lol, yeah well ArchangelMorph said it was gonna be 'Large' so ya never know.
Yeah, you'll definitely have to use tiles, and I would definitely consider zoning the map off into demand-loadable sections. 4.5 Billion tiles is WAY too much, considering most people have around 512 megabytes of ram installed. At 4.5 billion tiles, even if you only had two tile types, thus enabling you sqeeze eight map cells into one byte, you'd still consume about 90Mb. Of course having only two tile types would make an awefully dull game. Bare minimum would be 256 tiles I think, which would mean your map would consume 4.5 billion bytes of memory. You could reduce this with some sort of compression algorithm, such as RLE. Even then it's highly unlikely that you'd keep the size down to something manageable.

This topic is closed to new replies.

Advertisement