How to store levels and enemy patterns?

A place for people with an interest in developing new shmups.
Post Reply
User avatar
CaptainKraken
Posts: 45
Joined: Wed Nov 30, 2016 1:04 am

How to store levels and enemy patterns?

Post by CaptainKraken »

Ahoy there! Kraken here.

I've been working on a shmup in Java for a while now- development is going well and I will hopefully make a post about it sometime soon,
but there's one thing that I'm having trouble with. That is pattern storage.

How do you guys generally go about coding pattern storage. By that I mean where the enemies appear in a level, how each enemy behaves,
how each boss behaves, etc.

I do have a solution in place, but it doesn't seem elegant.
I've got a text file that I scan through as the game runs, and the game interprets the text file to spawn enemies.

For enemy patterns, I have a timer variable that is set to zero at initialization of the enemy,
and I have commands in the enemies' code such as "if timer is 50, shoot large burst."

Anyway, just wondering how some of you do it.
Squire Grooktook wrote:Make a game because there's something you want to exist that doesn't.
Shooting game never die!
mystran
Posts: 77
Joined: Tue Mar 12, 2013 11:59 pm
Location: Helsinki, FI

Re: How to store levels and enemy patterns?

Post by mystran »

Text files or something similar are the classics... but I would actually highly recommend writing an editor, either into the game (eg. as an "edit mode"), or such that it can host the game.

The way my most recent project does it, there's a map view where one can move a cursor around with the arrow keys, which scrolls when you hit the top/bottom (since it's vertical shmup). Different keyboard keys select enemy under cursor, add enemy at cursor, move/delete selected enemy, edit path way-points (each enemy has a spline-path), duplicate enemies (ie. to quickly make another with the same basic path) and a few other utilities (eg. grid snap). The whole things looks like absolute garbage, there is basically no actual "GUI" code whatsoever (just drawing a bunch of rectangles and a bunch of text) and it doesn't even know about mouse, but it still makes it pretty fast to edit things. Pressing 12345-keys jumps to a different stage and all of them are saved whenever the whole thing is closed. The only polish in the whole thing is a little bit of optimisation in terms of the keys used to do various things such that one doesn't need to move hands around on the keyboard too much.

