Saturday, January 22, 2011

Hex Maps!

So tonight I played with getting hex maps working right.  This is actually much harder than it sounds for lots of reasons :(.  Right now I've got a 1080x1080 hexagon map that can load in about 5.5 seconds, which on my *very* high end box is too slow.  BUT, it does load, and it does render, and it does zoom, and it draws borders, hex numbers, and a background color.  The mouse over to determine which hex the mouse is over works, but only on the default zoom (I have 7 or 8 zoom levels).

However as I load up all the hexes to start, this isn't going to work.  My goal is to map a planet in few files.  These files will be 4000x2000 pixels.  There will be a file for the terrain height, the terrain type, terrain color, and maybe another file for the water level.  There may also be additional files for height if you want to have underground terrain anywhere on the planet.  So that is 3-4 maps, each around 8-24mb each, for 2500 worlds.  That is about 20-60 GB *uncompressed*, likely 10% of that compressed.  That is acceptable these days IMO, and I may make an option to only download maps as you need them locally.

So, each of these maps have pixels that represent about 10km of actual space.  In the terrain type file each pixel is actually a pointer, by the color value, to a regional template.  This means a single planet could have from 255 to, well, BILLIONS of individual templates.  Yes, this system can be used to map the Earth in 1m accuracy!.

These regional maps are 10.8km in size, and each pixel has a defined scale.  By default that scale is 30m, so these maps are 360x360 BT mapsheets, or roughly 21x21 boards.  There will be support for multiple files, which are divided up by the year on that planet.  This allows a muddy fall map, a snowy winter map, a flowery spring map, and a green summer map... *if* desired.

There will be a few hundred regional maps at start I hope.  This should allow a planet to have coastlines, rivers, cities, forests, mountains, etc.  The maps will allow tiling and rotating, which will be randomly created when required with a random number seed for the planet (so its the same every time).  I *will* need help doing these, but at start I'll probably randomize 20x20 BT maps in each, though it'll be very unrealistic it'll get me *something*. 

The regional maps also have associated height maps, terrain types, terrain color, and again optional water/cave maps.  The terrain types are again dictated by pixel color, and these will directly point to a terrain table similar to BT movement cost charts.  These can also have day/night views (for light maps), and optionally persist damage (that can recover over time) and fires (oops, you just burned down an entire forest).  Each pixel is basically a BT "hex".

Hexes (like clear, woods, or jungle) are defined by the base terrain (grass, dirt, concrete, etc), a level of water, urban stuff, and things like trees.  Damage, fires, smoke, etc will be kept track of on the 10.8km maps, but be accurate per hex.  Each hex definition has textures defined so I can draw out pretty and semi-realistic maps.

Unimportant planets like various moons or other bodies in the system will most likely just have generic maps.

Oh, all of these files will probably be bitmaps, this should help with editing them, or viewing say fires on a planet.

Anyway, back on topic now.  My current hex drawing app can draw thousands of hexes in <1 sec, so it works great, but these are "loaded" hexes in RAM, and I can't do that with my above system.  Instead, with my system, I have to read the hex types out of a binary file dynamically as you move from hex to hex.  I have to create a caching system to ensure I have in RAM, what is needed when a unit goes from hex to hex, without loading things too quickly that may be reverted back to.  I've done this before for a 3D engine, so it *can* be done and isn't *too* hard, but its a lot of focused time I need to spend on it.

I still need some other stuff too, like A* hex pathfinding, some orbital mechanics code, and the code to dynamically generate planets based on their various attributes.

I'd appreciate any help people may want to give!


  1. You may want to use DirectX to create a tile-scrolling engine for your hex drawing app.

    While it may mean more up-front cost in development in terms of time, it also means that 20-60 gigs of graphic data can be handled more elegantly and you will have a nice generic tile-engine that can be used for different kinds of apps.

    Here's a link to some tuts for VB.NET development with DirectX:

    And here's where I learned about creating a tile-engine for VB.NET:

  2. Well I know DX has much better performance, but I never anticipated my game as being 3D until future versions of it. Showing planets and systems can easily be done in 2D, and the smallest scale I envisioned was showing the tops of soldiers/mechs, very much like megamek. There are *very* few resources for DX11 (I refuse to use old versions of any software) in VB.NET as well, and since I'm a jack-of-all-trades and master-of-none, I have to stick with what is easiest for me to do, and since even programming isn't my primary knowledge base, I'm sticking with GDI. Also, DX pretty much requires a 3D card, while the GDI would work on people's crappy laptops.

    I do appreciate the link though, haven't seen that book, will take a look.