The prize for having a clean environment (not merely code, nor even limited to code) is refinement of precisely the most intellectually pleasing sort: getting to uncover and solve interesting as opposed to tedious problems. In other words and as far as I can tell from direct experience, even coding really doesn't have to be at all "like plumbing" if the sewers are properly cleaned and it doesn't have to be sterile either if the willfully blind focus on idealia is discarded. In a reasonably clean - not perfect, nor even "best possible" - codebase1, there is both space for experimentation (aka introducing new things) and support for refining existing solutions. Arguably, there is even space and support for literate collaboration but this does tend to grow more slowly being as it is a fully organic culture in its own right. There is time, there always is... until there isn't.
The most recent concrete example of what made for me quite an interesting problem brings together knowledge representation, data caching, remote synchronisation over a lossy channel and even matters of time representation across different contexts. Then again, arguably one's problems can only get as interesting as one is able to make them to start with so perhaps it's all tailor-made indeed. Either way, I'm neither boasting nor complaining, merely describing so here's an attempt to sketch out the problem in its context:
- The game's client has to obtain, maintain and represent (including graphically but not only in such form) as accurately as possible the knowledge of the game's world as accessible to the player and as it continuously changes as a result of the player's own actions and as a result of others' actions or even simply the passage of time. In all cases, the actual changes are not known upfront nor automatically obtained - while the server decides at all times what and how is in the game's world, it's entirely up to the client to *ask* for whatever it wants, whenever it considers it needs it. Quite on purpose, there is no information pushed from the server to the client at any time and although all questions receive an answer, there is no guarantee that all answers make it back to the client in any given timeframe or even at all. Hence, the problem here is to find an effective way to find out as quickly as possible all that is new but also, arguably even more difficult, what has become obsolete! And possibly the most difficult part here is to even define what "quickly" means since there are at least several definitions of time itself in this context: the user's own time, the time in the game, the time as kept by the client, the time as kept by the server. What does "quickly enough" mean and when is something "too old" or even obsolete? What is the meaning of "1 second" in the game-world, what is its meaning on the network and how does one reconcile these two?
- The communication protocol defines the rules for a hierarchical structure that provides effectively the support for representing all the knowledge mentioned above but this structure is an ever-evolving one and with no specific limits to either depth or breadth at any given time, beyond a basic "it's always finite" guarantee. Moreover, any request comes with a cost and that's not even limited to time - arguably the resulting traffic is costlier, both as it *is* going to be included in the bill the user pays in one form or another (most likely directly wired into game mechanics) and as it can easily have undesired consequences clogging the client's communication pipe for instance or even... triggering undesired changes because yes, in some cases, merely asking for something means that something will change2. Hence, the direct, brute-force approach of "explore the whole knowledge tree at regular intervals" is not much of a solution to anything or not a long-term one, at any rate. And if one doesn't explore the whole of it then how does one figure out the holes in one's knowledge, those things one doesn't even know yet one doesn't know?
- The desired graphical user interaction (GUI) clientside adds some potential troubles of its own since it's quite difficult to provide meaningful immediate feedback to an action when its actual results require in the best case a confirmation from the server (when guessed correctly) and in the worst case a search for and figuring out of how the world changed (when the guess is merely incomplete perhaps, although it can even turn out to be entirely wrong). Sure, one can *hide* this and pretend that everything is known upfront, arguably making it thus more convenient or something of the sort but pretense aside, the reality of it is simply that the GUI is at best twice-removed from reality and as such always kind of struggling behind: the reality it can directly access is at best a local cache and that cache is in turn at best a fragment (perhaps already obsolete in places) of the remote world that is at all times on the server and ever evolving even there3. So how can the GUI be as truthful and responsive as possible when providing the user with a representation of the game's world, without limiting them either? Because the whole point of a GUI is to enable, after all and moreover, the game itself is quite on purpose as open as possible - the scope of what one can do depends on what they have already done, not on some predefined and fixed laundry list that some uppity GUI takes upon itself to enforce on behalf of the server.
The above is the overall shape of the problem and as complex or "that's not how these things are done" as it may sound, the core of it is already solved and working in practice. What still remains to be done, is really the refinement of this core of a solution. How interesting and rewarding such refinement turns out to be or not depends mostly on the person asking and working on it, as always.
As for myself, I certainly have even more interesting problems to solve on the serverside so I don't particularly intend to pursue more than absolutely needed anything clientside. The client is open source after all and it will only ever be as good or fit for your own purposes as you make it to be. Does this sound like a downside or an upside to you?
It's always improving though and the cleanliness really has to do with how supportive of improvements it is, not really with some perfection or best anything. First of all, lots of requirements, constraints and even actual extent of the problems to solve got clearer only with practice and the corresponding code reflects this. Second, I learnt a lot in the process too and this also shows - yes, the 2nd time one does something it will probably be better done than their 1st and the 100th time even better than that. Cleanliness though doesn't mean nor require skipping the first step nor the first 99 - that's just a way to get stuck and it's still silly even if very common - but simply creating that path that enables all the steps that may still come. So no, there wasn't nor is there some perfect anything, code included, to be "fully solved" or achieved in some entirely ideal form and then either worshipped or blown to pieces, depending on inclination. There's only sustainable growth, gathering up momentum and opening up new possibilities as it evolves, that's the best possible meaning of clean - it enables the growth of new animals and plants, not that of new fungi. ↩
Does it ring a bell, at all? ↩
Are you *sure* that this is all that different from the actual "reality" of what you see with your own eyes even when no computers nor games are involved as such? ↩
Comments feed: RSS 2.0