Random thoughts again

I feel like writing another blog post, has been a while. But I don’t have anything interesting about .Net to put up today.

So, to a completely different topic. I play LOTRO, in fact maybe that is why I haven’t had much to blog about recently… One of the developers ‘Orion’ has been posting a blog in which he details his daily work on reworking an existing area of the game. This blog has received a lot of comments, and I think that the general idea is good for player relations.
However in his latest blog post he decided to take some time out to respond to one of the comments claiming that devs ignore the players. As a personal time game developer for an old text based MMORPG, I have been exposed to a lot of player requests, and seen this complaint plenty of times. But Orion’s response surprised me in some ways. Specifically I don’t think he put enough emphasis on what I think is the most important part of being a game developer, which is interpretation.
When a player complains ‘a’ is too hard. That may be a decent complaint, although there are a bunch of people who aren’t complaining because they don’t find it too hard… But the problem can be solved to satisfy both parties. (Sort of… More on that later…) However player complaints can often be more like ‘you should change this to be like that’, they go further than just identifying the issue and start offering solutions. The problem now is that if you don’t do exactly what they say you aren’t listening to the playerbase, in their eyes. As a game developer you may receive 18 ways to address an issue – they will often be conflicting with each other, they will often result in there being no actual challenge left in the game. This last point I think is one which is very important, players often ask for stuff without realising that if they get given it, the net result will be a game which will bore them. It is a game developers job to interpret all of these factors and try to come up with compromises and solutions which keep the masses both feeling respected and entertained. This is really quite a challenging job and I think Orion should have made a bigger deal of it. The customer is not always right, but the customer does always have a point…

One of the ways in which LOTRO attempted to produce a compromise which produced a lot of negative feedback in public forums (although ultimately public forums are often the vocal minority…) is the concept of having two ways to do a piece of game play, one as an ‘easy’ mode and another as a ‘hard’ mode. Although they are trying to rename those as normal and challenge, I imagine the initial naming will be hard to get rid of in peoples minds.
I think that this is a pretty good idea – certainly has the potential to be divisive, but in general the concept is sound. The problems come in the rewards. There is a decent section of the playerbase of a MMORPG which is equipment centric, and if you make it so the only way to get a certain piece of gear (which is above normal standards) is through a challenge mode, you have caused a problem. Because the section of the playerbase which is gear centric and the section of the playerbase which is very good at playing, are not the same. So in the process of trying to satisfy the high end and average groups separately, you’ve take a section of the average group and failed to solve the problem for them.
So the trick here comes in working out what rewards you can give out without causing community division. I am thinking bragging right rewards (titles, housing items – useless in all ways except for bragging), and items which are obtainable from other locations. But if the items are obtainable from other locations why would you ever do the challenge mode more than the number of times required to get your bragging rights. I think the answer here lies in the quantity of the rewards (as opposed to the quality). If you make doing challenge tasks give out frequently used consumables in quantities which give a significant benefit in terms of time taken vs amount required compared to other non-challenge task options – people will keep doing them. Or if you make rare drops noticibly more common when challenge mode is completed. Letting people save time by doing things the hard way is the traditional rpg trade off, and I think should be perceived as generally acceptable.
When book 8 first dropped one of the bugs which many people noticed was that ‘normal’ mode was dropping the tokens for the good gear – and initially I thought yeap that’s a bug, because it didn’t match with their previous gear drop strategy of being only from ‘hard’ mode. Now I think this bug is actually the first step on the right way to do things. They just need to significantly improve the quantity of hard mode rewards, since they are currently very very boring.
(Hopefully none of my fellow ‘hardcore’ raiding kinship members read this, because they’re more likely to be in the small minority of players which think there should be truely awesome equipment which is only obtainable by being elite players – heh even I think that, I just don’t think its the right way to run the game… ahh self inconsistency…)

In other news one of my fellow workmates came up to me the other day and said ‘you’re famous’. I instantly had to wonder why – had I broken some code in some spectacular way… Or had he found me on the internet… why would he have found me on the internet was the next idea in my head – there are a number of avenues which can result in finding me on the internet (physics competitions/programming competitions/game development/my university web page/open source mailing list archives…). But no, he had just done a google search for WindowsIdentity and IDisposable and this blog was the top result.

Random thoughts

Thought I would post something, since it has been a while.

Looking forward to .Net 4/c# 4 news next week with the PDC. Session notes make it sound like BigInteger will be going mainstream so I can remove my dodgy reflection hack from TMD.Algo in the future.

Been doing some code cleanup at work for a couple of days as a change of pace and learnt a thing or two about fxcop – finally discovered what Gendarme is. (I’ve seen it mentioned on the mono mailing lists but I never really paid attention.)

