3
\$\begingroup\$

I recently played Knightmare Tower and was amazed by the way how different monsters are beign spawned.

I'm aware of time-based and count-based spawing systems in shoot-em-ups. Count-based systems allow a certain number of enemies on screen and spawn more as they die. Time-based ones spawn more at given intervals.

How are these spawning mechanism built? Is there some pattern or theory to it?


Additionally, such games typically have increasingly resilient enemies of increasing numbers of types. How are these balanced?

I'm looking for a general answer, independent of any particular game or technology.

\$\endgroup\$
  • 5
    \$\begingroup\$ For those of us not willing to play the game to understand what you mean, can you summarise why and how this spawning system is different from what you use? What about the spawning system is amazing you? \$\endgroup\$ – RhysW Aug 13 '13 at 10:10
  • \$\begingroup\$ As far as i can tell, it just seems to spawn a predefined set offscreen with variable x coordinates. Is there any progression or variation at all? \$\endgroup\$ – Casper Beyer Aug 13 '13 at 10:17
  • \$\begingroup\$ honestly I would just create a class that manages what type of enemy that can spawn, a boolean toggle for each to spawn, and some sort of weight for each type of enemy. Then as you break through barriers you can decrease the weight on weaker enemies, increase the weight on stronger enemies, and flip the toggle to so they become a valid type for that area. Then you have a single method exposed (SpawnEnemy(Vector2 position) or something) that will use the weights and toggles to spawn a random enemy at the target position. \$\endgroup\$ – Benjamin Danger Johnson Aug 13 '13 at 18:51
5
\$\begingroup\$

From playing Knightmare Tower from beginning to end, it seemed like the enemies were mostly predefined as opposed to being procedurally generated. There was some randomization, but from what I can remember it was very minor variance.

But to achieve something similar, I would do something along the lines of:

  • Have several collections of enemies to pull from, for each "floor", and replace the collection every time the player reaches a new floor.
  • Then have weights associated with the enemies based on difficulty to control how often they show up, and possibly have a maximum for each type of unit, so there is no way to get, say five of the wizard type mobs, that would be quite difficult for the floor to deal with.
  • Then to place them, you can just check and see where other enemies are, and place them decently far from the others.
  • As for timing, I would say pick a base enemy density, which increases as the player reaches new floors.

Spawning systems are so specific to a game, I'm not sure how applicable any general theorycrafting would be. I would just recommend hammering out a basic system for spawning, start playing the game, and refining it from there. For example, you could implement moving weights for enemy chance, say every time it spawns the weight goes down by 5%, to make it self correcting for some of the randomness, etc.

\$\endgroup\$
6
\$\begingroup\$

You want to slowly improve the strength, speed, and AI of these types of units. I'll provide a list of what exactly I would do in your situation:

  • You can add where they do new moves once they hit a specific level. For example, they may shoot fireballs at level 10.
  • Increase their reaction speed to your attacks. For example, they may have AI to predict when you attack, make the gap smaller.
  • Increase the amount of monsters that can spawn at once.
  • Increase their health.
  • Increase their damage.
\$\endgroup\$
1
\$\begingroup\$

Since you have asked multiple questions at once I will try to shed some light on the whole topic.

Composing waves of different enemy types

Similar to David M's answer I would suggest assigning an cost to each enemy type reflecting it's strength or difficulty. Then for each wave you have an budget which you can spend on different enemies which make up the current wave. By increasing the budget each level you can increase the difficulty of this level.

The strategy for distributing enemy types is up to you. You can spread them out evenly so each wave is essentially the same just with more and stronger enemies. I would instead suggest to have different wave distributions to make the waves more distinct. Each level you choose one distribution type at random which will prefer e.g. mostly ranged enemies, mostly mages and some melees to protect them or an balanced distribution among all types. This way you can give each wave an distinct character and force the player to come up with different tactics for each wave type.

This way you avoid having the same enemies in every wave which will result in the same tactic and same gameplay every time, just with more enemies.

If you have wave types with only strong enemies you should only enable them if you have reached a high enough budget so you wont have a wave with only one very strong enemy early on in the game.

Balancing difficulty

You can adjust or increase the difficulty for each level/wave with several methods:

  1. Increase number of enemies or choose stronger enemy types (increase budget)
  2. Make enemies smarter or give them new attacks
  3. Increase per enemy strength (e.g. more health, more damage)

In my personal opinion increasing the number of enemies and switching to more stronger enemy types should be your main method to increase the difficulty of a wave. Boosting their AI or giving them new attacks, skills or abilities is very good but often difficult to archive. Increasing the per enemy strength often feels weird and results in 'bullet sponges' (enemies with seemingly endless health) or enemies which can one-hit you, both behaviors which, in my opinion, are signs of bad game design.

Adjusting difficulty

This heavily depends on what type of game you want to create.

  • If you want to have some sort of highscore or generally want to make the game competitive in some way you need a fixed difficulty. You just increase the difficulty (e.g. by increasing the budget) each level/wave by some amount and wait for the player to die after level X because he isn't able too keep up with the increasing difficulty anymore. This allows the player to feel good after beating wave X because it's an archivement requiring some level of skill. The downside it that this can result in a player failing too often and feel weak, eventually give up after dying too often.

  • If you want the player to feel strong but always give them a challenge without overtaxing his abilities you may want to go for a dynamic difficulty. You slowly increase the difficulty and measure the players performance each level. If he performs well you increase the difficulty, if he fails or struggles you step down a bit and give him easier enemies. This will result in an more 'fun' gameplay but now you cant really assign some sort of highscore anymore because he only beat his own personal difficulty which is not comparable to want some other player has archived.

On this last topic of adjusting the difficulty I can recommend these sources:

  1. Vales AI-Director from Left for Dead (starting at page 51) http://www.valvesoftware.com/publications/2009/ai_systems_of_l4d_mike_booth.pdf
  2. This YouTube video on dynamic difficulty in general https://www.youtube.com/watch?v=zFv6KAdQ5SE
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.