BoardBuilder design

Introduction

BoardBuilder is a factory class used for creating Board model for the Farout game. In following I will briefly go through the design of the BoardBuilder and give you reasoning behind my decisions. In my next post I will go in more detail by showing you some source code and hopefully I have a working example as well.

By creating dedicated builder class we separate construction role from the model role that the Board class represents. It also keeps Board class simpler and makes it possible to change construction process without a need to touch Board’s implementation.

During the construction we have to allocate memory blocks which are no longer needed when construction has finished. By keeping those allocations in builder only it is easier for us to control how memory is used and when it is freed.

Construction process is divided into small simple steps to make source code easier to understand and maintain. As a rule of thumb every function has only one purpose and if I see copy paste code anywhere I will move that code into own function. I prefer a lot of small methods to few monolithic ones, therefore my classes usually have quite long definition.

Below is the static model of the BoardBuilder and after that you can find description of each class and their purpose.

BoardBuilder's static model

Vertex

Vertex represents single point in 2-dimensional world. It has x and y value defined as floating point numbers.

Segment

Segment represents one line segment that is constructed of two or more Vertices. Vertices are referenced by the Segments. Therefore same Vertex can be used in several Segments.

Hexagon

Hexagon represents one hexagon and is constructed of exactly six Segments. Neigbouring Hexagons share one segment with each other. Segments are referenced by the Hexagon instances, that way we can modify Segment and modifications are instantly visible in every Hexagon referencing the modified Segment.

Region<T>

Region is a tile that is constructed from one or more Hexagons. Region is defined as generic class and the unqualified type parameter is used for referencing the actual region data. Regions own instance of java.awt.Polygon that defines their shape. Polygon class is created because it can be used as a tool for several tasks. E.g.

  1. To check if certain point is located inside Region (e.g. region.shape().contains(x, y)).
  2. To mask (clip) textured blitting (e.g. graphics.setClip(region.shape())).
  3. To draw region borders (e.g. graphics.drawPolygon(region.shape())).
  4. To get maximum bounds of the Region (e.g. region.shape().getBounds()).

BoardBuilder

Board construction is handled by the BoardBuilder class. Construction parameters are given in a BoardBuilderParameters class. Construction happens in following order.

  1. Hexagonal Vertices are constructed
  2. Segments are constructed by connecting proper Vertices
  3. Hexagons are constructed by collecting proper Segments from all Segments
  4. Hexagons are dehexified as described in earlier post
  5. Regions are constructed from Hexagons by combining selected neighbour Hexagons, adjacency is validated when new Hexagon is added to a Region and if the added Hexagon is valid all, except the connecting Segment, are added to the Region
  6. Shape is constructed for each Region
  7. Board is created and ownership of the created Regions is transferred to the Board
  8. Created Board instance is returned to the caller and is ready to be used

About depixelizing

Depixelizing pixel artVectored version
Depixelizing pixel art

In my search for a solution to make my graphics scalable I heard a rumor about Nintendo having released their pixels-to-vector algorithm as open source! Could this be true? I haven’t found any reliable information of this yet.

What I am talking about is something like Johannes Kopf and Dani Lischinski had developed and described in their paper Depixelizing Pixel Art. Sadly, their solution is not available for public and it seems that I end up looking this paper after every search attempt… There is something going on at the SNES scene, for example xBr 2.2, but real time shaders aren’t exactly what am looking for.

Inaria Java..

This is a bit old stuff, but I wanted to share it with you. Inaria is a very simple role playing game that was originally created by Anthony Salter as a result of 40-hours game project. When Anthony released source code for Inaria, someone took initiative and ported it to C#. After trying out C# version I began my own Java port of Inaria and here are the results.

The basic game play should be equal to Anthony’s version. I also added some eye candy and improvements to the user interface. E.g. actions have shortcut keys, buttons are animated when pressed and there are some fading effects and animations added.

Select either Inaria Java without Line of Sight or with Line of Sight.

Requires Java Runtime 1.5 or newer to play this game.

Blog acting weirdly..

If you have wondered where expandable code examples have gone and what has happened to non-expandable ones, they have not gone anywhere. I am just making some changes to WordPress to make my own updates easier in the future. I have been implementing new plugin for WordPress and because I have no sandbox installation of WordPress to play with I am doing changes in live.

When I started to write my blog I had no means to present code examples in visually appealing way. First I modified WordPress style sheets and added new css class .code to apply into my examples. Soon after I started to add longer examples and noticed that they destroy the readability of the post. So I created expandable code blocks.

These blocks were created using javascript and embedded php code – needless to say they were really hard to use and extremely prone to errors. So I started to experiment different ways to do the same. In my best attempt I managed to get rid of javascript inside posts but php was still needed, and I was not happy with the solution.

