1. Star Child
  2. News

Star Child News

Star Child Dev Log #20

Jay Ingle - lead developer, designer, and artist:

This week, we are going to take a look at how I create an enemy for Star Child, from start to finish. Minus the graphics; I prefer to prototype and get it working first, then refine the visuals. This week I will talk about the nodes that I need, and how each are set up. Next week, I will talk about the code.

Here is our finished product, with placeholder graphics:



Here is what we can see in the editor. Note our node structure on the left side.



You may also notice that not all of my nodes are named very well, but that is not a big issue, since we will be using well-named variables that reference each node, in our code, as you can see here:



Our root node is an Area2D, which I like to use for enemies whenever they do not need to engage with the physics engine. Area2Ds can be moved around directly with code, or using an AnimationPlayer. We will be doing both.

We are using a Sprite2D node for the graphics:



A simple spritesheet contains each frame. You can see under the Animation heading on the right that this spritesheet contains 8 horizontal columns, and 1 vertical row. These frames will be accessed and animated by the AnimationPlayer.

I have created a Marker2D node, which marks the spot where our lava bombs will be spawning from:



Here is a look at our AnimationPlayer node:



We have two animations: 1 for Walking, and 1 for Firing. Our Walk animation autostarts when the scene is loaded, and our Fire animation starts whenever our cooldown timer finishes. This is what happens during the Fire animation:

First, you don't see it here, and I will talk about it more next week, but the enemy stops moving. I stop the enemy, then the animation is played, which means the enemy sits there for 1 second before beginning the actual firing animation. This telegraphs the attack and lets the player get out of the way.

Second, the attack animation begins, and halfway thru the attack frames, fire() is called. This spawns the lava bomb, and the details of how we spawn that bomb will be discussed next week.

Finally, at the end of the animation track, we call start_walking() again.

A few other nodes of note:

I am using four raycasts to detect walls and floors, and tell the enemy when it is time to turn around. For previous enemies I created, I just used two, and had them switch sides when the enemy turned around. I thought using four would be simpler, but to be honest, this way introduced another possible bug that I did not like. I resolved it, but I think in the future I will be doing it the previous way.

FireCooldown timer controls how long before the enemy fires again.

TurnAroundTimer fixes a possible bug where the enemy gets stuck turning around over and over. This might be solving a problem with the two-rays system that I'm not using here, but it has become somewhat of a standard thing I do for this type of enemy.

TimerDeath starts whenever the enemy is destroyed by the player. It waits a couple seconds then removes the enemy from the world. We cannot immediately remove the enemy, because then you wouldn't see the graphical effects that occur immediately upon/after death. More on that next week.

We also have a CollisionShape2D node, a ParticlesExplosion node, and a few Audio players.

And that is our basic node structure for this enemy, tune in next week and we will dig into the code and see exactly how everything works!


Janne - the other guy:

One of the things I had to change was a bit of the internals of the automap system. Previously I built it with the plan that we'd be building one large connected map, with individual levels identified by coordinates with A-Z for columns and 1-99 for rows. The plan changed and instead we wanted to support multiple zones with their own coordinate system.

What I decided on was that I didn't want the automap rendering part to know about any of this, so the data structures I had in place already for rendering shouldn't change and I would just change the values as necessary.

The initialization logic became a bit more complicated as I needed to initialize the structures for each zone, and determine the coordinate and zone from the file path, but in the end it didn't take very long to change. I already called a function in the automap data manager when switching levels, and now that function also checks if the zone is changed and switches the data structures given to the rendering layer to the correct zone.

Save structure also changed to support saving known coordinates for all different zones, but that was relatively simple as well since we're clearly in a pre-release state and I didn't have to care about supporting the data in the old save files, so instead I'm just throwing away the automap state in the old format.

Star Child Dev Log #19

Jay Ingle - lead developer, designer, and artist:

