Tuesday, November 28, 2017

Cosmoteer 0.13.1 - Perimeter of Death!

Cosmoteer 0.13.1 has just been released! The majority of changes are bug fixes, but there are still a couple of nice other improvements:

First, this update adds to multiplayer a feature called the "Perimeter of Death". This is a giant circle around the battle area that will quickly damage and destroy any ships that stray outside of it. It is intended to reduce the effectiveness of "kiters" (ships with long-range weapons and lots of thrust that simply stay out of range of enemies) as well as prevent players from simply running away indefinitely.


The other feature is something that a lot of players have been asking for: a "sort" function for the Ship Library. Now, players can sort their ships by name (the default), cost, crew, or date modified.


Sunday, November 12, 2017

Cosmoteer 0.13.0 - Multiplayer!!!

Given the lack of updates for the past couple of months, you'd be forgiven for thinking that I had stopped working on Cosmoteer. Thankfully, you could not be more mistaken!

I've actually been working on one of the biggest new features in the history of Cosmoteer: Multiplayer!

Those of you who have been following Cosmoteer for a really long time probably know that the original prototype versions had support for multiplayer in which players could design ships and battle them with their friends. But I realized that having to support multiplayer was dramatically slowing down the development of Cosmoteer, including development of singleplayer-only features. And so I removed multiplayer support from the game's code, hoping (but not expecting) that one day I would be able to bring it back.

Well, that day has arrived! I am incredibly proud and excited to announce that multiplayer is returning to Cosmoteer!

In this first version, multiplayer is a simple team-versus-team battle of up to 8 players spread across two teams. Each team has a certain amount of money (configured by the host) to spend on a fleet of up to 5 ships per player (or fewer, as configured by the host). Then the game starts and the players control their own ships, attempting to destroy the other team's fleet. The game ends and one team is declared the winner when either the other team's fleet is sufficiently destroyed or the timer runs out.


You can play with anyone on the same LAN (Local Area Network) as you, and you can also play with a friend anywhere else in the world by typing in the host computer's I.P. address. (There is not yet a public online list of games, but I hope to add that soon.)


This is just the beginning! This first version lays the coding foundation for more improvements to come. In the long term, I may add entirely different game modes, such as multiplayer co-op and creative modes. In the near future, I plan to add:
  • A.I. players in multiplayer battles
  • Observers (for streaming tournaments)
  • More than two teams & free-for-all battles
  • Some sort of boundary around the playing area to prevent people from being able to run away indefinitely
  • Limit price per-ship and not just total price per fleet
There's lots more details and plenty of other fixes and improvements in the full changelog.

Technical Implementation

You may be wondering why I've chosen to bring back multiplayer given the fact that I originally removed it because it was slowing down development too much. Wouldn't bringing back multiplayer cause all future development to become a lot slower?

Thankfully, the answer to that is mostly "no", and the reason for that is that I've taken an entirely different approach to implementing the multiplayer code.

The original implementation of the multiplayer code required that every single change in the state of the game (such as a ship firing a weapon, a ship moving a millimeter, a crew person walking a foot, or a bullet hitting an enemy) be synchronized among all players by sending packets over the internet. This was a huge problem for two very important reasons:
  1. In a game as complex as Cosmoteer with potentially dozens of ships and thousands of crew, that's a potentially huge amount data that needs to be transferred over the internet between all the players. We're talking megabytes per second of data for a large battle, which made the game really only playable on LAN or very-high-speed internet connections.
  2. The code for anything that could affect gameplay even in the slightest became way more complicated due to the need to send those aforementioned internet packets. For example, if I wanted a bullet to inflict 1000 damage on an enemy ship, I couldn't just call the TakeDamage(1000) function; I first had to construct a network packet with all the needed information and send it to all other players. This made working on gameplay code far more time-consuming that it would've been without having to send all those packets.
The new multiplayer code uses an entirely different approach that's called "deterministic lockstep". Essentially, this approach requires that two computers running the same version of the game with the same initial battle setup and same player inputs will simulate the game in exactly the same way. (Not even off by a millimeter, or else the butterfly effect will cause bigger and bigger errors until the game desyncs.) There are two big advantages to using deterministic lockstep:
  1. Only player inputs (commands issued to the ship) need to be turned into packets and sent over the internet. Everything else (physics, weapons, damage, etc...) will happen exactly the same way on every computer by virtue of them running completely deterministic game simulations. This saves massively on bandwidth, so much so that Cosmoteer now only uses a few KB of bandwidth per second.
  2. Code that affects gameplay no longer needs to be synchronized using packets sent over the internet, so long as the gameplay code can be written to be 100% deterministic. Writing deterministic gameplay code isn't very hard as long as you know what kinds of things to avoid (primarily code whose outcome could change based on framerate).
There are, however, some important disadvantages to using deterministic lockstep:
  1. The gameplay really does have to be 100% deterministic. 99% deterministic is not good enough. And non-determinism bugs can be very tricky to track down. I have written myself some pretty nice tools for debugging determinism issues, but it still took me several weeks to comb through the whole Cosmoteer codebase and convert everything to be deterministic.
  2. Games that use deterministic lockstep typically have more latency than other types of games. You may notice that when playing multiplayer Cosmoteer (and most RTS games) that there's a small delay after assigning a ship an order and before you see it actually respond. That's because it has to wait for the other computers to receive the order before it can process it. In action games like first-person-shooters, this would be a huge problem, but in slower games like Cosmoteer, it's not a big issue.
  3. Differences in how different CPUs compute floating-point (fractional) numbers can cause an otherwise 100% deterministic simulation to become only 99% deterministic, which due to the butterfly effect will ultimately lead to desyncs. In practice, this means that players running on 64-bit operating systems can't play with players on 32-bit operating systems. (Although there is a mode to force the game into 32-bits so that friends on different operating systems can play with each other.)
While these downsides are significant, none of them are deal-breaking, and are certainly preferable than the problems caused by the original way I implemented the multiplayer code.

All in all, getting multiplayer working again was a pretty huge undertaking -- one that I wasn't even sure I could pull off -- but in the end I think it has proven to be well worth it. And I'm looking forward to playing a ton of Cosmoteer multiplayer as a result!