Then I figured out that WordPress plugin is the way to go. It is possible to add new tags using plugin and it is not even hard to do so. Couple hours later I had two new tags to play with and everything looked great for a while. Then I remembered that I still had some customisations in the WordPress style sheets and a javascript file, that my plugin is dependent of, located under some WordPress directories. So I started to move these files under plugin but before I managed to get my job done, I had to stop for a night. And this is where we are now. Hopefully I have time to finish what I have already started today so you can enjoy reading the blog again.

Please, bear with me..

I am starting to like C#’s versatility

I have been coding small utility for my own use. This utility is about parsing rss feeds and juggling with files. Names of the files come from feed, so I may get anything. This project is also a learning project for C# and .NET, so it is not always clear how to achieve certain outcomes.

A problem I faced with file names is that they can contain illegal characters and therefore I would have to strip or replace illegal characters from the original string. How can this be done using C#? The answer is Regular expressions. Just by looking the example below you will see how versatile C# really is.

[scode]
public static string ValidFilenameFromString(string name)
{
string invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars()));
string invalidRegexpStr = string.Format(@”[{0}]+”, invalidChars);
return Regex.Replace(name, invalidRegexpStr, “_”);
}
[/scode]

Deform algorithms for dehexifying process

In my last post I talked about how to make hexagon map look less dull using dehexifying algorithm. I mentioned that we need to deform vertices but I did not give any examples how to do it. As you probably remember we need to do deformation in two steps, first for the hexagon vertices and later for segment vertices.

Deforming the hexagon vertices is pretty straightforward. We just move all the vertices by certain random amount. One thing to remember though, do not move any vertex more than half the width of the hexagon, and tag vertices that have already been deformed because same vertex can be referenced by several hexagons. Below is a very simple deformation algorithm implemented in Java.
[xscode etext=”Click to show example code” ctext=”Click to hide example code”]
// Vertex
class Vertex {
static Random R = new Random();

public float x;
public float y;
boolean deformed;

public void deform(float range) {
if (!deformed) {
deformed = true;
x += (R.nextFloat() – 0.5f) * range;
y += (R.nextFloat() – 0.5f) * range;
}
}
}

// Hexagon
class Hexagon {
List<Vertex> vertices;

public void deformVertices(int size) {
for (Vertex v in vertices) {
v.deform(size);
}
}
}
[/xscode]
Next I will show the simplest possible segment deformation algorithm. It is virtually same as Hexagon vertex deformation algorithm except for the range of deformation and how it is calculated. I have added Rules class to maintain creation variables. In example below we query segment deformation range from Rules class using method segmentVertexDeformRange() which takes number of vertices in the segment as parameter.

Using the number of vertices as damping factor we have better control of what the deformation result will look like. It is also good for preventing overflows in deformation which would result in silly looking hexagons.

In Hexagon class we just loop through every segment and call deformVertices() for each one. In Segment class deform() is called for each Vertex referenced by the segment.
[xscode etext=”Click to show example code” ctext=”Click to hide example code”]
// Hexagon
class Hexagon {
List<Segment> segments;

public void deformSegments() {
for (Segment s in segments) {
s.deformVertices(Rules.segmentVertexDeformRange(s.vertexCount()));
}
}
}

// Segment
class Segment {
List<Vertex> vertices;

public void deformVertices(float range) {
for (Vertex v in vertices) {
v.deform(range);
}
}
}
[/xscode]
In this naive solution borders can appear jagged. Jagginess can be controlled by tweaking the Rules, but what if we wanted smoothly curved borders? One possible solution would be the use of splines. Below is a sample implementation that uses Java 2D API for this task.
[xscode etext=”Click to show example code” ctext=”Click to hide example code”]
class Segment {
public void deformSplines(float range) {
deformVertices(range);
createSplineVertices(range);
}

void createSplineVertices() {
// Create path
Path2D.Float path = new Path2D.Float();
Vertex v = vertices[0];
path.moveTo(v.x, v.y);
for (int i = 1; i < vertices.size; i++) {
Vertex vold = v;
v = vertices[i];
Point2D.Float[] cps = randomControlPoints(vold, v);
path.curveTo(cps[0].x, cps[0].y, cps[1].x, cps[1].y, v.x, v,y);
}

// Collect new vertices from path
List<Vertex> cubicVertices = new ArrayList<Vertex>();
PathIterator pi = path.getPathIterator(null);
FlatteningPathIterator fi = new FlatteningPathIterator(pi, 0.1f);
while (!fi.isDone()) {
float[] p = new float[6];
fi.currentSegment(p);
cubicVertices.add(new Vertex(p[0], p[1]));
fi.next();
}

// Preserve reference starting and ending points
cubicVertices[0] = vertices[0];
cubicVertices[cubicVertices.size() – 1] = vertices[vertices.size() – 1];

// Apply new vertices
vertices = cubicVertices;
}

Point2D.Float[] randomControlPoints(Vertex b, Vertex e) {
Point2D.Float[] cps = new Point2D.Float[2];
float r = b.distanceFrom(e) / 2.0f;
float a = R.nextFloat() * PI_2;
cps[0].x = b.x + r * cos(a);
cps[0].y = b.y + r * sin(a);
a = R.nextFloat() * PI_2;
cps[1].x = e.x + r * cos(a);
cps[1].y = e.y + r * sin(a);
return cps;
}
}
[/xscode]
It is possible to mix naive and curved implementations to create even more realistic looking tiles. Just add random threshold point that will decide which implementation to use for the segment.
[xscode etext=”Click to show example code” ctext=”Click to hide example code”]
class Segment {
public void deformRandomly(float range) {
if (R.nextFloat() <= Rules.percentageOfCurvedSegments() / 100.0f) {
deformSplines(range);
} else {
deformVertices(range);
}
}
}
[/xscode]
We have seen that using deform algorithms it is possible to create realistic looking map tiles for hexagon maps. Deformation can be done in many ways and I have shown two different algorithms to do this. Next I would suggest you to experiment with different algorithms to generate even more realistic looking tiles.

