Jul 5, 2015

Progress Update July 2015

In the last couple of months I've continued integrating the fruits of my new terrain generator side-project into the main project. Progress has been good, and I should be up and running with the new terrain any day now.

I took a brief detour to explore network connectivity as I've always imagined that Bulldog would eventually support multiplayer functionality. Since I started the project with singleplayer in mind, there's a great deal of work to do to make the game client/server capable. I decided to kick things off by getting the new terrain generator to run on the server thread, and have the client request it via a network call, as it will eventually function that way for multiplayer.

Before I could get going on that I needed to decide on a network stack. I started rolling my own and got a little ways into it with a brief proof of concept that achieved listening and connecting before I decided to look around for pre-built network solutions for .net.  The first one I came across was RakNet, it's been around for quite some time, is used by a lot of people and supports C#.

I grabbed the source and I've spent 4 hours trying to get the examples compiling. I followed the c# tutorial and ran into issues, such as the build failing due to missing folders. So I fixed that by creating the folders. Then there were files missing from the project. I found them and added them to the project. None of the generated files have any standard "using" clauses, so I add the required "using" clauses to the generated code. Now I'm stuck with build errors such as "Cannot implicitly convert type 'RakNet.Row' to 'RakNet.TableRow'" or "Cannot apply indexing with [] to an expression of type 'RakNet.SWIGTYPE_p_DataStructures__ListT_DataStructures__Table__Cell_p_t'"... the list goes on...

The above paragraph is actually from a gamedev.net post I wrote in desperation after having no success with RakNet. Luckily, my friend, axefrog, saw my post and put me onto lidgren, which I'd also seen during my searches before I settled on RakNet.

I took his advice and checked it out and the difference was like night and day. It required one tiny tweak to get it working (Bulldog is built on .net 4 and the latest lidgren assumes .net 4.5 or higher). I hit the internet for tutorials to write some test code. Unfortunately most lidgren tutorials are slightly out of date, leading to a weird corruption issue with status messages, but I sorted that out quickly. In an hour or so I was up and running with a decent message-based network system.

This represents a big change. It's very unlike me to rely on 3rd party components. I much prefer to write everything myself as I can fix bugs in my own code or add functionality I need. I felt vindicated by the difficulties I experienced with RakNet and was itching to go back to the roll your own method. The subtext of my gamedev.net post was that if I didn't get some decent suggestions I was going back to my own implementation.

In the end I'm glad I didn't, and I'm indebted to axefrog for putting me on the right path.  Cheers, mate!

Apr 14, 2015

Progress Update April 2015

This morning I fired up Mercurial and noted that my last check-in was 6 weeks ago. I'm kind of surprised, I expected it to be much longer. The last couple of months has seen my day job almost completely take over my life. Working on the weekends and out of hours meant there's been little time to even say "hi" to my family, let alone work on this side project. Fortunately, the crunch is now over, and I can go back to a more manageable schedule.

What has happened in the last 5 months? Early on I decided to completely rewrite my terrain generator to incorporate a long list of improvements, as well as finally get around to producing correct biomes.  The main project is currently using my 2nd generation Terrain generator from a few years ago, and this new one will be version 5. What happened to version 3 & 4? They were experiments that failed but ended up teaching me the techniques I've now honed in version 5. The new terrain generator is faster and produces much more interesting terrain than before, but so far I've failed to achieve the full objective of producing biomes.

An example of the terrain I'm currently creating. 

The rainfall map generated for the same terrain.

Part of the reason is due to the intrusion of my day job into my spare time as outlined at the beginning of the post. The second is that I'm in uncharted territory and there has been a great deal of trial and error. One of the key factors involved in biome assignment is rainfall, which is a fairly complex phenomenon. In the real world, it involves temperature, pressure, moisture, wind and is affected by the topography of the land itself.

However, I'm not trying to simulate a full on climate system, so I've taken a bunch of shortcuts. Like others, I've tried to seed the world with moisture, then introduce winds, and let them move the mositure around generating rainfall. Since this is a gross abstraction of what is really happening, the results are quite unpredictable, and its taken alot of tweaking and fine-tuning of the overall algorithm to achieve useful results. That said, its still not right. Some areas are completely bone dry, and others receive the equivalent of an olympic swimming pool of water every hour.

