Devlog: Flowing Water

Unity Pro offers some great looking water in the Water4 package. Edge fade, foam, refraction, reflection (sort of) and surface waves are just some of the features. For our environments in The Wild Eternal however, we needed flowing water and Water4 does not offer this out of the box. Though the water does move, it is a very simple directional movement. For our creeks and rivers, we need real movement to bring them to life. Not to mention we can use the flow direction to affect gameplay!


Unity’s Water4 shader provides a static flow direction.

Consequently, I ventured to add flow map support to the Water4 package instead, and have been met with favorable results. Here’s the result. Note: the modified source can be downloaded at the bottom of this post.


My modified Water4 shader gives the illusion of water flow. The source can be downloaded at the bottom of this post.

When I set out to make this addition, I did not know how flow maps worked, and a part of why I wanted to add them was also to understand them. It’s a neat thing, and I’m all about understanding neat things. If you are too, I hope my explanation can get you there. If you want a comprehensive quantitative understanding, I suggest reading this great article by Kyle Hayward at Graphics Runner: Animating Water Using Flow Maps.

How Flow Map Shaders Work

It turns out the effect is fairly simple at its core. Like most materials, we want water to be lit according to some bump map texture. The bump map influences both lighting and refraction distortion, and the flow effect is all about animating the bump map.

For every pixel, we decide what normal it should have by sampling the bump map at some uv-coordinate plus some uv-offset. The uv-offset is the key here, and it requires a flow direction, flow speed, and total flow time. In pseudocode:

uvOffset = flowDirection * flowSpeed * totalTime
bump = ReadTexture(bumpMap, uv + uvOffset)

If we do just this, we will get flowing water, it’s really that simple. But there is a very obvious problem with this technique. Because our texture is being panned across the mesh in arbitrary directions for each pixel, the material will become heavily distorted as time goes on. The effect looks good right at the start, but it quickly becomes an ugly mess.


Using a continually increasing time variable eventually results in large distortions.

How do we solve this? Since it looks good at the start, we take advantage of that by keeping the uv-offset small. If we cycle the time variable rather than let it grow continually, the offset will never get too big and the distortion will not be noticeable. So when our time variable exceeds, say, 1, we set it back to 0 and let it cycle again. If we do just this, we remove the ugly mess as a possibility, but incur a jolting animation reset every time the time variable cycles over:


Resetting the time variable stops distortion from getting out of control, but we have to deal with an animation reset.

So our last problem is to devise a technique to hide the reset. It helps to look at a table to understand how we will accomplish this:

Game Time Cycling Time Bump Quality
0 0 START!
0.25 0.25 Looks good
0.5 0.5 Looks good
0.75 0.75 Some distortion
1 1 RESET!
1.25 0.25 Looks good
1.5 0.5 Looks good
1.75 0.75 Some distortion
2 1 RESET!

The effect looks good for the first half of every second, and worse as time goes on until it resets. If we were to add 0.5 to our cycling time variable, the effect will look good for the second half of every second, and poor for the first half. This is what we capitalize on to hide the reset. With two cycling time variables that increase at the same rate, but which are offset in their cycles so that one looks good when the other looks bad, we can compute the bump for each and fade from one to the other accordingly. Lets look at another table:

Game Time Cycling Time 1 Bump 1 Quality Cycling Time 2 Bump 2 Quality
0 0 START! 0.5 START!
0.25 0.25 Looks good 0.75 Some distortion
0.5 0.5 Looks good 1 RESET!
0.75 0.75 Some distortion 0.25 Looks good
1 1 RESET! 0.5 Looks good
1.25 0.25 Looks good 0.75 Some distortion
1.5 0.5 Looks good 1 RESET!
1.75 0.75 Some distortion 0.25 Looks good
2 1 RESET! 0.5 Looks good

Since one bump looks good when the other looks bad, its simply a matter of linearly interpolating between the two based on their quality. We want a value which ping-pongs between 0 and 1, in-sync with the quality of the bump results.

selector = 2 * |CyclingTime1 – 0.5|
bump = LinearlyInterpolate(bump1, bump2, selector)

Absolute value is a nice way to implement a ping-pong function. This final table shows how the quality selector evolves. Notice that I have decreased the time increment from 0.25 to 0.1 to show the granular changes in the selector variable:

