So, as many of you know, I planned to work on Mythruna this week as full time as possible. I took the week off from work to hopefully work past some of the larger issues that required undivided attention. This turned out to be significant in subtle ways. I wasn't able to work on things as much as I'd hoped but not having the specter of work looming over me from minute to minute has definitely freed my mind to work past some issues.
Last week up through Saturday, I was putting the finishing touches on an Open Source Java library for reading OGEX files. (My project:
https://github.com/Simsilica/jogex, What the heck is OGEX?
http://opengex.org/) This is part 1 of a two part project to smooth the model import pipeline of jMonkeyEngine. I have a lot of model assets I've purchased over the years and getting them into jME is always kind of a pin. I hoped to smooth that process. Anyway, it took me longer than I wanted but at least I was able to get that piece releasable before "Mythruna week".
On Sunday, I attempted to pick up where I left off like six months ago, re: networking. There were at least four (long) text documents I had to read to figure out what the heck I was thinking about before and catch up. This wasn't so much fun, really, but necessary. And I'm glad I'd left such extensive notes because I'd forgotten a lot of stuff. By Sunday evening, I was going through the code I'd written already and trying to relearn what I'd implemented and what was still left to be done. Monday I started back in on the client side trying to figure out where to hook things in.
It cannot be overstated how useful it was to have nothing overly taxing pending. Granted, familial obligations were still there and I had many cases where I ended up running an errand that broke flow. Mostly, when working past these really rough spots, if I'm not 100% motivated then any distraction is a huge one. "Ugh... I'm not sure what to do next with this connector stuff... wonder if anything is new on twitter?" And so on.
The real significance of having enough time is that I didn't feel rushed to push something through. When I only have a 1 hour block to work on something, I feel the pressure when I spin my wheels on design. All of the existing new network code suffered from this greatly. It was over-designed in the wrong direction. When I went to start implementing the actual client-side login piece, I hit the same wall I'd hit six months ago.
Old Mythruna had it easy here. I started by just hacking the client->server connection together and building stuff on top of it. A rudimentary login and account creation was kind of slammed on top of that. No password resets, no multiple characters, no nothing. Client pops open a screen, you enter some stuff, and BAM! you're connected.
New Mythruna did not have this luxury.
The first wrinkle is that the old password scheme was not as secure as it could be. I need to convert everything over to SHA256 instead of MD5. This means that I need to let users login with their old MD5 hashed password and force them to do a password reset. Furthermore, the implication is that some day I might even want to do something better and so on some level this stuff should be plugin-enabled like the rest of the code.
The second wrinkle is that I want to be able to handle Mythruna.com logins. The client has already started allowing logins to Mythruna.com, I just don't do anything with them. The token passing protocol, etc. has been designed for how this will work but it's all brand new. Twist the wrinkle a little more and imagine needing to handle cases where Mythruna.com is down but public servers still want to allow fallback logins or some servers who choose not to authenticate through Mythruna.com at all for some reason.
The bottom line is that this is not straight forward. I had a design and some code that I felt like were elegant when I only got to work on them 1-2 hours at a time. Plugin services that could handle different protocols (legacy MD5 versus new-hotness SHA256) with interception stuff for Mythruna.com logins. It had lots of nice accounty classes and felt plugin-ready and so on. The issue was the ridiculous amount of left-hand/right-hand distant coupling (the left hand can't be sure what the right hand will really do) between the plugin services on the back-end and the UI forms on the client.
If I had a stack of protocol support plugins on the server, I needed a similar stack of protocol forms on the client. These are dynamically loaded about as far from each other as you can get. It was even the impetus for me designing the plugin module deployment system because it made me really uncomfortable how tightly these things had to be coupled while still allowing for dynamic additions. The server sends a list of plugins required and you'd better hope that the client has them, too, or you just won't get any farther.
Late Monday or early Tuesday, I had an epiphany that his since led me to gut all of the account services stuff I'd made before. In it's place, I now have a more general request->response system. Back-end code can send a request for values and the client can choose how it wants to present those to the user... without even really having to understand what they mean. UI gets generated dynamically. This can also be used by regular game code that needs to request something from the user. (That was all kind of hackish before.)
I spent most of Tuesday implementing this and reworking my command line test client to use it. Another round of refactoring earlier today and I was starting to get back to the UI side. It's been going much better.
You can see from the screen shot below that I actually have a real network connection being setup and the server sends over the initial login form. The buttons don't do anything (yet) but the path ahead is way more straight-forward than it has been to date. Things are starting to come together.
I'm not going to lie. I wanted to be past this part by now and implementing networked physics... but really, once the connection has been established all of those other things have very straight-forward approaches to implement them. I'm hopeful that there are no more "requires 3x8 solid hours of thinking" road blocks in the immediate future.
Next will be to finish up login and account creation which is just a matter of finishing hooking up the dynamic UI support. After that, I need to bring over and hook up the rest of the remote world stuff. The entity system is already networked and ready to go but I need to rebootstrap the remote world change events and the remove blueprint database and so on. Hopefully I can get all of that working before my stay-cation is done.
...then physics networking.