Joined 7 years ago
I used to make games in Haxe, now I make them in Rust. Only gamejam games though … for now!
Using… you know it, Haxe!
Maybe I'll try to make a metroidvania?
For this jam I made (kind of) a sequel to Batterycorp, my Ludum Dare 39 game.
Glad to have finished a jam game after being unable to finish or unable to participate for the last couple of times.
I hope this helps you.
Who could be standing behind that podium?
Join us tonight at 18:00 UTC on DanaePlays channel for the launch stream to find out!
I just finished the timelapse for my entry:
Hope these are fun to watch :)
So the first Alakajam! is over and for those of you who enjoy data and visualisations, I've made some graphs!
Let's start with something simple, but certainly important – which categories are the most important for a good result overall? Here is the correlation table of the six categories:
It seems that Gameplay is the most important for a good Overall result, which makes sense. Audio and Graphics correlate less, so good games with terrible graphics and bad games with amazing graphics are both conceivable. Also note that all the values in the table are quite high (values less than 0.5 would indicate negative correlation). In other words, a "good" game will usually get better ratings in all categories, a "bad" game will get worse ratings in all categories most of the time. More on this later.
Next up, category averages by rating:
This probably tells us more about our voting preferences than the games themselves – people rate games high in Graphics more often, while they are more critical of Gameplay, the actual experience and fun of the game.
What about the best / worst categories for ranked games?
Note that there were no games where Overall was the best or worst rating-wise. It is common to rate the game in Overall somewhat close to the average of the five other categories, so this is not a complete surprise.
Let's look at votes a bit more. These are the counts for each rating value:
This looks like a nice bell curve, though it is skewed somewhat towards 7, as opposed to the true middle of 5.5. We can also guess there are some psychological gaps between giving a game an 8 and giving it a 9. Similar gaps are then 4–5, and 2–3. 2 probably seems extremely harsh to many people, so they'd rather shift their vote slightly towards a 3.
This "spread" is the difference between the lowest and highest rating given to a game in any category. This partly explains the fact that a "good" game more likely gets high ratings in all categories mentioned above.
Now let's see whether a game's results are at least somewhat predictable based on its popularity, measured in the number of received ratings:
Interestingly enough, there are quite a few games which ended up very high, despite being quite close to the minimum required votes (10). Some teams / developers may have forgotten about Alakajam! after submitting their games! Let's look at the same graphs, but this time measuring the number of received comments instead of ratings:
Once again not a super clear trend – we can only potentially observe that getting more than ~ 17 comments on your game means you are likely ending up in the top 40%. This may very well be within a statistical error, so until Alakajam! grows a lot and we can get better data, don't depend on this!
And finally, let's have a look at when and how people voted. The rating period was exactly 14 days. We can see how many votes were cast on each day:
The first day (first 24 hours) was when most people did their voting. The spike on the third day may have been people coming back to AKJ after resting for some time. There is a minor spike on the Saturday of the second day. The results hype attracted the last spike. 40 or so of these votes were from our stream with Danae though!
And finally, I was interested in whether or not the voting averages differed over the days:
Although there is quite a sizable difference (1.26) between the voting average of the fifth day and the eleventh day, I am not sure how statistically significant this is, as there were not so many votes cast on those days. A possible factor could have been that entries which get rated later on more likely need to be "rescued", because their teams forgot to rate other entries. This, in turn, may have been because the teams weren't very happy with their own games. But that is just wild speculation at this point!
Nonetheless, I hope you found these graphs interesting. Stay tuned for the next ones :)
(this is a mirror of the article at my website, so forgive the superfluous description of Alakajam!)
Unexpectedly enough, I participated in another rapid gamejam. This time, it was Alakajam! (mind the !), a 48-hour event held over the September 22nd – 24th weekend. I participated in the Solo division and enjoyed the experience thoroughly.
AKJ (the 'official' abbreviation for the event) is a completely new gamejam, this weekend being its first iteration. Some people think of it as a reaction to the terrible management of LD, which is probably not entirely untrue for many participants, including me. But, this is not a post about that, and in any case, AKJ already has a great community and is very interesting in its own right.
Unlike LD, AKJ is more suited for us, jammers based in European timezone. There was a lot of people eagerly awaiting the theme announcement in the IRC channel. Around 8pm, the theme Space Station was announced with a video. Due to votes in the last hour, the actual theme chosen was Alchemy, however. This was communicated quickly enough, but some people went through with their Space Station games, and then probably submitted in the unranked division.
I was happy with both of the themes, Alchemy was my number one choice, Space Station number two. As the theme voting results reveal, people finally got tired of 'You are the bad guy' and its variation, which LD has seen plenty of.
My initial idea was something along these lines: The player is an alchemist, living alone in a desolate world. However, they can create and mix interesting potions. Using a special looking glass instrument, they can look into their potions and even enter them, finding an entire world inside. Depending on the elements / substances / characteristics of the potion, the world would be different – different terrain, objects, features, people, creatures, etc. (Thinking about it now, this idea seems a bit similar to the linking books in Myst.) The game would then consist of the player entering various worlds and solving problems therein by mixing them with other worlds.
I was aware that this was pretty ambitious for 48 hours, but I wanted to take my game into this direction, even if I did not make it as far. So I started, hoping to waste less time on overthinking my idea. Once again, in gamejams and indie games in general, I find it very important to not be afraid to change directions, even drastically, based on what is fun to develop, what seems feasible, whatever random ideas you find along the way, and so forth.
Here is the first page of my journal for AKJ:
A lot of it is sketches for page-flipping curves. One of the first things I was actually implementing was the neat page-flipping animation for the (in-game) journal. Here is how it works:
A basic page flip consists of a page moving 180 degrees from the left or the right to the opposite direction. Usually a person would start turning at the corner, creating a curve with an axis not identical to the axis of the book spine. For simplicity, however, I assumed the page is made out of individual 'columns' of pixels – like a bamboo mat. This way, we can model the page flip as a 2D curve animation (if looking at the book from the bottom).
An animation consists of moving the columns along a half-circle – at each point in time (t ∈ [0; 1]), each column (x ∈ [0; 1] radii from the centre), is at a specific angular displacement (a ∈ [0; π]) from its starting point. We can say the angular displacement of any column is a function of its distance from the centre and the time – a(x, t) ∈ [0; π].
A basic assumption to consider – the page will begin flat and will end up flat as well. So, ∀x : a(x, 1) = π.
If the page was completely rigid, as is the case for a normal book cover, it would simply be a solid line tracing the radius of the half circle. In other words, ∀x, t : a(x, t) = t∗π.
Normal pages bend a little bit along the way though. For thinking about this, I imagined 4 points on the page curve (the one seen from the bottom). One quarter of the way along the page, one half, three quarters, and finally the tip of the page. Any points will essentially be interpolated. How do the four points behave? Parts of the page should lag behind, others should go faster than the 'rigid' cover. I imagined the halfway bit to stay exactly on the rigid cover curve, moving at a constant pace from beginning to end: ∀t : a(0.5, t) = t∗π. The point closer to the spine will go faster, points further from the spine should lag behind: ∀t, ∀x < 0.5 : a(x, t) > t∗π and ∀t, ∀x > 0.5 : a(x, t) < t∗π This gives it a nice progression.
To obtain this sort of function, I started with the basic linear one (rigid cover), then added a little bit of a quadratic: I've noticed y = x∗x is almost perfect for the lagging bits on x ∈ [0; 1] – it develops slower, but at x = 1 it catches up to the linear formula. I thought it would be nice to be able to get the same curve with the opposite bias. On a graphing tool I came up with y = (1 − t)∗x + t∗x∗x – with t ∈ [0;1] this is essentially a linear interpolation between the quadratic and the linear formula. Even better – negative values of t produce the opposite trend as expected.
And so, here is the final formula I used:
x ∈ [0; 1] t ∈ [0; 1] a(x, t) = π∗((1−t)∗(x∗2−1)+t∗(x∗2−1)∗2)
And a visual representation of the full animation, with the four points highlighted in red:
Note that the point at the spine would have a curve similar to point 4, except with the opposite trend.
To decide which side of the page has to be rendered, it suffices to know whether the last column drawn was to the left or to the right of the current one. The page shading is a bit more messy, but it is basically calculating an offset in the page colour palette based on the distance between 2π the half-way point and the current angle. I added some Bayer dithering to make it pretty, of course.
The animations led to some minor performance problems towards the very end of the 48 hours – the quest and recipe updates were not added until quite late, and as I was running out of time, I decided to rerender the full 40 frames of a page flip (20 each way) every single time that page changed. All at once! Post-jam I fixed this so the frames are rendered one at a time in the background, or in the worst case, just when they are needed on screen. Some people complained of their browsers messing up a lot and the audio freezing during the lag spikes, so I thought it was an acceptable fix.
Mostly happy with my journal but with little else to show, the first night was here. I started thinking about the gameplay and actual puzzle design. Some basic Wikipedia research led me to the seven planetary metals:
I thought this was a good place to start. If the seven metals had characteristics (primary, secondary, and tertiary), maybe mixing metals would result in substances with the primary characteristics kept? Maybe some characteristics eliminate one another? So I thought of seven vaguely appropriate characteristics and arranged them with the elements, until each metal had a unique primary characteristic, and each characteristic appeared exactly three times:
Clearly not all of them made sense, but this was alchemy in a jam game, so I was happy with this. To make the inconsistencies less obvious, I gave the characteristics pseudolatin codenames, and made a symbol for each (see previous journal page). I arranged them in a heptagram {7/3}, each characteristic having two vaguely-fitting opposites. Various tools / methods could then 'bring out' a characteristic (by removing its two opposites).
I also gave up on the idea of potions – substances with characteristics seemed a bit easier, since I was happy to draw pretty icons for items, not so much trying to make potions / flasks look unique enough depending on their elements. With this, I worked out a list of steps the player would have to follow to ultimately obtain the Philosopher's Stone, starting with just a couple of substances. Finding pure (containing a single characteristic only) substances would allow the player to fix tools, usually the tool two steps down on the heptagram.
The list was somewhat tedious to create, since I was worried that players could skip steps by using the right tools. At 08:00 in the morning, I was mostly happy with the steps, had the items (20 at the time) all drawn, and decided it was time to get some sleep!
All fresh and full of energy (ugh), I started my second day.
I sketched a hub world in my journal with various features, then started recreating it in pixels. Happy as I was with how it looked, I realised it will take some work to make it work – pathfinding, objects in front of the player, interactive objects, and so forth.
Somewhat unhappy that I did not have a better (custom) tool for this, I resorted to having a number of layers in Photoshop: the graphics, the walkmap, the interaction map, the overlay map.
The graphics layer is self-explanatory, I hope. It may be worth mentioning that at this time my palette was finalised, with 19 colours total – most for the journal shading. I reused them for the terrain, and that seemed to work.
The walkmap layer was mostly transparent, except for single coloured pixels at places where the player can stand. I differentiated three basic colours – green for 'normal', yellow for 'transition', and orange for 'behind'. Whenever the player is standing on one of the latter two, the overlay map is rendered. This was a surprisingly painless way to give a 3D aspect to the map. For finding out which walkmap node is connected to which, it was enough to ensure that their distance was below a certain threshold (roughly 17 pixels, with some scaling of x axis). Green nodes cannot connect to orange ones. And finally, A* to find paths. Yet again, surprisingly painless. Some pixels had colours like 0xFF111111
(a very dark gray), 0xFF222222
, etc – these serves as markers, their true type was hardcoded. Very ugly, but it worked and allowed me to refer to certain places in the map by a number.
The interaction map was the least elegant solution. There are pure black areas over objects the player can interact with. To identify them in code, I placed a marker pixel somewhere inside the area, and to the bottom and right of it a pattern, usually of 'letters'. In code I duplicated these patterns manually and this is how objects were paired with their scripted interactions.
The desk was mostly the same, except that various objects had to be separable from the graphic, because they had multiple states (i.e. the magnet could be broken or fixed). In the interaction map I placed markers with a pattern at the top-left of the object bounding boxes. The same pattern was then somewhere else in the bitmap (not visible), followed by the sprites for that particular object.
In the future I would very much like to be able to create 'tagged' image files (maybe using PNG metadata?) without having to do all of this during the jam. This would help tremendously when creating GUIs, frame-by-frame animations, tilesets, spritesheets, etc – I will see about integrating it into plustd.
The second night started and I was putting the alchemist's desk / workspace together for a lot of it. I made the crank work. Making the tip of the crank follow the mouse with some momentum was not happening easily with the amount of energy I had (none).
For anyone interested, the angle between the center of the crank and the mouse is calculated using atan2(crank.y − mouse.y, crank.x − mouse.x). This 'target' angle, as well as the current angle of the crank are normalised to [0; 2π]. If the difference between the target angle and the current angle is more than π (180 degrees), we need to turn in the opposite direction.
After the crank, it was the morning of the third and final day. I was drawing the Looking Glass (the blue device you see on screen when warping). At some point I realised I was not fully aware of what I was drawing – the device ended up looking weird enough for it, so I cannot complain. Morning is always the critical point for me when doing any long stretch of work without sleep. But, seeing as AKJ was ending in about 12 hours, I decided to keep going. In a previous LD, this has not been a good decision, but this time it worked out somehow.
I was also entering panic mode. I had the hub world and the desk, but I had not tested any of the puzzle progression, there was no story to speak of, I wanted to have multiple worlds to warp into, I needed an ending, more music (I have played the piano and transcribed a melody or two into the game at some point), and so on …
So I tried to make it quick – neither the Mars nor the Luna worlds are big, and the Mercury 'world' is … not really a world. I put all the important plot exposition in the final dialogue of the game, but oh well. I had a game that was playable from beginning to end. During the submission hour I packaged the game, added a simple title card, and waited until the AKJ website wasn't crashing due to people submitting all at once.
And … that was it! I made a game. Post-jam I added some prettified instructions to the submission page about the characteristics and the heptagram. It was overall a very satisfying experience for me, despite all the flaws in the game that I am aware of, some of which are:
I must say this jam was well organised, and its website a pleasure to use compared to LD. The next iteration is scheduled for February, looking forward to that! Thank you for reading, and I hope you found at least a little bit of this interesting!
Pretty happy with what I've got. The point 'n clicky bits are to make the actual puzzle mechanics (which I've insomnically developed over midnight) more interesting. Slept about 3 hours total so far, aiming to use the remaining 20+ hours fully!