Sunday, 5 October 2014

Unity Tron Bit

A nice and simple Tron bit in Unity. Which I think should be the 'hello world' for 3d game engines.  Sound samples from the Movie Sounds page for Tron.  The models themselves are pretty simple.  The neutral is a fade between a dodecahedron and an icosahedron.  Yes is an octahedron.  No is the only one that wasn't a basic primitive but it's wasn't far off, it's an icosahedron with a geodesic frequency of 3 (so it has more triangles).  Then I just moved the points out to make the faces spiky.  (I mention it as I like writing words like icosahedron).

you're a bit!
It was quite fun messing around with Unity's physics system to get a nice feel for spinning the bit around.  Also enjoyed shaping the scaling in and out to make it look right.  Added in some rpg elements just to be silly but you can turn it off.  Source code is included for download on the page too, enjoy playing with the Tron Bit, ask it anything, it knows all.


Tuesday, 9 September 2014

Unfinished

I've been stuck in the indie shame spiral for a while and to remedy the situation I'm going to tackle a couple of smaller Unity projects for the end of the year.  First up is this driftwood collection simulation.  I got into such a tangled knot with this. The idea was to implement this interesting paper on resource emergence from Modelling the emergence of resource-sharing conventions.  My final build so broken it's embarrassing. In a weird way though it's served it's purpose, just doing something else to clear my mind, even though it's poor you learn from these errors.  Having failed early I could take another crack at it but instead and I'm moving on.

driftwood

Unity Driftwood player
Unity source code

There are issues with how I structured bits of the code that meant I had a huge single class doing too much of the work and being quite messy as a result.  I hugely miss being able to 'run to cursor' in Visual Studio as a number of times I made Unity freeze up from infinite loops, or weird stuff was happening and I would have loved to be able to step through the code in the editor.  You can download the source too but there's probably not much of interest in there.

That's all for now.

Monday, 26 May 2014

Building Biomes

To add depth to the world generation I've added in a method of generating biomes onto the landscape.  There's quite a lot of biome types and classifications that you can ready about but I found the simpler, kid friendly websites the most helpful as they distil the variations down.  In particular I used blueplanetbiomes.org.

My biomes are a combination of temperature, rainfall and elevation and it was simply a matter of generating each of those layers and then combining them to define the biome.  I broke each layer into three too, for example temperature changes linearly from 1f to 0f from the equator, and I set the value to be hot, warm or cold depending on the range, e.g. hot > 0.8f.
Temperature (hot, warm, cold) from equator.
(left) without & (right) with simplex noise.
Rainfall and elevation use the same 3d noise function as the land/water generation.  I could have used the land values I already had but it would mean mountains would predominantly lie at the center of the land masses and I thought that was a little dull.

Rainfall and elevation.
Both with a low noise scale.
I had these all set up in a neat XNA project so I could interactively tweak all the values, varying the noise scale and the different ranges.  I didn't want to have dozens of different biomes, which would mean dozens of unique textures to be done, instead I broke it down to a handful that would give a nice variation for exploring.

Low elevation...
Hot Warm Cold
Wet rainforest deciduous taiga
Moist savannah grassland tundra
Dry desert grassland polar

Medium elevation...
Hot Warm Cold
Wet rainforest deciduous taiga
Moist savannah deciduous taiga
Dry savannah grassland tundra

High elevation is always alpine. Not sure if/how I'll represent hills, I might just ignore that element and treat the world as flat or mountainous.  Using elevation as three layers though stops mountains from appearing in the middle of deserts and adds to the randomness nicely.

Combining the layers results in a
single biome for each cell.

A feature I want is reproducibility, so if you have a map that you think is particularly fun to play on you should be able to save and share a small set of seed values in order to perfectly regenerate it.  I did have a different method of generating the temperature using a sum of sine waves with some random frequencies, but it wasn't reproducable.  Thankfully with the noise functions, you really only need to remember the seed values and a few other numbers for each layer and the result is deterministic.  I would be cool if I could compress those down into a neat little hashtag style string but I'll worry about that later.

Higher noise scale for better biome distribution.
Oceans break it up further.


Monday, 28 April 2014

Texture mapping small regions on a sphere.

(aka)How on Earth/Gaia do I make this look pretty.


 I've been really stuck on how to proceed and I figured building out the first pillar of the classic 4X system is as good as any to work on right now. That's singling out eXplore from eXpand, eXploit, and eXterminate.  The voronoi sphere I'm very happy with, it's a great starting point as an interesting layout to explore.  It led me into this mental puzzle of what else do I need to represent on it and what is it going to look like.  As always I can look at the great Civ which has a beautiful rich 3d representation of each terrain type.  That's a bit beyond me to accomplish and instead I want to pursue a more abstracted look.  This I think is a common indie game problem where you have to be careful and pragmatic about what you can build and accomplish to a good standard, it's why pixel art and minimalism rules.  So I went searching for maps.

