Wednesday, 3 February 2010

Azure / Silverlight hosting

Rather stupidly, I didn't make the connection between the Microsoft Azure emails saying "Your account is about to close" and the Silverlight streaming hosting I was using for the various Silverlight-based tech demos I had done for the game. The net result is that all the Silverlight apps I had on the site are now showing 404 errors, and I have no idea if I can recover the apps!

I can of course recover the latest versions of each one, but going back through source control and rebuilding them all is a bit tedious, so I might just make do with the most recent version of each app, which I'll rebuild over the weekend and redeploy to Azure.

Monday, 25 January 2010

BizSpark?

I recently applied for BizSpark membership, as I thought it sounded ideal for what I'd eventually like to achieve through everland and this blog (in essence, a completely free game / game engine) with tiny in-game adverts.

However, my initial application has been rejected; there was some semi-cryptic mention of email address (jamie@thecodespring.com) not matching the domain name (www.thecodespring.com) which I found rather odd, but maybe the answer is less obvious.. Do I need to register as a company, or will a sole-trader be enough? As a sole trader, I essentially have £0 start up costs, am able to pick a business name of my choosing, and have to complete income tax returns each year (which, for now, is irrelevant as revenue is £0!). Setting up an actually incorporated company is a different proposition altogether, and at this stage makes no sense.

Friday, 22 January 2010

Twitter

Just a short update - you can now follow us on twitter using @thecodespring.com. I'll use the account to post shorter updates that possibly don't merit a whole blog post.

The game had stalled partially over the holiday season, but development has restarted with a switch in focus from "getting the architecture right" to "getting it working and then getting the architecture right" - a kind of Rapid UI Development paradigm.

Monday, 7 September 2009

Silverlight limitations...

One thing I've noted when doing some further prototyping with Silverlight is that, for a true Hex based game, drawing individual Hexes using the inbuilt Polygon class isn't quite as fast as I'd like. I've expanded upon the last demo to allow zooming and panning of the map, and this is a little....clunky (which is entirely down to the sheer number of Hexes in the map). I think I need to work further on a level of detail viewer.

What I'd like is something like

  • Display the overall world map as an Image
  • When the User zooms in, display varying pre-rendered images depending on Zoom level
  • When the User zooms right in, display individually drawn Hexes

This should prevent the performance problems I've been experiencing (which aren't so much to do with Silverlight, rather the architecture). Something I am considering is using DeepZoom for this, but I'm not sure if that is really suitable. What I can imagine is, when generating the world, we would create several images, one for each zoom level, and integrate these with deep zoom. Of course we still need to draw polygonal (or individual images) for the highest zoom levels, so we can do things like positioning Units and detecting where the user is clicking.


Thursday, 3 September 2009

Archipelago

Finally getting somewhere with noise + terrain generation; what happens now is

  1. A noise map (think of it as a heightmap) is generated using the Improved Perlin Noise algorithm.
  2. This noise map is then parsed into Hexes.
  3. Each Hex is given a type based on its height - i.e. if it is height 0 to 20, it is an ocean tile. This is a bit trivial and will be expanded upon, but it works for now.
Give the Silverlight app below a go - keep hitting Generate Terrain until you're happy with the results, then Generate Hexes. It's a little hard to see, but the resulting grid is made up of thousands of Hexes.

This leads me to my next bit of work - writing a Level of Detail based viewer. If you're zoomed right out, you maybe don't want to see the Hexes, but when you zoom in you want to see them. Something totally new for me (surprise surprise!).

In case you were wondering, I will be updating the app below to generate different types of maps, but for now we're restricted to the Archipelago :)

Tuesday, 1 September 2009

Hex based pathfinding

Well, implementing Hex based pathfinding wasn't too difficult at all, and only required 2 fairly minor changes to the A* Pathfinding code I wrote.

In Summary, the changes between square based and hex based pathfinding are

  • Neighbours - each Hex has 6 rather than 8. You also need to figure out how you are going to number your Hexes into rows and columns - I went with the following scheme (row, column)I think this works pretty well, although it does mean that when you are working out Neighbouring Hexes, it depends if you are on an odd or even row. This tricked me for a bit, and resulting in some occasional odd paths which jumped over blocked areas, but once I figured this out it was quite straightforward.

  • Movement cost (ignoring Terrain for now), this is the same for all 6 neighbours. When using square based pathfinding, you would generally weight a diagonal move so that your pathfinder preferred straight paths. However for Hex based, we treat each direction as the same cost.
The end result is a fairly quick pathfinder - this is really just a UI spike, but I'm happy so far with it. There are a few things still to implement - most notably making it a bit more generic, refactoring the actual algorithm and taking into account terrain cost, but this is a big step in the right direction.

Thursday, 27 August 2009

Pathfinding revisited

