Development Update – Edge Detection

One of the things I’ve decided to focus on these past few days is to refine the look of the game, and try to develop a unique visual identity. Up until now, pretty much every visual decision has been made based on functional reasons.

Since architecture has been, and still is, a key theme of the game, I thought that would be a good place to start looking for inspiration. Eventually, I came across this post by Thomas Eichhorn about a shader inspired by old architectural drawings. Eichhorn originally wrote it for vvvv, but looking at the image of the final result, I thought this would be a good place for me to start.

I took his image of the final result of the shader, and added a layer of blue highlights to the upward facing surfaces:


I actually quite like the look. Immediately, it provides a sense of atmosphere, a warm, nostalgic feeling that takes me back to reading illustrated adventure books as a kid. I thought it would be a great style to offset to clinical/sterile nature of the game at the moment. Also, it didn’t look like any other 3D game out there, so this would help in establishing a visual identity.

But first, I had to roll up my sleeves and dive into shader programming.


I started off by looking at the edge-detection image effect script that comes packaged with Unity Pro. After a day of being totally confused, with a failed attempt at learning node-based shader programming with Shader Forge, I was eventually able to understand what the script was doing.

There are 5 different modes with Unity’s edge-detection script. For my purposes, the closet one to what I was looking for was “RobertsCrossDepthNormals”, which basically selects one pixel, and then checks to see if the surrounding pixels have similar normals or depth values. If not, then a edge is drawn. However, there were a few problems, namely, it wasn’t able to pick up several important edges.

Here’s a shot of a set of stairs, which is pretty common throughout Relativity:


With Unity’s edge detection applied, this is what it looks like: Edge_Detection-2014-03-31_18-35-50

So you can see the problem here is that the edges of the steps on higher section of the staircase are getting lost. This is because the algorithm is using both the normals and the scene depth to figure out the line, and in the higher sections, because you’re just seeing the front face of the steps, and not the top face, the normals are all the same.

You can increase the depth sensitivity, which does pick up the edges of the steps higher up, but also ends up with these black artifacts for areas in the distance, where there’s a large change in depth value. You can see the same issue happening on the side of the cube in the middle of the frame:


Another problematic area was when I had staircases on the side:


From this angle, Unity’s edge-detection works really well, since you can see very clearly both the front face as well as the top face of the steps:


However, from another angle, the edges disappear completely: Edge_Detection-2014-03-31_18-37-40

I decided therefore to create my own edge-detection algorithm, using what Unity has done as a starting ground. The main difference is that instead of checking to comparing to see whether both the normals and depth values are similar, I break it into two steps.

First, I do a check comparing only the normal values of surrounding pixesl. The selection of pixels is actually from the original Unity script. Basically, if the pixel we are examining at the moment is “A”, then compare the normal value of the pixel “B” vs “E” and then “C” vs “D”.


The reason why I start with normals first is that, in my case, there are no false positives. In other words, when you’re only using normals to do edge-detection, you will only miss edges, you won’t pick up wrong edges. Of course, this wouldn’t work if you had curved surfaces, but for me, since all the angles in Relativity are 90 degree angles, and everything is made up of boxes, this was no problem.

So I draw a first set of edges that pass the normal test.

For the second step, I then take everything else, and run it through a depth test. This time, I add up the depth values of pixels “B”, “C”, “D”, and “E”, then divide by 4, getting a value for the average depth value for the surrounding pixels. I then subtract this value from the depth value of pixel “A”, and if the difference is greater than 0.001, then it’s determined to be an edge.

In the following images, the blue lines are edges drawn in the first round by comparing normals, and the red lines are edges drawn in the second round by comparing depth values.  Edge_Detection-2014-03-31_18-59-35




You can see that where the normal test misses the edges, the depth test is able to catch them. And the sensitivity at which the depth test is set allows me to pick up the edges, while not getting any of the weird artifacts from the default Unity shader.

Here’s what it looks like with all black lines: Edge_Detection-2014-03-31_18-39-11

