Even the Ocean: Review

Disclaimer

I’ve never reviewed a game before, but I had been waiting to play this game for some time and now having completed the main story I have a lot of thoughts that Twitter’s character limit couldn’t do justice to.

The game offers plenty of customisation when setting up a new game, including options to skip cutscenes or all the story elements all together. For this review I changed no settings and went with the mode that was recommended to me as a first time player, my criticisms are entirely through this first time player perspective.

There may be some spoilers though I have tried my best to avoid everything major.

Introduction

Even the Ocean is the second game from Analgesic Productions duo Sean HTCH and Joni Kittaka, their first being Anodyne. I immediately became a fan of theirs having played Anodyne and decided to follow them in the hopes that they would continue to make more games. Sometime in 2013 I started to see screenshots and previews of their next title, and since then I had been anticipating this release.

I’m going to be drawing a lot of comparisons from Anodyne throughout this piece, because I think it’s interesting to see not just how this game stands on its own but also how Sean and Joni have progressed from their debut creation. At face value, Even the Ocean looks like a more ambitious title than Anodyne, which I think demonstrates Sean and Joni’s confidence in their abilities having carried the experience of their first release forward to this project, it boasts a much more story driven gameplay and a whopping 4 hour soundtrack (not including the 90 minutes of bonus material).

General Thoughts

After the first couple of hours with the game, my experience was mostly positive. I was feeling the same mysterious vibes I got from Anodyne, the atmospheric soundtrack, and the mashup of unique environments. I do have criticisms about certain aspects of Even the Ocean, but for the most part I don’t think they spoiled the experience, certainly not enough for me to stop playing anyway.

The opening area immediately gives you an idea of the effort that went into this.

Gameplay

Even the Ocean starts out looking like a regular platformer, but the core of the game is an energy balancing mechanic. You fit on to a spectrum of light energy which alters your vertical movement (allowing you to jump higher), and dark energy which alters your horizontal movement (allowing you to run faster).

The puzzle areas of the game are set out with a variety of obstacles and puzzle pieces which all have the ability to impact your energy levels, go too far to one side of the spectrum and your body disintegrates. There may be times when you need to unbalance your energy level in order to jump higher or run faster to clear a certain jump, but for the most part I would just find myself trying to maintain a balance for safety.

A platform lifts itself while you are stood on it.

Unless you’re speed-running the game, you’ll find that this mechanic plays into the level design more as a tool for puzzles to solve than for obstacles to avoid. For me this was one of the best surprises on offer, after Anodyne I was expecting another adventure, and I got another adventure but more in the narrative sense. When it came to using the energy mechanic I found myself solving puzzles, and with every new area I entered, new puzzles with new contraptions were introduced right up to the end of the game.

An energy spirit chases you until one of those blocks sucks it in.

Each puzzle or contraption was introduced excellently, despite the lengthy dialogues of the narrative driven parts of the game, the power plants were almost completely void of dialogue, you were left to your own devices to get acquainted with and understand the mechanics being thrown at you before moving on to the next room to receive harder puzzles.

The process of being shown a mechanic, figuring it out, and applying it to solve the puzzles, is very satisfying as we saw from The Witness earlier in the year, everyone with an interest in this sort of thing should check out “A Theory of Fun for Game Design” by Raph Koster, this was recommended to me years back and it completely transformed my approach to game design, the process used in both The Witness and Even the Ocean to teach new mechanics relates closely to the ideas discussed in this book.

A short-lived but fun redirection puzzle, in which your shield is used to fill in the gaps.

I felt that the weaker aspects of the gameplay fell into everything outside of the puzzle areas. From the moment you first start exploring Whiteforge for yourself, you are given options on the train service to go to places that you aren’t supposed to go to. I would flick through the list of options at each station, select them and then be told by the protagonist that they didn’t want to/weren’t supposed to go there right now, I feel like the option to go to these places shouldn’t be present until I’m actually able to enter them.

Want to explore? Tell that to the museum policy.

It’s a similar story in the overworld, which initially felt like it was being set up for an open world game where you roam from place to place developing the plot in no particular order. Instead, you might discover a new area, enter it, and then get the same “I shouldn’t be here right now” message before promptly being forced out of that area by the protagonist.

