Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Silent Wings 2491

A topic by tmseldon created Jul 04, 2022 Views: 334 Replies: 8
Viewing posts 1 to 6
Submitted (2 edits) (+1)

Hi! I want to share about my game concept so far. Any comments that you have is very welcome! :)

Inspiration:

I'm participating in the jam because I want to challenge me to make a game based on the time and theme of the jam. I started to think what could be a fun concept to take and develop from that.

So, I started to look for some free resources for some inspiration. I found a post on the Jam's forum from @maxparata offering some free resources. But one of the assets took my attention! it was a plane voxel pack, and it reminds me to a very old game that I used to love and play all the time when I was a kid on my Atari 800XL: '1942 Screaming Wings'.

'1942 Screaming Wings' screen:


Voxel pack from @maxparata, you can find more awesome assets!


Immediately, I knew that it was a great opportunity to take that game as a concept and start from there. Also, to make a homage for that game that I enjoyed so much long time ago.

Game Concept:

'1942 Screaming Wings' was a top down scroll shooter and the main goal was to reach the aircraft carrier at the end. It was fast and it needs some skills on later levels to avoid and shoot the swarms of enemy planes. So, how could I integrate the jam's theme into the game?

'Heal' is the theme for this Jam, I was toying with some ideas and then I imagine the player guiding this P38 Lightning plane but without weapon systems and also in very bad shape. The only thing that the player could do, it is to guide the plane to the nearest aircraft carrier to be 'healed' while swarms of enemies try to shoot down the player's planes.

However, after arriving to the nearest aircraft carrier, the player would look for a mechanic who could 'heal' her airplane, but I remember this painful image that I have in my memories as a kid:


So there, the mechanic in the aircraft carrier would say to the player that her airplane could not be 'healed' in this place, but they will offer the player some options, like +'x'% of armor, 'y' numbers of evasive stunts, etc. Some kind of buffs that allow the player to continue to other aircraft carrier. Basically, similar to the buff systems from roguelike games.

Now, I have a game concept that I like, a top-down scroll game where the player needs to control a airplane in bad shape, without the ability to shoot. The player needs to evade and escape in order to get to the next airplane carrier to look for someone who could help her 'heal' the airplane.

For that reason, it is that I'm calling this project 'Silent Wings 2491'.

Next things to develop:

    define the player's experience

    refine the gameplay

    start with some experiments: movement, camera, etc.

(+1)

Very well put idea and good explanation. If I understood correctly, the player can not shoot or fight back? It would be fun to add some "tail gunner" to shoot directly from rear of the airplane: https://en.wikipedia.org/wiki/Tail_gunner This guy can run out of ammo or get killed but player can replenish him at carriers.

Submitted

Yes, the player cannot shoot or fight back. The tail gunner is a brilliant idea! I could use it as one of the buff/perks that the player could get from the aircraft carrier. Thank you!

Submitted (1 edit)

[NEW UPDATE! n° 2]

Player’s experience

Now that I have the game concept, I can think about what kind of experience I want for the player. Since the idea is to reach safely to the aircraft carrier, the experience that I want to achieve is something fast, frantic and hurried.

That means that while the player goes deeper and deeper into the game, the challenge should rise accordingly. 

Gameplay Design

I draw this mockup to think on the gameplay’s elements:


The main idea is that the player will guide the plane (at the bottom) trying to evade the swarm of enemies. Enemies will have three kind of pattern: predefined, trying to hunt the player if they are near, and miniboss (they will stay a while on the screen, and then disappear)

The player will have some perks/buffs that will aid her to face this challenge: speed, armor, evasive stunts, dash, and a tail gunner (thanks @fancyfatfrog for the idea!). 

These elements will have a number of uses per level and some of them will have cooldown as well. So, the player should be careful about their management. For instance: at level 1 the player only has two evasive stunts and it cannot use another one after 5 seconds.

Evasive stunts and dash will provide a short time of invincibility; armor will provide some defense against bullets; increase in speed will be always active though, and tail gunner will shot from behind for a period of time (not sure yet if the tail gunner will shot everything that is half below of the plane, or it will shoot doing some patterns in the whole screen like a spiral.)

