Thursday, April 16, 2009

Extreme Refactoring and Java/Flex DTOs

I have this bad (or good, depending on your point of view) habit - I mercilessly refactor things.

I am a little squeamish about it sometimes, but usually I don't have any problems just completely breaking something I am working on. Over the many years I have been doing this, I've gotten quite adept at putting all the pieces back together again.

The only problem is when it's something you've put off too damn long, like I did with this one. Here's the situation.

Capo's server backend uses Hibernate for its data persistence. However, these can't be passed to the Flex client, because they're usually not complete objects - serializing them as is just causes either breakage (db session problems) or WAY too much data sent.

Plus, the backend needs to have access to data that the clients will never see.

The solution to this is the DTO (Data Transfer Object) pattern - basically you mirror your Hibernate VO (Value Object) with a DTO, omitting the data you don't want to transfer to the client. You can even (as I have done) have Factories that construct the DTO dependent on who is asking for it (ie, omitting information that one player might not know about).

Once you've got this DTO assembled, you simply serialize it to the Flex client and due to the magic involved in BlazeDS, it fills in an instance of the DTOs mirror class in AS3 (which you've had to create, of course.) There's an additional complication if you use the Externalizable interface in Java (IExternalizable in Actionscript 3) like I do to customize your serialization, as you have to write the readExternal() and writeExternal() methods on both sides. FUN!

Now, the problem with this is when you get really crazy amounts of classes. At my last count, I have 76 or so. And until last week they were all manually created, and it was a horror show.

So, last week I finally bit the bullet and wrote a code generator. There's several out there already, but none of them did what I required.