These design decisions create a false promise of free choice and open world exploration, in a game that is actually completely linear in its progression, these decisions are especially misleading to me having played Anodyne, where the world was completely free roam with inaccessible areas logically blocked off by gates or statues rather than dialogue boxes telling you to turn back.

These gripes only stuck out in the first few hours of play, most forbidden areas get explored sooner rather than later (at which point they are freely available to return to) and in the end it’s hard not to appreciate the sheer scale of the game given the size of the team working on it.

Visuals

Just look at that majesty

Another very strong aspect of the game. Anodyne had some stunning and wonderfully diverse environments, and I was hopeful that we’d get to see the same level of creativity from Sean and Joni in Even the Ocean. For the most part they absolutely delivered, the parallax backgrounds (and foreground elements in a lot of settings) convey a great vastness in every area you visit, Whiteforge is this stunning white metropolis that harnesses the power of light energy to defy physics and stand as this impossibly vertical pillar of structures. The natural world of Even the Ocean covers a whole range of environments that feel a lot more grounded in reality than Anodyne’s but still manage to diversify and create this great sense of wonder.

Stunning pixel scenery

My one minor criticism regarding the visuals is that the power plants felt bland in comparison, I value those areas for the gameplay so it’s not something that really bothers me, it was just a shame to see such stunning environments for only a few fleeting moments before being put into a much lengthier puzzle area, almost all of these areas were very desaturated collections of boxes and corridors, I realise that they are power plants but I feel like more could have been included in the same way that the natural landscapes took advantage of vegetation to fill the space, perhaps some exposed wiring, winding pipes, coils, gears, pistons or even some completely fictitious contraption in the background that could be justified as “something to manage the energy levels”.

It doesn’t look bad by any means, but take the large slab of brick wall, or the piping backdrop, they feel repetitive and are covering up a pretty nice looking background.

Audio

Just like in Anodyne, the audio work was integral to the game’s atmosphere. The eerie feeling I got from exploring Anodyne to a distinct lack of percussion was a completely new and unforgettable experience for me, and that same feeling is present in this game. I don’t have much more to say about it but this is one aspect of Sean’s work that I would never want to change.

Favourite tracks were “Magdal Woods Power Plant”, and “Concrete in the Woodlands”, the whole soundtrack is full of these wonderfully melancholy tunes but these two stood out, there is an air of hopelessness in the game as they’re playing, it’s fantastic.

You can listen to the soundtrack on Sean’s Bandcamp page. As with Anodyne, the soundtrack alone is worth a purchase, plus there is a massive amount of bonus material that didn’t make the final cut of the game!

Story

The story itself is a lot more present than that of Anodyne’s, for better or for worse. I’ve always preferred when the narrative takes a backseat to gameplay, these days Dark Souls has become an awesome example of achieving that.

Even the Ocean follows a power plant technician called Aliph, who rises to fame travelling between the power plants to maintain and fix them after a growing number of faults begin to emerge. The plot centers around the theme of balance, the parallels with the game’s mechanics were something I appreciated in that aspect.

The overall flow of the story was fine, the game is divided into acts, each one following a reasonably predictable structure of travelling between power plants to fix them. Though as I said before, it was the narrative heavy portions of the game outside of the power plants that felt least satisfactory.

Coming back to my early criticism regarding gameplay, there were times where it felt like my “access” to the game was bounded by plot progression, the most irritating example I can think of is the new arrival in Whiteforge, I could not leave the area to progress the game because Aliph felt the need to speak to this new arrival “for some reason”. Granted, this character becomes pretty important to the story, but I had no desire to speak to them myself, and the game didn’t really do enough to make me want to speak to them either, it’s another case of being given a choice that I don’t actually have, the cutscene should have just made me talk to them instead of handing control over to me for that brief moment.

I actually do not.

Moments like this made me feel as though the story was hanging over my shoulder like a backseat gamer, ready to nudge me in the right direction whenever I approached somewhere that was accessible but wasn’t “right for this moment”. In Anodyne, the story was very loosely defined by a few brief encounters with the Sage, along with a handful of non-intrusive characters in select areas who would maybe fill in a few small parts of the overall plot with some clues or descriptions.