I also discovered MoonWalker, which sounds excellent if it has an acceptible running speed and can be applied to real apps. (Although it would be extra cool if it had inner knowledge of SQL database lock acquisition which is caused by .Net code so it could diagnose mutual .Net/SQL deadlocks. I can always dream.) I haven’t tried it out yet.

Applying fxcop rules to old code is somewhat of an exercise in frustration, so many style issues are recognized which you can’t fix because they are breaking changes. And other rules fail so often you just don’t have the time to fix them all. Anything to do with naming has alot of false positives so we can throw those out quickly, and there are a few rules which are very dubious (Avoid unneeded assignments I am looking at you), but even after you pull all those away there is still usually way more than you can fix in a reasonable timespan.

FxCop 1.36 is definitely an improvement over 1.35 – much lower false positive rate. But there are a few rules which have gone away (admitedly false positive causing ones) which were really nice. Validate arguments to public functions is a really good rule, if only it didn’t give false positives everywhere. Another one which is gone is Dispose of objects before they leave scope. I haven’t seen many false positives from it but it is gone, along with ensure base.Dispose is called.

Rules for implementing dispose correctly are quite numerous so you get to learn them well and I think they are mostly pretty good – however I have run in to a fairly common scenario where my friends and I think they are wrong.
If you have a class which is only used as a singleton instance exposed via an Instance property, and that class maintains disposable objects, the rules state that the class needs to implement IDisposable. However if you implement IDisposable, you tempt users of your Instance property to call Dispose, which is bad. Additionally, Dispose will never be called because singleton is never torn down.
If the singleton manages unmanaged resources, then you need a finalizer, but you still don’t need Dispose.
An alternative in many cases is to have written the class as a static class in the first place, rather than go with the singleton pattern. But thats a whole different argument right there.

Globalization rules also crop up pretty frequently, and at first I thought fixing them in old code was way too high a cost to benifit ratio. But then I actually started to run in to scenarios which would have been caught by fixing the issues raised by these rules. Things like times in Itallian using . instead of : as the time separator.
But one thing which came to my attention is how frequently string.Format is used instead of string.Concat, in scenarios where string.Concat is really the better option. If you are joining strings which are localized, string.Format is the way because the grammar in each language is different, but if you are joining togeather strings for some custom logging, or in those cases where dynamic sql/javascript can’t be avoided, you often aren’t really formating, just concating.

One final thing – DataTable/DataSet.Locale – a property I never knew existed or would have thought to even look for if it wasn’t for FxCop. Now that I know it exists, I begin to think that maybe I will find a whole lot more places which should have a locale property if I go and look for them.

Anyway, thats all I have on the top of my head for tonight.

My UPS works… (sorta)

Shame the ISP connection dropped out.

I have 3 UPS for 4 computers, 2 monitors, a switch and an adsl modem (and a phone).

The alarms woke me up just after 4 this morning, although it appears that one of the UPS had already failed before I was awake.
I run a text based online role playing game server on one of the computers (which was connected to a UPS which hadn’t failed), so I logged in to warn everyone that the power was out, but no one was there because the adsl connection had been out for 2 minutes.

Shut everything down, but in the dark I couldn’t see where to turn the main UPS off.
Went back to sleep and an bit more than an hour later, the main UPS alarm was still going. It was light enough to see a bit then, so I could finally turn it off.

7am, power was still out so I went to work. Guess my text based MORPG won’t be back up online until I get home this afternoon. Looking at an 11 hour outage, which I think is as long as all outages combined since I last moved house.

Update: GCJ

Finalized results are out – 139th for me.

The third question would of gotten me 87th and finally 37 points was above the cut off.

In a moment of inspiration, I realised that my solution to the 3rd problem would have solved both the small and the hard, which would have gotten me through.

However, it fails to produce the correct result, even though it runs in time. I guess there is another bug in my ternary search.

Successful Fail

I came 143rd (out of 180 in the APAC).

With 2 minutes to go I started running my code for a test case which if it had passed, would have gotten me ~80th. However I was running debug code, with the debugger attached!
A couple of minutes after the comp finished, my code finished running.

Additionally, I was about a couple of minutes of coding away from getting out the first problem, which would have gotten me ~38th position. Which was close to the cutoff for 36th. Poor concentration during the early part of the comp on my part explains why I failed to see the last little bit until just after the competition.

However, I plan to keep working on TMD.Algo (which was practically no help in todays competition, of course) and hopefully next year I’ll get to those finals. (Although my best is still 2005, I’m not getting any younger…)

Stuff I’ve done in the past

