Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411500 Posts in 69373 Topics- by 58429 Members - Latest Member: Alternalo

April 25, 2024, 02:07:57 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsRick Henderson - 2D Pixel Art Horizontal SHMUP
Pages: 1 [2] 3 4 5
Print
Author Topic: Rick Henderson - 2D Pixel Art Horizontal SHMUP  (Read 18439 times)
Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #20 on: February 20, 2017, 01:31:24 PM »

Log 8: Upgrade system and weapon switching part 2 (Days Left: 196, Total Expenses: 1.735,19 EUR)


Intro

Turns out that thing aren't always simple as they seem at first glance. I spent more time than planned on overhauling the weapon pickup and replacement system i wrote about in the previous dev log. Apparently, despite the system being laid out well, there were some hurdles that appeared.

First of all, the weapon switching system that was meant to be extremely basic and function by simply activating and deactivating children objects (weapon objects with firing FSMs) on the gunpoint of the ship proved too common for the concept of weapon equipping, upgrading and dropping during the game. I upgraded the system and while it's very complicated and probably can be laid out a lot simpler, it works as intended.

The setup

Upon starting the game, Player is spawned, its child Gunpoint, and Gunpoint children, Basic Weapon Object (Level 1 out of 5 weapon) and Empty Weapon Object. You're probably wondering why would i put something like Empty Weapon when it's not even used, but we'll get to it. Every Weapon Object has two FSMs, Main FSM, used for the upgrade system, and Firing FSM, used for firing the weapon. Gunpoint object stores the Weapon Switch FSM. Bear in mind that Weapon Object can also be Weapon On Ship, or a Weapon Pickup, depending on the state in which it is and the fact that Player can have two weapons equipped, but only one active at the same time.

Weapon Upgrade System - how it works?


Main FSM controller on the Basic Weapon Object enters the first state. It searches for the Gunpoint object (place on the ship where it will be spawned. Search is done by tag, since it is quicker than searching for it by name). When it finds it, it stores it in the variable. By checking if the Weapon Object is childed to a Gunpoint or not, the Main FSM is branching in two directions, which determines if it's really a weapon equipped by Player, or a Pickup waiting to be collected.

Shorter branch is executed is if the Weapon Object is a child of the Gunpoint object. It is then stored in the Weapons On Ship array, and the Main FSM finishes it's job for now. That means that it is a weapon equipped by Player and it can be fired.

If it is not childed, it means it's a Pickup (drifting in space, waiting to be collected), its Firing FSM is disabled, a child which is an animated circle indicator for easier visibility is activated and the state machine starts its next event.

Weapon Object starts measuring distance from the Player. When the distance drops below defined value, Weapon Object can receive the key command from the Player, otherwise, it's non-responsive to key press. In game terms, when the Player hovers over the weapon, by pressing key following states can occur:

Simplest case occurs if the same weapon type of maximum upgrade level exists on the ship (checked by iterating through the Weapons On Ship array). "Weapon is at maximum upgrade level" message appears, the pickup eventually leaves the screen and it is despawned.

If the same weapon type of lower upgrade levels exist on the ship, it is upgraded. If the pickup is of the same or lower level than the weapon on the ship, the weapon on the ship is upgraded by one level. But if the pickup is one or more levels higher than the weapon on ship, the weapon on the ship is upgraded to that level. So, you get a pickup and it upgrades your weapon by one or more levels and it disappears. In game terms, it sounds simple, but actually there's a lot of mechanics behind it.

