<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4370499031293064813</id><updated>2011-04-21T18:08:31.911-07:00</updated><category term='breakage'/><category term='compiler bugs'/><category term='cloud computing'/><category term='refactoring'/><category term='software'/><category term='process'/><category term='clean cache'/><category term='isometric flash programmer art progress'/><category term='Flex WTP java combined Eclipse slow compile tech ranting'/><category term='game progress'/><category term='Flex'/><category term='Flex overlap canvas mouseevent'/><category term='flex 3 failure trace'/><category term='TODOList'/><category term='flex builder'/><category term='DTO'/><category term='AWS'/><title type='text'>Tamed Tornado Software</title><subtitle type='html'>The journey of a one man software shop making a boutique Flex-based MMO.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-7812533698024004681</id><published>2009-04-16T12:34:00.001-07:00</published><updated>2009-04-16T12:51:06.466-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DTO'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><category scheme='http://www.blogger.com/atom/ns#' term='breakage'/><title type='text'>Extreme Refactoring and Java/Flex DTOs</title><content type='html'>I have this bad (or good, depending on your point of view) habit - I mercilessly refactor things.&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Plus, the backend needs to have access to data that the clients will never see.&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-weight:bold;"&gt;Externalizable&lt;/span&gt; interface in Java (&lt;span style="font-weight:bold;"&gt;IExternalizable&lt;/span&gt; in Actionscript 3) like I do to customize your serialization, as you have to write the readExternal() and writeExternal() methods on both sides. FUN!&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;So now, here's my process:&lt;br /&gt;&lt;br /&gt;&lt;li&gt;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)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Generate the Hibernate VOs via an Ant script and the Hibernate Tools plugin&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;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.)&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-7812533698024004681?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/7812533698024004681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/04/extreme-refactoring-and-javaflex-dtos.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/7812533698024004681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/7812533698024004681'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/04/extreme-refactoring-and-javaflex-dtos.html' title='Extreme Refactoring and Java/Flex DTOs'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-1759947358054560345</id><published>2009-03-13T13:08:00.000-07:00</published><updated>2009-03-13T13:19:12.045-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TODOList'/><category scheme='http://www.blogger.com/atom/ns#' term='process'/><category scheme='http://www.blogger.com/atom/ns#' term='game progress'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>The Runaway TODO List</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;A poster on the &lt;a href="http://forums.indiegamer.com/"&gt;Indiegamer.com forums&lt;/a&gt; recommended a piece of software I love, years ago now - &lt;a href="http://www.abstractspoon.com/"&gt;TODOList by Abstract Spoon Software&lt;/a&gt;. 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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_dhNbdsNi9zU/Sbq-mMT9zdI/AAAAAAAAAXI/vvQ8KqzCdSM/s1600-h/TODOListScreenshot.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 294px;" src="http://2.bp.blogspot.com/_dhNbdsNi9zU/Sbq-mMT9zdI/AAAAAAAAAXI/vvQ8KqzCdSM/s400/TODOListScreenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5312768273786195410" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see, I've got 1560 current tasks - that's tasks that &lt;span style="font-style:italic;"&gt;aren't&lt;/span&gt; completed. Wow.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-style:italic;"&gt;another&lt;/span&gt; small, easily finished task. Etc.&lt;br /&gt;&lt;br /&gt;Usually it's not that hard to get motivated, for me anyway, but this approach still works very well.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Next time: Another great enemy of productivity, taking time off to post to your blog!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-1759947358054560345?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/1759947358054560345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/03/runaway-todo-list.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/1759947358054560345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/1759947358054560345'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/03/runaway-todo-list.html' title='The Runaway TODO List'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_dhNbdsNi9zU/Sbq-mMT9zdI/AAAAAAAAAXI/vvQ8KqzCdSM/s72-c/TODOListScreenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-4612620879795429641</id><published>2009-02-27T17:29:00.000-08:00</published><updated>2009-02-27T17:38:25.033-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='game progress'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud computing'/><category scheme='http://www.blogger.com/atom/ns#' term='AWS'/><title type='text'>Bogged down, but gotta push through</title><content type='html'>After around 90 days of work, with 10+ hour days and little to no breaks, I've hit the wall. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;To be expected of course, but the key when you hit the wall in any endeavor is to keep pushing through.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;I'll make sure to post the experiences I have getting AWS to work with my backend.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-4612620879795429641?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/4612620879795429641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/02/bogged-down-but-gotta-push-through.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/4612620879795429641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/4612620879795429641'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/02/bogged-down-but-gotta-push-through.html' title='Bogged down, but gotta push through'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-22064358119255105</id><published>2009-02-03T10:53:00.001-08:00</published><updated>2009-02-27T17:34:58.982-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='compiler bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='flex builder'/><category scheme='http://www.blogger.com/atom/ns#' term='clean cache'/><title type='text'>A couple of good rules of thumb with Flex Builder</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Nice. Thanks Adobe! You guys ROCK!&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-22064358119255105?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/22064358119255105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/02/couple-of-good-rules-of-thumb-with-flex.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/22064358119255105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/22064358119255105'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/02/couple-of-good-rules-of-thumb-with-flex.html' title='A couple of good rules of thumb with Flex Builder'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-8294761809491971265</id><published>2009-01-31T17:08:00.000-08:00</published><updated>2009-01-31T17:10:44.657-08:00</updated><title type='text'>Interview with a boutique MMO creator</title><content type='html'>&lt;a href="http://www.indiegamepod.com/"&gt;Indie Game Developers Podcast&lt;/a&gt; interviews Aaron Murray, creator of the indie MMO &lt;a href="http://domainofheroes.com"&gt;Domain Of Heroes.&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Some interesting talk about balancing, scaling, the economics of it, the whole bit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-8294761809491971265?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.indiegamepod.com/2009/01/podcast-interview-aaron-developer-of.html' title='Interview with a boutique MMO creator'/><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/8294761809491971265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/interview-with-boutique-mmo-creator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/8294761809491971265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/8294761809491971265'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/interview-with-boutique-mmo-creator.html' title='Interview with a boutique MMO creator'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-3138017350657689484</id><published>2009-01-29T20:11:00.000-08:00</published><updated>2009-01-29T20:15:47.934-08:00</updated><title type='text'>'Real' games starting to move into the Flash space.</title><content type='html'>This doesn't surprise me, since it's what I am doing and believe, but big money is starting to migrate into Flash games.&lt;br /&gt;&lt;br /&gt;I'm not talking about in the portal space, where sites like &lt;a href="http://kongregate.com"&gt;Kongregate&lt;/a&gt; have been grabbing up the traffic with their stable of games, but actual "real", non-disposable games are starting to be made.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;The story that brought this to my attention is &lt;a href="http://www.techcrunch.com/2009/01/29/quick-hit-signs-nfl-star-raises-8-million-for-rich-flash-based-football-game/"&gt;here&lt;/a&gt;, where some company raised &lt;span style="font-weight: bold;"&gt;8 million dollars&lt;/span&gt; for a Flash football game. Now, that's American football, not real football.&lt;br /&gt;&lt;br /&gt;But damn, 8 million. Where can I find a bizdev guy that can do that?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-3138017350657689484?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/3138017350657689484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/real-games-starting-to-move-into-flash.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/3138017350657689484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/3138017350657689484'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/real-games-starting-to-move-into-flash.html' title='&apos;Real&apos; games starting to move into the Flash space.'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-5531332967657469522</id><published>2009-01-28T17:46:00.000-08:00</published><updated>2009-01-28T17:58:33.222-08:00</updated><title type='text'>Creating a (small) MMO is a worthy challenge!</title><content type='html'>Ya know, it's kind of a cliche in the industry that every noob wants to create his own MMO.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Even the very small scope I have set out for this first game can be daunting - for instance, today I am tackling visibility.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Remove the squads old visibility record from anyone who could see him before&lt;/li&gt;&lt;li&gt;Check to see who can see him at his new position&lt;/li&gt;&lt;li&gt;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.&lt;/li&gt;&lt;li&gt;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.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;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.&lt;/li&gt;&lt;/ul&gt;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.."&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;It's interesting. I'm loving it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-5531332967657469522?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/5531332967657469522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/creating-small-mmo-is-worthy-challenge.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/5531332967657469522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/5531332967657469522'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/creating-small-mmo-is-worthy-challenge.html' title='Creating a (small) MMO is a worthy challenge!'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-5588249104586503440</id><published>2009-01-24T15:00:00.000-08:00</published><updated>2009-01-24T15:02:56.465-08:00</updated><title type='text'>The joys of a quiet(er) PC</title><content type='html'>I'm sure every non-laptop PC user has experienced this - your PC getting louder and louder.&lt;br /&gt;&lt;br /&gt;I actually bought my last PC with it being silent in mind. I didn't quite achieve that, since I didn't go that extra mile and buy the water cooling setup I had in mind. Although, with my P180, the drives properly mounted and the quiet power supply, it was quite good.&lt;br /&gt;&lt;br /&gt;That said, it's been somewhat over a year now, and my awesome P180 started to fail me - not one, not two, but ALL FOUR of the Antec Tri-cool fans started making noise.. So, I finally replaced them today and am back to my normal somewhat quiet hum. Bliss.&lt;br /&gt;&lt;br /&gt;Is it just me, or is everyone else getting sick of everything being so noisy all the time?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-5588249104586503440?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/5588249104586503440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/joys-of-quieter-pc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/5588249104586503440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/5588249104586503440'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/joys-of-quieter-pc.html' title='The joys of a quiet(er) PC'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-6329574176866286548</id><published>2009-01-19T17:53:00.001-08:00</published><updated>2009-01-19T18:05:22.059-08:00</updated><title type='text'>A note about Hibernate and the Generation Gap pattern</title><content type='html'>Now, the Hibernate gurus out there already know how to do this and not have it bite them in the ass, but here it is for those of you like me who got their ORM start on stuff like Propel, which just Does It For You(tm).&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.research.ibm.com/designpatterns/pubs/gg.html"&gt;Generation Gap Pattern&lt;/a&gt;, or GG from now on, is quite simple - you have your ORM objects like Business or Client or what have you generated as "_Business", or as "Business" but in a seperate namespace. Then, your actual class is Business extends _Business. This makes it easy to put object specific helper methods and properties into the Business class and not have it get wiped every time you re-generate the classes (using hbm2java in this case). Fine, it's very useful.&lt;br /&gt;&lt;br /&gt;Now, Hibernate lets you do this, but it's not obvious how, and the very little mentioned about it is forum posts that are almost 5 years old. They still work, but they're quite sparse. There's also a couple of nasty gotchas. So, here's a base example (from my current game Capo):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;lt;class name="Capo" table="capo" catalog="gangster"&amp;gt;&lt;br /&gt;      &lt;span style="font-weight: bold;"&gt;&amp;lt;meta attribute="generated-class" inherit="false"&amp;gt;com.tamedtornado.data.base._Capo&amp;lt;/meta&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;       &amp;lt;meta attribute="extends" inherit="false"&amp;gt;com.tamedtornado.data.Entity&amp;lt;/meta&amp;gt;&lt;br /&gt;&lt;br /&gt;       &amp;lt;id name="id" type="java.lang.Integer"&amp;gt;&lt;br /&gt;           &amp;lt;column name="capo_id"&amp;gt;&lt;br /&gt;           &amp;lt;generator class="identity"&amp;gt;&lt;br /&gt;       &amp;lt;/id&amp;gt;&lt;br /&gt;&lt;hibernate-mapping package="com.tamedtornado.data"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/hibernate-mapping&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Ok, now the XML formatting is awful, I know, but you should see what you need to do. I've bolded the important line.. That gets you a base class named _Capo in .base, and one important bit to note is the &lt;span style="font-weight: bold;"&gt;inherit="false"&lt;/span&gt; attribute. Very important - if you don't include that, weird things will happen. The first set in your file will be written out as your base class when you run the code generator. Ugh. Took me a while to figure that one out.&lt;br /&gt;&lt;br /&gt;The line under that is also useful - you can specify a base class for this Hibernate object to inherit from, so _Capo extends Entity in this case. In my case, Entity holds the HashCode, Equals, ID, etc code to make things work consistently.&lt;br /&gt;&lt;br /&gt;I hope that helps someone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-6329574176866286548?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/6329574176866286548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/note-about-hibernate-and-generation-gap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/6329574176866286548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/6329574176866286548'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/note-about-hibernate-and-generation-gap.html' title='A note about Hibernate and the Generation Gap pattern'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-5848334010664391012</id><published>2009-01-09T17:55:00.000-08:00</published><updated>2009-01-09T18:04:47.229-08:00</updated><title type='text'>Scripting missions in Java/Jython</title><content type='html'>The game I am working on has "missions" or "ops" or "capers" that involve the player choosing a bunch of his Crew for specific roles, such as say a Driver, a Lookout, a Thief, with specific skills. They then pull off the caper using their skills.&lt;br /&gt;&lt;br /&gt;Since this is going to be a major portion of the content in the game, I wanted to have this be pretty accessible to the designers, so I thought up a simplified node-based system where a simple tree is walked and skill checks are made, etc..&lt;br /&gt;&lt;br /&gt;Wow, what a waste of time that was.&lt;br /&gt;&lt;br /&gt;It turns out that it's quite hard to simulate something like a mission script, even a simplified one, like that in this game. So I gave up and am now doing it the way I wanted to do it in the beginning - with scripts. Specifically, Jython/Python.&lt;br /&gt;&lt;br /&gt;Now, this is slicker than it has any right to be. Basically you add the Jython.jar to your project, and if you want to use the JDK6 scripting support, you add the &lt;a href="https://scripting.dev.java.net/"&gt;JSR-223 "engine"&lt;/a&gt; that is basically a glue layer between the Jython API and the JDK6 standardized scripting. Going to that engine page is a little disconcerting, as the engines there are from August and are all listed as "draft" - I'm sure there's more up to date stuff somewhere, but I haven't found it yet.&lt;br /&gt;&lt;br /&gt;Anyway, if you use the JDK6 stuff instead of the Jython API directly, you get essentially transparent support for just about any scripting language you can think of. Jython is nice though, not only because it's Python and Python Est Good, but because it compiles the Python to JVM byte code, meaning it should be pretty fast.&lt;br /&gt;&lt;br /&gt;That said, I got the scripts executing pretty quickly and ran into my next hurdle: How to debug mission scripts. Ugly.&lt;br /&gt;&lt;br /&gt;Since right now op scripts are only running on a processor bean in the backend, and then generating results, etc, it's essentially very difficult to debug/create the scripts that way. I had to hack up a little Spring-based test app that loads the OpData I specify and then create a bunch of fake crew to meet the mission parameters, generate the Operation and then run the op script (first loading it from the "work" location rather than the database, where they will live when they are done.)&lt;br /&gt;&lt;br /&gt;That works ok. Of course there are still rough spots, but I'm really just spoiled now - for instance, my basic OpExecution helper class in Python is derived from a Java base class, and since I don't have something set up right, the code completion can't complete for methods in the Java base class. Oh poor me. :)&lt;br /&gt;&lt;br /&gt;Anyway, this is how I've wanted to do this kind of system in a game for a long time, and with how slick Java made it there's no way I'm going back!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-5848334010664391012?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/5848334010664391012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/scripting-missions-in-javajython.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/5848334010664391012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/5848334010664391012'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/scripting-missions-in-javajython.html' title='Scripting missions in Java/Jython'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-8417840055378314663</id><published>2009-01-08T20:44:00.000-08:00</published><updated>2009-01-08T20:46:11.531-08:00</updated><title type='text'>Another thing not to do</title><content type='html'>When creating your own data-bound components, don't set the value of the text field (for a data bound textfield) in the commitProperties() method, as proper as that might seem.&lt;br /&gt;&lt;br /&gt;I just spent an hour debugging a problem where for (still unknown) reasons, my data bound control would display the text of the &lt;span style="font-weight:bold;"&gt;previous&lt;/span&gt; bound object, not the one that was currently bound - even though I traced all through the code and every bit of it had the right text in the text property.&lt;br /&gt;&lt;br /&gt;Flex.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-8417840055378314663?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/8417840055378314663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/another-thing-not-to-do.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/8417840055378314663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/8417840055378314663'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/another-thing-not-to-do.html' title='Another thing not to do'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-5338328815240742771</id><published>2009-01-08T19:48:00.000-08:00</published><updated>2009-01-08T20:02:24.088-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex 3 failure trace'/><title type='text'>Flex 3s biggest failing - Silent Failure</title><content type='html'>Now, I've been doing a lot of programming in Flex lately.. Way too much, 80 hour weeks,  and I'm getting pretty familiar with it.&lt;br /&gt;&lt;br /&gt;The one thing that really kills me is it's major weakness, which stands out in sharp contrast to Java, which AS3 obviously aped in some ways. I've been doing my server backend in Java with Spring, Hibernate and BlazeDS, which is a winning (although a bit complex) setup.&lt;br /&gt;&lt;br /&gt;The biggest weaknesses of Flex 3 are Silent Failure and Lack of Feedback.&lt;br /&gt;&lt;br /&gt;When something fails in Java, if you've got your logging setup correctly, you generally see  why, and &lt;span style="font-weight: bold;"&gt;exactly where.&lt;/span&gt; In Flex, most of the time it doesn't tell you.&lt;br /&gt;&lt;br /&gt;A couple of examples from just today:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I have a CRUD tool for my games backend data, and after performing some surgery on one of my data structures, I had broken a section of it and had to make some changes. No problem, I make the changes and... It now refuses to save any of the objects. The save is basically a remoteObject call where I send the new objects in a hash structure to the server. The Flex code gets all the way to the remote object call and then in there somewhere, just silently fails. Even in debug, no trace, no nothing - the server just never gets the request. I found it of course, after some hair pulling, but Flex was no help whatsoever.&lt;/li&gt;&lt;li&gt;Passing some objects back from the server, some of them were untyped. I've run into this before, and of course it doesn't tell you WHY they are untyped, so I checked the usual suspects - yes, it has a RemoteClass metadata tag, yes the namespace and class names are correct, yes, yes, yes.&lt;/li&gt;&lt;/ol&gt;          It was a semicolon. For instance:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[RemoteClass(alias="com...snip..DTO")]&lt;span style="font-weight: bold;"&gt;; &lt;-- That&lt;/span&gt;&lt;br /&gt;   public class SkillCheckDTO&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;That semicolon, put there as I was programming this morning half awake, will cause Flex to just not type that object properly with no error.&lt;br /&gt;&lt;br /&gt;Programming in Flex (and to some extent Java with some of the OSS stuff I am using) is a little TOO much like the bad old days of programming on the Amiga, where my software tools generally had no documentation and the documentation they did have was wrong, so I had to figure it out by trial and error.&lt;br /&gt;&lt;br /&gt;And don't even get me started on the controls and databinding.&lt;br /&gt;&lt;br /&gt;Compiling - no feedback whatsoever. I want to see WHY my compile is taking so long (although it's much better now). Where's the verbose compiler output?&lt;br /&gt;&lt;br /&gt;If there's one thing they need to fix for 4, this is it. Overload me with optional information. I want to see everything you're doing, so that when it invariably breaks, I know why.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-5338328815240742771?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/5338328815240742771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/flex-3s-biggest-failing-silent-failure.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/5338328815240742771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/5338328815240742771'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/flex-3s-biggest-failing-silent-failure.html' title='Flex 3s biggest failing - Silent Failure'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-6292398391350507735</id><published>2009-01-05T18:59:00.000-08:00</published><updated>2009-01-05T19:15:30.552-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex WTP java combined Eclipse slow compile tech ranting'/><title type='text'>The evils of combined Flex/Java projects in Eclipse</title><content type='html'>Just wanted to give a little warning, as I just found out the hard way. :)&lt;br /&gt;&lt;br /&gt;When I first started this project, the easiest way to get it going was to make a WTP combined project, that's where Eclipse has the Java backend source and the Flex client source in the same project and it handles deployment and such for you. That worked great, to a point.&lt;br /&gt;&lt;br /&gt;Recently, I noticed the builds getting slower and slower. I did lots of experimentation to try to get the speeds back up, but nothing was having much impact. Even moving my embedded images to another project library/SWC didn't really affect anything that much.&lt;br /&gt;&lt;br /&gt;Then, I noticed another fun thing - once your server and your Flex client code get to a certain size, they each take a little while to compile (Flex MUCH more so than Java, sadly).. So I'd do something like this:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Adjust Java server code slightly&lt;/li&gt;&lt;li&gt;Run client&lt;/li&gt;&lt;li&gt;Client would require a workspace rebuild, in my case taking up to a couple minutes. (SLOW!)&lt;/li&gt;&lt;li&gt;Then it would finally launch, when all it needed to do was re-deploy the changed Java.&lt;/li&gt;&lt;/ol&gt;Another horrible thing was when I'd adjust something in my "testdata.sql" file (my world data so that when I blow out the db I can repopulate the world without having to run any code, this happens automagically in my ant scripts for generating the DDL schema from the Hibernate objects) - when I would change even one character there, that counted as a workspace change, and you got it, everything had to rebuild. Ugh.&lt;br /&gt;&lt;br /&gt;There was also the wonderful side effect that when you hit "launch" to launch the client, it would rebuild the workspace most of the time, then deploy it, and then launch it, but it wouldn't give the app server enough time to get it deployed and so the initial page load would fail (since the SWF wasn't fully there yet). Sometimes it would fail with really interesting error messages. What this boiled down to was pressing the refresh button the second the browser came to the front, since I knew it wasn't going to work otherwise. If I was forgetful and hit "debug" instead of just launch, this also meant launching the debug session again, since refreshing the browser breaks the debug connection. Pain.&lt;br /&gt;&lt;br /&gt;So, I finally bit the bullet and seperated the projects. While I was at it I restructured my SVN repo to be more sane, since I expect this code base to be around for a long time.&lt;br /&gt;&lt;br /&gt;I'll tell you the truth, it was kind of painful separating them. A couple months ago my Java know-how would have been insufficient. It's all stupid little stuff, but it is until you figure out how to fix it.&lt;br /&gt;&lt;br /&gt;The thing that might be a problem for you that took me a bit to figure out - the Flex client and the Java server both need access to Flex's services-config.xml in WEB-INF, but you don't want to put the client in the same directory structure as the server, since when Eclipse deploys the server there it likes to wipe that directory out.&lt;br /&gt;&lt;br /&gt;What I did was use Vista's &lt;a href="http://blogs.msdn.com/junfeng/archive/2006/04/15/576568.aspx"&gt;symbolic link feature&lt;/a&gt; (Unix and OSX both have this, but it's fairly new in Windows. XP has something equivalent, but I can't remember if it's this easy). This just let me link from the Java deploy directory (the Java project owns the flex config files, oddly) to the Flex deploy directory.&lt;br /&gt;&lt;br /&gt;Then, after adjusting the server settings for the Flex project, it should all work.&lt;br /&gt;&lt;br /&gt;When all was said and done, the two projects are now separated and living in their own Eclipse workspaces and being used with seperate Eclipse installs (I also had FlexBuilder/Eclipse 3.4 reliability issues, but that's another story) - and now BOTH sides are down to few second compile times. It's amazing.&lt;br /&gt;&lt;br /&gt;In short, WTP combined Flex/Java projects - &lt;span style="font-weight: bold;"&gt;BAD&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-6292398391350507735?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/6292398391350507735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2009/01/evils-of-combined-flexjava-projects-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/6292398391350507735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/6292398391350507735'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2009/01/evils-of-combined-flexjava-projects-in.html' title='The evils of combined Flex/Java projects in Eclipse'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-3337769183163360421</id><published>2008-12-28T21:50:00.000-08:00</published><updated>2008-12-28T22:01:45.852-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='isometric flash programmer art progress'/><title type='text'>Isometry, yay!</title><content type='html'>So, I managed to get my isometric code going today for my little MMO.&lt;br /&gt;&lt;br /&gt;I've never done it before, so it was a bit of a challenge. Being a 3d guy mostly, I was well prepared to break out the matrices and do what was needed, but I managed to find all of the old school pixel shortcutty algorithms (that all work very nicely with Flash, it being quite a lot like an old school platform.)&lt;br /&gt;&lt;br /&gt;The thing that bit me in the ass for the longest was the fact that my tiles weren't quite right.  I did my own programmer art of course, in Flash, and ran into all sorts of problems:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Flash anti-aliases even if you tell it not to.&lt;/li&gt;&lt;li&gt;Flash does weird things with the image size it outputs, sometimes it uses the canvas size, and sometimes something else. It's a bit weird.&lt;/li&gt;&lt;/ol&gt;There was more as well, but I've forgotten them. Flash however is great for programmer art - Vector art and programmers are a natural fit. Once I figured out what I needed to do to get isometric art going, it was a snap. Basically, you draw a square, you rotate it 45 degrees and then you squish it so its height is half its width. Bam, there's your isometric base panel, and all your isometric lines can derive from that. (Quite easily in Flash as well).&lt;br /&gt;&lt;br /&gt;So I had fun for an hour or two messing with isometric graphics, and got a good placeholder for my game. I still need a real artist, or I need to spend a few days myself (which I currently don't have) - we'll see how it goes.&lt;br /&gt;&lt;br /&gt;Behold, my programmer art!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_dhNbdsNi9zU/SVhm2hH63cI/AAAAAAAAAMg/wsXkA3FrJbo/s1600-h/Block_OnePiece.png"&gt;&lt;img style="cursor: pointer; width: 265px; height: 135px;" src="http://3.bp.blogspot.com/_dhNbdsNi9zU/SVhm2hH63cI/AAAAAAAAAMg/wsXkA3FrJbo/s400/Block_OnePiece.png" alt="" id="BLOGGER_PHOTO_ID_5285087249509834178" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Anyway, I'd like to put together a real post on how to do this, as I had to scour tons of different half-complete tutorials to put together what I needed to do this the right way. Lots of very old stuff out there.&lt;br /&gt;&lt;br /&gt;And is it just me, or do you hate it when you read someones post or tutorial about some math related thing and they don't define all their variables? GAH.&lt;br /&gt;&lt;br /&gt;Anyway, that's my shift at the salt mine, I'm off to bed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-3337769183163360421?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/3337769183163360421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2008/12/isometry-yay.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/3337769183163360421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/3337769183163360421'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2008/12/isometry-yay.html' title='Isometry, yay!'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_dhNbdsNi9zU/SVhm2hH63cI/AAAAAAAAAMg/wsXkA3FrJbo/s72-c/Block_OnePiece.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-1849896447536587780</id><published>2008-12-24T21:19:00.000-08:00</published><updated>2008-12-24T22:02:30.387-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Flex overlap canvas mouseevent'/><title type='text'>How to do something you really shouldn't do in Flex</title><content type='html'>Here's the thing: I'm not an artist. But, since I'm a one man band right now, I have to be. So, after having become completely sick of my "random colors, basic Flex skin" UI, I spent a morning in Photoshop mocking up a new UI.&lt;br /&gt;&lt;br /&gt;Any photoshop gurus in the house will definitely see my PS noob-itude when you see the screenshots.&lt;br /&gt;&lt;br /&gt;So, I get to the part where I have to take my glorious creation and make it real. Pshaw, I say! No problem. It's now just about a week later and I'm just about through the other side. I had to write a ton of components, and this is about one of them.&lt;br /&gt;&lt;br /&gt;Here's part of what I wanted to do:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_dhNbdsNi9zU/SVMZMwMPu9I/AAAAAAAAABI/fzrQ1Djfe_4/s1600-h/OverlappedInterfaces.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 98px;" src="http://4.bp.blogspot.com/_dhNbdsNi9zU/SVMZMwMPu9I/AAAAAAAAABI/fzrQ1Djfe_4/s400/OverlappedInterfaces.png" alt="" id="BLOGGER_PHOTO_ID_5283594494721113042" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;That's two Canvases with lots of stuff on them that come in from the top and the bottom of the screen and overlap each other. I didn't realize until I hit the wall what was wrong with that, and you may not either, so I'll tell you.&lt;br /&gt;&lt;br /&gt;Whichever Canvas is on top gets all the events, whether it has something there or not. So in my case the bottom panel was last (topmost) in the display list, so its button worked great, but the right button didn't work at all.&lt;br /&gt;&lt;br /&gt;I tried a few different things to get this to work, before I finally got something that did. I even in a moment of desperation tried to have a hidden canvas that found the controls in the intersection rect on both canvases and cloned them. Sadly, there's no generic clone method for UIComponents.&lt;br /&gt;&lt;br /&gt;So, what I ended up doing was this - those two panels are in a "smart" container that manages their sliding up and down and changing sizes and what not, and that container subscribes to the mouse events..&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; function addMouseListeners():&lt;span class="kwrd"&gt;void&lt;/span&gt;&lt;br /&gt;     {&lt;br /&gt;         addEventListener(MouseEvent.CLICK,handleIntersectingPanelMouseEvents);&lt;br /&gt;         addEventListener(MouseEvent.DOUBLE_CLICK,handleIntersectingPanelMouseEvents);&lt;br /&gt;         addEventListener(MouseEvent.MOUSE_MOVE,handleIntersectingPanelMouseEvents);&lt;br /&gt;&lt;br /&gt;     }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Passing the click events through turned out to be not too hard - when the effects finished playing (to adjust panel sizes or positions) - I recalculate the area of intersection of the two panels.. Then, when the mouse events fire, if I'm within that area of intersection, I clone the click and send it through:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;var panel:AbstractPanelBase = getChildAt(0) as AbstractPanelBase;&lt;br /&gt;&lt;br /&gt;for each (var uic:UIComponent in panel.getChildren())&lt;br /&gt;{&lt;br /&gt;if (uic.hitTestPoint(evt.stageX,evt.stageY))&lt;br /&gt;{&lt;br /&gt; // Hardcoded to button, to fix this make sure border objects and such are not in main children array&lt;br /&gt; if (uic is Button)&lt;br /&gt; {&lt;br /&gt;  newOver = uic as EventDispatcher;&lt;br /&gt; &lt;br /&gt;  if (evt.type == MouseEvent.MOUSE_MOVE)&lt;br /&gt;  {&lt;br /&gt;   // Moves have to be interpreted into ins and outs&lt;br /&gt;  &lt;br /&gt;   if (overControl!=uic)&lt;br /&gt;   {&lt;br /&gt;    if (overControl!=null) // Mouse out and mouse over&lt;br /&gt;    {&lt;br /&gt;     var newEvt:MouseEvent = new MouseEvent(MouseEvent.ROLL_OUT,true,false,&lt;br /&gt;      evt.localX,evt.localY,evt.relatedObject,evt.ctrlKey,evt.altKey,&lt;br /&gt;      evt.shiftKey,evt.buttonDown,evt.delta);&lt;br /&gt;     &lt;br /&gt;     overControl.dispatchEvent(newEvt);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Fire the mouse over&lt;br /&gt;    overControl = uic as EventDispatcher;&lt;br /&gt;   &lt;br /&gt;    newEvt = new MouseEvent(MouseEvent.ROLL_OVER,true,false,&lt;br /&gt;     evt.localX,evt.localY,evt.relatedObject,evt.ctrlKey,evt.altKey,&lt;br /&gt;     evt.shiftKey,evt.buttonDown,evt.delta);&lt;br /&gt;    &lt;br /&gt;    overControl.dispatchEvent(newEvt);&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;  } else&lt;br /&gt;  {&lt;br /&gt;   // Clicks just get sent through..&lt;br /&gt;  &lt;br /&gt;   newEvt = evt.clone() as MouseEvent;&lt;br /&gt;  &lt;br /&gt;   // Send only to topmost child, hopefully that is 0&lt;br /&gt;  &lt;br /&gt;   (uic as EventDispatcher).dispatchEvent(newEvt);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That bit of code passes the clicks through, but it also does ROLL_OUT and ROLL_OVER events since just passing MouseMove events through won't do it. We're not handling a few more complex cases here, like:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If the control we're worried about isn't a button. It's hardcoded like that because all I'm currently worried about are buttons, and there's some other stuff in the intersection area that would have to be accounted for otherwise. It would be easy enough to extend to a general case.&lt;/li&gt;&lt;li&gt;We're not handling overlapped items inside the the panels - if there are two buttons overlapped the hit test will just find the first one and send the event to it.&lt;/li&gt;&lt;/ol&gt;Now, the final bit is the ROLL_OUT event when your mouse didn't just roll from one control to another, that's basically right after the code above:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;// There was a control that was registered as having the mouse over it,&lt;br /&gt;// but this event didn't find one, so overControl is no longer valid and we need to fire a mouse out&lt;br /&gt;if (overControl!=null &amp;amp;&amp;amp; newOver==null)&lt;br /&gt;{&lt;br /&gt;newEvt = new MouseEvent(MouseEvent.ROLL_OUT,true,false,&lt;br /&gt; evt.localX,evt.localY,evt.relatedObject,evt.ctrlKey,evt.altKey,&lt;br /&gt; evt.shiftKey,evt.buttonDown,evt.delta);&lt;br /&gt;&lt;br /&gt;overControl.dispatchEvent(newEvt);&lt;br /&gt;&lt;br /&gt;overControl = null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// stop propagation of the old event here   &lt;br /&gt;evt.stopImmediatePropagation()&lt;br /&gt;&lt;/pre&gt;So that's the basics of it. If I'd known what a pain it was going to be, I probably would have designed my UI a little differently, but I really don't regard time spent learning how to do difficult things in Flex as wasted time. I've done quite a few out there things in this language so far, and I expect to do quite a few more.&lt;br /&gt;&lt;br /&gt;Oh, one last &lt;span style="font-weight: bold;"&gt;VERY&lt;/span&gt; important thing that I of course, forgot:&lt;br /&gt;&lt;br /&gt;You must remove all of the mouse listeners at the start of that event handler, and then put them all back as you leave it. It sucks, but otherwise you'll get a nice infinite loop. I experimented with mouseEnabled and mouseChildren and neither in any combination does it, unfortunately.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-1849896447536587780?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/1849896447536587780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2008/12/how-to-do-something-you-really-shouldnt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/1849896447536587780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/1849896447536587780'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2008/12/how-to-do-something-you-really-shouldnt.html' title='How to do something you really shouldn&apos;t do in Flex'/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_dhNbdsNi9zU/SVMZMwMPu9I/AAAAAAAAABI/fzrQ1Djfe_4/s72-c/OverlappedInterfaces.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4370499031293064813.post-8718767396156673278</id><published>2008-12-24T08:51:00.001-08:00</published><updated>2008-12-24T08:54:18.875-08:00</updated><title type='text'></title><content type='html'>Welcome to the Blog!&lt;br /&gt;&lt;br /&gt;Since I'm doing a lot of stuff in Flex and Java right now that I want to post, I started this blog back up. My old blog was neglected and most likely compromised by some very popular Wordpress security vulnerabilities, so I've pulled the plug on it. I will likely merge its (years, geesh!) of posts and this blog when I get another server up.&lt;br /&gt;&lt;br /&gt;Posts coming soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4370499031293064813-8718767396156673278?l=blog.tamedtornado.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.tamedtornado.com/feeds/8718767396156673278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.tamedtornado.com/2008/12/welcome-to-blog-since-im-doing-lot-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/8718767396156673278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4370499031293064813/posts/default/8718767396156673278'/><link rel='alternate' type='text/html' href='http://blog.tamedtornado.com/2008/12/welcome-to-blog-since-im-doing-lot-of.html' title=''/><author><name>Jason Maskell</name><uri>http://www.blogger.com/profile/14670503225955948928</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
