Tuesday, June 25, 2019

RTS_21 "Smoothing Unit Movement"

As part of my own personal engine extension, I had recently developed a system I called LerpQueue that let you queue up different positions inside Unity and then smoothly move objects between them. I had been meaning to do this for a while because it's a useful feature to have premade, but the reason I finally got around to making it was for this update:



Of course, there are no animations yet, but I'm a lot happier with it now. Feels good to have the unit at the very least slide instead of teleporting like they were before.

That's it for this one, I know it was pretty short and that updates are taking a bit longer but I've really been focusing on work and working on my voxel engine.

Sincerely,
Blake Gillman

Tuesday, June 18, 2019

RTS_20 "Exploration & Damage Text"

The workload on this update was a bit greater than usual. You'd think that something as simple as just displaying text on each tile where damage was dealt would be a lot easier!



That on its own took awhile to do, but just because it took awhile doesn't mean that there's a lot to write about! So I pulled extra hard and wanted to make sure to get a major feature in with this one.

Exploration in these sorts of games is extremely important. Not knowing the map in-advance creates new gameplay aspects and makes settling the world a lot more challenging. My main question, was how was I going to represent unexplored territory?

My first thought was clouds but that's just because Sid Meier's Civilization V did it, so I decided against it. My second thought was to render all unexplored territory as just being black but I felt that a dark color like that covering the screen took away from the bright cheery look that I wanted the game to have. That immediately made me think of using the opposite extreme, white, but that was going too far.

I ended up settling on a nice tan color to represent it as an uncharted map similar to Europa Universalis IV:




I keep saying this, but this really is another feature that makes the game feel so much more final. I can't wait until I say that enough times to where the game is in a state where I can start playing it with my friends!

Although this update is pretty important, it's not without its flaws. City & Unit bubbles still render over the unexplored tiles which means you can still see where units/cities are that are out of your sight:



I'm absolutely thrilled with this update, the game really is getting close to the point where I can start implementing multiplayer. Those will likely be the most boring update notes, because days of work would boil down to "This feature now works in multiplayer", which it's hard to write an entire blog post about that, so we'll see how that goes when we get there.

Sincerely,
Blake Gillman

Thursday, June 13, 2019

Blake's Vacation Adventure (2 / 2)

Generating over a million tiles in only 20 seconds on a 2D map was pretty exciting and all, but I wanted to take it up a notch. I wanted to create a lively island with cities and roads, so I started on that.

I spent around 4 hours writing a set of algorithms that I thought would be best for calculating a road between two towns, and after I was finally done I let the game run. After about a minute I knew the algorithm was too slow to be of practical use, but I was curious to see what it'd create. After an hour I thought, well I've waited too long to stop now, so I went to bed to see in the morning what an epic road it must have generated. When I woke up I saw that it had taken 7 hours to generate this red road:



Words could not express my immense disappointment. I was about to continue, but then I realized that the loading system I was using for chunks was something I had never done before and was likely the reason my system was as fast as it was. So I decided to turn back toward 3D and see if I could apply the same sort of system to a 3D engine. And that's when I made my breakthrough.

Mixed with what I've learned since Perlinia, and the load system I had created for the 2D project, I now have a 3D Voxel engine faster than my Perlinia one. That's fast enough to let the player place/destroy blocks:



I don't think I was capable of being any more excited. I had finally made a breakthrough, a 3D voxel engine worth using! And this breakthrough came on my birthday no less... (June 10th). I then spent the next couple of days playing around with it.

First I wanted to see if I could make the transition between biomes be smooth, something I had failed on all my previous engines. And to my astonishment, I had done it!



Next, I wanted to see if I could make the biomes generate differently, even inside of the same chunk, which I also managed to do!






This was all very exciting and gives me great hope for any future 3D voxel projects I take on. I'm so happy that I spent this vacation studying, I'm home now and work resumes but you can bet you'll be hearing about this engine again in the future.

Sincerely,
Blake Gillman

Saturday, June 8, 2019

Blake's Vacation Adventure (1 / 2)

I've said this in a few places, but just in case you were unaware, I'm currently on vacation! I started vacation on the 5th of this month and I'm currently in the upper peninsula of Michigan visiting my dad & sister.

It's been insanely relaxing to finally take some time away from everything. To not have to worry about the RTS, YouTube, contract work, web development, anything!

So I've taken this opportunity to practice some of my more favorite parts of game development. Now, sitting down and studying programming as part of vacation might sound like hell for some people, but it's actually quite relaxing. Procedural generating and code-heavy game development are some of my favorite things to do.

First I started on a 3D voxel engine. I hadn't done it in a while and I wanted to see if I could make it equal to if not more optimized than my perlinia one (https://perliniagame.blogspot.com/).

The answer was absolutely no, this engine froze and took awhile to generate anything, but it was still fun:


I was actually trying to generate caves in this, but they ended up just being long cliffs so I decided to make the bottoms blue and call them rivers lol.

For my next coding adventure, I wanted to work on something 2D. I took more screenshots this time so I can explain my progress.

First, I created an engine that was able to render chunks. For testing this I set every tile to be one of 5 random colors (black, white, red, green, blue):