I just realised that this site has no links to all the software I keep on it.

My old sudoku solver. Its not all that special… but it can print out its logic for most puzzles, so you can sometimes learn new things from it.

My raytracer. It uses TAL files which were defined in the University of Sydney computer graphics class. Although it supports a few custom extensions so it can do pictures like this.

My LoopDeLoop game. It is a generic implementation of the LoopDeLoop/Slitherlink/Kwontom loops puzzle game. It has a multiplayer mode and support for non-standard grids.

My AppleHunt game. This is a game I came up with at random which is kind of fun. The solver in it is unfortunately brute force, so it has a pretty limited range when it comes to generating puzzles.

My LOTRO chat log text to speech program. Seems someone had a similar idea with the same name so this will be renamed shortly…

Google Code Jam 08

So, its been a couple of years since I last entered the google code jam. Back in 05 I came ~120th, and after a few cancelations it almost looked like I was going to go to the finals.

This year however the google code jam has been run in a dramatically different format. No longer powered by top coder, everyone runs their code on their own machines. This lets google’s site scale alot better, although it does add to the overhead of cheat detection.

Also new this year are regional finals. The top 500 competing at a ‘nearby’ google office before the real finals in the US.

So in a couple of weeks I will be at Google Sydney competing to be in the top 20% in APAC, so I can go to the US. I am unsure if this will be tougher then top 100 world wide, but at least the competition won’t be at 2am like the last two rounds before it. Still, there are alot of tough competitors in the APAC region.

I do have an incentive though, a friend of mine recently had his internet company bought by Google and he is working for YouTube now. He has offered a game of frisbee golf if I make it over there.

They offer job interviews to a subset of the people going. I was offered one but I turned it down. Several people have already commented that I am crazy for doing so. Maybe I am crazy because I personally can’t think what I would do at Google.

Finally however, GCJ 08 terms and conditions allow for the downloading of publically available libraries to assist in the writing of solutions during the competition. Specifically any library used must be available to all other contestants as well.

I have started work on such a library tailor made for algorithm competitions, and over the next couple of weeks intend to release it under a BSD or equivelent license via this website. The library will be for .Net and I am going to target .Net 3.5 as VS2008 is available at the competition.

For starters, any data structure in CLR’s Introduction To Algorithms, which is not in the .Net base libraries, I intend to implement. Additionally any specific algorithm which can be generalized from this book I also intend to provide. I am going to see if extension methods can be applied to delegates, because I think that would be a nice way to write ternary/binary searches for minimum/thresholds.

I currently have an implementation of IList which is backed by a red-black tree for log(n) indexed inserts. I also have another one which tracks the sum of all elements of the list prior to the current one efficiently (Specifically, it is actually generalized based on delegates for ‘addition’ and ‘subtraction’, so as long as the operator in question can be ‘undone’ it can be any accumulating operation).

If I have time, I am going to investigate implementing ‘flattened’ versions of these data structures, which store indexes into an array of nodes and maintain a free list, rather than allocating the nodes directly on the heap and using pointers. This technique usually results in a performance improvement, especialy in a garbage collected runtime. Additionally, if the array is expanded using the standard List expansion logic, the amortized additional costs on inserts are O(1). There is a memory penalty, although on a 64bit OS, with a limitation of 2^32 nodes in the collection, the memory penalty is significantly lower due to using ints instead of 64bit pointers. I am interested to see how a flattened linked list compares to the .Net runtimes built-in linked list.

Free Will and Magic

I was recently reading a few New Scientist articles and reader letters on the topic of Free Will and Consciousness. Always a popular topic which I usually file in the ‘why do I care’ basket. However my mind wandered to Arthur C Clarke’s third law of prediction ‘Any sufficiently advanced technology is indistinguishable from magic.’

Having thought of this I came up with a few statements of my own.

  1. Any sufficiently advanced recursive analysis system is indistinguishable from a conscious system.
  2. Any sufficiently advanced recursive analysis system with a blindfold layer is indistinguishable from a system with Free Will.
  3. Any sufficiently advanced recursive analysis system with an internal random source is indistinguishable from a system with Free Will.

I should probably explain the concept of a blindfold layer. A blindfold layer is a part of the analysis system which only provides inputs to the rest of the system, it is not recursivley linked. This means that the consciousness which comes from recursive analysis cannot see what is happening in this additional section of input.

2 and 3 are linked via ‘Any sufficiently complicated chaotic system is indistinguishable from randomness’.

Finally, I conclude from my thoughts of the above postulates that ‘Any system of free will which is not based on 2 or 3 involves data sources which are neither random nor deterministic.’

So umm… yeah.