Dehexifying a hex map. Say what?

Hexagon has appealing characteristics for a map tile. It has six neighbours and the distance from any hexagon to its neighbour is exactly same. More traditional square based map tile has eight neighbours and distance varies from 1 to 1.414.., depending on in which direction particular neighbour is located at. However, they both have one characteristic in common, they look dull.

If you take a closer look at Small World map you will see that map tiles have hexagonal aspect and they do not look dull. Tiles have pretty strong border in high contrast which separates tiles from each other. Hexagon segments have been deformed and the tiles are textured using hand drawn textures with some extra details on top of them. These little finishing touches make them look great and pretty hard to spot hexagon aspect when you look at the map.

As a part of Farout project I have been playing around with Dehexifying algorithm to make hexagon map looks something like Small World map in the image above. Algorithm is simple, yet the results are quite stunning. Algorithm can be divided into following steps:

  1. Create vertices for hexagon map (in my implementation caller gives number of hexagons in horizontal and vertical direction, and width of one hexagon as parameters)
  2. Connect vertices into segments, every segment contains exactly two vertices at this point (segments reference to vertices, therefore altering one vertex affects every other segment using same vertex)
  3. Create hexagons from segments (hexagons reference segments, therefore modifying one segment alters other hexagons using same segment)
  4. Deform the vertices (this could be done before step 3 it just happens to be 4th step in my implementation)
  5. Split segments into several vertices. Number of vertices created for segment depends on the segment’s length after step 4. The longer the segment is the more vertices will be created.
  6. Deform newly created vertices to make segments non planar.

 

Dehexifying algorithm steps
Dehexifying algorithm steps

 

After these six steps hexagon map looks surprisingly lot like a Small World map, depending on how well your deforming algorithms work. One has to remember that this is just a model for the dehexified map – what it really looks like depends on rendering algorithm, which I will talk more about in my next post.

Dehexified map example
Dehexified map example with textured rendering

Heavy infantry graphic tile evolution

Human heavy infantry graphic tile evolution
Human heavy infantry graphic tile evolution

 

Here is an example image of how difficult it is to make use of old 8-bit graphics in a modern game development. The first image on the left was drawn way back in the late 80’s. It was the first attempt to create a heavy infantry icon to our game, then called Warmaster for Amiga OS. The second to the right is just a doubled image of a later SVGA-version for Windows. Third image is a experiment with HQ2X – an attempt to speed up the graphic design process. It’s better than the plain nearest neighbour scaling but we have to admit it lacks the detail and refinement of a hand crafted icon. Although pixel editing is slow and considered a skill from the past, we’ll have to stick to it unless there soon pops out a powerful pixel-to-vector-converter somewhere.

Graphics, my preciousssss graphics..

Long time ago we had a small game project called DragonWars. It was a strategy game using hexagon maps and hand drawn graphics. Unit graphics are nice  but the  problem with them is the size.  Units are 16px * 16px which is way too small for today’s modern games. Therefore Juha has been playing around with different scaling algorithms to see how we could use those old graphics without the need to fully redraw them. The most promising algorithms have been Hq4x and Microsoft research center’s Depixeling the Pixel art -project (DPA from now on).

Hq4x is widely available while the DPA has no reference implementation available. What makes DPA more appealing in our eyes is the fact that DPA generates vector graphics from the raster graphics while hq4x just scales the raster graphics into new fixed size raster graphics. For our longer plans vector graphics would be ideal but for now we will have to stick with raster graphics and hq4x.

If Juha gives me his permission I will later post some example icons to this blog.