About ctz
ctz's Trophies
ctz's Archive
Deadweight: post mortem
My first LD, and well, that was a lot of fun!
I called the game I made Deadweight. It’s a puzzle-platformer which revolves around a boy taking his narcoleptic sister on a day out.
Overall I think it’s pretty successful. The gameplay is simple, with variety and challenge coming from level design. There are 12 playable levels, plus two for intro and outro.
I economised on art by choosing a cartoon style, and having all characters made of circles. I think they turned out with a lot of personality, considering…
Assorted technical details
Levels are defined by way of numbered PNG images, starting from 0.png. Pixel colours in each file define the world, and gameplay parameters such as start and goal position. Each pixel is one game metre, so the images are small.
Here’s the first level and seventh levels:
Each level PNG has a text file for dialogue — this is a pipe delimited file displayed before gameplay begins. It’s used for the start and end levels as well as the name of each level.
Source documentation
A quick tour. The source looks like it was rushed because it was!
- BallEnemy: this is the red enemy balls, which try to knock you around. Before each physics step, they apply an impulse toward the player. You can probably tell the ‘prephys’ method was hacked a lot to balance their strength.
- BoxEnemy: these were originally enemies, but I changed my mind. They are the grey cubes and circles which are mostly inert.
- Consts: tuning constants.
- Eyes: shared code for eyes. I spent a long time on this. Eyes have three modes: search, random or movement. In ‘search’, a small AABB is queried around the eyes for other things with eyes — the eyes look at the eyes of this other thing. In ‘random’, the eyes choose a random target vector each blink (so, they look around). ‘Movement’ makes the eyes look in the linear momentum vector.
- GoAloneListener: libgdx ApplicationListener. This manages movement between levels by instantiating ‘LevelStage’ objects and directing calls to them as necessary.
- Help: big heap of boring static functions.
- Input: a libgdx InputProcessor. This stores input state which is applied each physics frame. It also allows input to be blocked for a number of physics frames for debouncing purposes.
- LevelStage: you know God classes being bad? This is one. This takes care of physics steps, entity management, rendering the level, level state management, building the background gradient quad, panning the camera to follow the player, reading and rendering the dialogue, and reading the world. Phew!
- Player: this is the player entity. It draws itself, and implements movement left and right (both on land and in air, which was irritating to implement!) and jumping (with debouncing).
- Runme: libgdx stub which makes a GoAloneListener.
- Sister: the inert sister entity, and also the mother.
- Sound: Plays game sounds and music.
- Textures: loads the single texture atlas and doles out textures from it by name.
- Weight: unused (a precursor to the sister class which I forgot to delete!).
- WithPhysicsBody: A bunch of concepts common to most entities in the world — like ‘things with eyes’ and ‘things subject to physics’ and ‘things with a position, size and rotation in the world’.
- WorldTile: cloud and world tiles. Includes bonus layering violations!
Things I would have done differently
- Be happy with the physics parameters before making non-trivial levels. The size, mass, bounce, friction of entities changed late-on which required rework of all levels — a total waste of time which would have been better spent adding to levels.
- More frequent breaks. I was burned out 6 hours before deadline, so I could have taken it easier on Saturday.
Things which worked out
- The level construction method was pretty fast, if a little ghetto.
- libgdx. Really useful features, without imposing structure. I found a bug part-way through which happened to be already fixed, so I rebased on a later version.
- Fruityloops. I got this only recently, but I turned out some satisfying music in a couple of hours.
Things still to do
- Android port. It’ll need some onscreen controls building and I’m a little burnt out now.