Of course, there’s still some issues, such as the normal lines being thicker than the depth lines, and I still need to fade out the lines in the distance to help with player depth perception. But overall, I think it’s a pretty good start, especially since considering yesterday morning, I had no idea even how to approach this.

Development Update – GDC Feedback

Hey all! It’s been a while since the last update. March has been a pretty busy month. Between trying to implement all the feedback from IndieCade East in February, attending GDC, and starting playtesting again, I haven’t found the time to post here as regularly.

Anyway, finally made enough progress on the different fronts to take a small break and write up an update.


So, this was my first time attending GDC, and just as everyone had told me, it turned out to be awesome. I only had an expo pass, so didn’t get to go to any of the talks or workshops. But even then, for me, it was amazing just meeting other developers and getting feedback on my work.

There were so many indie developers whose work I respect that were there, and all of them were super approachable and generous with their feedback. Some of the people who I had playtest the game and get feedback from were Justin Ma (FTL), Marc ten Bosch (Miegakure), Brendon Chung (Quadrilateral Cowboy), and Pohung Chen (Perspective). They all had very different and interesting insight and feedback on the game.

Relativity_2014-03-30_v8 2014-03-31 16-36-58-14

Justin talked about having a clear distinction between areas where the player is solving a puzzle, vs areas where the player is supposed to be exploring. If there’s confusion between what the player is supposed to do, the player can’t quite approach the problem with the right mindset. For me, this was a really good insight, because I had noticed that sometimes players would walk into a puzzle room, and when they don’t get the puzzle right away, they would turn around and walk out, thinking they had missed something they need earlier.

For me, when playing other puzzle games, this is a really frustrating feeling to have. Is the reason why I’m not able to solve this puzzle because I’m not getting it? Or is it because I just don’t have the right tool? This is why I really enjoyed Portal’s puzzles, because you knew in each test chamber, that all the elements you need were right there, you just needed to piece them together correctly.

From this, I know I need to make the distinction between puzzles and exploration areas more clear. The challenge is that, unlike Portal, there is backtracking in Relativity. I don’t seal off a test chamber once you enter it, so how can make sure that the player understands that they have everything they need right there to solve it? Fortunately, because the player can walk on all different surfaces in the game, I can place the entrance in an area that’s not as easy to go back into once the player enters a puzzle area, so that it’s clear, “hey, this is an isolated area with a puzzle”.

He also had some feedback with the visuals, and really emphasize the need for the game to have a unique visual identity, to distinguish it from a lot of other FPS puzzle games.

Relativity_2014-03-30_v8 2014-03-31 16-37-42-44

I showed the game to Marc ten Bosch and Brendon Chung separately on Thursday afternoon at GDC, one after the other, and both gave me really good feedback on puzzle pacing and level design, specifically on how to isolate individual concepts, and introduce them one at a time. I didn’t realize until then that in a lot of my earlier puzzles, I was actually introducing 2 or more concepts at once, and a lot of players would get confused on what they were supposed to take away.

It was also interesting to see their approaches to puzzles. Marc, himself working on a puzzle game based on an abtract mathematical idea, found the difficulty level in the puzzles to be just right, and said that any hints or additions to make them easier would ruin the puzzles, but Brendon, who does more linear narrative based games, found the first puzzle to be really challenging. In a way, both are correct. The puzzles don’t need to be made easier, but there needs to be other puzzles before those, to correctly lead up the player. This way, it can address the issue of pacing. For example, I ended up adding another puzzle before what was originally the first one, to isolate one of the concepts, and but kept a lot of the other designs. From playtesting I’ve done since then, this seems to work a lot better.

Relativity_2014-03-30_v8 2014-03-31 16-38-23-13

Pohung gave me some awesome insight on puzzle design. He used an analogy from the Chris Nolan film, The Prestige, specifically this line about the structure of magic acts:

