You excel at Transfiguration. One of the most
dificult classes, you seem to be a natural at
turning a coke bottle into a homework pass.
Which Class at Hogwarts Would You Excel at?
brought to you by Quizilla
Mood: amused
Music: Bad Religion - Sorrow
Welcome to the latest incarnation of my website.
The Unreal Engine renders beautiful scenery, although I had to turn some visual details down to get a consistently high framerate (on my P4 1.6ghz, 512mb RAM, GeForce 4 Ti 4200 128mb). Some of the levels are really, really pretty - and really pretty big! The Unreal engine's handling of outdoor areas continued to impress, although it is still obvious that tricks are used to ensure that you can never see too far away (occlusion culling keeping framerates high); on the few levels where this isn't the case, framerate stutters. Sound quality is crisp (despite awful voice acting!), especially the music which is excellent (the intro music really made me want to play Deus Ex!). Control is reasonably sharp, but has the 'slightly squishy' feel that dogged Unreal 2 (but not the original UT); it is less like QuakeWorld's fast turns and tight air control, which is more realistic but also more frustrating.
The game itself is a mixed bag. Double domination (like Domination from the original UT, but tweaked) and Bombing Run (basically rugby with guns; it reminds me a lot of Urban Brawl from Shadowrun!) are both great, CTF is decent, and deathmatch isn't bad - but the squishy controls prevent it from feeling great. The instant action mode is nice. League play feels like a bad attempt to squash EA Games style management into an FPS; if the bot personalities were a bit more differentiated, it might be worthwhile. As it is, they universally suck - so it really doesn't matter who is on your team. In one Bombing Run game, neither side's bots ever actually found the ball!
Map design is mixed. All the maps are beautiful, but there are fewer 'flavour' maps than in the original UT; no ships, flying fortresses, or low gravity maps (at least that I've found so far). Maps instead focus on being balanced. This leads to solid, predictable games; fun, but not as fun as flying around a low gravity parking lot!
Weapons are a very mixed bag. The bio-rifle is back (ugh). The flak-cannon has a slightly less spammy spread than the original UT, but is still nice. The shock rifle is about the same as before, albeit slower moving (MUCH easier to perform combos!). The sniper rifle has been replaced with the lightning gun, the single most stupid weapon ever: its zoom is slow, it has a recharge time, and it looks goofy. It also seems to require less precision than the old sniper rifle, while having a little lead time on firing. So you are more likely to hit, but less likely to get a headshot. Sadly, a lone sniper can no longer hold a base in CTF!
Overall, this game would be good for $20, but isn't worth full price. It is a really hard product to place; it is heavily tournament oriented, quite balance obsessed - but lacking much required skill to make yourself noticed (lots of spammy weapons, reduced emphasis on headshots!). Epic have announced that UT2004 is coming out - maybe it'll be better!
Mood: geeky
Music: Ozzy Osbourne: Crazy Train
find . -type f xargs sed -i.bak "s/oldtext/newtext/g"
Mood: busy
Music: Sisters of Mercy: I Was Wrong
I did some searching around for other object-relational systems for .NET, preferably a lot more advanced than mine - considering only free software (both as in beer and as in speech). I found two on SourceForge. NHybernate appears to be a dead project, largely because the designers tried to copy a mature Java project class-by-class, rather than realising that the .Net Framework and Java libs work very differently in some cases. It does serve as a great example of database-agnosticism, though. (Hibernate for Java appears to be a pretty impressive ORM system, although I think that I might get angry using it; it tries to abstract away all of the little databasey details such as when to cache and when to commit to disk!). A more promising contender - at least in that it is still alive - is OBJ.NET. This is based on OJB/Java, part of Apache. It exhibits some very nice design, including transactionality (with explicit commit), not saving until you mark an object as dirty, and cacheing. It also features some horrible database code (OLE.net only!), but the developers say this is due for fixing in a later release (it is still very pre-alpha). The XML mapping between tables and classes isn't bad, but it looks like it might add a bit more overhead than I would like. Definitely a project to watch!
This got me thinking about ORM in general. It seems to me that in a traditional n-tier system, several tiers are all struggling to gold-plate their job and take over - and fuzzy thinking has allowed this to happen. Looking at a typical 3-tier system:
The 3-tier model above makes a great deal of sense. It separates out three very different types of problem. So far, so good. Unfortunately, vendors just don't get it - and seem to be working pretty hard to make it easy to break this mold. For example:
All of the above problems can be avoided by avoiding fuzzy thinking, and applying some discipline to development. Everyone has made at least one of these errors (myself included), and it is really easy to make them over and over. Vendors screaming and shouting about their latest solution to a nonexistant problem (ie. a way to break a rational system by offering shortcuts) certainly don't help. (The general disdain for applying scientific method to business computing doesn't help, either!)
What seems to be needed is an easy way to create formally-correct tiers from a logically-correct data representation. Ideally, I would be able to create a logical representation of the data I wish to store - and it would be created in an RDBMS (with full integrity constraints), skeleton object mapping code would be created for the business logic tier, and an easy way to expose objects to apps would be presented to me. Oh, and if the database changes - as we add more requirements (reqs. are never static in the real world!), I want it to update the framework without (substantially) breaking higher levels of the system. I can do all of this with separate tools and much time/effort - why isn't there a one-stop-shop, yet? Am I asking too much?
Mood: restless
Music: Robert Plant - Tie Dye On The Highway
Today has, thus far, been somewhat less useful. Our CenturyTel connection was flaking badly this morning. Received mail was working fine (it automagically uses the other connection as needed), but not being able to deliver to remote servers had the Charizard queue growing by several hundred messages an hour. Fun! Anyway, by the time I'd failed everything over to the Tranquility connection, CenturyTel were fine again. Grrr.
Anyway, I learned a bit from this. No matter how nice your automated ping-failure detection, sometimes errors don't show up in ping times. DNS-based failover is nifty - with the right TTLs, you can keep downtime down to minutes rather than hours; combine with MRTG graphs, and you can see success/failure in near-real-time, too. Nifty. Also, DNS_Balance, by Hiroshi Yukota is sweet. x.farm.tsghelp.com redirects to a copy of Balance, which dynamically replies with either of our connections based upon a simple text file. That file is trivial to update (I'm working on scripts to do it automatically), and traffic gets directed as needed. Nice and simple, and its in Ruby so no buffer overruns!
My TSG database programming continues apace. Last night, I validated by LightWeightList design - it is MUCH quicker than DataSets, which is good. I should have a somewhat-working prototype soon.
Also, SqWebmail is a great product - fast and lightweight, but butt ugly. My new mission is to make it look prettier!
Mood: hungry
Music: New Model Army - Ballad of Bodmin Pill
The last 12 hours or so have been strange. After sweltering my way through a long day in an un-airconditioned office, I headed to Sonic with Kris. Last time I ate at Sonic I was really sick - so this time I avoided anything cheese-like, and survived! Pancake on a stick is definitely an oddity - take a regular sausage, wrap pancake around it, and deep-fry; the result is then dipped in syrup. Whacky, but tasty.
After Sonic, we headed to Wal-Mart, bought some acrylic paint, and headed out to John's house to paint Warhammer figures. On the way, the Red Peril (Kris' cellphone) goes off - and Eric "Gustav" Johnson is on the line! He went missing three years ago, and had been successfully avoiding every effort at finding him - and now he's back in circulation, and on his way to CoMo! So, we sat down and painted figures - my Dark Angels don't suck quite as much as they could, but they are definitely testament to my failing eyesight. Ah well, at least they look angry! Kris did a really nice job on most of her Dark Eldar. Towards the end of the evening, she went off to find Gustav, and I went to bed.
Sleep was very poor: Boda the Hamster was at her noisiest, knocking stuff over, dancing, making her wheel squeak, etc. - definitely enough to keep me awake! On top of that, I never sleep well with strange people in the appartment; for some reason, my system just won't rest until the second or third time someone has slept over.
Around 8 this morning, my Mother called my cellphone to let me know that the Twiglet Zone has now encompassed Glasgow - or at least the Student Loans Company. Everyone's least favourite quango has apparently completely forgotten that I have an address (to which they have written many times, and from which I have responded many times!), and instead decided to send mail to my mother - even though noone ever gave them her name, let alone her address! For some reason, they are sending me a collection letter - even though I filled in my deferral forms, etc. Wankers. I'll call them later today.
Mood: confused
Music: Incubus Succubus - Pagan Born
Friday (July 4th) was a mixed bag. It was hot during the day, as well as being really humid - so we lurked and watched Buffy for much of the day. Kris' Mom took us out for Mexican early afternoon, and I really enjoyed a Mexican ommlette (it made me very full, too!). Later on, Judy came over and we ate ribs, chicken, coleslaw and beans. The food tasted great, but was really greasy - so I couldn't eat very much, and it repeated for much of the night! Judy was talking a lot about her online gaming/chatting habit; I was overcome by a sense of dread as she started talking about how someone else she new could "make emotes in chat". Poor Kris was bristling, ready for the strike even more than I was. Finally, she asks "can you emote?" Ignoring the temptation to demonstate how bad I am at drama emoting (although my face is stretchy!), I tried to narrow the scope. Eventually, it turns out that in Yahoo! chat there is a method of emoting (that is, producing text along the lines of "Herbert strangles the stupid end user"), but it confuses Judy. Judy complained that when she examined it it was all gobbledegook, with thinks like "left bracket font right bracket some text left bracket" - stuff, and I quote, that nobody can read. (I write this in raw HTML, for the record!) :-)
Anyway, our brush with end users and an overdose of food hadn't left Kris or I in the greatest of moods. After more Buffy (waiting for darkness), we headed out to Rittle Bridge to set off fireworks. Kris's Mom brought along a lawn chair, and things should have been great... in fact, they started out pretty well, with lots of neat explosions, pretty lights and similar. Unfortunately, people started showing up - first a Sheriff (who was really nice!), and then some people making drug deals. Not good! We headed for the hills - and ended up in Walmart. As Kris pointed out in her blog, long periods of time in Wal-Mart are bad for me. General Waynesville-inspired-twitchiness, repeating food, horrid Wal-Mart light and an alarm that kept going off had me pretty close to the end of my tether. Nobody died, but I'm sure that I wasn't great company. :-(
After Wal-Mart, we went home, and went to bed. I slept surprisingly well until about 8am, at which point the dogs made sleep difficult by getting excited about, well anything, really. Not long after we got up, we drove home - a nice, uneventful drive. After that: a nap!
This afternoon, I've been experimenting with some C# programming. My programming has had two focusses: .Net remoting using semi-persistent objects with a PostgreSQL back-end, and creating a Windows Service.
Remoting with PostgreSQL Persistance
I was really torn as to how to approach this, and there isn't as much literature around on the topic as I would have liked. Remoting itself is easy: you build a marshalling object, make it available as a channel (using TCP binary channels, since I don't need webservices) and ensure that any object I send over the wire is easily serializable - about 5 lines of code on the server-side, and 2 (more if you want to tweak options, particularly for performance) on the client. Really, really sweet! The difficulty comes with deciding how to persist data. The options I could see were: (a) simply stream objects to a datastore, (b) write objects that match the back-end with load/store/storenew methods per object, and (c) the Broker/Controller model in which I stream DataSet and similar data types with all logic controlled from a Broker object on the server side. There are advantages/disadvantages to all three. (a) suffers from versioning issues - if the objects change substantially between versions, I have to figure out how to get the data out of the old binary format and into the new one. Ick. Even with XML transforms, that sucks - so i didn't go that route! (c) is what I tried with the last incarnation of the TSG Office Assistant; it works very well, but it is ugly, and I'm not sure I like having to rewrite huge chunks of code when the storage-tier changes. Also, DataSets are heavy, and DataSet updating proved to be less reliable than one would like; so I'm not pursuing (c) this time around. (b) suffers from creating a lot of objects, leading to heap fragmentation - and potentially poor performance under some circumstances. It also lends itself to elegant code; I greatly prefer having classes for each data item derived from an abstract class (forcing me to implement GetID/Store/Load/StoreNew, and adding serialization automagically). This is also the most OOP approach. So far, performance is good, the code is elegant (although I dislike writing all of the INSERT/UPDATE/SELECT queries and parsing necessary!). I'm thinking of adding unit tests into the mix, as opposed to broad testing. More on that in another update, when I've tried it!
Windows Services in C#
I always hated writing services (that is, processes that show up in Admin Tools->Services) in MFC/C++ - it was clunky and horrible! .Net has streamlined this process a lot, although it still isn't as easy as I'd like. The Windows Service Wizard creates the basic structure very nicely, but it completely skips the need for an Installer class - leading to services that work but cannot be installed/used without additional programming. Fortunately, I found some tutorials (via Google) that helped me figure this out. It is also clunky having to install services via the command line, and then attach to them for debugging - but it could be worse. I guess having service installation/uninstallation in the GUI could cause more problems than its worse - getting rid of rogue services in the registry is no fun at all.
On the upside, a windows service makes a great remote channel host - and performance is noticably better than a console based server.
Mood: curious
Music: Incubus Succubus: Goblin Jig