Because I regularly have to stop and start, sometimes weeks or months apart, I keep finding the Spring codebase has changed and generally in a different direction to my requirements. I've also changed my requirements recently to require support for 100+ player persistent games (MMORTS) and non-x86 client platforms like Android, iOS and WebGL.
For that many players and platforms to ever have a chance of working I have to ditch Springs' peer-to-peer synchronisation model and switch to a traditional client-server model. It's worth noting at this point that peer-synced sims have a historical justification due to bandwidth restrictions. Age of Empires was the first game to openly use the technique and it was developed in 1997 when 28.8k modems were still common. Given that a typical internet connection in 2012 is approximately 50-100 times faster than back then I don't believe the bandwidth problem is as critical as it once was.
There's a really good article on the tech here. It includes a quote from an AoE programmer that goes: "A few quick calculations would show that passing even a small set of data about the units, and attempting to update it in real time would severely limit the number of units and objects we could have interacting with the player. Just passing X and Y coordinates, status, action, facing and damage would have limited us to 250 moving units in the game at the most. "
I can see how that was an issue back then but if we assume a conservative 50x speed for DSL vs 28.8K modem then (50 x 250 = 12,500). That means I can theoretically send data for 12.5K units per update and i've yet to see a Spring game come close to that for total units in-game let alone units visible on screen. In short I believe peer-synchronised RTS is a largely obsolete technology due to significant problems with desyncs under different client architectures, languages and compilers (32 vs 64bit, x86 vs ARM, Java vs Obective-C vs C++, VisualStudio vs GCC, etc).
I also plan to increase the time between "frames" by up to 0.5 seconds and let the clients handle animation and tweening in a way that fits their capabilities. That is to say the server will treat the game as turn-based and tile-based but clients are free to disguise this by faking smooth movement and projectile effects between states. The goal here is to recover some of the bandwidth we lost in the switch from peer-sync by removing some precision. In RTS precision and response time are typically not as important as an action game and I intend to exploit that. Players will notice a small delay between giving an order and seeing the correct outcome but in general the game will still appear fluid.
The planned changes are:
- Complete seperation of codebase for server, clients and AI.
- Game simulation to run entirely server-side (x86(64) only).
- Clients send input to server and selectively render game updates based on their capabilities and needs. For example the client could request updates only for the part of the map currently in view. The server only sends updates for units in LOS for efficiency and cheat prevention.
- AI to be implemented as remote clients, not compiled into server. As far as the server knows they are just another player and have the same restrictions with respect to LOS and updates.
- Support for WebGL/Canvas and OpenGL ES2 clients (Mobile)
- Simplification and unification of lobby and autohost protocols
- Reworking of projectile code to minimise update bandwidth
- Non-lua widget support. Clients can implement their own native widgets in whatever language they are written in (eg, Javascript). These widgets communicate to the server using the same protocol as used for player input and AI.
- Remote OpenGL proxy. This will extend the work zerver has done on his GML rendering proxy (for spring-mt) to pass server-side OpenGL calls and assets over the wire to a client.
- Remove FPS unit control. This has always been buggy and crap anyway but it becomes even more unusable when combined with my changes
Obviously there are too many major changes to support existing Spring games directly however I do plan to maintain compatibility wherever it makes sense. Ported games would need to rewrite their widgets as gadgets (or native widgets) and modify some incompatible assets but should otherwise not require a total rewrite.
Once I have a working alpha I'll give the project a name, post code on github and update this thread. This announcement is just a heads-up for anyone interested in collaboration, testing, advice, questions etc.