To add to the complexity, I decided to take into account seasons. In the real world, average wind patterns change with the seasons, leading to vastly varying rainfall. I wanted to achieve something akin to realistic conditions on earth. Eg, some places have about the same rainfall all year, others have a distinct wet season where the rains are torrential, whilst others receive very little rainfall all year round.

I said earlier that I failed at my objective to produce biomes. I decided to have a go at the terrain generation rewrite because I'd made good progress in the previous months re: updates and thought I needed to work on something a bit more experimental for a few weeks. That ballooned into several months, and its not even finished yet, so tangible progress on the main project is non-existent, because the new terrain generator isn't finished enough to make use of.

Time to knuckle down and finish.

Nov 23, 2014

Progress Update November 2014

Earlier this month I finally released my first development snapshot in over 14 months. It's kind of depressing that it took so long, and when objectively comparing the difference between the old snapshot and the new one, it almost seems like a step backwards, not forwards. The last 14 months has seen some extensive refatoring going on behind the scenes. I completely ripped out my old inheritance-based creature/item/etc classes and replaced it with an Entity Component System, which has taken a little bit to get used to it, but now it seems like its always been there!

In addition to that, I started switching the entire game project to Unity for a few months before deciding it was not for me. I also found it hard to dedicate any time to the project for many months, and time just slipped away so fast. I've remedied this in recent months and finally decided to polish what I had and show it off to my friends and work colleagues to get some feedback. I managed to get quite a few people involved who'd never seen it before, so the pressure to have progressed from the last snapshot wasn't really there. I got some great feedback that re-energised me and I've made great progress on the new snapshot, which has seen some exciting new features implemented, and some UX/UI improvements.

All in all, the experience was positive, and I'm keen to produce snapshots more often. By next post I hope to have some exciting news to share about the project as a whole. We'll see how that pans out.

Oct 2, 2014

Progress Update October 2014

The last couple of months haven't been the best for the project, but I'm still moving forward, albeit at a slow pace.

I won't go into excessive detail, but I'll just mention that I was sick for about 4 weeks with the flu, which meant I was barely keeping it together enough to head into work on the good days before coming home exhausted and collapsing into bed. The bad days were... unpleasant. This means I didn't have many contact hours with the project in the past few months.

That said, what have I been working on recently? I decided to finally implement the virtual file system I've had as a TODO item for months.

Virtual File System

The virtual file system is there to allow you to reference files or resources using a virtual path, eg: "/textures/UI/border.png", and then resolve that to a concrete asset when needed. That file could be part of the standard path of the game's data folder, or it could be part of a packed resource file that contains many different files. By removing the reliance on hardcoded paths, patching (and maintaining the patches) for the game will be considerably easier.

To issue a patch, I'll provide a packed resource file that contains a file manifest, and that will automatically be included (and supersede) the already installed files. So the request to "/textures/UI/border.png" will be re-routed to the patch file instead of the original files.

This should also make developing and maintaining mods for the game relatively easy. I've converted approximately 50% of the file-loading code in the project to use the new virtual file system, and it appears to work quite well.


Another thing I looked into was incorporating a scripting language into the project. I'd previously investigated this about 2 years ago, when I had a crack at introducing IronPython support. It took a while to get working and I converted some of my GUI creation code into python. But it seemed like I was struggling to find code that would make sense to convert, and it seemed easier for the interactions with the rest of the code if it was all in C#. So I eventually backed out the changes and went back to pure C#.

Jump forward a few years, and I now have an Entity Component System that runs the whole show, and adding a new "EntityScriptComponent" was pretty much trivial, and would allow entities to run custom code where needed. I decided to revisit my original thought on using Python, and looked around for some good .net compatible Lua implementations. NLua pretty much fit the bill and I had it up and running it 10 minutes or so.

So Bulldog now support scripting to a limited extent. For now, I've created hooks for OnSpawn(), OnDespawn() and OnGameTick() for entities themselves, but as I develop the game content further I'll expand on those as appropriate.

Parting Thoughts

I'd really like to get this Snapshot 10 finished, as I've been promising it for months now. I'm slowing reducing the list of bugs introduced by the refactoring brought about by the push for crafting, and am slowly bringing the project back to a more stable state. Soon.