Map inspiration.
Top Left - LOTR
Top Right - Elder Scrolls
Bottom Left - Battle of Cerro Gordo
Bottom Right - Game of Thrones


Maps are awesome.  I found all these great fantasy and battle maps, a little sample of four that peaked my interest in the image above.  The old paper look with little ink markings seems like a really good fit for what I need.  It's got a nice texture to it and it's graphically simple enough that I thought I got do a pretty good approximation of it myself with my programmer art skills.

First problem, texture mapping.



art de programmer

I needed to get 2d coordinates for the texture mapping onto my polygons.  Well each region has a central point.  I can use that to get the longitude and latitude, then rotate it first along the longitude then the latitude so that it's sitting directly on top of the sphere.  At this point you can disregard the Y value, like you're looking straight down from the top, you're now dealing with a simple 2d case.

I use these equations for the longitude and latitude. (Sorry not very good at pasting in code)

// Return the longitude & latitude of a point on a sphere
// X=longitude  Y=latitude
public static Vector2 GetLongitudeLatitude(Vector3 position)
{
   //make sure it's a unit vector
   position.Normalize();

   //latitude will be from 0 to pi
   double latitude = Math.Acos(position.Y);

   //longitude...use dot product with prime meridian
   Vector2 vec = new Vector2(position.X, position.Z);
   vec.Normalize();
   //prime meridian
   Vector2 mer = new Vector2(0f, 1f);

   double longitude = Math.Acos(Vector2.Dot(vec, mer));
            
   //for our sphere at origin.  we know everything that's -x
   //is to the left our prime meridian, range of 0 to TwoPi
   if (position.X < 0)
   {
      longitude = MathHelper.Pi + (MathHelper.Pi - longitude);
   }

   return new Vector2((float)longitude, (float)latitude);
}

You can set the texture coordinates easily from this by just plugging in x,z positions to map to the u,v texture coordinates with any scaling/offset desired.  But we're not done!

Insetting

If you look at most old paper textures, the paper darkens as it gets to the edge.  I'd also want to fade out any icon/patterns to a blank texture to make the region transitions nicer.  For that I needed to inset the polygons.  As per bloomin usual this is not entirely trivial, and of course it's the edge cases that get you.  Namely when a very small edge is inset you neet to collapse the point.

Collapsing points to make neat insets.

Very happily though In this case I did find an amazing library that would do the work for me...and it even compiled without hassle for Unity.  It's the Clipper library.   (and like many bits of 3rd party code it used some C# syntax I've never seen before).  It also slightly threw me for a loop when I found it only worked with integers, so you scale everything by like a billion then back down again otherwise it just gives you zeroes.

Almost done with the insetting at this point, but the path you get back from clipper doesn't necessarily match.  Imagine the outer edge and the inner edge are like two railroad tracks, you need them to be in sync for laying the railroad ties, i.e. building the indices for the polygons. So that was a little tricky to sort out.  Then the last step is to reverse the rotation to place it back in the world again.

hmm - little gaps

One last glitch needed fixing.  Transforming there and back again introduced just enough of an error that little gaps appeared.  To fix I kept (and also had to order from correctly) the original positions.  So the inset will actually be ever so slightly off but you'd never notice.

Shading

Almost there.  We have our UV map and our inset.  Now we want to blend from one texture to another to create a nice faded paper effect.  Unity didn't seem to have the shaders I needed in built but I found enough info via the wiki and forums to get me there.  First was a vector colour shader,  it shows me what colour I've inputed for these vertices so I can check it for debug.  These colours will define the blending between a couple of textures, so white (outer edges) will be one texture and black (inner edges) will blend to another.

Coloured vertices to define blending

Now I just needed to plug in some actual textures into these channels.  There are looooads of 'old paper' effect tutorials on the web and I just followed one of them to create a basic main texture, then darkened it for the edges.

Old paper effect on sphere.

Not too shabby, I kept the outline as I liked the look even if it doesn't quite fit with the old timey feel.  The slightly different shading comes from a random offset for each region, otherwise the mapping will be very neat and regular which is a useful quality to be able to turn on and off if needed.

Two meshes, land and water.

Right now I really only have two terrains, land and water, so I added a second set of textures to differentiate them.  To be clear each type of terrain is it's own mesh and material in Unity.   Changing the colour was nice and easy (for once), blue for water with some little waves drawn on.  So this weeks task is mapping different terrains on and associated textures, like desert, ice, forests etc.  As a 'look' for the game though I think it's a coming together ok.  Tweaking colours is easy enough.  Sketching  little trees and hills, very simple shapes like in the maps at the top, shouldn't be too outside my artistic ability.  Once I get some more terrain types in I think it will be a pretty cool world to explore.

Wednesday, 26 March 2014

Software complexity

