Saturday, February 4, 2012

An example of getting sidetracked...

Today I just would like to give you a small example of how easy it is for me to get sidetracked while developing ADOM II. The underlying reason causing this to happen very often probably is that ADOM II still is pretty raw in many areas compared to ADOM (while in some other areas it already now is so much better). Yesterday the following happened...

I had a couple of minutes of spare time before breakfast. Nothing better to start a day relaxed than by implementing some small addition to ADOM II I thought to myself. Amulets of life saving came to my mind (which still were missing in ADOM II). So things started to happen...

Warning: Technicalities mixed with internals and all kinds of other stuff coming up... I don't know if such ramblings make sense to anyone but me but here you go in any case...
  • I decided to "quickly" add amulets of life saving yesterday morning before breakfast.
  • Implementing the actual amulet was a matter of something like 5 minutes.
  • While doing so I refactored a couple of interfaces for awareness (in that case OnDeathAware) and added another one for the basic event mechanism in ADOM II - which took another 10 minutes or so.
  • Then I tested the new feature, fixed one bug (5 more minutes) and suddenly noticed that the occasional (more) prompt that is inserted into messaging doesn't work as well in ADOM II as in ADOM. The reason for this is the aforementioned awareness/event mechanism. When "something regular" happens the regular time flow in ADOM II quite often can be interrupted by "something else". I'll give you an example: 
The regular combat flow is "attack, maybe hit, maybe damage, print messages in the meantime for each step". Now when damage causes a being to be killed an interrupt occurs and the OnDeathAware awareness is checked to see if anyone or anything is interested in that specific event. When wearing an amulet of life saving said amulet will be interested in your death to prevent it. Usually it will succeed in preventing your death, print some messages and interleave them with (more) prompts for more drama. Now sadly (more) prompts so far are created by synchronous calls to the UI interface (e.g. something like Game.getUserInterface().more()). Now to prevent intermixing messages during combat (the one situation when basically every micro-action could yield something special, e.g. poisoning, paralysis, attribute drain) all non-direct combat action messages are delayed after the main message (e.g. "The goblin attacks you critically hitting... and killing you!") is finished. Which worked nicely up until to the now new more() call mentioned above which is synchronous and thus might yield something like "The goblin attacks you critically hitting ... (more) (more) and killing you! Your amulet glows in a silvery light! You have been resurrected!" instead of "The goblin attacks you critically hitting ... and killing you! (more) Your amulet glows in a silvery light! (more) You have been resurrected!". Woe of a programmer not managing his internal program events correctly.
While pondering a solution I came up with the idea of using a special character sequence in the messages in order to cause the (more) prompt to show up instead of doing that with a separate UI call. E.g. using "Your amulet glows in a silvery light! <<more>>" instead of printing that message and calling Game.getUserInterface().more()(because then the delayed message handling also will cause the (more) prompt to be delayed and everything would be fine).

  • Said and done. I searched for the correct place to add that special token code (which was easy to find)... and then noticed that it would be a great place to pick up an older discussion we had on this bog concerning message types
  • And added message coloring because that was at least as exciting. Messages now can be rated from "very good", "good", "neutral" to "bad" and "very bad" by inserting <<++>>, <<+>>, <<0>>, <<->> and <<-->> into arbitrary message positions leading to coloring in the message display (configurability of the colors will show up in some later ADOM II version). 
  • Again I tested and fixed a couple of bugs.
  • Just to notice that time for breakfast ran out and I now had to hurry (yesterday being in a hotel in Hamburg). 
  • Later in the evening I finished the color implementation and proceeded to fine-tune it.
  • Getting back to the amulets of life saving I noticed that in ADOM they included special handling for the rare situations when the PC dies of old age... so I added that. 
  • Now you need to understand that I am a kind of "top down programmer". I usually write down the high-level code first, using lots of not-yet-existant classes and types when introducing new concepts.
  • Which was the case now... as aging requires something like age categories (e.g. young, old, ancient).
  • So I introduced a new enumeration called AgeCategory to reflect that and wiring up all the required logic.
  • Just when I wanted to proceed to the next level of detail by actually creating and implementing the concept behind AgeCategory I was surprised by the fact that Eclipse told me that said definition already exists in ADOM II. Scratching my head I searched for it... and Eclipse was right. The code stated that I actually implemented AgeCategory at the 3rd of March, 2008... and then forgot about it. Some part of the code was uncommented (which is usually never the case in ADOM II) which in turn indicates that I got sidetracked on said day by something else and never quite finished the concept.
  • The good thing was that that old implementation was much better with what I came up on the spur of the moment yesterday evening and it also is way more robust than what is in good old ADOM. So I was very happy to find that I actually had done a lot of groundwork years ago. 
  • So I finished the aging implementation, finished the special age code in the implementation of amulets of life saving... and noticed that I had not yet tested the new <<more>> code :-)
