And needing a hex-map means that I need hex-mapping software...
I tried a few different free hex-mapping applications, but they all had the problem that they are designed for simple rectangular "grids" of hexes. I want to be able to map entire planets - which means I need something that will wrap the hexes around a sphere in a reasonable manner.
So I decided to write one myself. Hence "HexWorld"!
It is by no means finished, but I've got the basics up and running (screenshots to follow at the weekend - I'm posting from work now).
The first thing you do is define the size of the planet that you want to create. The program then creates an icosahedral projection of a planet of that size, filling each face with 72-mile hexes. It then creates a cube of 3d Perlin Noise and intersects the true-3d location of each hex centre with it in order to give each hex a terrain type based on the noise value at that point.
So far this is just re-inventing the wheel - since that's the same as what IsoMage's application does.
However, this is where my application and IsoMage's diverge.
Rather than produce a single flat image, my application holds the world in memory as a collection of individual hexes. You can view the world in one of three modes:
Globe - You see the world as a 3d sphere with the hex grid mapped directly onto it. This gives you the best view of how the planet looks as a whole, with the continents displayed at their real locations and with minimal twisting and skewing. You can rotate and zoom as much as you like to view the planet from any angle or distance. Given the nature of mapping hexes onto a curved surface, each individual hex is somewhat deformed in this view, but the deformation is smoothly distributed so they don't look too bizarre (except for the inevitable 12 pentagons, of course).
Icosahedron - You see the world as a 3d icosahedron with the hex grid mapped onto it. This is very similar to the globe view, except that instead of deforming each hex in order to make the planet look right, it distorts the planet in order to make each hex look right. It's like viewing a huge d20. As with the globe view, you can rotate and zoom to your heart's content.
Net View - You see half the world (a single triangular "face" plus each of the three adjacent faces, plus each of those three faces' other adjacent faces) flattened out as a seamless net. This view cannot be zoomed, but you can scroll around the planet in any direction. The net re-aligns itself on the fly, so you can seamlessly scroll from one face to another. If you do so, the peripheral faces will shift and rotate accordingly.
The net view allows you to edit individual hexes from a palette of hex types, and switching to either of the other two views instantly shows what your changes look like in the "real world".
The power of editing in the net view is that you can edit features anywhere on 90-95% of the planet seamlessly without having to start hex-counting in order to align features that would normally be split when the icosahedron is flattened. The only places where these splits are visible is if you are editing right up against one of the 12 vertices of the icosahedron. However, even in these cases a small amount of scrolling will ensure that the split is always at the opposite side of the vertex to the hex(es) that you are editing.
One consequence of this seamless editing is that there is no definitive "up" direction for any hex, and therefore the top of the screen will not always be facing north. Because of this, the program needs to be able to display the hexes of any face in any orientation - and therefore must store the every individual hex tile independently rather than just storing an image for each face. If it just stored an image for each face, the symbols on the hexes would get out of synch with each other and point in crazy directions. By storing the hexes themselves and drawing the faces on the fly when needed, the hexes can always be drawn the "right way up" even when the map face that they are on is drawn at an unusual angle.
This has two big drawbacks:
1) Drawing the hexes (both flat an in 3d) is very intensive work, and therefore requires the use of hardware-acceleration. I'm therefore writing it in C#, using XNA 4.0. While this is giving great performance (I'm getting 60 frames per second on an Earth-sized planet of approximately 27,500 hexes) it does mean that it is explicitly a Windows application and will probably have performance issues on PCs that are more than three or four years old.
2) Because I have to be able to draw each hex at any orientation, hexes can only contain standard symbols. You can't draw free-form sub-hex features such as rivers or roads. This isn't that much of an issue, since the application is designed for large scale planetary and continental design rather than small scale work.
This is very much a work-in-progress at the moment. I have all the above features working, but the following features are still missing:
- Although I've made sure that there is a nice separation between graphics and data, and all the data is stored in memory in forms that can easily be written/read from disk, I haven't yet written the load/save functions. Currently every time you start the application it creates you a new planet and you lose your work when you close the application.
- Similarly, although I've made sure that the initial world generation is all done from two numbers - a random seed and a size - there's currently no way for the user to input them. The seed cannot be input by the user (to reproduce a specific pattern of landmasses) and changing the size currently requires tweaking a value directly in the source code.
- I haven't yet written anything to export the map to image files. Currently the only way to take a copy of the map is to view it and take a screen-capture.
In particular, I'm wondering about smaller scale maps. It would be lovely to be able to take a section of 72-mile hex map and use it as a backdrop to draw a 24-mile hex map on top of, and maybe even do the same - using that 24-mile hex map to draw an 8-mile hex map on top of. Obviously, you wouldn't want to have those smaller scale maps for the whole world, only selected areas. Similarly, you'd want those maps to be fixed orientation so that you could draw free-form features such as roads, rivers, and detailed coastlines on them. But how to select those areas and handle the transition from world to region is something that needs much thought...