Game Time Cycling Time 1 Bump 1 Quality Cycling Time 2 Bump 2 Quality Selector
0 0 Looks good 0.5 Looks good (100%) 1
0.1 0.1 Looks good 0.6 Looks good (80%) 0.8
0.2 0.2 Looks good 0.7 Looks good (60%) 0.6
0.3 0.3 Looks good (60%) 0.8 Some distortion 0.4
0.4 0.4 Looks good (80%) 0.9 Some distortion 0.2
0.5 0.5 Looks good (100%) 1 RESET! 0
0.6 0.6 Looks good (80%) 0.1 Looks good 0.2
0.7 0.7 Looks good (60%) 0.2 Looks good 0.4
0.8 0.8 Some distortion 0.3 Looks good (60%) 0.6
0.9 0.9 Some distortion 0.4 Looks good (80%) 0.8
1 1 RESET! 0.5 Looks good (100%) 1

So there we have it! Our final pseudocode looks something like this:

uvOffset1 = flowDirection * flowSpeed * cyclingTime
uvOffset2 = flowDirection * flowSpeed * (cyclingTime + 0.5)
bump1 = ReadTexture(bumpMap, uv + uvOffset1)
bump2 = ReadTexture(bumpMap, uv + uvOffset2)
selector = 2 * |cyclingTime – 0.5|
bump = LinearlyInterpolate(bump1, bump2, selector)


Linearly interpolating between two out-of-sync cycles produces a satisfying result.

How Flow Maps Work (and how to make them)

For some of us (like me), generating the textures are just as hard, if not harder, than getting the shader working. Flow map textures are a fairly straight-forward information map, but that does not mean they are easy to make. Still, lets understand them first, then see about making them.

For each pixel in the texture, we want to embed the flow direction and flow speed. This can be done just like a normal map — store a vector which has a direction and magnitude — except we only need two components, not three. Pretty easy, right? Unfortunately, just like making normal maps, its very hard to draw vectors like this. Fortunately, a developer named LoTekK has produced (see if you recognize the engine!) a Flow Map Painter program which can be used to generate flow maps by drawing in the direction of flow. Though it has some usability issues, its the best solution I have found so far for free. I would love to hear about alternatives if anyone finds or makes one!

Flowmap Example

An example flow map texture for The Wild Eternal. Beautiful, isn’t it?

Implementation Details

I have not packaged together the perfect product for you. Sorry. I have instead packaged up the implementation that we use in The Wild Eternal. Below are some details about what I have changed in the Water4 package and what I have not:

  • My modifications only extend to the high quality version of the shader. Medium and low quality implementations have not been changed.
  • The vertex displacement effect that comes packaged with Water4 (called Gerstner Displacement) animates trigonometric waves according to some global directions. The flow of these waves is not in accordance with our flow map system, but still looks good alongside it.
  • Tiling is now forced to be square, and foam tiling can be set explicitly, rather than being derived from the bump tiling.
  • The foam can be animated just like the bump map. This is implemented as well. Bump and foam flow speeds are independent of one another.
  • I have changed the foam implementation to have a smoother falloff and to use the alpha channel for alpha blending.
  • Bump size has been made proportional to local flow speed according to the flow map, which produces a satisfying result for both lighting and refractive distortion.
  • The flow map needs to be stretched across the water surface. In The Wild Eternal we use terrains heavily within our scenes, so it is natural for us to unwrap our flow map according to the terrain size. This is how it is implemented. You will need to provide your own  terrain or world-space coordinates in a script.

I am more than happy to answer any questions in the comments section below.

Download Water4FlowmapSupport.zip

Devlog: Environments

We knew going into The Wild Eternal that we wanted the player to experience a variety of unique places, each with distinct flora and fauna (and color!). The game is split into four acts, and each act contains a varied number of chapters (levels) which connect to each other and can be played in any order (or even skipped, but more on that in another post).

Need something a bit more concrete?

  • Act 1: 1 chapter (blue pre-dawn)
  • Act 2: 2 chapters (yellow mid-morning)
  • Act 3: 3 chapters (green afternoon)
  • Act 4: 2 chapters (red evening)

As you can see, we designed the game to gradually provide the player with more exploration choice as they progress through the acts, so that exploration potential climaxes in act three with three chapters and then becomes a bit more linear as the experience draws toward its conclusion. In addition to each act having its own color scheme, each chapter will be thematically unique. For instance, act three contains a swamp, a lightly forested battleground, and some rather haunted hills. Pictured below is the swamp from act three and a village from act two.

A Swamp In Act 3.

A City In Act 2

Devlog: Foxsplaining

