With the upcoming patch dealing with terraforming and player built settlements we also need to upgrade some of our current tools to better suit the challenges these new systems pose. The most basic such system involving the terrain is the one visualizing where players can go - the slope display.

As part of the work on the PBS patch we have upgraded the slope display so you'll not only be able to see where your robot can go, but also where robots of other classes can venture. More importantly the new slope display will also show areas which need to be flattened before a building can be raised at a certain area.

As these new tools won't be needed all the time we're making them optional. You'll be able to cycle between the different display modes using the slope toggle button.

Also, most of the server side code work on the individual PBS nodes has now finished and we're in the process of building the terraform blueprint system while the artists work on the gfx for the nodes. And before you ask, the next part of the PBS series blog should be out next week ;)

Here's a bit of a pre-xmas sneak peek on the progress of the new terrain engine. We're still heavily working on it, but the difference is already very notable. What do you think? Let us know in the comments below!

Here's a sneak peek of some of the upcoming shader 3 changes. Keep in mind that this is still heavily work in progress, and the final version will include even more upgrades. Shadows are deliberately turned off at the moment, these images show the level of changes upcoming to the terrain engine and the water renderer.

Before:

Before

After:

After

Time to talk about the next update to Perpetuum, as per usual we have a few interesting changes and new features coming to the game.

First of all as I've written previously, we're updating the roaming NPC system. Roaming NPCs will travel in caravans around the islands, and we're adding new flocks of NPCs for more varied random encounters on the terrain. This is only a very first step in our plan to bring a whole bunch of new content to the game for more stuff to do "between PvP sessions". We'll be adding a whole lot of new features to this end in later updates, which will be revealed a bit later. Various areas of the terrain will go through some small rearranging in this patch. Changes include new decorations around teleport stations, terrain updates here and there, and even a teleport station moved a bit farther away from a terminal.

We're bringing in a feature that was originally suggested in a very early brainstorm by a player during the beta. We liked the idea very much and had everything ready for it for quite a while now, but other priorities meant that this had to wait. The paintjob on your robots will now get worn down gradually as you engage in combat. This change is only aesthetic and will be undone as soon as you pack your robot together, however it's a small thing you can brag about and show off.

So now for the more interesting updates :)

A new type of plant will make its debut with the coming update. The special thing about this plant is that on its own it won't be growing anywhere, it can only appear in the game world if players plant it. This plant will contain a new harvestable material for use in the manufacturing of high end items. Beware of people trying to harvest or even destroy your crops!

One of the most fixed things in Perpetuum up to now was the constant, fixed distance of 1000 meters players could see each other. The upcoming update changes this. First of all: how far you can see and how far you can be seen from will both vary based on the robot you use, and the two will not necessarily be the same anymore. This alone would be an interesting change, but we're also adding modules to help modify these values during gameplay: The detection type module will allow you to see farther away. The flare type module will make the target show up for people farther away. And of course, the stealth type module will allow you to be seen from a shorter distance. These changes will bring the PvP on the beta islands to a whole new level, and we're excited to see how players will be using the new features to give them a tactical edge over their enemy.

Let us know what you think about the upcoming update in the comments!

I took the liberty to hijack the blog from BoyC to start a little skunk-work series of tech-articles about the stuff that goes on behind the curtains in Perpetuum. There's some fairly unusual ideas and solutions we came up with over the years and I hope they're as interesting to you as they were for us to invent / implement. (Or well, potentially more interesting, and without the malnutrition / hangover / sleep deprivation.)

So, maps.

The main principle

What is the task at hand, what are the conditions we can work under?

  • We need to have a map in the game where players can see the main navigation points. The goal is the map to look as good as possible within the given circumstances, since players will be staring at it for prolonged periods, and we don't want them to stuff their own eyes into the recycling facility 5 minutes into the first transport mission.
  • We do not have expendable artists who can spend time on painting maps manually, but more importantly, unlike other games, the map here needs to be as accurate as possible, for strategic reasons.
  • The terrain is a height-map - we can safely assume the client has access to this data, but this data has the possibility to change fairly often. (Think terraforming, either by players or by level design.)
  • Not really a mission-statement as such, but resolution-independence is a plus.