It's been a little while since I posted and an update seems in order.  I got a little stuck in the doldrums with the code, such is life. The best analogy I can think to make is imagine you're a writer and you have an idea for a scene and before you can even begin to write you have to go away and build a font from scratch.  I really envy the programmers that have that sixth sense when it comes to structure, for me it's a little more protracted.  There's a great quote from Steve Jobs (video embedded below),

"It's all about managing complexity. It's like scaffolding, and if you keep going up and up eventually the scaffolding collapses of it's own weight, right?  That's what building software is. "




I've mostly been rewriting some of the code to work a little neater, particularly with regards to grouping units and buildings together.  Just to prove the game does still exist check out the ui tabs.  And those tabs actually work y'all.

TABS!

Monday, 24 February 2014

Finite State Machine for handling input.

This is maybe obvious but for whatever reason I struggled to work out how to handle a simple left click of the mouse.  The problem being that a single left click could mean many different things depending what state your in.  Take selecting a unit as an example, it could be interpreted as, 1) select this unit 2) deselect current and now select new unit 3) move to 4) attack.  etc.  Keeping track of the state you're in then is vital, and I'm using an enum which is perfect for this.

enum pickingState { nothing, unitPicked, cityPicked, moveTo}
pickingState curPickingState = pickingState.nothing;

The next step was breaking down the methods for moving between states.  To go from (nothing --> unitPicked) we'll need a Select() method.  And likewise, to get back to nothing selected (unitPicked --> nothing)we need a DeSelect() method.  For the raycasting itself, Unity provides excellent collision checking for that, mine looks something like this.

//picking code looks something like this
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;

//left click
if (Input.GetMouseButtonDown(0) && Managers.OverGUI == false)
{
  //did we hit something
  bool hitResult = Physics.Raycast(ray, out hit, 100f);


  switch (curPickingState)
    {
      case(pickingState.nothing):
        Debug.Log("nothing selected state");
        handleSelection(hitResult, hit);
        break;
      case(pickingState.unitPicked):
      case(pickingState.cityPicked):
        handleDeselection(hitResult, hit);
        break;
      case(pickingState.moveTo):
        Debug.Log("in moveto state");
        handleMoveTo(hitResult, hit);
        break;

   }
}

private void handleSelection(bool hitResult, RaycastHit hit)
{
//bring up gui elements here
}

private void handleDeselection(bool hitResult, RaycastHit hit)
{
//fade out gui elements here & call the picking code again
}

private void handleMoveTo(bool hitResult, RaycastHit hit)
{
//set target
}


Using a switch() statement with enums is a perfect match. as you can see, and neater than a big ol' pile of if() else() statements.  An element that may be a little confusing is calling handleDeselection() if we have a unit picked already.  This was a minor eureka moment for me, and when I worked out I neeeded to seperate out selection and deselection correctly.  So if the player has decided they wanted to select a different unit when one is already selected, you first need to correctly change back to the nothing selected state, then we simple call the picking code again and it will correctly interpret us back into the correct state.  It simple be the player clicked off map to deselect entirely, which would be hitReseult = false.

The last little piece is the Managers.OverGUI bool.  Unity handles interface input in the OnGUI() method for things like buttons etc.  You don't want to have clicks going through the GUI into the world and so for that we need to check each loop if the cursor is over a GUI element, and if so we don't want to handle any 3d world picking and instead let our GUI code handle it instead.  

I'm sure much of the above is second nature to some programmers but I really struggled getting all the bits and pieces working together correctly.

Monday, 17 February 2014

Little by little, turn by turn.

I developed the 'battle' system a little more.  I was getting mired in indecision but I eventually got a version that I think will work.  Better to get something up and running to get a sense of how it all fits together, and there still more pieces to do until I can get a better overall picture.  Tortured metaphors done, here's a screenshot.

xna protoype with number revealed

prototype in unity with icons

The battlefield will consist of a front line and a rear line.  So I was having trouble working out how support units would fit into the mix, like archers or catapults, and using a second line that gives bonuses to the front line helps works them in. The art is just programmer placeholder stuff for now.  It ties into another requirement I gave myself, which is to have the same art/representation on the battlefield screen and on the main map.  If you have a battle screen that is wildly different you have double the art work to do...and I'm probably going to struggle with one lot as art is not my forte.  I'm using a similar size and shape to Total War as I really like their implementation.  In researching I found the artist who did the great iconography for Rome Total War II.  If I got anything close to that I'd be very happy.

ui thoughts
I also went round in a circle on the UI.  I tried some little pixel art decorations but ultimately I think I prefer the simple red and black motif.  Altering the sprite font in Unity is maybe possible but not worth the hassle as far as I'm concerned.  There's certainly been a trend towards simpler/minimalistic interfaces in games, and I'm certainly a fan of that style.  I mostly just want the information to be clear and easy to read.