Every great magic trick consists of three parts or acts. The first part is called "The Pledge". The magician shows you something ordinary: a deck of cards, a bird or a man. He shows you this object. Perhaps he asks you to inspect it to see if it is indeed real, unaltered, normal. But of course... it probably isn't. The second act is called "The Turn". The magician takes the ordinary something and makes it do something extraordinary. Now you're looking for the secret... but you won't find it, because of course you're not really looking. You don't really want to know. You want to be fooled. But you wouldn't clap yet. Because making something disappear isn't enough; you have to bring it back. That's why every magic trick has a third act, the hardest part, the part we call "The Prestige".

In the same way, a great puzzle should follow this structure. Pohung used one the puzzles from Relativity that he felt did this correctly (which was actually unintended on my part). The puzzle had two parts. The first part is pretty easy, and is meant as a build up to the second part. The second part at first seems like the first part, but actually requires a variation of the technique. Pohung talked about his line of thinking in approaching the second part, going “Ah, this looks easy, it’s just what I did before…. wait a minute… that’s not going to work here… hm….. ah ha!”. As such, this puzzle shows something ordinary (a simple technique that the player learns), then something extraordinary (the puzzle looks similar, but it seems the technique no longer applies…), and then brings it back (player realizes a variation of the technique would work).Relativity_2014-03-30_v8 2014-03-31 16-38-45-43

Anyway, it’s quite difficult to talk about puzzle design in depth without showing you the actual puzzles. However, hopefully there’s some high-level stuff that you may find helpful in approaching puzzle design for you own games.

Development Update – New Gifs, Screenshots, and GDC!

This past week has been crazy busy for me. After IndieCade East last month, I came home with a lot of ideas for level design, new mechanics, as well as the overall structure of the game. I wanted to implement a lot of these features in time for GDC so that I can get some feedback to confirm I’m headed in the redirection, or make corrections if necessary.

As it turns out, because the project has gotten so big and so advanced at this point, that everything I’m adding takes an incredibly long time to implement. For example, a few weeks earlier, I was working on the water mechanics for the game. I had finally worked out several key design issues with water, and just had to sit down and write the tech stuff. The water itself was pretty tricky to begin with, getting redirection and gravity behavior correct, but what made it extra difficult was that it had to work with all the other systems I had in place.

And that was just one issue among many. Anyway, after many many late nights, I finally got a demo ready. I’m doing some last-minute testing, and there are still a few minor bugs, but the thing is more or less playable, and I’m really happy with it so far. It really feels like the game is starting to come into its own.

If any of you are attending GDC next week, and want to try out the demo, just let me know! I’ll most likely be wandering around the convention center, and will have my laptop with me. Best way to reach me would be via twitter: @willychyr.

To celebrate getting a demo ready after many late nights, below is a completely new set of gifs and screenshots:

Relativity_2014-03-16_Gameplay-01 Relativity_2014-03-16_Gameplay-02 Relativity_Screenshot_01 Relativity_Screenshot_02 Relativity_Screenshot_03 Relativity_Screenshot_04 Relativity_Screenshot_05 Relativity_Screenshot_06 Relativity_Screenshot_07

Development Update – Dynamic Water Redirection

Yesterday, I went back to the drawing board, and programmed another water stream from scratch. It doesn’t even look like water at all, but I got dynamic redirection working, and it’s much closer to what I have in mind:


I then added a way to rotate the redirection cube. Right now you just click the left mouse button to rotate the cube, but this might change later on:


Here’s dynamic water bending with multiple redirection cubes together:


Development Update – Water Flowing

Wow. Can’t believe it’s already March. I’m now entering the 16th month of full-time development. When I started this project back in November 2012, I actually thought I’d be done in 3 months…

Cheesy <– my current self laughing at my past self.

Anyway, after a very unproductive week and lots of trial-and-error programming, I am finally getting somewhere with the water stuff in the game:


It’s probably the ugliest-looking water stream around, but I’m just happy it’s flowing. I have enough game development experience now to know that everything starts out looking terrible, so it’s only going to get better from here.

Also, just want to share that Relativity is in the latest issue of the TIGSource DevLog Magazine! Special thanks to TIG user Bandreus for reviving the magazine!