Since my participation in the Ludum Dare 54 Extra in October, @dindotdout and I had been talking about participating in a game jam together. I finished my year-long self-study of music theory in February and finished reading the Project Management Body of Knowledge (PMBOK) in March, and thought that this would be a great opportunity to put all the acquired knowledge into practice. I got bored of making 2D pixel art for my games, and so in order to spice it up, I knew I wanted to do a 3D game this time around.
Preparation
Last time I participated with barely any knowledge of Godot (although I had used Unity and also implemented some of my own game engines before), so in order to be better prepared this time I did both the 2D and 3D tutorials, as well as reading the best practices page from the Godot documentation. @dindotdout had work experience with Godot, so that was really helpful. I also watched some videos on how to use Blender. The fact that Godot could easily import .glb files exported from Blender was really handy.
I set up a shared Google Drive folder and created three documents: Project Development Approach and Life Cycle, Project Team and Work Distribution, and Tools.
In the Project Development Approach and Life Cycle document I detailed the project development approach, the stages of the project, how the event works and how the stages fit in with the way the event works, and what will be done in each stage of the project. I decided on a hybrid project development approach, with up front planning to be completed before development so that everything is more or less clear and everyone is on the same page as to what game we are making, and then the development itself being agile. I decided on this approach because in my experience, planning on the go leads to team members being confused and not knowing what to do and wasting time idling and waiting on other team members to clarify things. This does not mean that changes or new ideas cannot be proposed later, but that having a clear game essence prototype as a basis early on is more efficient.
In the Project Team and Work Distribution document I listed the team members and what role is assigned to each team member. We tried to get another developer and composer on board but they decided to go their own way and make a game separately. We also tried to get a game designer on board but they had too busy a schedule to participate. So in the end it was only the two of us.
In the Tools document I listed the tools that would be used to make the game.
I also set up a Trello Kanban board and GitHub repository with a blank Godot project, and created a Links document in Google Drive so that team members can find the link to the Trello Kanban board at any time.
The Jam begins
The planning
On Saturday, April 13th at 3 AM CEST, the Summoning theme was revealed and we had an on-site meeting. We first knew that we were going to make a puzzle game with multiple levels, where in each level the player had to go from point A to point B, overcoming obstacles and hazards by using cards to summon creatures and objects. I had the Idea of making a hand of cards 3D UI to summon creatures and objects. @dindotdout proposed the idea of making a 2D platformer with a card effect that is something like a slingshot, where you can adjust the trajectory. We then had a debate between making the game in a first-person 3D view and a platformer game-like 2.5D view. We eventually settled for a 2.5D platformer game-like 2.5D view. The next topic of discussion was whether to make the game turn-based or real-time. Initially, we were working under the assumption that we would be making a turn-based game where each card use counted as a turn. Under this assumption, we had to split the cards into two categories: basic actions such as walking and jumping, and summons. We worked out some card ideas: a fire-breathing dragon that burns enemies and obstacles (and the player too, if they were not careful setting the position and orientation of the dragon), an air-breathing dragon that could be set and oriented either to blow upwards or forward, a catapult to propel either the player or a dragon, a block to be spawned mid-air, and a teleport, which I had the idea to make into a UFO.
So far we had the following clear: we were going to make a turn-based 2.5D physics-based puzzle platformer card game.
We planned for some hazards to appear in the game: death by friendly fire if the player made the fire dragon breathe in the player’s direction, enemies that shoot at you and spikes. Here we detected a problem with the turn-based aspect of the game: if one shot is all it takes for the player to die and the enemies have perfect aim, then how is it possible for the player to dodge and not die in one turn? Hence, to make things simpler, we dropped the turn-based aspect of the game and decided on having free player movement instead. This also simplified the card system, since we no longer had to split the cards into actions and summons, only summons remained.
Cutting corners
In the end, out of the planned cards, the fire-breathing dragon was dropped, the wind-breathing dragon made it but without the ability to set its orientation, the catapult was dropped and so was the block that spawned in mid-air, although a similar unplanned card did make it: the Sticky Slime, which is a static object that can also be spawned mid-air. The teleporting UFO also made it into the final game. No hazard and no dynamic obstacle made it into the game, so in the end we made a purely map-based puzzle game with no way for the player to die. There was one more thing that was planned but we forgot to put it in the game: a counter of the remaining cards in the deck, besides the visible 3 cards in the hand. Also the hand of cards UI was implemented in 2D and not in 3D as originally envisioned.
In the middle of development I came up with an idea of cards passively affecting gameplay: pulling out a cursed card from the deck that kills the player if they move right while the card is in the hand and the only way of getting rid of it is to pull a scissors card that cuts another card in the hand. There are unused unedited illustrations left over that were intended to be used for these cards.

