Linux Game Jam 2018
Status | Development | Source |
---|---|---|
Ongoing | Inactive | GitHub |
1st Day
Since our plan was to use separate repositories and keep them roughly in sync I
created a GitHub repo with a mostly empty Godot project for everyone to fork.
This way GitHub can visualise the flow between the different forks.
While our artists started work on the tile sets and main menu graphics, I set out to get some basic controls for the player and another programmer started work on the main menu logic.
After a short while I had a kinematic body controlled by the player and bound by gravity. Using placeholder graphics this means I played a rectangle sliding around on a platform. Also a rectangle. Both in white.
Gravity proved to be a little tricky at first since kinematic bodies aren’t usually subject to it in Godot. So it had to be implemented manually. Following a simple tutorial and overlooking some things my downward velocity kept increasing even when standing on the platform. So after a bit I would shoot down like a bullet if I moved over the ledge.
After some searching and hints the issue was fixed and the player is now correctly accellerated by gravity and stopped by the ground. I also added jumping to the rectangle’s capabilities and cleaned up the input code.
In the meantime the first tile set neared being finished. But it getting late the dimensions weren’t quite suitable and the image had a non-transparent background. So not ideal to work with.
I decided to whip up a quick texture and build a simple demo level to hop aroudn it. The tile set is hideous, but I’m a fabulous rectangle jumping around on some floating platforms, so I don’t care.
2nd and 3rd Day
Over the weekend we played around with the game’s gravity. Its strength greatly
influences how “snappy” a game feels, especially when jumping. A “standard”
gravity of 9.8 (m2/s) often feels sluggish and tends to look like
your protagonist is walking on the moon. “Giant steps are what you take…”
Similarly games trained us to be surprised if a jumping character actually
follows a parabola like an object in vacuum would. Not so much because they
model air resistance but because many increase gravity on the way down, if they
use physics at all, or just play a faster animation.
It just feels springier. After several tries we settled on 3.5g “standard”
gravity with a factor 4 for falling.
I also spent some time creating a larger tile set for the demo level. Firstly to get a better feeling for which tiles could be useful and secondly to have more freedom in creating levels for early play testing. Doing this I noticed that the 36 tiles I created are far from a complete set and that the approach of creating all tiles for all situations (which type of tile neighbours on which side) in all rotations may not be the best approach. Since Godot allows for rotation and flipping of tiles, only one instance of a certain type is required. Also it may be advantageous to layer background, border and effects separately, which may allow for more freedom in the look of tiles.
There were some changes in the team, too. Two members left us, as they weren’t partaking in the development of the game in any way. A programmer and the tester. The programmer was replaced and we have now three active programmers, as the fourth is still primarily doing graphics.
Our happy rectangle has a much more complicated task now.
4th and 5th Day
I started implementation of the whip, our primary weapon. As per usual I used a
rectangle as placeholder graphic. The first question to answer was which
PhsicsBody2D
to use. We don’t want the whip to collide with enemies or the
environment in the physical sense, so Area2D
seemed the logical choice. Which
is not to say that it was my first choice. But after seeing the whip move due to
being extended through the ground I settled for something “non-corporeal”.
Then I needed to figure out the necessary transformations to point the whip in
the direction of the mouse pointer, which I chose as the appropriate input for
that task. At some point we may want to support a gamepad, but first things
first.
With the whip oriented correctly, appearing on mouseclick and disappearing 0.2 seconds later, while also enabling and disabling its collision, the basic functionality was implemented. Now for the fun stuff.
We want the protagonist to be able to swing on the whip to clear large gaps or jump a little higher. Indiana Jones, anyone? So I needed to find a way to constrain player movement to a circle around an achor point. First I tried actually constraining the player position around a centre the way you would in a top-down view.
- Check the distance to the centre
- If distance is larger than radius calculate new position
- Set new position if required
This approach worked fine when the player is above the anchor point, limiting
the jump height. When the player is supposed to be suspended in mid-air by the
whip, however, it behaves in wonderfully glitchy ways.
Having found no simple way to do this I opted for a somewhat cheaty alternative.
An out-of-the-box solution. I decided to place a capsule shaped collision
polygon around the player when tethering him to an anchor. With the polygon set
to segment collision this restrains the player to the inside of the capsule,
serving the same purpose as the previous approach. But I don’t need to do
anything for it. Godot’s physics engine does all the work. The downside is, I
need to convert the player to a RigidBody2D
, which means I have to rewrite a
good portion of its script and rework the input concept. A task that lies ahead
of me, as of writing this. And I’m not looking forward to it.
6th and 7th Day
While my team-mates have kept busy with tiles, animations and enemies (which
aren’t quite there, yet) I finished up the implementation of the whip.
The introduction of a capsule to mimic being suspended on an anchor point proved
a great workaround for implementing actual physics. Converting the player to a
RigidBody2D
, however, was not. In fact it turned out quite the opposite.
Trying to coax the rigid body into behaving like a kinematic one really wasn’t
going to be worth the effort. While it can easily be configured to move like a
KinematicBody2D
and has to be moved through code in the same way, it doesn’t
offer the same API and is therefore much more hassle to control.
It turned out to be fairly easy to implement the bit of missing physics for the
kinematic body, but it took several hours of trying otherwise to come to that
conclusion.
However I did eventually and now the whipe will tether the player to stalagtites
in a believable enough way. The player can then jump off from there, for a
little extra height or distance.
This mostly finishes the implementation of our core mechanic and I’ll probably
turn to creating the final tile sets from the graphics our artist made and
perhaps create a proper level.
8th Day
We’re very much on the final stretch. I created a tile set for the graphics that
were finally finished, added the animation to the player and messed around with
creating an enemy a little.
The enemy doesn’t currently hurt the player, but is just a general pain to be
around. It’ll walk straight into the player if it can see them within a certain
distance. It’ll happily block you into holes and dead ends. Luckily it’s also
dumb as a rock and just barely capable of navigating its surroundings. It will
happily walk into any hole in the ground in its attempt to reach the player. So
it can be outmaneuvred fairly easily.
Final Day
The last day did not go as smooth as I had hoped. I had planned to only polish
up what we had, but it seems I didn’t communicate that plan clearly enough.
We ended up making a sprint to implement or at least to try to implement several
more or less crucial features. A proper jump animation turned out to be out of
reach in the short amount of time. As for a motivation, we opted for a simple
fetch-quest through a cave maze. Given our relatively obscure control scheme an
explanation was necessary and thus implemented. In my opinion the chosen
solution was overly elaborate, which cost much of what little time we had left.
As was the credits screen.
In conclusion we ended up being unable to submit our entry due to a what I
presumed to be a hickup in Godot. The editor had repeatedly stumbled when git
changed the working directory due to merges or checkouts. Usually those glitches
resulted in resources not being found or incorrect errors being displayed.
Previously they could always be fixed by restarting the editor.
Looking over the code in the peace and quiet of post-mortem it turns out that
all elements of our level are on the same physics layer. This causes the finish
marker to trigger a collision as soon as it’s loaded, as it collides with the
environment, loading the credits scene. Mystery solved.
I fixed the project and made a final commit. It was a fun experience and very educational. I won’t continue development of this project and what I gather from the others, neither will they.