The Wild Eternal is a quiet game. Among the many critters wandering the forests, meadows, and hilltops there is but one who talks. The Fox Demon is a self-appointed central character, appearing at numerous locations throughout as a sort-of Cheshire Cat, and providing both narrative and gameplay focused conversations (many of which tend to revolve around the fox itself).

Casey: The fox was one of the first creatures we designed and one of the first creatures implemented into the game. At the beginning of the project I was new to art development in games; my skills as a 3D modeler, texturer, rigger, and animator were newborn and untested. But it’s not the beginning of the project anymore and I’ve gotten a lot more capable of doing my job (which is nice). So I spent some time this week tweaking the mesh, giving it a fresh coat of paint, adjusting some bones, and doing some animations, while Scott spent some time plugging in those animations, making sure they blend properly, and giving the fox some logic to walk and sit and look around. We also did a bunch of other stuff this week, but this is a post about a fox!

Attached is the fruit of some of our labor, comprised of a sit_idle with some tail wag and talk animations layered on top. Over the top? Not fox-like enough? Unsettled by the purple eyeliner? Let us know in the comments, or on twitter! This isn’t the first iteration of the Fox Demon and it probably won’t be the last. Cheers :)

Devlog: Swatty Tigers and Mustard Hills

Hello! So, we’ve come a long way this year as new devs, and are finally ready to start blasting through content creation and building out the rest of the playable world. The first of these spaces is a sort of mustard-colored country-side, which provides a stark contrast to the blue-dawn of the first chapter. Featured in the screenshot is a tiger with quite the personality; you’ll want to pay careful attention to her to figure out how not to get swatted and bumped around. She’s out on the hunt, so you may find her or others like her wandering the paths, forcing you off-road and into the grassy hills. Not featured: The cute rats and rather lethargic lions that you might also find in the area.

We are going to try to be a bit more available/transparent on here now, posting screenshots, devlogs, and answering questions. Thanks for your likes, follows, and interest!

rajagaha tiger

 

An Emerging Uncanny Valley, RE: The Trouble with Immersion, also Aladdin?

Adrian Chmielarz of The Astronauts recently wrote The Trouble with Immersion, or the Opening of Metro: Last Light, where he suggests that in order for devs to be able to immerse the player (without spending bucket-loads on edge-cases), players have to promise not to try to break the game. He hopes that this would enable developers a greater freedom to create more immersive experiences, but is careful to point out that it might not work. But whether it works or not, the overall perspective isn’t quite doing it for me, so let’s have a conversation about uncanny valleys and the purpose of play.

What follows is the beginnings of an idea, not fully formed, about the conflict between immersion and realism. The blog is most assuredly not bullet-proof. Feel free to challenge it, or add your own thoughts in the comments below. <3

The Nature of Uncanny Valleys

Polar Express Uncanny Valley“The uncanny valley is a hypothesis in the field of robotics[1] and 3D computer animation,[2][3] which holds that when human replicas look and act almost, but not perfectly, like actual human beings, it causes a response of revulsion among human observers.”

The effect is quite noticeable in movies and games which use realistic looking CGI characters. Movies such as The Polar Express, or Final Fantasy: The Spirits Within provide good visual examples.

The uncanny valley is most often used to discuss the realistic portrayal of humans, but it can also be used to describe the realistic portrayal of anything else, especially um, the whole world. Which is to say that as games become more realistic looking we expect them to behave more realistically.

The Purpose of Play

As kids (and throughout life) we play with stuff in order to better understand it. In our early years, we’d throw balls, hold buoyant rubber ducks under the water in the bathtub, build dams, etc, and learned about physics. We undressed barbies and learned about boobs and maybe sex. We went where we weren’t supposed to go, and did things we weren’t supposed to do, because we were still testing cultural and physical boundaries. Cause and effect is basically the most interesting thing in the world. Play, even pretend play, is an act of experimentation.

The uncanny valley is an issue because we have real world experience. We know how the real world is supposed to work, look, act, feel, sound, and so the more real a game tries to be, the more right it has to get all of these things. Just as we see people in games and expect them to move and act and look a certain way, we also see the physical world in games and have similar expectations.

So it is important for designers to keep in mind that when the player enters a game world for the first time they are entering a whole new world which they yearn to understand. But as we learn early in on life, to hit the wall, to be slapped on the hand and told “No!” is to know your confines; it is the quickest way to know exactly how free you are. And so we test our games in the most ruthless ways to see what we can get away with. This is what play is for, and this is how games excel: by enabling players to enjoy the act of testing new rules. For example, if a game tries to engage in graphical realism, are the graphics realistic enough, are the physics and sounds and animations and narrative on the same level as the graphics? The more realistic a game looks the higher our expectations for the ways in which it realistically behaves.

