Table “grid_layouts” contains grid parameters, like maximal X-, Y- and Z-coordinates, maybe a grid name and frequencies of different cells. This way we can have several grid templates. The columns are:

id

layout_name — a dozen of characters

max_x — number

max_y — number

max_z — number

description — many characters

what else?

Table “hex_layouts” contains all possible types of hexes that can be encountered on a grid, information on whether they are inhabitable, fertility, sunlight/temperature, and water/humidity:

id

inhabitable — boolean

fertility — percent from 0 to 100

humidity — percent from 0 to 100

sunlight — percent from 0 to 100

OK, that was it so far. What hex types do we need here?
Uninhabitable:

fertile-humid — 110:110:80 (or maybe I should make it even more imbalanced, comparing to the previous three)

fertile-sunny — 110:80:110

humid-sunny — 80:110:110

So, there are 10 types of hexes. I need to decide on the distribution (like a hex of basic type should have no more than two uninhabitable hexes adjacent to it) and frequencies of each type. Exact frequencies are not very-very important, but it would be interesting to make a mechanism to adjust frequencies after the distribution rules were met. Say, if while populating the grid (hex by hex, row by row, checking for rules in the previous row), uninhabitable hexes turned out to be too few, the probability of the next hex being uninhabitable should be larger than average. Mmm … that still does not guarantee that the number of outcomes is strictly equal to the probabilities/frequencies…

It took me a while of contemplating a Robik’s cube and thinking about 3D coordinates before I came across a system of cell/tile notation that would fit my purposes. So, here is the story.

Two orthogonal axes are not good for hexagonal cells, because cell coordinates will not be integer numbers (look at figure 1).

Figure 1. Orthogonal coordinates

Two non-orthogonal axes can have integer number coordinates, like in figure 2, but calculating distances between cells is not straight-forward, so they are not good either.

Figure 2. Two non-orthogonal coordinates

If two coordinates don’t do, then what? Three coordinates???

First consideration. A square belongs to a vertical file and a horizontal file, which is exactly why Cartesian coordinates perfectly fit for both easy numbering and easy distance calculation. A hexagon belongs to three files at the same time: a horizontal file (from “West” to “East”), a file going from NNE to SSW, and a file going from NNW to SSE. Thus, one could pick a cell, number it (0;0;0), and number all other cells depending on how many files to, say, South, ENE and WNW they are with respect to the origin.

Figure 3. Three coordinates

I’ll try to add a better illustration and a bit of explanation later. So far, I want to mention two important things:

Somehow the values of all three coordinates always sum up to 0. This sounds strange and irrelevant, but it has an explanation and it has important implications.

There are both positive and negative values. Negative values are a bit annoying and look unnatural.

The distance between any two cells is calculated by formula . The distance between two adjacent cells is equal to , but we can always normalise it by dividing to formula above by this number.

So far, we obtained a nice system of coordinates where (1) all cells are numbered using three integers, and (2) all distances are calculated by the same formula irrespective of the direction. The last thing I wanted to do was to get rid of negative numbers.

I recalled reading somewhere that a hexagon can be thought of as a projection of a cube on a plane. This way, we can think of hex grid as a Rubik’s cube made of many little cubes. Because the tiles of our grid do not overlap we need to take only those small cubes that lay in the same plane, i.e. laying edge to edge to each other. This plane crosses the faces of the big cube (Rubik’s cube, the grid in 3D) at 45 degrees and thus can be described by a simple equation , where ‘a’ is some constant. If a = 0 we have the system of coordinates described above. We need to take ‘a’ large enough to make all values within our grid positive, but not unnecessarily too large. ‘a’ is deternimed very simply: count all files (1) from N to S, (2) from ENE to WSW, and (3) from WNW to ESE, then pick up the largest of the three. Done.

Preliminarily, the grid itself will represent a large hexagon, with one side equal to 32 cells. This means there will be 63 files in any direction. So all values of coordinates will be comprised between 0 and 63.

The main problem is that almost all resources look at hex grids with adjacent upper and lower cell, while I want a grid with adjacent cells located to the right and to the left. So I will learn conversion between coordinates and the math behind it, by implementing the same examples to “my” grid orientation.

To start with, I took Tim Holt’s hex map example, read about a game called Lights Out, and implemented a hex version of it in JavaScript and plain HTML, using no PHP for grid rendering (in contrast to Tim’s example). The result is here. It has a fairly easy solution, the design is wanting and the code is surely buggy, but it’s fully functional and playable.

Today game development took a bit unexpected path. Instead of creating and populating the grid and continuing with initialization stuff, I went into automation of what I already can do. So I started to create an “admin panel” for the game.

At this point, it can create and delete the database. Besides it reports the result in AJAX manner, without reloading the page. It took me a while to understand AJAX and implement it.

I learnt how to create MySQL databases from within php scripts and started the game initialization module. Next I want to create a table for grid cells and randomly populate the game map.

Plan:

Populate the table based on hex coordinates

Create a formula to convert from hex to Cartesian coordinates (e.g. for distance calculations).

Create a script to plot them on the screen.

Ideas here:

Cells might be divided into inhabitable (with different humidity, sunlight and minerals) and non-inhabitable.

“Desert” would correspond to zero humidity or zero minerals, and be good only for sunlight. “swamp/river/lake/sea” would be good for water and/or minerals only. Non-inhabitable cells will be exploitable by a player, if they are adjacent to the player’s plantation.

Possible types of cells, ranges of parameters and frequencies of appearance are to be stored in “constants.php” and used by “init.php”.

Another problem is security. Who will run init.php? How to protect it?