The way the game itself is sequenced, the screen scrolls at a constant pace (well, midbosses/bosses can alter the scrolling, or they can let it scroll, but prevent any other enemies from spawning, so certain waves get skipped if you don't kill a midboss fast enough) and around the playable "screen" there's an "activation region" where as soon as an enemy is within this larger region it gets "spawned" (well, technically "activated" as I spawn them when the stage starts) and starts moving. There is some extra space on the sides as well, such that one can path enemies to "go around" before they enter the playable space, so as far as gameplay goes, they don't need to enter from the top. You could also add things other than enemies (eg. triggers or whatever), but I haven't had a reason to.

Now, the part that absolutely makes this worth the programming effort (which is actually pretty low, unless you fall into the trap of trying to make it look like a serious application) is the killer feature you absolutely want to have: you hit space (or some other suitable key) and the game itself immediately starts running (actually I have it side-by-side with the live-updating editor view) from whatever camera location you have scrolled into in the editor view. It won't spawn any of the enemies that would have already spawned if we'd scrolled here normally (so one doesn't get instantly overwhelmed; other "waiting" enemies will continue to activate normally though), but this allows one to very easily test a segment just by scrolling a little bit backwards and hitting space. As soon as you hit space again, it will restore the camera position that the editor had just before the gameplay was started and you're back to editing (or restart the game from the same place again if you hit space twice).

As for the actual behaviour of the enemies/bosses... I just program those directly for each of the enemy types. Each of them has a spline-path set in the editor, so generally most enemies will just follow the path, then either stop or keep their current velocity when they hit the end of the path. I intetionally don't normalise the movement along the path, so putting more control points allows slower movement, putting fewer makes them move faster and putting a bunch of points at the same place makes them stop for a while. For bosses, I use the path to bring it into play, then let it move algorithmically (eg. following some sort of subtle sine wobble). My attack patterns are basically stackless co-routines (built in C++ with some preprocessor macro abuse) that can do basically anything, but generally they spawn bullets and then wait a number of frames. In case of bosses they also move from one pattern to another depending on boss health and/or destroyed body-parts, but that's about it.

I suppose a lot of it depends on the style of gameplay you are going for.. but the one thing that will certainly save you gray hair is being able to place the enemies visually and most importantly quickly iterate any part of your stage design without having to play through the stage all the way to the point that you wanted to test.
User avatar
tiaoferreira
Posts: 252
Joined: Fri Aug 21, 2009 9:29 pm
Contact:

Re: How to store levels and enemy patterns?

Post by tiaoferreira »

I believe this varies from author to author.

I, in particular, can not even be called a "programmer," I'm more of a curious, enthusiastic. I have technical programming courses, yes, but that was in 1988, specifically in Basic for the computers of the line Apple II Unitron, something that neither is used more presently.

However, the concepts learned in the past are valid for any tool or language. Since we did not have the advanced capabilities of today, the solution I used was mathematics pure and simple. In reality, what these new tools do today is nothing more than exposing the result of mathematical operations on the screen. The "cat leap" is in the user's participation, which no longer has to worry about performing the calculations or breaking the head with formulas. Just click, drag and drop. The rest is result of logic.

In my case, I have not yet been able to learn most of the tools and languages ​​available. I have identified myself (and concentrated) on Basic (for Apple II, but for MSX, my preferred, I am very bad), Flash Actionscript 2 (AS2), Dark Basic and GML (Game Maker Language). Still, I'm no expert on any of them, but I can turn around (okay, every once in a while, I burn the patience of our friend Rozyrg, hehehe).

Faced with this scenario, my option is to use and abuse trigonometry. Combining trigonometric operations with the use of variables (boolean or not), it is possible to create apparatuses that enable to activate / deactivate enemies, to change their firing sequences, to make them vary of movement, to increase / decrease the difficulty, to construct scenarios in a random way (this part is a lot of fun), in fact, with the simple use of mathematics you build a universe, define its laws and execute them.

The use of "triggers" and other types of conditioning factors is paramount for everything to work with satisfaction. It is up to the designer to foresee all the possibilities of something to occur in a different way from the planned one, and thus, to circumvent the problem, making the program resume its "natural" order.

I also use variables based on cycles, which are constantly checked during their execution. If certain conditions are met, the magic happens.

Here is an example in simple GML, which, I believe, can be adapted to any progamming language:

// - - - - - - - - - - - - - - - - - - - -
// In the "create" event

// Defines a variable that allows the enemy to fire, and another variable that controls the interval between shots

shoot = 0
time_shoot = 0

// - - - - - - - - - - - - - - - - - - - -

The next part defines the duration of the firing check cycle. As it is, the cycle has been set to a count and 0 to 10. Reaching the maximum allowed value, the cycle back to begin. You can change the values ​​at will, depending on the duration you want.

 // In the event "step"

time_shoot + = 1
if (time_shoot> 10) {
time_shoot = 0
}

// - - - - - - - - - - - - - - - - - - - -

By default, Game Maker has its own function to calculate intervals, called "alarm". In the example above, the user is allowed to get various results without depending on the said function, which has limited use to eleven (though you are unlikely to use more than that).

Image

With the predefined shot cycle code, the conditions for triggering must be established. The code, as it stands so far, only serves to count from 0 to 10, in an infinite cycle, until something happens and forces the machine to take another step.

Is it necessary to use this? Many will say "NO". I like it, because I can create almost unlimited options, depending on the combination of calculated variables.

The previous part of the code tells you to count in a closed cycle, in loop. It's an unconventional variation of the classic "for ... next".

Let's fire now?

// - - - - - - - - - - - - - - - - - - - -
// Still in the "step" event, just after the first part of the code:

if (time_shoot == 5) {
shoot = 1
instance_create (x, y, object_bullet)
}

// - - - - - - - - - - - - - - - - - - - -

The code now defines that when the cycle check variable reaches the value 5, the variable that allows firing changes its value. This value, which was 0, now changes to 1 (the famous boolean). With this satisfied condition, an enemy on the scene will shoot automatically, regardless of what happens around them, as long as it is "alive."

If you add a few lines to the code, repeating the formula and changing the values, you can cause the enemy to perform various actions, within the range of the predefined cycle. This simple scheme allows you to not only make an enemy make an enemy fire a burst of bullets, but also to make him change direction, attack, evade, counterattack, change form, use another type of weapon, anything.

You can also connect these conditioning factors to infinite others, associating the actions of that enemy within a certain period of time, at a certain point of the mission, to a specific place in the scenario, there are no limits to creativity.

See some usage examples:

Environments made with semiprocedural generation
Image

Environments and attack patterns
Image

Using a similar code with little and simple modifications, you can manage all game elements and build a dynamic environment, that almost never repeat itself. See my 1st prototype made in AS2, ten years ago:

https://www.youtube.com/watch?v=VAe4HodY7Zg&t=3s

Too many bullets with a simple code (in AS2):
Image
spmbx
Posts: 482
Joined: Sat Aug 01, 2009 5:22 pm
Location: The Netherlands

Re: How to store levels and enemy patterns?

Post by spmbx »

Post Reply