And that's where I am now several implementation hours later with colored messages and aging having been added to the next version of ADOM II although they are not listed in the DevState to do list but the original problem with the "quick" amulets of life saving implementation and more prompts has not yet been tested (and I have a nagging feeling at the back of my mind that there will be a definite problem with the implementation that I missed when initially thinking about it).

So you might call me a "distracted programmer" - but only when doing ADOM II. Usually I'm very focussed but it's so easy to get excited by some new concept for ADOM II that I can get kind of lost. But now am happy as this will add even more cool features to the next release. The sad thing just being that "the quick addition of amulets of life savings" actually spawned so much new stuff that I get delayed ever more. Oh well, judge for yourself.

I probably just should not try to add "small things" between real periods of work on ADOM II ;-)

12 comments:

  1. Oh man, it is so easy to get side-tracked. I'm just impressed you even remembered how you ended up at the final end. ; )

    ReplyDelete
  2. I think it's great that due to getting sidetracked you end up adding more functionality than planned... although it wouldn't hurt to make new releases so that we can try the new stuff even if not all the functionality planned for the next version is done yet :)

    ReplyDelete
  3. Seems to me the compromise is to set traps for yourself in such a way that the "incidental" sidetracks end up taking you down the paths you moreso "need" to do anyhow. Still, good progress is good progress---how else would surprise elements get underway with each version save from surprising yourself?

    ReplyDelete
  4. I'll probably just go ahead and release an incomplete 0.2.3 pretty soon ;-)

    ReplyDelete
  5. Maybe you should try to use some kind of SCRUM mechanism to prevent this "sidetracking". ;)

    ReplyDelete
  6. Keep up the good work Thomas! I think we all liked the "release early release often" style of yours after untold eons of JADE slumber, but sidetracking can often lead to some new ideas we'd like twice as much!

    ReplyDelete
  7. Fun stuff, but personally, I wish for a GUI whose text area is sufficiently large (or resizable) to eliminate the need for prompts :/

    ReplyDelete
    Replies
    1. Actually you basically can do that - kind of. Just look into the "View" menu at the top of the screen - there you can define the height of the message area. In some cases (when lots of stuff is happening) this still will not work as there is too much text but I like the idea from an earlier blog post about abbreviating combat messages quite a bit (e.g. instead of "The goblin slashes at you with a poisoned curved dagger and critically hits you severely wounding you." the message display also could print something like "g -> @+S" or so. Very different and only for power players but highly efficient as far as space usage goes. Might be an interesting option.

      Delete
  8. You almost talk about being sidetracked as if it's a bad thing, but now we've got age categorys working, and the wording in messages cleared up - and all we were going to do was add an extra amulet! You should get sidetracked more often!

    ReplyDelete
  9. If sidetracking means you add stuff to ADOM II and enjoy the process, then I don't see any issues with that...
    I'm impressed you're consistent enough with your variable/class etc naming that you'd come up with precisely the same name for the same property, 4 years apart! I frequently forget what I've called something on the same day.

    ReplyDelete
    Replies
    1. Yeah, no kidding :) If it had been me in Thomas's place, there would now be two implementations of age categories in the code. One ad-hoc and in-use, the other better designed, but forgotten.

      Delete