Outside of those encounters, the narrative was very much decided by you and your exploration, you effectively built your own story by connecting these Sage dots with progression. This difference means that there is very little room for story-building in Even the Ocean, which in itself makes narrative sense as you’re literally being told the story by a Storyteller, but wouldn’t it feel more satisfying to a player if this story being told was one where they had much more freedom to explore? I personally would feel like I had a hand in crafting the story as it unfolds.

Due to the heavy narrative in this game, it felt a lot more serious than Anodyne, which managed to make room for some good humour in between the existential and ponderous characters and bosses dotted around The Land. Of course, Even the Ocean still had its moments…

King Croissant breaking the news to me. Honourable mention: Wilbert the Clown.

Before wrapping this up, I decided to explore the other gameplay options. Thankfully there are settings to make the narrative less intrusive, if you’re so inclined you can remove it from your playthrough all together, choosing Gauntlet mode skips the story and lines the power plants up as a series of levels, putting you in this very nostalgic looking warp room:

Feels like I’m back in Anodyne!

To sum up, I thought the story itself was fine – I actually enjoyed it a lot more towards the end (especially the ending itself but I won’t go into that). I just didn’t care for the way in which the story dictated the flow of gameplay.

Conclusion

This is an excellent game, and for all my gripes surrounding the story’s impact on the gameplay, the options in the main menu show that Sean and Joni did put a lot of thought in to the experience in an attempt to include everyone, it’s a staggering amount of work for just two people, and exactly why I became a fan of their work following the release of Anodyne.

As with Anodyne, they made their game the way they wanted to, creators should do that. Sean and Joni have an amazing knack for creating a unique and mysterious atmosphere in their games, and I think this title stands strongly alongside Anodyne in their increasingly impressive portfolio.

I look forward to their next title, whenever that might be.

NpSceneQueries::multiQuery Mobile Error (Unity)

Basically jotting this down here as I recall it, will try to better lay out my solutions later.

Part of this competition involves publishing your finished game to the Windows store as a universal app. After some headaches with getting the Windows phone emulator to work, I had this error bombarding the development console built-in to developer builds of Unity games:

NpSceneQueries::multiQuery input check: distance cannot be negative or zero

I got this on two different occasions, and there doesn’t seem to be a lot of documented cases of this happening out on Google. One Unity forum thread I found had multiple devs experiencing this issue when developing for Android, people seemed to think that the problem was caused by the physics engine.

With that as my only clue, I set out to try and make the error go away.

First Thing to Try: My protagonist is able to wall on ground and ceiling, when it switches to the ceiling I was inverting its Y-scale, having a negative scale seemed to cause this error first time. Removing the scale inversion in favour of adding upside-down versions of the character’s sprites fixed it. Having now encountered this, I would personally advise against using negative scales (for all I know this may have already been common knowledge to some?)

The Next Cause: Was Physics.Raycast. This is more of an issue to resolve, my protagonist has a function that returns true if it collides with an obstacle, triggering a lose game sequence. I’m using basic geometry to handle collisions with the environment, but this won’t work for enemies and dynamic obstacles. I’m going to attempt swapping raycasts out for OnCollision/OnTriggerEnter checks

SFAS Days 4 & 5

So day 4 ended up being especially busy for me, I was only able to get back-end improvements done to the project. The code was restructured to better allow for multiple level appearances and characters, since currently I was editing the prefab’s inspector variables manually to see change.

Over both days, here’s what I got done:

  • Restructured code
  • Created some more character and environment sprites
  • Improved shader code
  • Rubble spawns from broken rocks, coins can also be obtained this way
  • Score counter
  • Game states are back, and it’s now possible to lose the game

There are a couple of things I was asked to go in to detail on, I’ll try to do so on a break, that’s all for now. Next goal is to implement a high-score and total-score counter in order to unlock the extra content.

~ Oli S-L

SFAS Day 3

I took a break yesterday, then got back to work in the evening to add coins and our character’s “super move” which bursts through all the obstacles. Despite not putting so much time in to the project yesterday, a lot of interesting things went on to make all of this happen.


Making it Rain