This was able to be rendered in 14 seconds (16x16 tiles per chunk, 16x16 chunks in the world, for a total of 65,536 tiles).

Now that I had rendering working it was time to do some generating. First I generated some noise and made the dark half blue and the white half green:


I didn't log how long this took, but I'll estimate around 15 seconds. Now that I had noise working properly, I needed a reason the player couldn't leave the borders of the map so I added a gradual falloff map which resulted in an island:


At this point I had also added seed support, so entering new seeds would result in different maps. This map in particular is the seed "Hello World!".

With that update also came being able to define what noise values rendered which color. So I added a couple more to polish up the map:


And finally, I'm going to want to know where key locations such as cities will generate, so using the same technique I used to find spawn locations in the RTS (Poisson Disc Sampling) I created a series of random potential points:


With that update also came increased density. Chunks are now 64x64, still 16x16 chunks total. Which makes this map size 1,024x1,024 or 1,048,576 tiles.

This is the most optimized 2D procedural engine I've ever written, so you can imagine just how happy I was when the times reflected that:

Generated & Rendered In-Editor: 40s
Generated & Rendered In-Standalone: 20s

And I'm working from a slow Windows 8 laptop (Bc on vacation). So as you can imagine I'm very very happy with how this has all turned out.

I was laying down on my bed with my laptop eating some cheez-it's, and suddenly I became very nostalgic. This is the first summer since I graduated High School, but yet here I am at my dad's practicing programming just like I did the last 4 years.

I'm calling this part one because I'll still be on vacation for 1~4 days (Depends on some currently unpredictable factors), so I'm sure I'll have more done by then to warrant a second post.

I just thought I'd make this to keep you guys up to date! I'm not really sure what game I'm making with this 2D engine but I'll figure it out!

Sincerely,
Blake Gillman

Saturday, June 1, 2019

RTS_19 "Capitals & Random Name Generating"

I was actually pretty excited about this update. It involved a lot of math & pure-programming which is some of my favorite kind of programming so it was quite fun to work on.

In order to make it feel more final and part of the game I added 2 more test players to the game (Totalling 4), which I think is the perfect amount for this test map size (64x64):





Each player has a distinct color so that they're easy to tell apart. I've also introduced random name generating for creating new cities. Eventually, you'll be able to name cities yourself, but they'll always start off with a pre-determined name.

These sorts of updates (Ones that involve a lot of math & a challenge) are my favorite kind. Now, let me break down how spawns are determined:

First, a set of points are generated across the map using Poisson Disc Sampling. This means that not every hex on the map will be checked.

On a 64x64 map, there are 4,096 hexes. Having to then go through and check all 4,096 of them to see if they're a valid spawn point or not would take an insane amount of time. So using my method of Poisson Disc Sampling only 652 hexes are checked.

So here is the original map:



And here are all the points that are generated:


As you can see, it's a lot fewer than having to check every single tile! The pattern it creates is also intentional, I didn't want it to be a straight grid since I wanted every tile to have a chance of getting added to the list instead of just every other which would then guarantee that certain tiles had a 100% chance of never getting checked, which I didn't want.

After that each point goes down a checklist, each time getting more and more specific. This was done so that the harder calculations were done last, that way if it checked off an easy one it would never have to check the hard ones. This also helped reduce calculation time significantly.

So now, what makes a valid spawn point?

A) If the spot is in shallow or deep water, it is removed from the list.
B) If the spot is on a river, then it is removed from the list.
C) If there is a mountain with 2 tiles, then it is removed from the list.
D) If the tile has no shallow water tiles near it within 1 tile, it's removed from the list.
E) If all the shallow water tiles near it have ridges, it's removed from the list.

After having met all of those criteria, we finally have our list of valid spawn locations:
(Note that all of the points on these maps were colored manually so I may have missed some)

Here's that same map but with arrows so that the valid spawn points are easier to identify:


With this map, there are now 33 valid spawn locations.

Now that we've determined which spawn locations are valid, each player is assigned a spot from the list randomly. If the spot they've been assigned is within 16 tiles of another player's spot then they do it again until they find one that's far enough away.

With all of that out of the way, what have we accomplished? Well, the player will:
  1. Never spawn in the water lol
  2. Always spawn a distance away from mountains as to avoid getting trapped.
  3. Always spawn on the coast so that they have a good spot for a harbor.
  4. Always have at least one shore tile clear of ridges so that they have a spot to build.
  5. Always spawn a good distance away from other players so that they have to chance to expand before running into anyone else.
On this particular map, all 4 players had a valid spawn location within half a second, so I'm very happy with how it turned out. Another reason it turned out so well is I have it all running on a separate thread which will ensure that your game doesn't freeze during this calculation & that it'll take less time to do overall.

You may be wondering why I spawn a capital city instead of a settler, and that's because I think that starting off with a settler takes away from the game, I'd rather that players be able to get into gameplay right away by already having a city.

That's all for this update, I'm really happy with how it turned out and it was pretty important to do sooner or later so I'm glad it's all taken care of.

Sincerely,
Blake Gillman

P.S
As part of my push to move things out of the editor, I moved the button to generate the map onto the player's UI. This button is completely temporary, but it'll let me generate the map while playing the game which is more convenient.