Godot has a neat AnimationPlayer node. It can do just about anything you can imagine. It can even call functions located in other places, so the power is nearly unlimited.

When I first began using Godot, and I needed something to happen at a certain time, I would use a Timer node. Then I would set up an AnimatedSprite2D node for the animations. Let's say I want a hitbox to be enabled at a certain time during an animation. Well we can start the Timer and the animation at the same time, and then when the Timer finishes, we enable the hitbox. Then when the animation finishes, we can start a different timer that will restart the animation.. and restart the other Timer... and hopefully you can see how this quickly becomes complicated, even for something simple. The other problem is that the animation is not exactly tied to when the hitbox is enabled. It SHOULD be synchronized, and if I have set my Timers correctly, and animations are a certain length, then things will be synchronized, but will very easily break. Any change to any component will destroy the timing. AnimationPlayer nodes remove all the guesswork, and tie things together real nice.



Above, we have added sprite frames from a Sprite2D node, and we call functions enable_hitbox() and disable_hitbox() at specific times. We have a nice visual where we can see which frame is shown at the time of those function calls. We could easily set this to loop, but at the end of that timeline I am calling start_timer(), which is how long until we restart this animation again, because I want a little more control of how long the flame is inactive.



Here we can see that you can even keyframe aspects of a particle system. We can change colors, increase or decrease amount of particles, and many other things.

If you are new to Godot, and you are using AnimatedSprite nodes, I would advise switching everything to Sprite node plus AnimationPlayer instead. Especially if you are not too familiar with animations and keyframes in general. AnimatedSprite nodes are very simple, very basic, and do their job well, but AnimationPlayer nodes are much more powerful, and will save you a lot of time and effort. Let them do the heavy lifting!

Star Child Dev Log #18

Jay Ingle - lead developer, designer, and artist:

Let's say you want to make a video game in the Metroidvania style. You have a large amount of reference material, but how do you make your game unique? One way is to use The But Technique. Here's how it works.

In the original Metroid, there is a seahorse-lookin thing that rises up out of lava, and shoots at you. Like this:



So far, all we have done is copy what Metroid did. Now let's apply The But Technique. We have a seahorse-lookin thing that rises up out of the lava and shoots at you.. BUT... but what? But whatever you want! How about... a seahorse-lookin thing that rises up out of the lava and shoots at you, BUT the projectile is massive.



Now we have something much more interesting, and even unexpected. This was just the first thing I thought of. But ideas are easy when you just let them roll out of your brain:

A seahorse-lookin thing that rises up out of the lava and shoots at you..

BUT... the projectile is massive.
BUT... the seahorse rises all the way out of the lava then shoots in all directions, then explodes.
BUT... the projectile is an enemy that hits the ground and starts hunting for the player.
BUT... the projectile is a planet.

Apply The But Technique by brainstorming a list of a bunch of random alterations to the original idea, unfiltered and straight out of your own personal unique creativity. Then pick the best ones and try them out!

Now I don't remember the first time I heard about this technique, or even what it was called then, but shoutout to Dev Worm on Youtube for reminding me of it (Dev Worm has good tutorials for Godot beginners).

Star Child Dev Log #17

Jay Ingle - lead developer, designer, and artist:

Sometimes I wonder what this devlog should be about. Is this a bullet-point list of what I have spent my work hours doing this week? Do I really want to tell you everything? There needs to be surprises!

Sometimes I feel like talking about broader issues in independent game development. How do you learn to code? What tools do you use?

Sometimes I want to talk about more personal things. Motivation, inspiration, work ethic.

I did a lot of things this week. I spent time working on automatically adjusting particle effect colors for new environments. I created some lava for you to fall into. I created an enemy that rises up out of the lava and spits at you. I also added the ability to switch the music to the next song by hitting a hotkey, for me and the playtesters as well. I also installed a Godot plugin, called G.U.I.D.E., which handles input. Remapping keybinds in Godot can be a massive pain, and G.U.I.D.E. does a great job at providing a much simpler framework. It also has full documentation, as well as several video tutorials on Youtube, created by the developer. Highly recommended.