Game designers and parents try so hard to teach by telling (bad tutorials tell, good tutorials are invisible). As players we don’t want to be told what we can and can’t do. We want to experience the rules first-hand and to see the effects of our actions on the world around us. We want the game to communicate to us through its own rules just as the real world does.

So make games that people can test–because play IS testing–and allow your carefully designed, expected experience of immersion to be broken. If your players are doing crazy things you never expected, it means they are engaged, maybe even immersed.

A Couple Of Examples Of Immersion Problems

In Adrian’s post he specifically talks about Metro: Last Light, where a bunch of army dudes animate infinitely after speaking their lines in the opening minutes of the game. This broke his immersion because he was reminded that he was playing a game and that the people surrounding him were actually lifeless automatons with nothing else to do. For some, this might not actually break immersion, or it might not even be a thing required to immerse us in the first place.

Bioshock Infinite struggles to balance the player’s semi-realistic (yet rather forced) relationship with Elizabeth, and murder-by-numbers FPS mayhem. The two mechanics conflict with each other because one pulls you into the world and makes you expect a sort of realism, and the other splatters blood all over the screen and sends you flying on a roller-coaster of infinite murder. Patricia Hernandez wrote an exceptional article which touches on this: ‘An Effin’ AI in Bioshock Infinite Is More Of A Human Than I Am‘.

The Uncharted series struggles to balance the notion of a good, wise-cracking every-man, with mass murder and destruction. Yes, the badguys are out to kill Nathan, but why is killing so easy for him? One of the immersion breakers, I think, is that he makes light of it.

What Is Immersion? Does It Matter?

I’m pretty sure there’s a videogame commercial or two out there where the ho-hum real world fades away around the player, revealing a gameworld bursting with bloom and magical beasts behind them. And it’s true, that is sorta what happens when we are immersed in something; we become so engrossed that we actually tune everything else out. Someone calling my name for dinner? Didn’t hear it. Cats on fire? Didn’t notice…

We can become immersed for a number of reasons, but with videogames it really helps if the content is compelling, abides by its own rules, and doesn’t get in our way as players. Did you notice I didn’t even mention realism? Realism isn’t at all required for immersion. Simple games have an easier time immersing the player because there’s less stuff to juggle and less rules to follow. But when a game approaches the real we expect a ruleset that is similarly realistic and complex. We might expect something as simple (and potentially frivolous) as water that splashes and ripples beneath our feet, or NPCs that never repeat the same animation twice. Does it service the gameplay? Depends on the game and player expectations.

So then it’s all about framing and first impressions. The way the designer initially presents their game to the player will inform the player’s expectations going forward. If you can’t simulate the real, don’t set the player up to expect it. If you’re going to place a guard who has one line of dialogue and enters into a looping animation afterward, you have to expect that the player will listen to the line, and then wait to see if more lines will be spoken, and you can’t be upset by that behavior because you are the one that gave the player incentive to stop and listen in the first place. You taught them to stop and watch!

Since we learn through play, designers have the ability to shape player behavior through their designs. If you don’t want your player to play your game a specific way then make sure you don’t reinforce that behavior through your own design decisions. For more on that last bit, and to end sorta back where we started, check out a different blog post by Adrian Chmielarz.

FIRST!

Do you know that sense of awe you get when a game’s world feels bigger than the game itself? Like burning a bush to reveal a hidden stairwell, or bombing a cracked hole in the wall to reveal a series of secret rooms. Or leaping from platform to platform to reach beyond the boundaries of the TV screen, to run past the end of the level to the secret end, where warp pipes lay waiting to take you to who knows where.

A game should not feel like it exists to honor you, it should feel like it exists in spite of you: like it has a life its own. We’re still trying to figure out exactly all of the bits of magic that have to come together to create that feeling, but I think we’re on the right track with The Wild Eternal…

The studio is currently just a pair of us: Casey Goodrow (the elder brother), and Scott Goodrow (the taller brother). Height and age are probably not the best method of description, but at least now you have an easy way to pick out who is who if we should ever have the opportunity to meet.

The bottom line is we like games, we love the games we grew up playing, and we want to capture the magic we felt when we played those games.

We hope you’ll stop by from time to time and check out our posts, leave feedback, and join us as we endeavor to create a world that’s worth exploring.

See you when the fog clears!