The coins themselves were easy to implement with what I already had, the sprite is animated using my SpriteAnimation script, and Unity’s collisions take care of collecting the coin, but having the coin just disappear on you is boring. I wanted the coins you collect to fly in to the top-left corner where the score counter is going to be.

There are two coin prefabs in use: one to be collected by the player, and one “post-collection” coin whose only purpose is to curve to its destination and then vanish.

To curve the coin I wrote a BezierCurve script, you set it up with the coin’s starting position, a destination and some random point to the right of the screen

A rough diagram to show what the Bezier Curve is doing, ‘u’ transitions from 0 to 1 .

So this worked, the next issue was when to remove the collected coin from the scene.  If you’re familiar with Unity you’ll notice that the coins in the gif used Trail Renderers to create the yellow streak that follows their path. Removing a GameObject that has a TrailRenderer component attached will remove the trail abruptly.

The cost of aesthetic.

So instead the collected coins has a configurable value for their ‘end lifespan’, when they reach the end of the path, they will go invisible for this amount of time giving the trail time to catch up and finish gracefully, at which point the GameObject is then removed.


Super Move

In addition to collecting the coins, I want for a special powerup to exist in the game, when collected it sends the player in to an over the top rainbow-charged frenzy that allows them to charge full speed through the game, destroying all the blocks in their path.

This was again done with the use of a TrailRenderer and ParticleSystem, probably the most challenging part of this for me was tackling shaders, something I’m not familiar with yet.

Unity’s standard shader (left), and then two of mine.

The Unlit/Cutout shader was my first test run with Unity shaders, since it was bugging me that I had to use a lit shader in order to preserve the transparency on my sprites. If you’re looking to get started quickly with shaders in Unity, Dan Moran’s video tutorial offers a very fast review of the basics, more than enough to get started (and then I’m sure there’s plenty of more advanced documentation of writing shaders out there)

The Unlit/RainbowPower shader was the result of plugging random numbers in and experimenting with the _Time and _Sin or _CosTime variables (Unity docs on built-in shader variables, a great resource)

I plan to experiment more with shaders as I’m starting to realise just how powerful they can be. One simple tweak I would like to make is having the rainbow shader transition through the colours more frequently.

All that was left with Super Move effect after this was to attach the shader to the trails, particles and player, then activate it at the right moment.


Breaking the Terrain

This was probably the toughest to get right, the approach is straightforward but it’s easy to make a mistake on some of the lower level parts.

  • We find the tiles surrounding the player
  • If they are solid, the Wave needs to be updated to set them to non-solid.
  • The TileMap for that Wave then needs to update the appropriate tiles to match the changes.

That last point is where a few attempts were made to get it right, remembering that I wrote the TileMap so that it would auto-tile: When a block is removed, the surrounding tiles must also be updated to no longer connect to it.


 

On to Day 4

I was actually up until 4am finishing off most of the stuff above, and I managed to optimise a few of the texture handling scripts while I was fixing the terrain breaking mechanic. That said I’m now ready to continue!

Today’s goals are to add rubble for when a block is destroyed, a get game states reimplemented (the skeleton project we were given to start us off has this set up already, but I disabled the original scripts while I got my concept to work.)

As always, you can direct your feedback or comments to my Twitter @Jindont.

~ Oli S-L

 

 

 

 

SFAS Day 2

View post on imgur.com

After yesterday’s work, I ended the day with something playable! The level generator adds waves as the player progresses, and removes waves that have strayed off-screen. The player must tap to swap surfaces, avoiding all walls and future obstacles.

I’m going back to work today as I’m ahead of schedule with this project, so I expect to get less done this time, but my next two goals are 1) Make it look nicer, and 2) add obstacles and collectibles!


 

The Level Class

The Level class is responsible for managing the waves, and for retrieving tile data for the player. It iterates through the existing waves (which maxes out at 3 before they start getting removed) until it finds the wave that the player is on.

Waves have a width, height, starting X position and an array containing their collision data. So checking that the player is on a specific wave is as simple as making sure they’re between startX and startX+width. If the Player wants a tile, it calls level’s GetTileAt(x,y) function, which then calls the appropriate wave’s GetTileAt(x,y) function, and returns that result.