For example, Player is equiped with Level 1 Weapon, and there's a Level 1 Weapon Pickup which we collect. Level 1 Weapon Pickup iterates through the Weapons On Ship array, and it finds the Level 1 Weapon of the same type. It gets the position of the Gunpoint object, spawns Level 2 Weapon and adds it to the Weapons On Ship array. It also checks if the Level 1 Weapon in the array has its Main FSM enabled or not. If it is enabled, that means it's an active weapon (we'll also get to it when we get to the Weapon Switching mechanism), which means that the Level 2 Weapon that is spawned should also be active which is done by activating Firing FSM on Level 2 Weapon nad adding it to the Active Weapon array (needed for the Weapon Switching mechanism). Firing FSM on Level 1 Weapon is disabled, it is removed from the Active Weapon array, removed from the Weapons On Ship array, Level 1 Weapon equipped on ship itself is despawned and Level 1 Pickup is finally despawned at the end of the last state. If the Level 1 Weapon on ship is inactive (its Firing FSM is deactivated), the Level 2 Weapon also spawns with its Firing FSM deactivated, but is not added to the Active Weapon array.

What happens if the Player is equipped with one or two weapons that are different from the pickup?

Things get a bit complicated there. If Weapon On Ship array does not contain any of the levels of the Weapon Object that is the same as the Weapon Object pickup, a Replace Active/Replace Empty state is entered. Remember the Empty Weapon object from the setup? It is used as a placeholder when picking up a weapon that is different from the basic equipped weapon. By iterating the Weapon On Ship array and finding no weapons of the same type but finding an Empty Weapon object, it is simply despawned, removed from Weapons On Ship array and replaced by the picked up Weapon Object. Since it is not active, spawned weapon Firing FSM is also not active, thus not added to the Active Weapon array.

A different Active Weapon acts similar to an Empty Weapon object if all slots are taken. It is removed from the Weapons On Ship array, removed from the Active Weapon array, deparented from the Gunpoint, its children activated (circle indicator that makes it visible more better on screen), and the pickup is spawned on the Gunpoint. As i said in the beginning, whenever a Weapon Object spawns, it immediately checks if it is a parent of the Gunpoint or not, and then added to the Weapons On Ship array or not.

Switching Weapons

Finally, switching the weapons. First we need to make sure that the Player can't cycle between the equipped weapon and the Empty Weapon object. As long as the Empty Weapon is in the Weapons On Ship array, cycling is not enabled. When it is no longer contained in the array, Player can freely switch between weapons. Every switch gets the first and second index numbers of the Weapons On Ship array, stores them as Weapon 1 and Weapon 2 variables, enables and disables Firing FSM on them, adds the Weapon Object with enabled Firing FSM to the Active Weapon array, and removes the Weapon Object with disabled Firing FSM from the Active Weapon array. We need the information about the Active Weapon so it can be replaced with the pickup that is different from it. That enables the Player to upgrade the weapon of the same type as the pickup on ship whether it is active or not, or select which weapon will be replaced (if both are different from the pickup) by simply switching weapons to active or not.

Oh, by the way, you can visit www.fatpugstudio.com for version with bolded arrays, objects and things of interest, it didn't copy it nice.

« Last Edit: February 22, 2017, 12:36:10 PM by Fat Pug Studio » Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #21 on: May 04, 2017, 12:36:19 AM »

Log 9: The Anatomy of An Endless Mode Part 2 (Days Left: 119)

I've been on a month+ hiatus due to exhaustion and some personal stuff, but the things are ready to move forward now. I had some issues with the weapon switching system, mostly due to my inept dealing with arrays, but the fresh mind made things alright. As usual, it was just a minor unwanted behaviour (removing the array item which resizes the array instead of rewriting the value on the actual item position) which was hard to spot due to system complexity. Pickup and upgrade system, and together with them, HUD showing the active and inactive weapons as well as heat levels is working good now. Such a joy to see a simple system work, and the knowledge that a massive system is actually behind all of that is priceless.

Anyway, now that the most of the elemental mechanics are done, it's time to make a full time commitment to the actual gameplay.

Let's do a small recap of how things work in an endless mode.

First level:

3 + 0 60 seconds waves with a warp sequence between each of the waves to give player time to rest. At the end of the last wave, you fight the random variation of the first level boss, and warp into level two.

Second level:

3 + 1 60 seconds waves with a warp sequence between each of the waves to give player time to rest. At the end of the last wave, you fight the random variation of the second level boss, and warp into level three and so on.

I will make it quite hard to reach and beat the last boss, and even if you do so, you start all over again, but with bigger score multiplier and tougher enemies.

 
Now let's go a bit in-depth. As i mentioned earlier, 5 spawners are scattered on each side of the screen which makes a total of 20.

During the first wave, only the spawners on the right part of the screen are active and only one at a time can be active. That means that if a spawner spawns a wave of enemies that lasts for five seconds, no other enemies will be spawned during that time. To avoid waiting for the next one to start if you destroy them quickly, the wave also ends when you destroy all the wave enemies and the next one automatically starts.

So, in a way, the better you play, the game is going to throw stuff at you quicker. When it throws the stuff quicker, EXPERIENCE variable, which updates with every destroyed or ended wave, enables the game to do the following:

Activate additional spawners when EXP reaches a certain level
Enable more and more spawners to be active at the same time
Cut off spawning of the waves that are marked to be under EXP threshold (too easy waves)
"Unlock" spawning of the waves when certain EXP threshold is reached
Modify the Bosses' health/attack variable so they also match your skill level

But what about the waves themselves? How are they generated? Well, that's the hardest work of all. There are a couple wave types:

Squadrons separated in a few classes (Big, medium, small). Classes are determined by EXP (higher EXP unlock bigger and harder squadrons). Squadrons are a pain to make, they are a combination of a few enemies in a predetermined pattern (for example, a bomber protected by a few fighters flying in an arrow pattern). There needs to be literally a few hundred of them.

Waypoint enemies. Single enemy types following a certain movement (spline or bezier) and shooting pattern.

Single enemies. Usually very big enemies or few small enemies spawning on a random spawners in a random patterns if there are more than one.

When all of there are combined (along with random events like meteor rain and similar stuff), with randomized spawning locations and spawning based on EXP variable they should all provide an adaptive and enjoyable play experience.
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #22 on: May 13, 2017, 02:55:27 PM »

Log 10: Endless Wave System Prototype (Days Left: 101)

Finally started on prototyping the endless wave system.



Here's a small update on the wave system, it's growing into a spaghetti monster!



The start wave is the first wave that spawns enemies from a "small wave" pool of enemies, random wave, random squadron (but inside players experience points limit), the it goes to the "check experience points" state, where it check if you're inside threshold for starting the boss wave. If you are, further spawning stops until all the enemies on screen are killed or went offscreen and then the boss wave commences. If you are not, it checks how many enemies are on screen (every enemy that spawns adds a certain value into array which is being checked). So if there's already a lot of enemies on screen you're probably not doing to well and the game will send only a small wave again. If the screen is almost empty, you're bound for a big wave incoming. Also, every wave has it's duration based on type of enemies in it etc.

Anyway, when the boss wave starts. the state checks when it is dead and starts the fancy hyperspace event with animations and creates a random event! Random event can be meteor storm, laser storm, big asteroid field etc. Each one of them grants a bonus during that wave. The next wave starts and so on. Expect even more complicated state machine next time and even more insight :D

« Last Edit: May 31, 2017, 12:04:30 AM by Fat Pug Studio » Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #23 on: May 20, 2017, 09:12:46 AM »

And a small gif i made for today's #screenshotsaturday on twitter, amazing feeling to see things getting shape and all that backend work turns into something that can be seen and played!

Logged

Danc
Level 0
**


View Profile WWW
« Reply #24 on: May 20, 2017, 09:56:43 PM »

As someone who learned to do pixel art by spending countless hours staring at Bitmap Brothers games, this is looking great. Keep up the good work! Those purple ships in the earlier screenshots are gorgeous.
Logged

Spry Fox, Lostgarden
Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #25 on: May 21, 2017, 02:53:43 AM »

Thank you! As i mentioned, all the credits go to Lighterthief, a pixel artist from Netherlands, he's been doing a really good job under my guidance. I have done and i will be doing the backgrounds, that's actually been going good to me, not much of a pixel artist otherwise.

Btw i loved bitmap brothers style, it was really unique.
« Last Edit: May 21, 2017, 03:24:16 AM by Fat Pug Studio » Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #26 on: May 31, 2017, 02:13:42 AM »

Log 11: Further insights on the Endless Wave System (Days Left: 95)

The Endless Wave System spaghetti monster i mentioner earlier grows even larger now, but i'm encountering some stuff that needs to be addressed. Since the whole endless thing is, let's say, semi-random (predefined squadrons, random number range single enemies and enemies that move via paths, all spawned randomly based on experience points range and number of enemies on screen with their own "weight" values) the pool seems to small to give a sense of variety.

Squadrons

They have the largest number of variety, but they can be painstaking to make if a large number of ships is involved. For example, this is a basic one, Marine Carrier in the escort of five Provokers, six ships total.



Due to Unitys limitation of nested prefabs, i can't just pop them into scene view and save the whole squadron as a prefab (which would be really awesome and speed things up), instead i have a prefab which instantiates ships on defined coordinates in local space. That needs a lot of tweaking, entering values manually then pressing play to see where they are actually positioned. In the whole process, waiting for Unity to start the game to see where the ships are spawned takes the most time. Obviously, the time spent is the largest con, but the pro is that i can simply replace prefabs in the squadron in a blink of an eye. That means i can change those Provokers escorting the Marine Carrier with another ships in only a few seconds, or even set each position to spawn a random ship, thus making the ships following the carrier different each time and even spawn different ones according to the players experience level.

When you take into account around 40-50 ships made until now, you get the idea how tiresome can sometimes be to make all these squadrons, but it keeps the game away from being a procedural generated crap, it keeps the randomness factor but in a structured way.

Random Number Range Single Enemies

Now this is the actual procedural generated crap that is to be avoided, but when used properly it functions great. What does that title actually mean? There are several enemy spawn points scattered all around the screen, by utilizing this approach, depending on certain variables, they will spawn single enemies that follow their own behavior, be it the regular "move forward and shoot" or something else. There are some cool thing regarding this. For example, i can spawn 1, 2 or 10 ships in a random pattern based on the players experience level or number of ships already on screen. They act like fillers, we already have one or two squadrons on screen, so let's drop a few more small baddies that do their own thing. It also keeps the players on toes since they don't know what to expect. A horrible drawback is that things can get too random if not controlled by various parameters that need to be finely tuned.

Enemies That Move Via Paths

I'm sure you'll agree that the game would be very boring if all the enemies would just move forward towards players side of the screen, no matter how many types of them there is. Using paths to move the enemies further deepens the variety and the semi-randomness factor of the game.

Obviously, paths can be used for both Single Enemies and Squadrons. They work great for single enemies since we can set a wave to spawn, let's say, 5-7 small ships and then use a path that's branching, like this:



In this example, when the ships get to the first waypoint (purple square in the upper part of screen) they will do a check which will apply random branch choice, some will keep moving forward towards the left part of the screen, and some will circle around and go back right, or maybe sometimes we'll set them all to follow the same path, so for a path like this, we actually have three outcomes: all follow path 1, all follow path 2, all branch random, which is flexible and great.

Using paths in Squadrons take a bit more time to work on, but they add further variety to squadrons. The Provokers following the Marine Carrier in the first picture may spread or fall back after a while.

Another important option that using paths gives is the easing of movement. Ship may start moving slow, than speed up while moving down the path. Or other way around. That can be randomized to, per ship, squadron, or a whole wave. It gives a lot more natural feeling to movement since ships moving at the same speed constantly may feel mechanical and boring.



Utilizing all this stuff drives the game away from the classical "memorize the pattern while moving on rails" type of play. It takes a lot more time to work on but definitely keeps every game session exciting and fresh and rises replayability to a whole new level. Unfortunately for some, not using seeds for procedural generation means you won't ever be able to replay the level you played, maybe some other time Smiley

Logged

jctwood
Level 10
*****



View Profile WWW
« Reply #27 on: May 31, 2017, 03:35:30 AM »

Really interesting breakdown of something I kind of took for granted in Shmups which is how you design the wave patterns without making them unfairly punishing. This looks really nice! Would be cool to see some comparison of patterns similar to the grid of graphs visualised above.
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #28 on: May 31, 2017, 04:51:33 AM »

I must admit it's a system that needs further tweaking and finer granulation. My goal is to make an optimal gaming experience, and there are two possible mechanisms i can use utilizing the current system of adding ships' "weight" to a pool.

As already mentioned, every ship holds a different value, small ones from the screenshot are worth 1, and that nasty marine carrier is worth 5. When they appear on-screen, the total value in the pool is 10 (five small ships worth 1, and one big ship worth 5). The pool size is growing with players experience, which increases by killing enemies.

Now, i actually need your help since there are two possible scenarios here.

Scenario 1 - Smoother gameplay, not enough breathing room if you play well

I can do a check of the total pool value in smaller intervals (like a second), and according to total pool value and experience points variable, further ships are spawned, but not above the maximum pool value determined by experience points. For better players that manage to do their kills quick, this will actually provide a constant flow of enemies. For the ones perhaps struggling a bit, it won't spawn enemies as fast. The con to this is having no breaks if you are good, which can be tiresome. I don't plan the levels to be too long (from 30 seconds on the first level to 2-3 minutes on the later levels) and the pauses will be in the form of hyperspace between levels, but some other form of taking a breath would probably we welcome, maybe a subset of waves in the level.

Scenario 2 - More natural progression, more breathing room, risk of not so smooth gameplay

In the other case, i would make a total pool value check a bit more dynamic. When the game starts, the checks can be done every few seconds, and the time between checks can get shorter as the player progresses. While this provides some breathing room between the waves and a more natural progression of the difficulty level, it tends to group everything. If you clear the screen before the next total pool value, the game can throw a lot of things at you if the pool is already at such a level it can hold a lot of enemies.

On early levels, if you are a good player, you will clear the screen in a jiffy and then wait for the next wave. If the wait is too long, it gets boring over time and, like mentioned in the last paragraph, the next wave can be overwhelming.

There's also a possibility of a fixed wave timing, but that sounds boring to me.

Quote
Would be cool to see some comparison of patterns similar to the grid of graphs visualised above.

What do you mean? Mockup of a wave of ships moving on path using different easing?

Logged

jctwood
Level 10
*****



View Profile WWW
« Reply #29 on: May 31, 2017, 05:07:05 AM »

Hmm it is a difficult balance between flow and breathing space.

What do you mean? Mockup of a wave of ships moving on path using different easing?

Yeah, I would be really interested to see what it looks like in action!
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #30 on: May 31, 2017, 05:13:09 AM »

Sure, i'll post it when i do it, in a day or two probably Smiley
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #31 on: May 31, 2017, 01:26:28 PM »

Got some free time so i did a few variants.

In Cubic Ease



In Expo Ease



In Out Circ Ease



In Out Elastic, obviously not for this type of enemy, but just showing the possibilities



These are just hastily made, without any special tweaking of time or look ahead, but you get the idea about the possibilities, especially with multiple ships involved. All of that can be done in code too with regular physics, but tweening makes it quicker, easier to adapt and reusable.
« Last Edit: May 31, 2017, 01:56:33 PM by Fat Pug Studio » Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #32 on: June 01, 2017, 02:38:35 AM »

Here's a small graph of the system, i think the weight system is the way to go, just need to set the timing right and the prefab pools to avoid overfilling the pool or spawning the same squadrons. I think it's gonna be a lot harder than i think  Screamy



Array which represent the number of ships on screen will still be in use though, to enable stopping the further spawning when the experience threshold for spawning boss is met. It can also be used as a secondary check, if the pool is not too filled in weight value but there are a lot of small ships on screen, it will prevent further spawning.

But sometimes it won't  Well, hello there!


Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #33 on: June 03, 2017, 03:18:31 AM »

It's #screenshotsaturday!

Here's how the design goes, i doodle at night, mister Lighterthief turns my fantasies into pixel reality.



I used to be a techno DJ and producer when i was younger, and i know i shouldn't be doing any sound until i get to the point when the technicalities are finished, but that Ableton icon was tempting me, i haven't started it in two years. So i started making some music for the game. Nothing special really, but that's how i imagine it, i don't like the metal stuff people usually put in shmups, i'm more into Wipeout/Rollcage type of music.

https://soundcloud.com/kruko/rick-henderson-and-the-artifact-of-gods-track-1
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #34 on: June 06, 2017, 04:41:24 AM »

Hey,

Here is another dev born in early 80s. I can see your progress. It is looking good, just keep in mind that the thing that will take you most time will be designinig levels and making them right. Programming is the smallest thing from the whole thing.

Good luck with the project!!



Well, i've come to the point where creating a vast variety of waves and squadrons is an absolute necessity if i want to test and upgrade the endless wave system. My god it's tedious. With about 30-40 enemies until now, it's gonna be a long work. I made some templates so it's basically dragging and dropping presets and spawn points into appropriate boxes with some tweaks, but still.

Good thing is that it brings me closer to some gameplay videos and demo Smiley
« Last Edit: June 06, 2017, 04:46:35 AM by Fat Pug Studio » Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #35 on: July 01, 2017, 07:49:53 AM »

I'm quite busy with my Adaptive Difficulty System as i call it, but today i'm having some fun, so i put debris for larger ship explosions and implemented some composite killables.

Debris flying


Second one is in twitter link, sorry, i accidentally erased the gif from desktop.

Composite killables
https://twitter.com/FatPugStudio/status/881154635851067392
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #36 on: July 03, 2017, 10:50:04 PM »

Log 12: The Anatomy Of A Roguelike Endless Mode, part 3

I joined all the Endless Wave System posts into one and made further additions, it's a good read!

Endless Mode, for now, will be the backbone of the game. I don't much like the term, but let's call it Roguelike. For those not unacquainted with the term, it's pretty simple. The basics of roguelike games are permadeath (which means you start all over when you die) and procedurally generated levels. Procedural is basically a fancy catch-phrase for controlled random. It means that the levels are made by parametrized procedures that keep the random factor under control by defining the aforementioned procedures, certain value ranges and all sorts of parameters you want randomized. Anyone ever trying to make a completely random piece of any sort of art, be it visual or sound, knows that it usually turns out horrible. With the assistance of parameters like harmonies and scales in music, or color palettes, fractals and similar stuff you can get bettes results, but without the human input it's usually a meaningless chaos with only glimps of something human-like.

Then what is it good for you ask? Well, with proper parametrization, you can get a gameplay experience that is different every time you play the game, yet it has the same essence and feeling. How does that work in my game, more precisely, in the endless mode? The most obvious thing that can be parametrized is the appearance of enemies on screen, so how do we do that?

Triggered Spawners

For spawning enemies, we need spawners, predefined locations on the screen where the enemy ships appear. Since we want the illusion of ships flying IN the visible part of the screen, spawners are set OUTSIDE the visible part of the screen, just a little bit beyond camera frustum. There are a total of 20 spawners, 5 for each side of the screen, and each of them spawns enemies by the command sent to them. That command, in the form of a triggered custom event (hence the name Triggered Spawners), is chosen randomly by a set of rules.

Rules are not made to be broken

In opposite of the old saying, rules in roguelike game must be well designed and not broken, unless you want your whole game to be broken. A tight set of rules need to be implemented to the enemy spawning system for it to be challenging enough, but not too hard and various enough, but not too random. So besides the variety, by making the rules for a procedurally generated Endless Mode i came up with something i call the Adaptive Difficulty System. Here's how the whole thing works:

You start the game with 0 Experience Points (the first variable), empty Enemy Value Pool (the second variable) and empty Enemy Array (the third variable, let's call it Enemy Counter from now on).

Experience points are the core to the system and a lot of stuff depends on them:

  • You earn them by destroying enemies.
  • Enemy Value Pool is the value of all enemies present on screen. When they appear, their value (based on their characteristics, HP, weapons, etc.) is added to the pool. When they are destroyed or they leave screen, their value is subtracted to the pool.
  • The Enemy Array is simply a counter of the enemies present on the screen, when the enemy appears, it's added to the array, when it disappears by means of leaving screen or death in flames, it is removed from the array. The thing is, Enemy Value Pool has a limit that is based on your experience level and it is raised higher as you earn more experience by destroying enemies.
  • Trigger for unlocking more complex and harder waves, new types of enemies and upgrading already unlocked enemies.
  • Trigger for bosses appearing, and transports with pickups appearing (that means no level is of the same length).

Enemy Value Pool works in conjunction with both experience points and the Enemy Counter and it is crucial for the difficulty level adaptation. The game will never spawn more enemies than the pool can hold, so it ensures a gradual progression in difficulty based on your skill. If you're not such a good shot, experience will rise slowly, and with it the pool size. If you are a hotshot and hit 'em dead on the spot, you will progress much faster, get upgrades much faster and get to the bosses faster.

So what's the Enemy Counter for? Тhe Enemy Pool Value has a certain limitations without it. You can have a pool half empty, but a lots of small enemies on screen that already pose a challenge by sheer numbers. Based by Enemy Pool Value only, the system will start an event of filling it up by spawning more enemies. The Enemy Counter serves as a fail-safe system against this. Instead of spawning more enemies, it will either delay further spawning if the number of enemies it too large, or perhaps launch one big enemy to add some variety to the situation.

As stated before, enemy waves are spawned in a controlled random manner, featuring procedural and hand-crafted elements. Procedural elements would be random number of single enemies moving on their predefined agenda or via paths with their numbers and type defined by experience points, while hand-crafter ones are squadrons.

Squadrons

They have the largest number of variety, but they can be painstaking to make if a large number of ships is involved. For example, this is a basic one, Marine Carrier in the escort of five Provokers, six ships total.

Due to Unitys limitation of nested prefabs, i can't just pop them into scene view and save the whole squadron as a prefab (which would be really awesome and speed things up), instead i have a prefab which instantiates ships on defined coordinates in local space. That needs a lot of tweaking, entering values manually then pressing play to see where they are actually positioned. In the whole process, waiting for Unity to start the game to see where the ships are spawned takes the most time. Obviously, the time spent is the largest con, but the pro is that i can simply replace prefabs in the squadron in a blink of an eye. That means i can change those Provokers escorting the Marine Carrier with another ships in only a few seconds, or even set each position to spawn a random ship, thus making the ships following the carrier different each time and even spawn different ones according to the players experience level.

When you take into account around 40-50 ships made until now, you get the idea how tiresome can sometimes be to make all these squadrons, but it keeps the game away from being a procedural generated crap, it keeps the randomness factor but in a structured way.

Random Number Range Single Enemies


Now this is the actual procedural generated crap that is to be avoided, but when used properly it functions great. What does that title actually mean? There are several enemy spawn points scattered all around the screen, by utilizing this approach, depending on certain variables, they will spawn single enemies that follow their own behavior, be it the regular "move forward and shoot" or something else. There are some cool thing regarding this. For example, i can spawn 1, 2 or 10 ships in a random pattern based on the players experience level or number of ships already on screen. They act like fillers, we already have one or two squadrons on screen, so let's drop a few more small baddies that do their own thing. It also keeps the players on toes since they don't know what to expect. A horrible drawback is that things can get too random if not controlled by various parameters that need to be finely tuned, like mutual distance that avoids overlapping the sprites.

Enemies That Move Via Paths

I'm sure you'll agree that the game would be very boring if all the enemies would just move forward towards players side of the screen, no matter how many types of them there is. Using paths to move the enemies further deepens the variety and the semi-randomness factor of the game.

Obviously, paths can be used for both Single Enemies and Squadrons. They work great for single enemies since we can set a wave to spawn, let's say, 5-7 small ships and then use a path that's branching, like this:

Enemy Waypoints

An example of a branching waypoint
In this example, when the ships get to the first waypoint (purple square in the upper part of screen) they will do a check which will apply random branch choice, some will keep moving forward towards the left part of the screen, and some will circle around and go back right, or maybe sometimes we'll set them all to follow the same path, so for a path like this, we actually have three outcomes: all follow path 1, all follow path 2, all branch random, which is flexible and great.

Using paths in Squadrons take a bit more time to work on, but they add further variety to squadrons. The Provokers following the Marine Carrier in the first picture may spread or fall back after a while.

Another important option that using paths gives is the easing of movement. Ship may start moving slow, than speed up while moving down the path. Or other way around. That can be randomized to, per ship, squadron, or a whole wave. It gives a lot more natural feeling to movement since ships moving at the same speed constantly may feel mechanical and boring.

Utilizing all this stuff drives the game away from the classical "memorize the pattern while moving on rails" type of play. It takes a lot more time to work on but definitely keeps every game session exciting and fresh and rises replayability to a whole new level. Unfortunately for some, and in contrast to a usual Roguelike practices, not using seeds for procedural generation means you won't ever be able to replay the game you just played, but i see it as a great thing.

Further randomizations

While not essential for gameplay itself, backgrounds are randomly changed with each level. But what IS essential for gameplay are the Random Events that come with some of the background. They are created in a brief moment of whiteout when ship enters the hyperspace after defeating the level boss and further improves the challenge and replayability. Some of those include meteor rains, ion storms or asteroid fields, adding up to the difficulty, variety and that juicy bonus multiplier.

Weapon upgrade system overhaul

Last, but not least important is the overhaul of a weapon upgrade system i spoke about in the last devlog. After a few weeks work it turned out that the weapon pickup and upgrade system is not functioning really well when handling the pickup after the first weapon switch. I refactored some array related stuff regarding the active/inactive weapon status and now it works like a charm.

It can be further improved by introducing a case-switch which i will do in the next iteration. It will further simplify the machine, but i don't think it can go simpler than that, at least using the state machine.

For now, that concludes the story about the Anatomy Of A (Roguelike) Endless Wave System. I will let you know if it has some further improvements, but for now system seems to be working solid.
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #37 on: July 05, 2017, 06:03:23 AM »

My artist did a cool laser animation today, things are starting to look pretty good!



Do you like it?
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #38 on: July 17, 2017, 12:45:19 PM »

Hello, this time i wrote about something different on my website, but equally important. Many of you (myself included) experienced burnout due to too much work. Here's some advice on how to avoid it. Hope you enjoy the read!

Burn-out, in shortest possible, is a state of physical and mental exhaustion. Is is caused by too much work and stress, and not enough rest and sleep. It can lead to severe health problems, with the smallest one being clinical depression. Apparently, it is very common in game development professions.

I started working on Rick Henderson And The Artifact Of Gods a year and a half ago. First, everything was going fine. Fueled by passion and motivation, i stayed late many nights and used weekends to recover from that maniacal tempo. Then the weekends weren’t enough. I started barely waking up and functioning very lousy. Eating too much to get energy, drinking too much coffee. Quality of work started to fall, and it took me more and more time to finish stuff. My concentration was going down. I got frustrated when i simply couldn’t stay up anymore because i lacked energy. When i did stay up, it was a torture of mind and body with work quality falling down even more. Depression started to creep in. A vicious circle of guilt and exhaustion that ultimately led to a month pause during which i couldn’t even look at my game. After one big and one smaller burnout (the other one was a reminder) i experienced, i learned a good lesson. Making a game is not a 100 meters sprint of passion, it is a 42 kilometer marathon that requires perseverance, determination and motivation. To stay determined and motivated we need to take care of our bodies and minds. Typical, a bit satirized, representation of a programmer is a skinny or a fat bold guy with glasses and a generally neglected appearance (stubble, lousy wardrobe and so on).

Turns out, there’s a grain of truth in every joke. This type of work takes an enormous amount of time and while not physically demanding it DOES impact the body, and with it the mind enormously. I am determined to avoid burnouts in the future, and here is what i can recommend to you to avoid them too.

Sleep Well

Developing games can be addictive, especially when you get into The Flow (or in the zone, as it is sometimes referred to). As i already have a full-time job and family, the flow usually comes late at night, when family is asleep and after an hour or two already in the works. I get completely immersed and have a distorted feeling of time and space, hyperfocus and increased productivity. If you think you can use this time well, make sure you can be absent from the work tomorrow so you can regenerate and have a good night of sleep. However, i wouldn’t recommend doing this often. It’s better to save that energy when you’re close to some goal that requires a large amount of work that you feel you must do in one push or you will lose focus if you split it in chunks.

Sleeping less than 6 hours increases obesity (you feel like eating more to compensate for lack of energy), chance of stroke, heart diseases and diabetes. Not to mention that you will be forgetful, need lots of coffee or caffeine drinks to make it through the day and be irritable as hell. Depression also creeps in. Make sure you sleep at least 7 hours and try sleeping in on weekends if you can.

Eat healthy

I know it sounds obvious and like a cliché, but if you are mid thirties like i am, this fact needs to be repeated all the time. Make time to prepare a healthy, balanced meal. Eat vegetables, fruits, fish and meat. Besides making your own meals is the healthiest choice of all, it helps rest the mind by physically and mentally distancing you from computer. I find cooking relaxing and sometimes similar to long bicycle rides when my mind wanders off.

Drink water and tea, not sodas full of sugar.

Avoid too much caffeine, it actually makes you harder to concentrate if you overdo it, makes your brain foggy, causes caffeine crash and messes up your sleep quality when taken too late (if you manage to fall asleep). While we all love coffee as a stimulant, don’t forget that it is addicting and withdrawal symptoms can last very long, so it’s best to consume it in reasonable amounts.

Exercise

Besides sleeping enough and eating healthy, exercise is one of the most important things in whole thing of staying mentally stable when working on a game.  Get your juices flowing, ride a bike, pump some iron, run, cross fit, whatever makes you sweat. You will feel better, happier, healthier, have more energy to work, need less sleep, wake more rested and most important of all, have your brain functioning better due to improved blood flow. If you are like me, sitting in the office for 8 hours staring at a screen (like most of us actually) and then doing that again in the afternoon, be realistic, it does horrible things to your body and mind and you must be fit to endure it.

Don’t forget friends and family

Life doesn’t just stop because you are working on something that takes an enormous chunk of your spare time. You’ve got a family to spend time with and take care off and friendships you have to cherish. Socializing helps to take the mind off of your work, relax or perhaps vocalize the things that worry you or you are having problems with in your development. Even if someone is not into that, a fresh and naive look at your problem can be an eye opener.

After all, friends and family is all that matters in the end.

Take days off

No matter how great your passion and motivation are, being involved in anything 24/7 is just not good. You will get saturated, lose objectivity of your work and ultimately repelled by the sole sight of computer. Make goals on which you are working on, and say to yourself “when i finish this boss design, i’m going to treat myself with 3 days off”. And do it, feel satisfied with the work you’ve done and enjoy in your days off without guilt because you deserved them.

Relax (away from screen if possible)

Since you are probably already a full-time screen starer and you stare some more when you get home, i recommend you get some relaxation that doesn’t include staring at any type of screen. Cooking is a great way to relax, walk your dog without your smartphone, pet your cat for hours, read a book or a magazine, make a bubble bath, lay on the floor and stare at ceiling thinking about nothing, ride a bike out of town. It’s all relaxing and helps soothe your exhausted and work saturated mind.

Work on something different

If you really feel the need for working on your project, switching between the things you do often helps to avoid saturation. When i got bored of working on enemy waves, i switched to searching for sound effects and making some music. This development blog is also part of my avoiding burnout by doing something different. When you get sick of coding you can do some drawing if you’re apt at it, making music, writing a storyline, whatever jingles your bells. Just make sure you track your goals and don’t spread yourself too thin as it lowers the productivity and quality of work.

Managing it all

That’s all nice and dandy, taking care of yourself, but when you will find the time to work on the game with all this relaxing, exercising and cooking? It’s up to you to figure it out and integrate it into your lifestyle. It’s probably not going to translate into a lot of work hours, but what matters is the quality of those work hours. Most helpful thing if you are not able to work regularly on your game (i.e. have a family and a job) is to run a development log. Not just any, but a very tight one, with clear goals cut into smaller chunks you can handle and work on whenever you can grab some spare time. Besides knowing where to continue with your work after a few days of AFK, it will be motivating to track your progress. I’ll probably write more about it next time.

Stay healthy and take it easy!



Appendix 1

Thanks to the encouraging critique from folks at reddit/r/gamedev i decided to update the article with some quantification of the problem. Being an already a full-time employee, hour tracking of work done can be tedious when working irregularly and takes too much time in my case, but i had a more or less regular work schedule before the first big burnout to prove that it’s simply not worth it and you should respect your body.

Let’s say i worked on the game for two hours and on top of that extra two hours every workday of the week. Those hours were always, as mentioned in the article, late at night, after full 8 hours of work, when i am already tired and my work efficiency is largely decreased. Every workday i worked an extra two hours led to a total of 40 hours of sleep debt (since the only time i could afford was borrowing a chunk of sleep). That comes to 5  nights of good sleep monthly or whole two months per year! Imagine not sleeping for an entire week per month or not sleeping one night every week of the month. That leaves horrible consequences to your mind and body.

Every one of us has a different organism, gender, age, need for sleep, physique that can withstand more abuse than the other, so it’s quite difficult to determine someones need for rest. Being a 34 year old male, some general proposition is not less than 7 hours of sleep. That can be an ungrateful number, since i usually don’t feel quite rested if i sleep under 8 hours of sleep, but let’s take that as a general rule of thumb.

If i worked an extra two hours per night and cut off my sleep for two hours, i gained 40 extra hours of development per month. When you look like it’s great, almost 500 hours per year, that alone is a figure that can net some serious results. But how was the quality of that work? Being already exhausted, we can say that it was 75% efficient compared to a workload when i was fully rested. There’s stuff to work on that don’t require much concentration or brain power and there’s not much efficiency deficiency on those, but there are some intensive tasks (writing new mechanics, creative tasks etc.) that need a lot more mental power to be done efficiently and that brain power is already spent. I reckon the diminish can go up to 50% on that one (i was really struggling on creative stuff when i was working late nights), so we get down to the number of 75% on average.

So, we have 75% efficiency workload of 2 hours, which comes down to one and a half hour of full efficiency work. “That’s still ok!” you think. As the month goes by, it diminishes even more, due to increased fatigue, frustration and saturation by work but let’s leave it at the figure of 75% for an easier calculation since you used weekends to sleep in and get some of that sleep debt back.

After a month of burning out, you are already overwhelmed by the exhaustion and you tell yourself “Alright, i can’t take it anymore, i need a break”. You gained 30 extra hours that month and you deserve a rest. How long will it take you to recover depends on many factors. If you already have a job and a family, you will find that all of that itself is quite exhausting by itself. You take a week of break (two weekends and one workweek) and during that time you lose 10 hours of development, so your net gain is now even lower, it’s not 30 hours, it’s 20 extra hours. You worked 40 extra hours for a month to gain only 20 hours of extra development time and the chances are you are not fully recovered at all! Not only that, you distanced yourself from the project and it will take some time to get to continue where you left off.

Those are some simple maths that may prove something else of what i’m trying to prove, but it was a bit different in my case. For me, it took a month to recover after that kind of crunch and i didn’t fully rest. After a month! When i got back to the project, i didn’t know where i stopped and what should i do next and i still had a feeling of not being quite ready to keep working. I simply needed more rest. Not to mention the fact that i was eating more (especially late at night which is bad by itself) because i was constantly tired, getting fatter, weaker, had no power to workout at all, had a lower quality of sleep for not respecting the usual times of going to sleep and getting up and drinking too much coffee. All those symptoms didn’t get away after a month of resting by doing absolutely nothing except going to work where i was equally as useless. First the guilt and frustration comes in, for being weak not to work on the project, then depression usually knocks on the door. A depression so severe in my case that it took me three weeks just to snap out of it and start feeling a bit better about myself.

There are always times when you can push yourself to the limit and find an excuse for it. Whether is it “I just need to punch in the foundations and it will be easier later” or “release time is near, i have to give my best” at the end of the day it’s just not worth. Extra hours in a profession that needs a lot of time investment by itself, is damaging to your body since you are practically not moving for a lot of time and requires your brain to be fully rested are just a drop in the sea compared to what you are losing in the long run. The damage you do to yourself is usually not possible to repair fully, especially if you are not in your twenties when you could handle a lot of abuse and just keep going.
Logged

Fat Pug Studio
Level 2
**


View Profile WWW
« Reply #39 on: September 13, 2017, 03:32:51 AM »

Hi guys, it's been some time, i was on vacation and had some other stuff to do. Summer end is coming so i guess i will be spending more time with Unity Smiley

I started making backgrounds for my little game and i'd like to share a technique i use with you. There's a cool nebula generator on https://29a.ch/sandbox/2011/neonflames/ where you can generate random nebula swirls by choosing colors, messing with parameteres and simply drawing on the screen. Here's how the generated nebula looks like.



Though pretty, it's not something we could actually use in a pixel art game, huh. So let's fire up our favourite photoshop since we'll be doing some tricks. First we change the image to indexed color so we can lower the number of colors in the image. I usually use 16, there's really no more need for more than than, even less is welcome. After that we get it back to RGB for editing. I use a very useful filter under Artistic > Paint Daubs which rounds up the edges and makes it look like it's hand drawn. The colors are usually nicely separated so we can select them with magic wand and cut out the separate layers for better manipulation, or select the color range if we want some transparency and not so sharp look.

Then comes the hand drawing part. In this one, i placed some big stars and hand drawn some gradient layers that follow the nebula shape and lose brightness as the go away from the star to simulate some depth and bring more color into the image. You can knock yourself out with drawing planets, any texture drawn is usually fine, but it's nice if they match the nebula color (i got two in the image which will be moving in separate speeds for distance simulation, you can spot a dark one in the upper left corner of the nebula). Additionaly tweak the layers' transparency, you can play around with the overlays too, generate a starfield and tint it to match the color and voila!



I'm having some more in the work and they're getting better and better, i'll be sure to share them with you Smiley
Logged

Pages: 1 [2] 3 4 5
Print
Jump to:  

Theme orange-lt created by panic