Tickle

software/Tickle.jpg{teaser}

A 2D Game Engine for the Kotlin programming language.

The main goal is to make games easy and fun to write. Supporting new and old hardware alike, running on Linux, MacOS or Windows (currently it's only been testing on Linux). I also plan to target Android, but that's not currently a high priority.

Don't be put off by the naffness of the Pac-Man clone shown above; that just happened to be the first game I wrote with Tickle. The second Tickle based game, Rapid Rag Doll is more indicative of what Tickle can do.

It works fine on crusty old hardware (it was written on an ageing T400 Thinkpad, which has a really crappy graphics chip compared to modern PCs).

It's built on top of LWJGL (Light Weight Java Game Library), which uses OpenGL for rendering.

The source code is freely available on Git Hub, along with an example game PillPopper and Rapid Rag Doll.

Design Philosophy

Simple things are be simple

Getting a sprite moving takes three lines of code. One for the class declaration, one for the method declaration, and one to actually move the sprite. Scaling will take one more line. Having objects collide and bounce takes one more line.

Common things are be simple

I expect many games written in Tickle to require less code compared to any other game engine.

Complicated things are possible

Help but don't force

Tickle has a lot of code which is not part of the core system which can be optionally used. For example the classes ActionRole and Neighbourhood are really nice, but you are free to ignore them, or even write similar versions that better suit your game.

No 3D models

If you want a true 3D game, go elsewhere! Note, this doesn't include isometric and other "fake-3d" games, such as the original Age of Empires - Tickle is great for those!

Few (if any) assumptions about your game's design

While the main game loop, and rendering of sprites is done for you by Tickle, Tickle can be extended to meet your needs. For example, you are free to write your own fog-of-war view, but Tickle will still perform the actual rendering.

Customisable only where it makes sense

Many of Tickle's classes cannot be sub-classed. This is deliberate. The following interfaces are the primary places for your game code :

Role, Action, Director, Producer, Stage, StageView,

Choice of Languages

Tickle is written in Kotlin, however, you can use whatever JVM language you like, including plain old Java.

You can also use Groovy as a scripting language - no need to recompile, and re-run to test code. Just make your change and try it out instantly. I still prefer to use a compiled language for almost everything. YMMV.

Current Status

The game runtime works well, and is reasonably feature rich. The editor is pretty good, but lacks polish in a ferw places.

I've written a few games using Tickle : Rapid Rag Doll, Pill Popper and Drunk Invaders. Pill Popper is a naff Pac-Man clone (I wrote this when Tickle was still in its infancy). Rapid Rag Doll is a fun physics based game where you throw articulated rag dolls at targets whilst avoiding knocking over fragile items. Drunk Invaders is another simple games (I wrote it to test out Groovy scripting).

Completed Features

  • Resources Editor. This where you define the meta data for each of your game character, the images they uses etc, plus other stuff, such as fonts, input controls and screen layouts.
  • Scene Editor (where each level of your game is designed)
  • "Actions" - A very flexible mechanism to break down each of the game object's behaviour into simpler blocks. I love 'em!
  • Abstracted input handlers supporting mouse, keyboard and game controllers. Game code only needs : if (left.isPressed()) {...} where "left" is defined in the editor as one or more mouse buttons, keyboard key and/or game controller button or thumb-pad.
  • Custom attributes. Your game code can use "@Attribute" annotations on fields, and their values can then be set in the Resources Editor, and the Scene Editor. Attributes, such as "initial speed", or "direction", are editable as a plain text input, but also by dragging "control points" with the mouse.
  • Multiple views. The window can be split into different sections called a "View". Two views could share the same "Stage" (for a 2 player split screen for example). Or more typically each view has its own Stage holding completely different sets of game objects. Multiple views are supported out of the box, without *any* lines of game code needed. The views can overlap, or occupy different areas of the screen.
  • Rotation, scaling, reflecting of game objects, as well as rotation and panning of the view(s).
  • Neighbourhood. Applies an invisible grid to the game world, and keeps track of which objects are in which block of the grid. This is useful for grid based games, such as Pac-Man, but can also be used to optimise non-grid based games. The data structure is created dynamically, and will grow to cover all of the objects in the scene (it doesn't need predefined maximums).
  • Object "hash-tagging". Find game objects based on their tags, without the expense of iterating over every game object.
  • Events: An abstraction which de-clutters your game code. For example, when a Pac-Man power pill wears off, don't specify the new image(s) for the ghost, just call ghost.event("notScared"), and let the meta-data choose the new image for each ghost. An event can also trigger sound effects. This is surprising good when used well!
  • Sound. (Very basic: Costumes can have sound events, but they are not directional, nor is the volume changed based upon distance).
  • JBox2D integration, for physical simulation. Define the shape, density, elasticity etc of objects, and let the physics engine take care of the collisions. For simple objects colliding you won't need to write any code. Even if you scale an Actor, Tickle will automatically scale the JBox2d "Fixtures". You will have to interface with JBox2D for more complex scenarios, such as joints between Actors.
  • Pixel based collision detection. This is faster than using JBox2d, but JBox2D is still preferred if you want natural collisions between different shaped objects.

Notable Missing Features

  • Documentation. Absolutely nothing yet - even the Javadocs are very sparse (or their Kotlin equivalents).
  • Analogue inputs from game controllers
  • There is currently only one kind of view, where objects are drawn in z-order. Other types of views are needed for isometric (2.5D) games. Also no support if you want to reproduce old-school classics like Asteroids or Defender, where the world wraps round from one side to the other.
  • Destructive landscapes (think of the game "Lemmings", where objects can be "eaten away").
  • Path calculation (known as A-star).
  • Scene transitions, such as fading from one scene to another, or sliding one scene away to reveal the next.

Speed

My aforementioned crusty T400 quite happily handles 8,000 circular objects bouncing around and colliding with each other at 60 FPS. And I haven't even started optimising the rendering yet. Using JBox2D, it achieves only about 1,200 circular objects, but the simulation is far superior, and much more flexible.

For the kind of games I want to write, and given that my laptop is very old, the speed is perfectly acceptable for my needs.

Multi-Threading

There is currently no multi-threading in the main game loop. The rendering happens after the game objects' behaviours, which all happen in series. This makes writing games simple, as there are no concerns about locking and such. However, this doesn't make the most of your CPU!

When A-Star path calculations are implemented, these will be in a separate thread, and game writers can spawn threads of their own if desired.

Garbage Collection

A major downside of using Kotlin (or any managed language) for games is the dreaded frame-drop while the garbage collector does its thing. To alleviate this, many objects, such as Color, and Vector are mutable, and rather than creating a new Color object, you should alter the rgba values of an existing Color object. This helps out the GC, but does mean you need to be careful not to share a single instance. For example, you cannot have a single static Color.WHITE (being mutable means it may not *stay* white!).

The Far Future

Don't hold you breath, it's possible that I'll never work on these features, but it's fun just thinking about them!

I would like to support Android devices, but I've not even looked at this yet.

It would be nice to have HTML5 support too, but that's probably harder than Android. Kotlin does support compiling down to Javascript, but I've never tried it.

A Scratch-like version of the editor suitable for young children with no programming experience. Stripped of many complexities, and with the same drag and drop GUI based programming as Scratch. This would be wonderful, but a lot of work!

History

Over a decade ago, my nephew, Matthew introduced me to Scratch. A really nice product for young children to get into programming in a fun, and simple manner. However, I really disliked the anti-patterns that Scratch encourages. For example,every character had its own code, and if you wanted two of them, you had to duplicate the code. Eeek! (Hopefully this has improved since then, but I haven't checked).

I wanted something that was a step up from Scratch - avoiding those anti-patterns, and using *real* classes, and real code (not the drag and drop GUI). i.e. something suitable for teenagers to take the next step in their programming journey.

My first attempt, called Itch, was written in Python, and I soon realised, that I hated Python. Being a dynamic language, even something as simple as renaming a class or a field is HARD! I did finish Itch, but created only one decent game - a souped up version of Thrust - A BBC Micro classic.

So, I started again from scratch (no pun intended), and created Itchy, written in Java. At the time SDL 1.x seemed like a good back-end, but it has its limitations. Firstly, it doesn't use hardware graphics acceleration. The speed was still decent though. Oddly, I tinkered with SLD2, which on paper should have faster, but turned out to be slower. Not sure why. Hmm. The bigger problem was caused by the lack of Java binding for SDL. They did exist, but sucked. So I created my own, called Jame. Together, Jame and Itchy did what I wanted, but maintaining Jame became too onerous. I have a strong dislike of Windows, and its lack of dependency management. Compiling Jame under windows was horrible. It required a dozen or so dlls, many of which I was not sure of their veracity. Downloading executables from random web sites doesn't seem like a good idea, and there was no way to automate the C dependencies that I needed. Compiling under Linux was a bit weird, but worked well.

Despite my (too gentle?) persuasion, my target audience for Itchy (my nephew) didn't use Itchy, which is a shame, but I did create numerous games myself, including Pyrox, which is a Repton/XOR style game, also BBC Micro classics, both of which I loved as a child.

About a year ago, I discovered the language Kotlin, and it soon supplanted Java as my favourite language. It was time for a Kotlin based game engine, and Tickle was born. After a mere six weeks work, Tickle reached the point where I can start writing full-featured games.

I don't consider Itch and Itchy a waste of time. Firstly, they were both enjoyable to write. Secondly, it has been fascinating to reimplement the same basic design goals three times. I can see how much I've improved as a programmer. It's also given me insights by comparing different technologies : Python vs Java vs Kolin and also PyGame vs SDL vs LWJGL.

One reason for Tickle's rapid development is the re-use of another of my projects : ParaTask. The Resources Editor relies heavily on ParaTask, and the Scene Editor uses it a little too.