Jario Update: Sounds and Semi-Passability!

Yes, thank you Chrome, only one of those is a word, and yet Jario now has both! Sounds were ridiculously easy to add through a generic SoundSystem with a handful of static sounds (courtesy of http://www.freesound.org/) and a static queue-push method, and then the single-line calls were peppered throughout the systems as required. The result is a game which is a lot more fun to play! Despite still being about 60 seconds long.

Go ahead, try it out!   Launch Java Web Start button

The issue of passability is a more technical one. Previously, all detected collisions were handled directly by each of the colliding entities. This is great for many cases, but there are some times when you don’t want to handle a collision, or when you want to not handle it under certain conditions, and for which adding in a bunch of conditional guards is ugly and inefficient.

My solution was to sneak an extra layer into my collision handling hierarchy (which I’ll talk more about when it’s a little more polished), right up the top, to manage collision persistence. In this context, persistence means that when two entities collide, all future collisions that are detected until they stop colliding can be grouped into a single collision, and handled only once at the beginning. This is important for a number of gameplay mechanics.

For example, the two cases I added just now were semi-passable platforms and improved handling of player recovery. Semi-passable platforms are those ones that you can jump through from below, as well as stand on top of. One way to get this behaviour is to say “if the collision is not from the top edge, do nothing, otherwise block the entity”. This may work, depending on your collision detection mechanism, but for the time being mine is very basic, and detects the edge of the collision based on the X and Y distance the two entities are overlapping by. The result is that if you jump through from the bottom, a bunch of collisions will occur for the handful of frames you’re passing through, and as you are about to exit from the top, one of those collisions will be detected as “top edge”, and the default behaviour is to place the player on top of the platform. The behaviour we want is for the player to keep jumping, eventually fall back down, and then be placed on the platform.

My solution is a little more complex than perhaps it needs to be, but it’s a good starting point. When a collision occurs, the handling systems can register the collision as a “passing through” case, after which future collisions will not be handled by the entity that is passing through (the ‘passer’) until the entities separate. However, the entity being passed through (the ‘passable’) will continue to receive handling calls in case the circumstances of its passability change. It can therefore also check whether the colliding entity has been previously registered as a passer. All of this handling is contained in PersistentEntityHandlingSystem class, which all current collision handlers extend.

In the case of the platforms, this is straightforward. On the first collision, if the player collides with a non-top edge of the platform, the platform registers the player as a passer, and the player continues unhindered. Once the player exits at the top, they are unregistered from the platform, and the next collision will be handled appropriately on the top edge.

Player recovery is a little trickier. By “recovery” I mean the period of invulnerability you get after being damaged with >1 health. During this time, you shouldn’t be able to stomp enemies from inside (i.e. walk into them from the left, then jump and kill them on the way out). So for this case, when the player collides with an enemy, he first checks whether he’s in recovery mode, and if so, if the enemy is not already registered as passing through, then the registration occurs. The enemy passing through the player means that the enemy is oblivious to the collisions (and so can’t die until the player leaves and comes back), but the player’s handler is still called each frame. Therefore when the test for recovery fails (i.e. recovery time has expired), then the enemy is unregistered as a passer, and the collision can be handled normally.

But wait, there’s more. It’s possible for recovery to expire while the player is standing right in the middle of the enemy, and if the position is right, it will register as a top-edge collision, and “handling normally” means the enemy will get stomped. This is not the desired behaviour – if the the player is standing inside the enemy when recovery expires, the player should get stomped instead. To work around this, I added a parallel map that records which passable-passer relationships should be unregistered in the next frame. This gives the player collision handler a chance to handle the collision manually and correctly (take damage) before unregistering. If the player manually takes damage AND unregisters in that frame, by the time the enemy handles the collision it will appear unregistered, and the potential top-edge problem persists. By delaying it one frame, the player’s damage will have been fully accounted for, and the enemy collision will not occur at all.

Problem solved! You can see all that in PlayerHandlingSystem if you like. Like I said, it’s quite complex and I’d like to simplify it a bit, but it’s a start. By experimenting with this approach, I’ve gained even more of an appreciation of the Artemis framework. You really can tackle your problems one at a time, in isolation. Even in the case of a two-entity collision, the collision handling of the two entities can be neatly decoupled. The future is looking bright!

Why Use Slick?

Slick logoI talk about the Slick 2D game library a lot because I use it a lot, and with good reason. I thought I’d take a minute to go over some of that reason and give a little overview of what Slick is.

Slick is, like I said, a 2D game library written in Java. A game library is essentially a framework which provides a big chunk of functionality that is useful or necessary for creating a game. This primarily involves rendering the visual aspect of the game, but also includes some conveniences such as implementing the game loop and providing simple methods of changing the game parameters (such as the window resolution and FPS limit).

Slick is written in Java, is open source, and uses the Lightweight Java Game Library (LWJGL) for rendering. Many (if not all) of the ‘serious’ commercial game libraries and engines are written in C++, mainly for performance reasons, but Java has its advantages:

  • All the code runs in the Java Virtual Machine (JVM) which is implemented on most operating systems, meaning a game written in Java will be playable on Windows, Mac, Linux and other systems, with no extra effort from the developer.
  • There are a couple of low-effort, high-convenience deployment methods for Java programs. They can be automatically downloaded and run locally using the Java network language protocol (JNLP), or run in a browser applet embedded in a Web page. Both methods ensure the end user always has the latest version.
  • Java is a much more developer-friendly language than C++, which counts for a lot on a project as large and diverse as a game.
  • The performance typically isn’t quite as good as C++, but it’s more than good enough more often than not, especially for 2D games.

It should also be noted that there are an increasing number of handy C# game libraries, comparable to Java but with DirectX support at the cost of being cross-platform (or at least cross-non-Microsoft-platform).

But how does Slick compare to other Java game libraries? The most comparable alternatives in the 2D arena include GTGE (last updated in 2005), JGame (still active, and ported to Flash), and PulpCore (primarily for applets and animation). There are some 3D options too, such as libgdx and the Java Monkey Engine (JME), which can of course render 2D graphics, with a little more arm-twisting. The main advantage of Slick however is that it’s very easy to use, and remains consistently so thanks to its exclusive focus on 2D graphics.

It also provides a lot of practical features out of the box, best expressed in bullet point form:

  • Graphical flexibility for drawing images, primitives, and fonts using OpenGL.
  • Integrated sound and music playback with OpenAL.
  • Integrated and very easy input handling for keyboard, mouse and controllers.
  • Handy functionality built into the library, such as game states and path finding support.
  • Additional libraries to provide further features, such as powerful tilemap support and particle editing.
  • Helpful community, continued development and extension, and plenty of documentation and tutorials.
  • Total library download size of under 2MB, including LWJGL.
  • Open source and totally free (BSD license)!
  • A build in development for Android support, further extending the reach of your code.

Although it may not offer some of the more advanced features such as 3D graphics and physics, it’s a good (perhaps the best) choice for those games that don’t need them. Honestly, the main reason I started using Slick was because it was prescribed in one of my university subjects, but there was good reason for that too. I’ve yet to find a more suitable framework for painless development of 2D Java games.

As an added bonus, it’s the target library of the Artemis framework which I’ve fallen in love with recently, and which I will write more about very soon.

Where Is Forgbook Going?

Of my large (and still growing) handful of projects that I’d like to be working on right now, Forgbook is taking up most of my attention. Hopefully I can get some kind of super-early release out in a few weeks, but until then it’s worth noting a few shifts in focus and philosophy.

As much as I love the Web, I find it hard to submerge myself in Web development due to the chronic pains of browser incompatibility, and perhaps the need to be constantly responding to user experience. Once a product is released, I feel an obligation to keep it updated, which can at times conflict with a desire to put a project to the side for a while. It’s much safer in term of user response to work on a project privately until it’s complete and polished before releasing it rather than releasing pre-alpha kind of work and iterating consistently all the way through to a final release. I guess I value my flexibility pretty highly, because after all this work is effectively my free time.

Forgbook is (or will be) my largest, most ambitious project in functionality terms, and I believe it will be of the most value to myself and others, so I want to get it right. I’ve been thinking about what I want it to offer for some time now, and I’ll be updating the project page with more details as I solidify them. From a technology perspective however, the interesting decision I’ve made is that I’ll be switching from a relatively unambitious attempt to combine Flex and PHP to a Web-native Django application leveraging the Dojo JavaScript toolkit for the more flashy UI components. This means however that I have to familiarise myself with the environment Django offers; it’s immediately clear that it’s extremely powerful and scalable, but the decoupling that is its strength results in a variety of idiosyncratic idioms that will take some time to adjust to.

Why the switch? One of the requirements I’ve come to be very passionate about is making Forgbook accessible from any common device – PC, smartphone, tablet, perhaps even consoles – so that it feels more like an encouraging companion rather than a chore you must log into every day. This is best achieved using a native Web interface (HTML, CSS, JS) over something requiring a plugin (Flash, Silverlight), as it should at least be accessible by any device with a Web browser, in the scenario that I don’t/can’t customise an interface for that device. It would be suicide to jump into creating a sophisticated Web application without a framework, and my love for Python (and mere tolerance of PHP) combined with the popularity and support for Django make it a perfect choice. The integration of Dojo via Dojango is a big bonus too.

I’ll document the progress I’m making with Django in the next couple of weeks, and hopefully get a stripped-down-but-working version (basic user and task management) out in the wild before March. From there, I’m hoping the development efforts will feel more rewarding, and I’m sure there will be many more fun things to handle (feedback and reflection followed later by advertising and analytics). I’m looking forward to it as much as ever.

P.S. If anyone can think of a quality name for a sophisticated event/task management application (Forgbook is very much a working title), let me know (comment or contact). If I like it enough that I decide to use it, I’ll be happy to give you free access to pretty much anything I release forever. Hopefully one day that’s worth something significant.

Goodbye, IBM

As of yesterday (I believe the next day starts around sunrise, not midnight), January 26th, Australia Day, 11pm, I completed my internship with IBM Australia. This experience was easily one of the most significant of my life, so having handed my gear back in today and wrapped everything up for good, I feel like writing a brief report about the whole experience.

My internship was full-time for 12 months, and was for all intents and purposes a ‘real’ job. I would catch the train into the city and walk to the office each morning, put in a full day of productive work, and head off home in the evening. If you’ve ever had a full-time job (or even if you haven’t) this probably doesn’t sound very exciting, but it was for me, because it was the start of a new way of life, the way I knew I would spend most of my life after graduating from university. At first I was enamoured at how much work I was able to get done by putting in a solid 8+ hours each day, but by about month nine the novelty of working all day on all weekdays began wearing thin. This was a remarkably long time, I gathered, as my friends, family and the other interns found it difficult to believe any job could be this good.

The critical factor in my enjoyment was that I loved my work. I was developing a complex internal Rich Internet Application (RIA) with Adobe Flex, and since I was working to implement my own manager’s vision, I was more or less in complete control of the development; a team of one. This might not sound very attractive, and indeed it made those all-important networking connections a little harder to come by, but there were an array of benefits too:

  • Having taken a prototype and effectively started from scratch, I had the freedom to design the structure of the application from start to end, meaning I could actually make it good – decoupled, flexible, extensible, scalable, all the things I would need it to be if I was going to be working on it for a year. What’s more, as the sole implementer, I learned a lot about all of these things in the process.
  • My choice of technologies (I ended up using Flex, Swiz, MySQL, PHP and XML, needing a little HTML and CSS too). I certainly learned a lot about all of these as well.
  • The freedom to work any hours I liked from anywhere I chose (including home), just so long as the work got done. This kind of freedom is exactly what makes you want to get the work done, and to the best of your ability.
  • And, of course, I get to take all the credit ;) .

Very long story very short, it was a very, very good year. My manager was sublime, always challenging me to do better and offering all the support and information I could hope for, all the while being completely fair, friendly and approachable. Unlike the ‘traditional’ vacation/internship job roles, I was never stuck printing photocopies or making coffee; every day I would come into work, sit down and start creating, extending, expanding my own little project. The feeling of progress was palpable as the application gradually came together before my eyes.

It was everything I could have hoped for from an internship and more. I learned so much about the IT industry, IBM, the software delivery life-cycle (SDLC), software engineering and programming, and just the corporate world in general, and I now have the development of this application as a major achievement next to my name. All of it has worked wonders for my confidence, and I feel as optimistic about the future as I ever have.

I also feel compelled to evangelise IBM as the amazing company they are. They may not be as trendy as Google or Apple, but they exhibit at least as great a commitment to innovation, quality and excellence. This is reflected by the fact that they’re one of the most successful companies in human history – this year is the 100th year they’ve been around. That’s a very large number.

If you’re a bright, motivated student looking for an internship opporunity, you could do much worse.

And I know that personally I couldn’t have done any better.