This week, I studied a lot. If you are looking for the best overall pixel art course that I have found online, check out Pixel Art Master Course on Udemy. It's very thorough and helpful. I spent time reading a game design book called Level Up! by Scott Rogers. It is very good at breaking down all of the details of game design. I read Beginning Game Development with Godot (2021). I did not learn much. I am not THAT much of a beginner. I also read some of a French comic book called "The Obscure Cities" and the mysteries in the stories are very much inspiring my subversive creativity.

Here are some tools I use for game development. The Godot game engine. Very nice, open-source, constantly being updated, and learning resources are abundant. Pyxel Edit. This is the best tool for creating tilesets, period. It is not as fully-featured as Aseprite, lacking powerful features such as custom brushes, but for simple pixel art, tilesets, and animation, it is extremely useful.

Now how is my personal game development journey going, for me? Well, I am motivated. This is my dream job, since I was a little kid, and I have a huge drive to create worlds, craft stories, and provide unique experiences to players. I want to create games that are infused with my own personal creativity.

Once upon a time, I watched Twin Peaks season 3. I thought it was the single most uniquely creative visual project I have ever seen. Everything single moment of the show was pulled from the depths of David Lynch's creative mind. And I was ashamed. Why am I not putting ALL of my creativity into everything that I am doing with my life? I remember this moment, and I continue to work to release the unique vision that I have inside.

Star Child Dev Log #16

Jay Ingle - lead developer, designer, and artist:

First, there was Purple Alien. This is the environment we have shown in most of our screenshots and videos to this point. Our task was to fully create ONE of several environments in the game, and besides a bit of art still to do, everything is functional and not a huge step away from release-quality.

The Purple Alien environment includes a purple tileset for walls and floors, several types of plants, mushrooms, and rocks, native enemies, and a few environmental hazards/mechanics. The Purple Alien environment also has its own background, and music track.

This week my task was to create the next environment, which I have dubbed Fire Mountain. A simple palette swap works for the base tiles, since this is also a rocky-type environment. Hue-shifting my starry sky background to a nice yellow seems to work well.



As for the local flora, a palette-swap of the Purple Alien plants does not seem appropriate for this hot place. So, I created plants that hopefully appear to fit into this area.



Some good news is that I don't have to rewrite code when it comes to having these plants animate whenever they are brushed against in the game. I could have one single plant object that changes to a different type based on environment, but since this is a different plant, which will be used in a different place, I choose to make it a separate object.

For environmental mechanics, so far we have pillars that rise when you shoot the appropriate switch, and blocks that crack and then break and fall away when you step on them. I showed these in the previous devlog. I will also add lava tiles, you have to have lava in a Fire Mountain after all.

And enemies. I have ideas, I have sketches, and it's time to get back to work. Come back next week to see what fiery bitey things will be chasing you all over FIRE MOUNTAIN!


Janne - the other guy:

Lately I've been doing a lot of things outside the game itself, e.g. setting up our official community Discord server with clear rules, roles, channels and all that, as well as preparing all the things needed for playtesting to start. Requested our playtesting keys from Steam and set up tracking for which ones we've used already, wrote guides for how to get the testing done and what kind of feedback we're looking for, and coordinated with Jay to ensure that we have a nice amount of content for people to test. It's still early stages though so the content is just a small fraction of what there will be.

You can now join our community Discord at https://discord.gg/yQRADXHvXY

I also got to experience the joy of previous good habits paying dividends when I fixed a bug with some character state not being saved correctly being fixed essentially with 3 lines of code in the same file with the state. The really nice thing here was that it was really easy to find the relevant code after not having touched it for months. Another potential complaint was that we might not be fully resetting character state when starting a new game, and a likely solution took only 2 lines.