The Wait is Finally Over!


This is, essentially, the postmortem to a rewrite of a game prototype.

After wrestling a few-hundred-too-many times with Phaser's lack of a standardized programming pattern (you have to use three patterns to instantiate some objects -- and they don't see the issue if you complain about it) and poor documentation, I went looking for a new engine.  Phaser is what happens when you have too many cooks and not enough oversight in open source (but light-years better than with Flame, I might add, just to poke that Flame beast once more and plug Pogo instead).  Anyway... I landed on Godot because it builds easily to WebAssembly (important) and gives me WebRTC as well.  I thought Godot would also give me a Firebase RTDB plugin but, well, I ended up writing my own Godot Firebase Lite plugin -- which is another story you can find elsewhere.

Now, nearly a year later, I have finally finished the Sendit Soccer rewrite in Godot.  Of course, I didn't work on this full time, but it was still maybe three or four months of work.  Was it worth the switch to Godot?  I think maybe so... but it's really hard to call it right now.  While I don't regret leaving Phaser behind, Godot was such a fight to get the game port working, I can't be sure I'll ever get back the time lost between Phaser and Godot.  Also, the Godot build came out at about 6 times larger than the Phaser build (the minimal Godot custom-web-engine build being about 8 times larger than the sum of the packages I used with Phaser).  If itch.io would implement gzip support for HTML games, I could compress Godot's wasm file small enough to not worry about the size increase.  But, alas, I can't, and I worry about the 9.5 MB overhead being too much.  Too much for my liking, anyway, for a browser game.  Then again, hey, it could have been worse.  It could have been Unity's wasm engine (which, I think, is self-zipped to not make it seem so fat... luckies).

Aside from the Firebase disappointment and subsequent adventure ("Yay! Godot users now have a better Firebase option."), the biggest slice of work with porting to Godot was adapting to their absolutely crazy kinematic character controller.  This was so insanely-maddening of a physics controller it led to me blogging about it here: The Annoying Quirks of Godot’s Kinematic Bodies.  That was definitely the worst thing about Godot... and avoidable if you ignore kinematics and go straight to dynamic rigidbodies (and maybe what I should have done with Sendit Soccer, if I could guess the performance impact of it in a browser).

After that, Godot's inability to refactor classes without throwing dependency errors all over the place, also wasted a stupid amount of time.  You see, Godot won't re-evaluate such class errors unless you reload Godot and/or the project (or you get very lucky with some super-secret mojo-like editor actions).  It should be relatively easy to add more class-evaluation triggers to mitigate most of this... but reading the issue discussions reveals that nobody cares to even try to fix the worst parts of this... because they can't also fix the edge complaints as well.  Whaaaaat!!!!!  They're waiting for a hopeful class system rewrite in Godot 4 instead -- or some excuse like that.  Always waiting for a better Godot.  Sigh.

On the positive side, this rewrite brought about a total rethink on the lobby code and the result puts it in a much better place for filling out the needed features there.  That's a pretty big win.  Also, the annoyances with the kinematics forced me to redo the collisions in a much-more-deliberate/less-lazy way.  As much of a pain as that was (and still is) it should bring about much better performance -- something that might prove critical with a lot of players on the field in a browser-as-a-server (BaaS?) product.  How overall performance compares between Godot and Phaser, I don't know.  I don't immediately know how to test that myself and I don't care to look it up to try right now.  Maybe I just don't want to know.  I can admit that.  I am curious, regardless, in spite of myself.

One other perk with Godot is that it gives an easy route to native builds for Windows and Linux.  (No apologies, but Mac has become too difficult to bother supporting anymore as an indie dev -- use Safari.)

Overall, I'm happy with Godot... but it sure can be a hard beast to love at times.  Hard to contribute to as well with it's 5,491 open issues, onerous reporting expectations, and jerks aplenty.  Expect most things to be swept under the rug.  Perhaps more the fault of open-source circumstance than those involved (aside from the jerks).  For free, however, it's outstanding and I'm hooked!  See ya, Unity.

Photo credit: Tambako The Jaguar - Flickr

Updates

As to the game, this rewrite doesn't bring much in the way of new features.  But, just because, I did add a few.  Godot also helped me break many things.  I eventually worked around most of those, but not all.

I upped the version to 0.3.0 mostly because of the rewrite.  Not features.  Features, however, should start coming quicker now that this big lift is done.

Added

  • Sniper Mode!  In this mode -- which defaults to "on" because, well, what did you think "send it" meant? -- when you "send it," the ball essentially becomes a bullet and knocks down anyone in its way.  It will go through them as well (except for goalkeepers -- it should bounce off the goalkeeper while knocking them down [when I get around to making goalkeepers]).
  • Gamepads are now supported (as well as browsers can support them).
  • Better disconnect handling and notification... maybe.
  • Some super-secret surprise I'll let you discover.