Summed up, we need a fairly non-linear data flow coming from a 2D dataset, and ending up in a good looking texture. In other words, procedural textures. Luckily, we're fairly comfortable with that. (*wink* *wink* 64k *cough*)

The steps

Let's look at our starting dataset first:

This is the actual terrain height-map, a 2048x2048 2D dataset of 16-bit height values. The reason it looks so dark is because this is a linear mapping of the 0..65535 range to the 32 bit colors available on your screen. Given that we don't really have to care about the peaks so much, since robots can rarely pass those, we can re-map the range of interest between two completely arbitrary values following "This Looks Good Enough"-principle, ideally somewhere around the water level for the low value, and the highest walkable point on the map for the high value.

This already looks a lot more usable. Sure, the mountain peaks become a big white spot, but we don't have to concern ourselves with those because they're rare, usually uninteresting for the player, not to mention the strange yodeling sound they emit.

It's time to add color. Cartographers generally follow a principle where they assign certain colors to certain heights, which works perfect for us, because we can use a look-up table internally to do so. This look-up table, in our case (and ideally), is a simple 256 pixel wide bitmap, painted by a graphics artist:

So if we use this to color up our altitude levels, we get this:

This almost looks good enough and no-one would blame us if we'd stop here (no, you wouldn't, shut up), but we knew we could do something more interesting given the data at hand a little maths. The image already has a nice faux-natural quality to it, but it needs contrast, the same way maps often have a little lighting / shading on them.

Adding contrast

At this point, the idea was to take the altitudes, more specifically the altitude-differences (or slopes), and turn them into shading. For this, what we've done is an implementation of what generally bitmap-manipulation software call as "Emboss", and basically means taking surrounding pixels, and calculating a normal vector out of them. Many of you might wonder if it means we're calculating a normal map, and in one sense yes, but the trick here is that the direction of the light can be fixed, because why not, it's Good Enough, and that allows us to speed up the calculations simply by assuming that the light always comes straight from the left.

For less technical minded: This practically could mean that we start walking (figuratively speaking) from left to right on every row of pixels, and if the next pixel is a point higher, we get a bright point, if it's lower, we get a dark point. (If you're indeed a code-savvy person, please refrain from gnawing out your own cerebrum at this stage because of this rather sloppy explanation, I was trying to make a point here.)

If we take this normal value and map it (with a bit of magic number wizardry) to the grayscale color range of 0..255 (0 meaning the next pixel was lower, 255 meaning higher, 128 meaning it was the same level), we get this:

Not the prettiest of pictures, but it's a vital component towards what we want: contrast.

So we have a colorful picture with no contrast, and we have essentially a bump map with no colors - how do we blend the two without calculating lighting on every pixel?

Simple: Prepared lookup-tables. We know we have 256 levels of color, and we know we have 256 levels of contrast, so we can pre-calculate a 256x256 pixel lookup table with all the possible combinations and utilize that to render the final image:

This lookup-table is ostensibly the above gradient, with the top half fading to black and the bottom half fading to white. Between that, in the very center, is our original gradient.

All it remains now is to run the following little lookup, matching our color and contrast:

for every pixel {
  tx = get_remapped_altitude() // 0..255
  ty = get_contrast() // also 0..255
  final_color = shaded_gradient_lut(tx,ty)
}

And here's our final image:

The difference is subtle, but definitely visible when the maps are zoomed up close - which is what will happen in most cases.

The advantages of this method are manifold: it's fairly fast (it's entirely fixed point arithmetics), it's resolution-independent, it looks Good Enough, and most importantly, it's responsive to the level of immediacy, i.e. every change done on the map can be rapidly re-rendered on the map as well. (This also goes for the passable terrain calculations, but that's a whole new story.)

That concludes our first visit to the forsaken wretched nadirs of the Perpetuum codebase. I'm not sure what to write about next time, but I suppose a quick look at the "number of changes per line of code" graph will quickly indicate where the "interesting" bits in our code are.