Currently, the player only requests 3 tiles from above or below its current position (depending on the direction it’s falling). If a resulting tile is solid, an AABB collision test occurs between two rectangles formed from the player and the tile positions and scales.


 

Frog Bro

The current protagonist!

Coming from a Flash background, I’m not a huge fan of Unity’s animation tools. I find it very slow and overkill when trying to animate a simple 2D sprite, I’m assuming it’s meant for bigger tasks than that but it remains a painful process for cases like this.

So I wrote an AnimatedSprite script, it takes a Texture in the form of a spritesheet like the one above, and an array of animation data (name, frames used, and speed of the animation). The object can then be called on to set its animation to whatever you gave it, it will select the appropriate frame from the spritesheet and draw that on to a Quad.

I’m quite pleased with the result of this script, and a change of parameters is all it takes to implement a new sprite. When I have more time I’ll probably polish it and release it here.


 

This is all I have time to write for now, later today I hope to make a start on collectibles but we’ll see how that goes. For queries and feedback, reach out to me on Twitter @Jindont!

~ Oli S-L

SFAS Day 1

My 2 weeks started yesterday for the second round of the Search for a Star competition. The competition is a nationwide programming challenge for students and graduates that attempts to mimic an application process.

The second round gives contestants 2 weeks to make a game in Unity and publish it to the Windows Phone store. Last year my project got me a ticket to the final round interview, which was a miracle in itself given how restricted I was working on a slow, near broken laptop. I even had to take it to lectures to make progress as it was the only way I’d have time to finish everything. It was also one of my first times really using Unity.

Not my best work, but for a 2 week time-limit I was more than pleased with it!

Upgrade Your Workflow

This year, my placement has afforded me a proper setup, complete with a high-end desktop and multiple monitors, in addition I’ve booked time off work to focus on the project for its duration!

Having a faster machine has also allowed me to spend time looking at workflow improvements before going ahead with implementation. In my first blog entry I was looking at creating Tilemaps out of meshes, and said that I’d like to create an editor to allow for user created tilemaps.

So that’s what I focused on for Day 1, I rewrote the tilemap scripts and scriptable objects infrastructure, then proceeded to write an EditorWindow with very basic functionality for creating a level (or “Wave” as it’s called in this project)


Draft 2D Level Editor

It’s no Tiled but it will certainly do.

So how is it used? First you set the dimensions of your wave, and the window will resize itself to accommodate a grid which fits your given size. Left-click dragging will create black ‘walls’, while right-click dragging will erase them. All that’s left then is to enter a name and click ‘Save Wave’, Unity then creates an asset out of your drawing.

The ‘Wave’ asset, the string property is an artifact from not having the level editor originally, you can change the level with this provided its length agrees with the width and height.

Under the hood, the window itself works by calling DrawRect() and referring to a 2D array of integers to determine which colour to use for each rectangle, the window automatically resizes as you change the dimensions of your level as well.

Since my tilemap script attempts to stitch edges and corners together algorithmically, I have no need for a tileset display or the ability to see what tile you’re placing in this version, though it wouldn’t be too tricky to implement and certainly something I would add before releasing any of it.


On to Day 2

Today’s work will involve getting a factory in place to generate the level, the level is made up of ‘Waves’ which my editor is used to create. A Wave is just a segment of the level, I’ll create a large pool of preset waves which the factory will then choose between when it comes to generate the level.

Level will be assembled from randomly selected presets, Player will ask Level if it’s colliding with any of the tiles in each Wave.

Having an editor allows me to ensure that the waves are surpassable, and also allows me to do things such as pick viable locations for collectibles such that they will never be unreachable.

Hopefully my post tomorrow will give more of an idea of the actual gameplay as I wrap up on this workflow business.

If you’re interested to see more about the Tilemap solution, see my previous blog post. If you have questions or feedback, feel free to reach out to me on Twitter @Jindont!

~ Oli S-L

Tile Maps in Unity

I’ve been experimenting with Unity a lot lately. I’ve usually worked with 3D prototypes but this weekend I wanted to investigate the work that was involved in getting something tile-based up and running.

I was going to do an introductory blog post first, but I’ve made some interesting developments with this so I thought I would document it all here now.