Changed

  • Much nicer menus (with back buttons even!).  "Thanks, Godot, you kicked Unity's butt on this front!"
  • Godot's scripting performance is also somehow really bad compared to JavaScript, so palettizing the sprites takes forever and a day now... so I had to put up a progress bar for it.  You would think that after export to JS and Wasm, this would catch up with JS but... whatever.  I think it is something about Godot's dictionaries.  I should try dumping them for more arrays.
  • Fewer characters allowed for player names due to using a raster font atlas instead of TTFs.  Latin extensions for all of Europe should be included.  A few other interesting characters included.  I may try to add Hangul and the kana next.  We'll see.
  • 22 players max changed to 24 max (just because).
  • Minor art tweaks.

Fixed

  • Certain characters in the name field and/or certain names were bombing connections.
  • Something about tackling.  I forget what exactly.  It was a long haul.

Broke

  • I just noticed (because it only happens on itch.io, not locally) the keyboard doesn't work in full-screen mode UNTIL YOU SCROLL THE MOUSE.  Very weird, Godot.  Very weird.
  • The game window steals all the browser keys, failing to pass them through (and this Godot post was entirely unhelpful regarding that).  This makes sense given how the engine works... but the workaround, if any, should be mentioned somewhere.

TODO next... maybe

  • Harden the networking code to prevent short disconnects from killing the game.
  • Allow a return to the lobby/room.
  • Oh, yeah, update the CHANGELOG.

Files

sendit-soccer.zip Play in browser
Nov 18, 2021

Comments

Log in with itch.io to leave a comment.

Hah, fun rant! I always had trouble understanding where in Phaser's docs to find how to actually do something. And even then, when I did, I could never seem to remember how to do it again later. So it was either back to the docs or back to poking through old codebases - I often preferred the latter. I had always assumed it was me being bad... But glad to hear I'm not alone on being lost in their sea of "stuff."

Congrats on finishing the rewrite! Sounds like a journey. So despite the trouble, Godot is the new goto? As I recall, its object types are all part of an inheritance hierarchy, and even though the visuals may look like Unity components, they're really not components at all. Was that weird to get used to? (assuming my assertion isn't just flat out wrong :p)

(4 edits) (+1)

Hah, "rant" is indeed the correct word.  I hope, at least, that when I rant, I rant constructively (or fun).  To counter my own criticism of Phaser docs a bit, when I was deep in it, I found a startup doc project that was pretty helpful: https://rexrainbow.github.io/phaser3-rex-notes/docs/site/.  It did a much better job of sorting out all the config-object/setter-methods/helper-methods/properties confusion and showing only what you need to know to get something done.  On the other hand, it was also (understandably) focused on so many next-version features it was often misleading.  It could use some version tagging and/or filtering as it evolves.  Thus, I spent a lot of time flipping between it, the official docs, and the examples site.

The one thing I liked about Phaser was its arcade "physics" and how it helped get arcadie movement and collisions up and running quickly(ish).  On the other hand, it just might have been the inconsistent ordering of arguments in the physics function calls that broke the camel's back here (but was probably the inconsistent use of `update()` across objects).

So, yes, "despite the trouble, Godot is the new goto."  My note of caution here is keep in mind that open source may never catch up to some of the commercial products.  Some things in Godot will likely never be as easy to rig up as in Unity and the others (and we both know Unity ain't exactly wonderful to use either).  Particularly in the 3D realm, I hear.  Although, 3.4 made significant improvements there, I also hear.  Simply put, you have to be willing to do more lifting in Godot.  You have to want it more.  A weird statement considering many find it easier than Unity to get started in.  Godot gets naughty quickly when you start reaching for the stars.

As to engineering, I found it more similar to Unity than dissimilar.  Yes, the lingo is weird/unhelpful and throws you off but, really, a "game object" in Unity is loosely a "node" in Godot (game objects and components cross over with scenes and nodes), a "prefab" in Unity is a "scene" in Godot, and a "scene" in Unity is the abstract "owner" scene in Godot (I guess).  Godot appears to be heavily hierarchy oriented, but I found it to be no more or less so than Unity when it comes down to it.  In short, I found the component system to be similar to Unity and found myself making many of the same kinds of decisions as to whether to build something up in the GUI editor or in code.  I lean heavily towards the code side but still split it here and there.  Some tools are very odd and need to be looked up to get.  I found the animation tool onerous for busy sprite sheets and redid those in code instead (with no help from the docs when it comes to exemplifying code workarounds).  Stuff like that pops up here and there.  Also, there is something very wrong with how scenes/nodes and node classes are wired to each other.  I'm not enough of a language engineer to describe what it is, it just doesn't quite grok with me.  It feels wrong, for example, that instancing a scene does not run the _init() constructor in attached classes -- that only a new copy of a class made from code will init it.  I get the data differences, but the diff feels not tangible enough and, thus, unnecessarily confusing.

And, just to throw another wrench into the conversation, Unity would still be the right choice for my other game, GRITS Racing.  The 2D physics in Godot is too simple compared to Box2D, and Godot's package library (while pretty okay) can't yet compete with the pro quality of some Unity packages.  There are some Box2D plugins to Godot but, like I said before, you've got to want them more to use them (I say to someone who writes his own physics regardless).  Some of the other packages I use in GRITS Racing have no replacement in Godot.  But... I'm ready to leave much of that behind in many of my planned projects.