The Engine Overhaul

Posted by [email protected] on December 12, 2014 at 5:45 PM Comments comments (0)

Hey folks, so some people may have noticed that we have somewhat recently changed our release date from Winter 2014 to a sort of vague estimation somewhere around Mid 2015. Well, we've been meaning to explain some of the reasons behind this decision, but honestly have been in such a heads-down development state that we haven't yet gotten the chance to. So here's a post explaining a bit about what's been going on with Deeper development.


In a nutshell, we ran into some size limitations with our previous engine Gamemaker Studio, that proved to cause a lot of trouble with the build, making it unstable. After working our butts off trying to optimize the game as much as we could without sacrificing what we considered essential elements, we decided it would be best if we switched to a new engine. We've run into several similar problems with the engine along the way, but these last problems (networking issues and data leaks among them) proved themselves to be insurmountable if we wanted to deliver the game as we envisioned it.


So we made the difficult decision to switch to Unity, which has a pretty steep learning curve. Basically, anything that was easy to do in Gamemaker winds up being pretty difficult in Unity, but the things that Gamemaker made difficult for us (like dynamic animation, which had to be coded by hand) Unity has nifty features like Mechanim to help streamline. Allowing us to significantly shrink the size of our game's memory, and thus allows room for a higher number of animations for our game world within our budget constraints. Additionally, because this requires a bit of an overhaul with the way some of our base systems work, we've been able to approach this new build with features that would otherwise take too much time to implement before in mind. Features like controller support and split screen game modes are now back on the table as we consider ways to implement them right from the start as we work on rebuilding the game's features and structures.


Needless to say, as with any engine switch, this switch will cost us some extra time initially, but we hope it will help us bring an even better product to everyone. As you can see from some of the above posts, this switch also certainly hasn't stopped us from overhauling assets and polishing the things we had before now that we've had experience testing out many of our game's features. So design work and other tasks are still in a very forward-moving direction as we work to rebuild what was there before but newer and shinier. Bottom line: we need more time, please don't hurt us.

A Little on Networking

Posted by JordanFarr on December 30, 2013 at 10:55 PM Comments comments (0)

This post is a bit of a change of pace. As far as these go, we usually like to showcase features that we've been working on, but I thought it would be interesting for those thinking about making a networked game to talk about some of the potential problems and solutions that come up regularly when attempting something like this. The example I'd like to share with you guys is what we have been calling the unfixable break.

First, a little background: A break is a breach in the submarine’s hull caused by anything from the bite of a shark to the slamming of a tentacle into the submarine. These breaks constantly spew water into the sub’s interior, which fills gradually and can inevitably drown your characters. In order to prevent the sure drowning death, players can take out a wrench and literally whack the break until the hole is fixed. Once all breaks have been repaired, water begins to drain out of the interior, and the players inside are safe—at least from that threat.

But what if you can’t fix a break?

Worse yet, what if you can’t fix a break, and on someone else’s screen, that break is completely repaired? What we have here is a gigantic desync nightmare, which has in testing led to a player dying on one screen and living on another. Based on how we work with death, this created a “ghost” of the character who had died on one screen, popping in for one frame and disappearing everytime a keypress message came in. While this bug, among many others, is hilarious, we had to find a way to prevent this from happening.


One thing I’ve avoided saying thus far is what actually causes a break to be unfixable in the first place. Because we work on a slightly loose client-server model, the player who acts as the server is authoritative on breaks’ creation and deletion for all players ingame. The short version of why a break would become unfixable can be summed up in two words: packet loss. As it stood only a few versions ago, when a client nearly finished repairing a break, that break would only fix when and if the server believed it to be fixed, at which point the server would issue a “destroy this break object” command. The server, also carrying a local client, would receive its own mass-issued message, immediately delete the break object, and stop caring about it. But what if one of the other clients didn’t receive that message? The server wouldn’t carry any more information on that break, and would never send forward that crucial packet again.


A Pretty Nice Fix


Now, I’m not going to say I’m all-knowing on networking junk (in fact, this is the first multiplayer game I've ever attempted), but I was pretty satisfied with this fix. To remedy the unfixable break, I took out the server’s immediate response to what they saw as a break ready to send the “destroy” message about. Instead, I gave the client whose player is closest to a break object ready to be destroyed the authority on its fixing. That is to say that if you are the player closest to a break ready to be fixed, you will contact the server and request it to mass-message the “destroy this break object” command. If you don’t receive a reply between 0.5 and 1 seconds after your request, you’ll ask again. Finally, if another player does not receive this message, when they approach the break and attempt to fix it, they too will make that request for the fix—and will wait the same amount of time before asking again. Using this model, there is nearly no scenario in which a break object cannot be fixed, even when desync occurs, save for total disconnection.