Something which we wanted to do but didn’t due to time constraints is adding decorations to the barren map. There is an unused grass texture and an unused rock model and texture.

The development
Due to personal commitments, we started development on Sunday, so we only had two days to develop the game. It is worth mentioning that we used Trello as a Kanban board to remember and distribute the tasks. What follows is a log of the order in which things were implemented.
Development log
Sunday, April 14th
@andriybyelikov: implement the 3D world scene using a GridMap and a player character scene with basic character movement and jumping physics using a CharacterBody3D.
@dindotdout with @andriybyelikov: implement the hand of cards UI and the UFO’s teleport card effect, using Camera3D’s project_position. Add “Contra musas privo boni” as placeholder BGM. We now have a working prototype with a level map, player movement and jumping, a hand of cards UI and the teleport card effect of the UFO.
Monday, April 15th
@dindotdout: implement summoning range mechanic and click terrain collisions.
@andriybyelikov: create the player model, textures and animations.
@dindotdout with @andriybyelikov: attempt to implement the Wind Dragon effect using an attenuation with distance function. Does not work. Look up @andriybyelikov’s uplift force generator demo implementation and fix it by constraining a maximum distance around the dragon inside which the force is active. Add player character “levitate” animation. @dindotdout later removes the maximum distance constraint and re-adds attenuation with distance as a factor.
@andriybyelikov: create the Wind Dragon, UFO, Sticky Slime and the rock models and textures.
@dindotdout: implement Sticky Slime behavior. The player can’t jump when stuck in it, while the Wind Dragon is frozen in place.
@andriybyelikov: replace placeholders with actual models.
@dindotdout: add a stuck speed parameter to the player and increase player normal speed.
@dindotdout: fix the player character spawning on top of the next level goal.
@dindotdout: implement the ability to restart a level and design levels 1 and 2.
@dindotdout: add particles to the Wind Dragon card effect.
@andriybyelikov: draw and edit the card illustrations.
@dindotdout: design levels 3 and 4.
@dindotdout with @andriybyelikov: replace placeholder UI with edited card illustrations and use the UglyQua font.
@dindotdout: implement the ability to cancel summoning with right click.
@dindotdout: adjust level camera.
@andriybyelikov: fill card descriptions.
@dindotdout: update the reset level button font.
@dindotdout: update summoning range texture.
@dindotdout: add Sticky Slime idle animation.
@dindotdout: change level lighting from a directional light to an omni light.
@dindotdout: add the R key as a shortcut to restart a level.
@dindotdout: fix the player sticking to the ceiling.
@dindotdout: replace placeholder level background with a noise texture.
@andriybyelikov: record and edit sound effects. Add sound effects in the game except for the UFO.
@dindotdout: add UFO animation and sound effect.
@dindotdout: create post-processing shaders.
@dindotdout: create title screen scene.
@dindotdout: create credits AcceptDialog in title screen.
@andriybyelikov: compose original music for the game.
@dindotdout: removed random card order and set it to fixed by level.
@andriybyelikov: replace placeholder BGM with original composition and create tutorial billboard textures in GIMP.
@dindotdout: add tutorial billboards in level 1.
@andriybyelikov: create level 6 (5) as reference to the “Time it right!” map.
@dindotdout: fix player sticking to the ceiling (again).
@dindotdout: discard level 5 and add level 6 as the fifth level.
@dindotdout with @andriybyelikov: fix texture gaps in the GridMap by making the blocks in the mesh library slightly larger and adjust chromatic aberration intensity.
@dindotdout: fill credits AcceptDialog.
@andriybyelikov: build and submit the game.
Implementation details
I will now explain how the physics are implemented for the player and the Wind Dragon, as well as the implementation of the Sticky Slime and UFO card effects.
Player
The player character is a CharacterBody3D, which means that it is not affected by built-in physics, but is instead moved based on its velocity. Each physics frame we set a target velocity for this physics body. For moving left and right this is trivial, we just set the target X-axis aligned velocity to be a predefined constant with the sign of the direction pressed by the player. For jumping, we check if the player is on the floor using Godot’s helper is_on_floor function and if the player pressed the jump action, an upwards impulse is applied to the player. Applying an impulse usually involves dividing the value of the impulse by the object’s mass, but for this game we considered that the player character has a mass of 1, therefore it is simplified to simply adding the value of the impulse as-is directly to the target Y-axis aligned velocity accumulator.
Something I learned from reading books on game physics is that one must never apply a force for jumping, since jumping is instantaneous. Due to how game physics are implemented, if one were to apply a force for jumping, it would be like applying a certain amount of force for a certain amount of time delta: the time between physics frames. If this value delta is too large, then too large a force would be applied to the physics body, resulting in a huge leap instead of a jump. An impulse, on the other hand, is independent of this delta, therefore we are applying the same impulse only once in one physics frame, no matter the delta.
The fall acceleration also has to be implemented manually for the CharacterBody3D, and we also have a small fix that stops the player from gaining Y-axis aligned speed when on the ceiling to prevent the player character from sticking to the ceiling.
The player also has a force accumulator that is evaluated to a velocity component and cleared every physics frame. This was necessary for implementing the interaction with the Wind Dragon, which is a force generator.
Wind Dragon
The Wind Dragon is a force generator that has a cylindrical shaped collider. Each physics frame, if the player character is detected colliding with it, a force is applied or added to the player character’s force accumulator. The exact force to be applied is
normalized_dragon_up * force_strength * attenuation,
where force_strength is a constant parameter and where attenuation is
1.0 - clamp(dist(player_pos, dragon_pos) / max_distance, 0.0, 1.0).
The fact that the effect of the Wind Dragon is a force that is added to the player character’s force accumulator means that having multiple Wind Dragons affecting the player stacks their effects. Thus, a player could stack three Wind Dragons on top of each other and the player character would go higher than if there was only one Wind Dragon.
Sticky Slime
The Sticky Slime is simply an Area3D that interacts differently with the player character and a Wind Dragon. If it detects that the player character has entered it, then it sets a flag in the player character that changes the player character movement mechanics preventing jumping and adding the ability to move up and down the Sticky Slime volume. If it detects that a Wind Dragon has entered it, then it sets that Wind Dragon’s RigidBody3D’s freeze flag, so that gravity and forces are not applied to it anymore.
UFO
The UFO does not exist as an independent entity but is instead a model that is used in the player character animation and the teleportation effect is implemented as a special case of confirming a summon by left clicking.
Music
A single original piece was written for the game. I chose the E Double Harmonic Major scale for the main motif in order to achieve an exotic and magical feel. The instruments used are: viola with spiccato for the main melody, seven string electric guitar with amp for the accompaniment consisting of the main melody's structural tones, a string section (viola, cello, first contrabass, second contrabass) for the I-iv-V7b5-I chord progression (with the second contrabass doubling the voice of the first an octave lower), and a drum machine for the percussion (kick, hi-hat closed, mounted crash cymbal). As a fun fact, the funny whistling sound of the chords was not intentional, but added a nice gimmick to the overall sound. I managed to isolate the instruments that cause it: it is the consonance between the vibrations of the viola and the cello. Those who have Bitwig Studio and want to toy with it have the project in the music/ld55_1 folder of the source code. I will also embed the YouTube video with the music below. The video description also has a list of the learning sources that I used for studying music theory.
https://www.youtube.com/watch?v=ZTPTDhJzwgg
Sound effects
The sound effects were created in the following manner. I recorded the sounds using my phone. The wind breath sound effect is me blowing into the mic. The UFO sound effect is a sped up recording of a friend of mine who is good at whistling (I am not). The slime sound effect is a fragment of me slushing some wax with my fingers as loudly as I could, although in retrospect it doesn’t really fit. The card shuffle sound effect is a fragment of me dealing poker cards.
Feedback analysis
I created a Google Sheets spreadsheet compiling, classifying, analyzing and summarizing the feedback received in order to identify areas where the game should be enhanced as is and areas where it should be improved.
We managed to get 73 feedback samples from 33 unique users. The users were split into two groups: commenters and streamers. We got 49 samples from 28 commenters, an average of 1.71 samples per commenter, and we got 24 samples from 5 streamers, an average of 5 samples per streamer. From this data we concluded that streamers give 2.92 times more feedback samples than commenters, aside from valuable recorded gameplay in the form of VODs, for which we created a document listing the links to the VODs and the timestamps of when our game is played.
The samples were then grouped by topic. For each topic there is a count of positive feedbacks, negative feedbacks, score balance between positive and negative feedbacks (p-n), a summary of pros, a summary of cons and conclusions. What follows is the summary of the results of the feedback in the 13 extracted topics.
Map predictability
Amount of feedback samples: 9
Amount of positive samples: 1
Amount of negative samples: 8
Balance: -7
Summary of pros: One player reported that they liked the last level, the one with less predictability.
Summary of cons: Most players reported experiencing frustration from not being able to see further in the map, as it made them waste cards and forced them to restart the level. Mostly in level 5 but also sometimes in level 4.
Conclusions: Unpredictability makes for slightly more interesting gameplay, perhaps also slightly more challenging. Maybe we need to single out what causes the players frustration.
Card system
Amount of feedback samples: 4
Amount of positive samples: 0
Amount of negative samples: 4
Balance: -4
Summary of pros: No data
Summary of cons: Most players reported experiencing frustration from not knowing what cards they would be getting beforehand, and didn't understand whether the cards were dealt in a random order. One player didn't know that more cards would be coming.
Conclusions: No randomness is involved in the dealing of the cards, just human short memory span and removing cards from the hand at random positions makes it feel random. Also we need to indicate that there are more cards coming from the deck.
Chromatic aberration
Amount of feedback samples: 3
Amount of positive samples: 1
Amount of negative samples: 2
Balance: -1
Summary of pros: One player reported that they liked the chromatic aberration.
Summary of cons: Most players reported having difficulties with reading text with the chromatic aberration and annoyance at the expansion pulse.
Conclusions: We need to remove the chromatic aberration from the text and decide what to do with the pulse. We think that this is most biased towards the title screen, for which we forgot to tone down the chromatic aberration.
Music
Amount of feedback samples: 9
Amount of positive samples: 9
Amount of negative samples: 0
Balance: 9
Summary of pros: All players reported liking the music.
Summary of cons: No data
Conclusions: 🤩
Game essence
Amount of feedback samples: 13
Amount of positive samples: 12
Amount of negative samples: 1
Balance: 11
Summary of pros: Almost all players reported liking the game essence.
Summary of cons: One player reported they didn't feel like they were doing what we intended, as in solving the level as intended.
Conclusions: Make puzzles more flexible in terms of intended sequence and add card reloading so that players don't have to reset levels. We think that having to reset a level is a game killer.
Graphical style
Amount of feedback samples: 7
Amount of positive samples: 6
Amount of negative samples: 1
Balance: 5
Summary of pros: All players reported liking the old-school, low-poly, noise-textured graphical style, as well as the design of the player character. One player reported liking the aspect of mixing 2D and 3D.
Summary of cons: One player reported feeling that the map lacks graphical detail.
Conclusions: There was a rock model and grass texture planned to be used as map detail, which weren't used due to time constraints.
Card effects
Amount of feedback samples: 9
Amount of positive samples: 2
Amount of negative samples: 7
Balance: -5
Summary of pros: Some players reported liking the combination of the Sticky Slime with the Wind Dragon and stacking Wind Dragons.
Summary of cons: Some players reported having trouble understanding the Sticky Slime, stating that the description is insufficient. One player reports disappointment at the fact that the UFO doesn't combine with the other two cards. One player experienced inconsistent momentum when using Wind Dragons. One player thought that the effect of the UFO was not what they expected.
Conclusions: It seems like players like to combine card effects most. Some card effect behaviors must be corrected and adjusted, such as the Sticky Slime stickiness and the Wind Dragon momentum consistency. The Sticky Slime needs to be properly described in all its aspects: that it sticks in mid-air and that you can't jump from it.
Technical
Amount of feedback samples: 5
Amount of positive samples: 1
Amount of negative samples: 4
Balance: -3
Summary of pros: One player reported that the bug of the Wind Dragon falling off screen was funny.
Summary of cons: Players playing on high resolution displays reported that the UI was too small.
Conclusions: We need a UI scale solution for large displays. We can keep the dragon falling out of the screen as an easter egg but not as a bug.
Content
Amount of feedback samples: 7
Amount of positive samples: 1
Amount of negative samples: 6
Balance: -5
Summary of pros: One player reported liking that it's a concise game and not a long game with repetitive little content.
Summary of cons: Players want more cards and more levels.
Conclusions: As expected. The concise game idea is opposed to the boring procedurally generated levels idea that so many players dislike. So we need to make hand-crafted levels.
Level design
Amount of feedback samples: 3
Amount of positive samples: 3
Amount of negative samples: 0
Balance: 3
Summary of pros: Players report liking the level design. One player reports liking the tutorial billboards and soft level tutorials.
Summary of cons: No data
Conclusions: Invest heavily in soft tutorial levels.
UI
Amount of feedback samples: 2
Amount of positive samples: 0
Amount of negative samples: 2
Balance: -2
Summary of pros: No data
Summary of cons: One player reported that the credits dialog is too cluttered and that the range indicator should display green when you can spawn the effect and red when you can't, as most games do, instead of red/black, which is not intuitive.
Conclusions: We agree with the observation.
Presentation
Amount of feedback samples: 1
Amount of positive samples: 1
Amount of negative samples: 0
Balance: 1
Summary of pros: One player reports liking the polished presentation of the game.
Summary of cons: No data
Conclusions: Invest heavily in good presentation.
Sound design
Amount of feedback samples: 1
Amount of positive samples: 0
Amount of negative samples: 1
Balance: -1
Summary of pros: No data
Summary of cons: One player reports not noticing the sound effects.
Conclusions: Change and balance volume levels for sound effects.
Mistakes
There was no plan to make a dedicated game cover. I believe we would have benefited from a more eye-catching game cover for our game to receive more ratings. I believe that we should have opted out of the humor category, as the game does not have any humor elements aside from a funny bug. Some players did not rate our game in the category and I believe that it will impact our overall score.
Thanks
We want to thank the Ludum Dare organizers and community for making this event possible, and to the users who rated and left feedback on our game. Special thanks to @saryah, @ategon, @digitaliliad, @justcamh and @stanov for playing our game live on Twitch.