Experiments with new Input System

I decided to use the new Unity’s input system for this project since I haven’t experimented too much with it. Also, I have the intention to make a mobile version of this game after the jam and I saw that the new input system allows to make that transition in a seamless way.

I implemented the basic movement, dash and evasive stunt. It was a quick implementation of these elements. The next thing that I need is to think how to make isolated states for each of them (maybe a state machine?)


Basic Movement:

Dash:

Evasive stunt:


Next things to do:

  • Enemies movement, implementation of the three strategies
  • Implementing a base stat class for each element on the game
  • Think on the state machine or alternative for the perks/buffs

Nice progress. I am also working with Unity. Have you consider using any "Tweening" library for movement/animation? I specially like "DoTween" for its speed and simplicity.

Submitted

Thank you! never used it. I was looking the DoTween's documentation and it seems really great. You can also control some lightning, materials, and sounds. I'll definitely try to use it and learn more about "tweening" in general. Thanks again!

Submitted

[NEW UPDATE! n° 3]

Enemy development 

Hi! I’ve been busy developing the ‘enemy part’ of the game. However, I managed to make a huge progress in this part. I’m also including some problems that I had during the development of this part. Maybe it would be helpful for you..

Enemy variants and movement

As I posted before, there are three types of enemies: following a pattern, trying to chase the player and minibosses. I started to think in a way to increase the difficulty of these enemies once the player reaches new levels.

So the first thing that I did was to develop a way to modify the enemies’s stats based on levels. I created a scriptable object that manages all this information. This allows me to fine tune the parameters in an easy way.


Also, I make some variants of the assets in order to make the game more colorful. Since the stats of the enemies are stored in the scriptable object. I managed to separate the stats and the look of the airplane (prefab asset). 


This separation is important for me, because I can manage to instantiate any airplane based on its “type/stats” and later manage to associate the asset. In order to do that, I created two main objects: enemy spawner and object pooler.

The object pooler is responsible for instantiating a pool of airplanes and storing them in categories piles. Later on, the enemy spawner can take some of these instantiated assets and merge them with the corresponding stat info. Once the airplane asset is not needed, the object pooler will deactivate it and store its reference on the pool. (I implemented a Queue stack for that)


Every time that the enemy spawner calls a new enemy asset from the object pooler, it will give to the enemy asset the information about movement, stats and other data; based on information about the wave. This is also a scriptable object that has the information about the enemy’s stat, enemy movement, and other data. 

Enemy Spawner  ←—----> Object Pooler

(wave config)                (level information)

The following images show the waypoint pattern and chase pattern. Minibosses are a variant of the waypoint variant.





Problems found

These 3 problems where the most time consuming issues that I faced in this stage: 

1.- Race condition with the object pooler: The object pooler instantiates the enemies based on the quantity and type of the airplanes:

   

Then, it creates a table (dictionary) where it stores the references of each of these elements. This is done to later, be able to manage the deactivation and activation of the objects in the pool. However, I put the method to create this table on ‘Start’. And I was getting a null reference, since the spawner was trying to get the info from this table, but it was not already finished yet. So I moved the method to ‘Awake’ instead.

2.- Prefab and  camera orientation: because I’m still implementing these systems in a ‘testing scene’ I didn’t notice that the camera was orientated in a way where the x and z axis were reversed. Also, the airplanes' prefabs have different orientations. When I started to apply some rotation to the enemies, I got strange results. Later on I noticed these problems.

3.- Reset conditions on the airplanes: I forgot to reset some internal conditions when I put the enemies back into the object pool. Because of that omission, on the second call of these elements, there were strange behaviours once they would be called later. I implemented a ‘reset’ method to fix this issue.

Next steps:

  • Player’s stats, health and perks/buffs 
  • Improve player’s movement

Submitted (1 edit)

[NEW UPDATE n°4]

Hi! I just wanted to share a strange behaviour that I got while making my game, that might be useful for everyone. So the long story short is that I was implementing a 'roguelike' skill selection screen. I created a method to get some random skills to show. This is the pseudocode:

Skills[] listSkill;

float[] values;