So now, here's my process:

  • Generate the Hibernate XML, adding meta data on specific fields like "DTO.optional" to tell the later steps that this object is not always there, or "DTO.fulldata" to indicate that this data is passed as a full object, rather than just a reference to an object (its id)

  • Generate the Hibernate VOs via an Ant script and the Hibernate Tools plugin

  • Use my spiffy new code generator, which generates both base and concrete classes for the DTOs on both sides - this is the "Generation Gap" pattern, where you have a base class that is regenerated often and thus is never human edited, and a derived class where you put all of the custom code. Very helpful.

  • Now, after changes on the server side, Eclipse builds the DTOs automatically for both sides, leaving out regenerating the derived classes if they already exist (thus leaving your custom code alone.)

    Of course, you can imagine the chaos this causes when after nearly 4 months of hardcore development you replace the base data classes. After about 3 days of mind-numbing bug fixing, I've got it down to almost 0 errors and now it's time to start finding the runtime bugs, instead of the just the compiler errors.

    So, the takeaway: Do your tools first. I avoided doing this because I thought doing it manually would be manageable.. If I had spent the 3-4 days at the beginning instead of right now, it would have been way smoother.

    Friday, March 13, 2009

    The Runaway TODO List

    Since Capo (my current project) is a one-man with contractor project at the moment, I've been going pretty old school in my project planning.

    A poster on the forums recommended a piece of software I love, years ago now - TODOList by Abstract Spoon Software. It's a basic piece of .NET software that allows you to make a hierarchical tree list, and most importantly for me, is very customizable.

    I have mine set to be quite simple - prioritized entries, with completed entries crossed out AND ghosted. Occasionally I'll even "Archive" the entries, which takes older, completed entries out of the active TODOList. Here's a screenshot:

    As you can see, I've got 1560 current tasks - that's tasks that aren't completed. Wow.

    But it really helps. When you're a solo dev and have to largely motivate yourself (ie, no coworkers or rabid fanbase screaming for results) - you need to be able to have concrete goals and meet them.

    For instance, when I am feeling really, really unmotivated it's quite helpful to pick a small, easily accomplished task on the list. If I've done my job and broken the task up as much as I should have, that's easy. Once that's done, I force myself to do another small, easily finished task. Etc.

    Usually it's not that hard to get motivated, for me anyway, but this approach still works very well.

    Another helpful thing is at the end of your work day/period/whatever, take 20 minutes or so and break up your tasks, add detailed sub tasks, etc - this will help you when you come back and can't remember where you left off.

    Next time: Another great enemy of productivity, taking time off to post to your blog!

    Friday, February 27, 2009

    Bogged down, but gotta push through

    After around 90 days of work, with 10+ hour days and little to no breaks, I've hit the wall.

    For those that don't know what I'm talking about, the wall is when you hit a point where you just don't want to go on anymore - you're bored, or you're burnt out, or what have you. In my case, I'm pretty burnt out and having trouble maintaining my level of self-motivation.

    To be expected of course, but the key when you hit the wall in any endeavor is to keep pushing through.

    The wall I'm currently struggling through is the Legal system in my current game. It's quite hard to design a gameplay-friendly way for your players Crew to get arrested and charged with things. It's taken quite a lot of brainstorming to get it even close to right, and so I've been basically stalled the last few days as I thought it over and did minor bits of code.

    Thankfully, I think I've got most of it nailed down now. This is the last major component (aside from corp/Family stuff and the monetization) that needs to be put into place before I can start testing it.

    At some point after this I'm going to start showing bits of it off. I've been reluctant as things have been pretty much in flux, but it's time to start promoting this baby soon.

    After I complete the legal system first draft, I have to work on getting my Amazon Machine Image(s) setup - that's right, the game will be hosted on "The Cloud" - which is the ideal way to host an MMO that might be small, big, or anywhere in between.

    I'll make sure to post the experiences I have getting AWS to work with my backend.

    Tuesday, February 3, 2009

    A couple of good rules of thumb with Flex Builder

    When it's being flakey, clean the project. I just had a bug where what the debugger said a class instance was and what it ACTUALLY was were different.

    When I cleaned (after having had successfully rebuilt the project and ran it a few times, as well as stepping through the code!) - the compiler then told me there was an error in the code that wouldn't allow it compile. An error in the code that I had just been stepping through.

    Nice. Thanks Adobe! You guys ROCK!

    Second - and this one bites me in the ass a lot since I am lazy and haven't set up a proper way to enable this in the HTML templates yet - make sure your caching is off when testing your Flex browser app. I occasionally forget to turn this back off and get a really weird bug bite me in the ass before I remember.

    Saturday, January 31, 2009

    Interview with a boutique MMO creator

    Indie Game Developers Podcast interviews Aaron Murray, creator of the indie MMO Domain Of Heroes.

    I don't usually link everything under the sun, or even much of anything really, but I found this interview quite interesting, as unlike just about every other interview of a developer I've read, it's actually quite meaty.

    Some interesting talk about balancing, scaling, the economics of it, the whole bit.

    Thursday, January 29, 2009

    'Real' games starting to move into the Flash space.

    This doesn't surprise me, since it's what I am doing and believe, but big money is starting to migrate into Flash games.

    I'm not talking about in the portal space, where sites like Kongregate have been grabbing up the traffic with their stable of games, but actual "real", non-disposable games are starting to be made.

    Flash is more than stable and capable enough to make a very good platform for just about any (non-3d) game you'd care to make. You can even make a pretty decent MMO client with it, and have a whopping 98% penetration and decent performance.

    The story that brought this to my attention is here, where some company raised 8 million dollars for a Flash football game. Now, that's American football, not real football.

    But damn, 8 million. Where can I find a bizdev guy that can do that?

    Wednesday, January 28, 2009

    Creating a (small) MMO is a worthy challenge!

    Ya know, it's kind of a cliche in the industry that every noob wants to create his own MMO.

    Now, I've been programming games for over 20 years now, and I'm very good at what I do, but I'll tell ya - this is challenging.

    Even the very small scope I have set out for this first game can be daunting - for instance, today I am tackling visibility.

    In this game, the players can only see things that are within sight range of their units/territory. Pretty standard war game stuff. However, it gets less standard when you're talking about an MMO. With a standard single player, or even non-server based multiplayer war game, you can store the visibility state locally and it's all good.

    With an MMO you not only have to handle visibility for all of the arbitrary number of parties that could be involved, you also have to do it asynchronously - so in my case, if a player moves one of his Squads into another players sight area, I have to:

    • Remove the squads old visibility record from anyone who could see him before
    • Check to see who can see him at his new position
    • Send a message to anyone who can't see him anymore so that the client can remove the piece and show the Squad moving off out of sight range.
    • Send a message to the players who CAN see him so the client can add the piece and show it moving in from the fog.
    • Check to see what the Squad can see at its new position and then relay that back to the player that moved the squad in a message as well as adding those new records to the db.
    Then, add in that the fact that the player doesn't have perfect information about the things he sees unless they are his or an allies, and then add in that the player shares visibility info with his "Family.."

    Now add in scalability -you have to make sure your server cluster is going to be able to handle this for potentially hundreds or thousands of concurrent players. In my case, that might mean firing the visibility check off to a JMS queue that then is consumed by one of the servers in the cluster that has some time, which then fires off a message to the client when it's done.

    It's interesting. I'm loving it.