Tile-Based Anything in Unity

The main annoyance I’ve had with trying to do anything tile-based with Unity is that a lot of the documentation and tutorials I’ve read seem to steer you in the direction of using GameObjects for each individual tile. While this approach is simple and easy to follow, I don’t feel that it scales well, and I generally dislike approaches that clog up the Hierarchy this much (granted steps can be taken to organise it properly)

Fortunately, there are some techniques that can be learned to get around the use of GameObjects per tile, this fantastic tutorial series by quill18 introduces you to the concept of creating meshes programmatically, and even touches on extending the editor, a technique that I think is essential to getting the most out of Unity.

I followed enough of the series to get a basic understanding of the process, and set off to produce this:

What we have is a script component in which you specify your level’s dimensions in tiles, along with the scale of each tile in Unity units. The script will take this, generate a mesh and a texture to produce what you see on the left. quill18’s tutorial also shows you how you can add a custom element to the component’s inspector in the form of the ‘Rebuild’ button, which in my script allows you to generate a new level, the changes are also visible in edit mode.


The Process

The end goal with this was to produce something seamless with a very minimal tileset. Something like these which contain just enough information to construct what you see in the above screenshot:

These have of course been scaled up, each tile is 16×16, making each tileset 48×48.

The map is an array of 1’s and 0’s, where 0 is air and 1 is a solid block. Initially the mesh was only textured to show solid tiles, with no inclusion of the edge tiles. Below is a screenshot comparing this original look (foreground tileset) with the new, auto-tiled look (background) which gives all adjacent tiles a connected appearance:

Getting the auto-tiling to work was an interesting challenge on its own, and one that still needs some work before it will work with any tileset I give it.


Auto-Tiling Our Level

The first step in my approach was to assign numbers to each of the corner and edge tiles surrounding the center ‘wall’ tile, like so:

Then, for each tile in our level’s array, we compare its surrounding 8 tiles and add the corresponding number from the above image.

int getAdjacentTiles(int x, int y) {
    int value = 0;
    int center = 0; // have we reached the center tile yet?
    for (int i = 0; i < 8; i++) {
        int currentX = x + (i%3) - 1;
        int currentY = y + (i/3) - 1;
        if (currentX == x && currentY == y) {
            center = 1; // for offsetting i after the center tile.
            continue; // skip the center tile
        }
        if (tileOutOfBounds(currentX, currentY) 
        ||  levelTiles[currentY,currentX] == 1) {
            value |= 1 << (i - center);
        }
    }
    return value;
}

After getting this value for a tile, you can determine which edges/corners need to be added by checking if the expression:

value & (1 << i)

is non-zero.

In Unity, stitching adjacent textures together on to a single tile was easier said than done, although I could be something crucial in Texture2D’s functionality. Traditionally, you can use Texture2D’s getPixels() and setPixels() to effectively combine portions of textures together. This is fine so long as you don’t intend for your pixels to overlap, but in my case this was not so, and as a result the transparent pixels would overlap the colour.

I got around this with a naive rewrite of the setPixels function, which attempts to ignore ‘transparent’ pixels so that only the non-transparent parts of an image are overlayed:

private void setPixels(ref Texture2D texture, int x, int y, int w, int h, Color[] p)
{
    for (int i = 0; i < w* h; i++)
    {
        if (p[i].a != 0) // if the pixel to be written is solid
        {
            texture.SetPixel(x + (i % w), y + (i / w), p[i]);
        }
        else
        {
            // this was a hack to ensure that the image wouldn't
            // lose its transparency, like I said it needs work.
            Color c = texture.GetPixel(x + (i % w), y + (i / w));
            if (c == Color.white || c == Color.clear)
            {
                texture.SetPixel(x + (i % w), y + (i / w), Color.clear);
            }
        }
    }
}

This is something I will come back to, since I’m sure there’s going to be a better way to get around this then what I went with. That said, I’m very pleased with the end result. I have a script generating a mesh, a random level and auto-tiling the mesh according to that level’s data.


What’s Left?

The next step with this is that I want to extend the editor further to allow the user to draw the level on to the mesh themselves, at that point I may release what I’ve got so far for others to mess around with.

~ Oli S-L