listSkill = MethodToGetRandomSkills(out values)

for(int index = 0; index < subsetOfListSkill; index++)

{

    button[index].OnClick.AddListener(

    delegate {

            ApplyThisSkillToPlayer(listSkill[index], values[index]);

    })

}

The problem was related to the delegate part, I was getting bad values, applying different skills and values. Not the one I selected. Then I found this explanation about using 'Addlistener' in a loop: https://answers.unity.com/questions/1195925/when-using-addlistener-can-multiple-...

I tried the local variable fix and it works when I called the method for the first time:

for(int index = 0; index < subsetOfListSkill; index++)

{

    Skill tempSkill = listSkill[index];

    float tempValue = values[index];

    button[index].OnClick.AddListener(

    delegate {

            ApplyThisSkillToPlayer(tempSkill, tempValue);

    })

}

After other calls of the method, I was getting other strange behaviours. At the end, I solved it by not using AddListener, but storing the selected skills and values in a global array. And calling the method using the 'OnClick' on the Unity Editor, not from the code.

Submitted

[NEW UPDATE n°5]

Final implementation

Now that the demo is already available to play here I can write about the final stage of implementation. 

Collisions


I forgot to mention about collisions in my previous updates. In order to reduce impact on performance, I created two layers: player and enemy. On the enemy layer, both enemy airplanes and bullets were added; while the player was on the player layer. Then, on the collision matrix, I selected to only consider collisions among those two for the game.

Skills Manager

I talked a little bit about this section in a post where I found a strange error. The main idea was to develop a manager who could show to the player a few options to enhance some skills (like in most roguelike games)


I wanted to create a system who could manage different levels of bonus/buffs based on the skill. For that purpose, I implemented a scriptable object with this information so it was easy to modify in the future.

When the selector skill is called, it chooses 3 possible skills at random and then shows the lesser bonus first (level 1). Once the player selects a skill, this skill is removed; so later if the player selects a bonus involving the same skill, it will show a next level bonus (level 2)

In order to do that, I created a dictionary where the keys are the different skills (speed, armor, roll, dash) and a ‘queue’ as a value. In this queue, the different bonus/buffs levels are listed in order. So, when the queue is called, it takes the first element, and then continues when the next when is called again to the same skill.

That is why I got the strange behavior that I detailed in my previous post.

Implementation of the scene


With every system created, it was time to put everything together. This moment was the most fun for me, because you can see how your idea takes form in front of you. Also, I have always had fun by integrating graphic and sound assets in a game.

At the beginning, I wanted to make a procedural or random generated landscape. But because of not having so much time, I decided to take a simple solution:


I make a strip with the different assets that rolls according to the time of the round. Each round (At least in the v0.1 demo version) takes 60 seconds. This stripe calculates the required time to go from beginning to end (the portal) in those 60 seconds.

When the player reaches the end, the GameManager stops the game and activates the skill selection screen. (the round end is a time based event)

In the initial design, at the end of the round an aircraft carrier would appear triggering the end of the round. With little time, I needed to make a decision since I didn’t have the asset to do that. So then I started to look for other assets and I found that an alien portal would be great for the end of the round (Also, I’m a big fan of Stargate SG-1)

Sound FX and music are elements that are important for the player experience. At least, they should be aligned with the theme or the idea that I want to transmit with the game. It was great to find chiptone, it helped me a lot in producing some sounds.

Finally, I realized that making an HTML5 version of the game at this stage would be preferable. So it could be easy for everyone to try it. In future updates I will implement the PC and Android versions since I used the new player input, it seems easier to apply new means of controlling the game.

Balancing and trying the game


Thanks to the fact that every important parameter is implemented on scriptable objects, it was easy and useful to change and try different things. I think that the game might require more fine tuning in the future though.

These screenshots show some of these scriptable objects: wave config has the information about a particular wave, and the round is implemented by using a list of those wave configs. 



Next!


I will write about the ideas of future updates and my general experience with #myfirstgamejam in a postmortem post. But I must say that I am happy that I chose this jam as my first game jam. It was great to learn from this experience and watch how the community tries to help each other.

Thanks to everyone!