I have previously written about pathfinding a couple of times - the last iteration was a small Silverlight app which allowed you to place obstacles and would navigate (hopefully) a path through them.

The version below should be a bit more robust - it auto generates some obstacles (the dark blue squares), and you simply click to place a start and end point, and the path will then be generated. The red squares indicate the path, while the orange shows the search area (something that was missing from the previous app.

The next stage in this is to replace the squares with Hexes (and to allow / prevent diagonal movement) - I'm hoping this won't be too difficult, but I do expect a fair number of changes. Feedback on the app below appreciated - if the app can't find a path (when it looks like it should), I'd appreciate a screenshot!

Wednesday, 26 August 2009

Perlin Noise

In a previous post I mentioned terrain generation briefly, and how I had explored a few separate techniques for generating the initial game world.

To that end, I have implemented a simple Perlin noise generator (in fact, I've implemented 2 of them, one using the original algorithm and another using the "updated" version .

I won't go into the algorithms themselves (that is probably outwith the scope of this post), but I'm fairly pleased with the results of the improved Perlin algorithm. The following 2 images were both rendered using it (obviously they are too small for use as a map, but you get the idea;

Both are generated using the same algorithm with slightly different parameters (Frequency in this case).

I need to do some work on producing Hexes from the above maps, but I think the Map Parser I already wrote should suffice - it will create Hexes from each point on the above images based on their Alpha value (for example black would be sea/ocean, while the brightest colours would be mountain). This is obviously quite trivial, but it should do for now.

The algorithms can be found within the eland.utilities namespace at the usual place. I'll delve further into this topic later in the week.

Thursday, 20 August 2009

Units, Game Turns and Remembering what I was doing...

Troy put up an interesting post, taking the State Pattern idea further and providing a great code sample on how he did this (thanks Troy). I've taken this, and in the few spare moments I've had this week, have been working on integrating it with the game.

I have, however, hit a small stumbling block. With Troy's solution, the game engine, each turn, passes a TurnContext into each Unit, telling it what to do essentially.

However, from the Users point of view, imagine you are playing Civilization, you don't want to have to re-tell each unit what to do every turn. You expect that you can give your Soldier a move command, and each turn he will advance until he gets there, at which point he will become Idle and need a new command. We also don't want the Game Engine to have to remember each Units previous command - the Unit itself should do this.

Therefore, each Unit needs to remember what it was doing the last turn - what we essentially have to do is this

  1. When a Unit is given a TurnContext, we store this until we get a new TurnContext
  2. When the game "ticks" (moves to the next turn) we handle our stored TurnContext (unless a new TurnContext is passed in)
  3. If we have finished, we probably switch to an IdleContext or similar.
The solution is really quite simple - a small modification to Troy's code, but I am also trying to integrate pathfinding at this stage which is taking a little longer than I had hoped. My previous pathfinding examples were written using Squares rather than Hexes, which means it needs quite a few tweaks before I commit anything.

Friday, 14 August 2009

State Pattern : Transitions

Troy made some interesting comments on the last post, which got me thinking on a slightly higher level about how Units, States, Transitions and the like will work.

Something which isn't totally clear from my previous posts is how States change. In simple terms, each State handles the transition to the other states (when it needs to). The Units themselves don't handle State transitions.

There is a base State (in this case, Idle) which has default transitions to every other State. Simply put, the Idle State is this:


So, when a Unit is Idle, it can move straight to any other State.

Some specific examples

  • The Move state doesn't need to explicitly handle a transition to Attack, because the behaviour is default (i.e. no extra handling required) so it doesn't handle it. The framework then falls back to the Idle state when it can't find an AttackState handler on Move, and this moves directly to Attack. So we go Move -> Idle -> Attack.
  • The Fortified state does need to handle a transition to Attack - in that it can't be done. So if we are in the Fortified state, and the Attack command is issued, we handle this by

    Which means that Fortified -> Attack transition is prohibited. If we didn't specify the Handle(AttackStateContext.... method above, the framework would use the fallback transition on Idle which would permit the transition.
Troy also asks "Are Attack and Movement really different states of the Unit?"

Good question! What I eventually envision is something like

  1. Unit in idle state is issued an Attack command to a Unit 10 Hexes away
  2. The AttackStateContext is passed in to the Unit
  3. The Unit has a Range of 1 (hand to hand) so the Attack state moves to the Movement state
  4. The Movement state moves each turn (I need to implement ticks still)
  5. The Movement state eventually gets to the target Hex after X turns
  6. (assuming the enemy is still there) the Movement state transitions back to the Attack State.
  7. Attack State does the attacking!
That is a highly simplified version of what I'd like to eventually do, and there is a lot of work to be done, but I think it's possible. I'd love to hear opinions on this though, maybe you've done something similar, or have an alternative idea? All welcome! :)