Shmup level editor, enemy and bullet question

A place for people with an interest in developing new shmups.
Post Reply
User avatar
laxa88
Posts: 51
Joined: Mon Mar 10, 2014 10:32 am

Shmup level editor, enemy and bullet question

Post by laxa88 »

Hi all,

I've gotten past the collision detection part of coding my shmup's engine, and am stuck at designing my level editor. I spent some time searching through the forums but again, results weren't what I expected so I opened a new thread instead.

How do level editors normally work? I'm not sure what exactly is the elegant way of designing it, but here was my attempt:

- The camera has a global trigger
- The background is a long vertical map, filled with "enemy wave triggers"
- The background scrolls down slowly, giving the feel that the "players are flying forward"
- When a wave trigger touches the global trigger, the appropriate enemy wave/pattern is generated

I'm satisfied with this approach of "making enemy waves appear" at the exact time I want, as long as I adjust the position of the wave triggers.

Here comes my problem:

How are enemy waves designed? I could think of adding enemy "actions" to a list, which would execute in sequential order, like this:

Code: Select all

// pseudocode
// 1) The code below is attached to every enemy object
// 2) The enemy trigger objects will call the Start() of every enemy object
// 3) Every Update() will trigger each enemy object's Update() to execute their actions accordingly

GameActionList _actionList = new GameActionList();
bool isBusy = false;

void Start(){
   _actionList.add("enemy1", "moveTo", position, moveSpeed, duration);
   _actionList.add("enemy1", "pause", duration);
   _actionList.add("enemy1", "moveTo", position, moveSpeed, duration);
   // ... and so on ...
}

void Update(){
   if (_actionList.length > 0){
      if (isBusy == false){
         ExecuteNewAction( _actionList[0] );
         _actionList.removeAt(0);
         isBusy = true;
      }
      else{
         ContinueAction(); // when the action is complete, will set isBusy = false
      }
   }
   else{
      destroyThis();
   }
}
I was quite satisfied with this approach until it hit me -- Enemy movements and enemy bullet waves are independent actions; they may execute alongside or at completely different timings. If I were to write a list like this, then it would mean enemies can only move OR shoot one at a time, but not at flexible timings, such as:

- at time 0:00, move somewhere for 5 seconds
- at time 0:02, shoot at player
- at time 0:05, move somewhere
- at time 0:05, shoot at player again

Does anyone have any ideas on how enemy movement and bullet sequences are designed? I appreciate the response, and thank you in advance!
Doodle/development tumblr : http://wyleong.tumblr.com
Art (rarely updated) : http://animenifestor.deviantart.com
Ixmucane2
Posts: 773
Joined: Mon Jan 19, 2009 3:26 pm
Location: stuck at the continue prompt

Re: Shmup level editor, enemy and bullet question

Post by Ixmucane2 »

You almost answered your own question: enemies need to do two things at the same time, moving and shooting. The game loop should execute one current movement and one current attack from two queues, not one current action from a single queue.
For greater flexibility you could allow an unconstrained set of ongoing actions, particularly multiple attacks (usually with different weapons) while moving and special actions like changing forms without affecting movement and attacks.
User avatar
nasty_wolverine
Posts: 1371
Joined: Sun Oct 09, 2011 11:44 pm

Re: Shmup level editor, enemy and bullet question

Post by nasty_wolverine »

Code: Select all

enemyupdate()
{
enemymove();
enemyshoot();
}
i dont know much about level editors, i am just hard coding stuff for levels. But i can tell something on enemy actions.

generally you would want shooting and moving as seperate elements. bunch of things you can do really.
- hard code it into a functions. so something like shoot every 30 frames at player, follow path from internal array and interpolate in between.
- have a text or binary file which has parameters stored in them, you update function just evaluates them to what they should be doing next.
- procedural bullshit.

in any case each enemy will need to have internal data structures to store current state. read up on FSM's and how they apply to video games and AI.
Ideally you would be using catmull splines for movement and for shooting you would either shoot at every 15 or whatever frames, or something "if active frames at 60, shoot pattern one, if active frames at 150 shoot pattern two, if active frames greater than 120, shoot pattern three every 45 frames".
generally it is easier to keep movement and shooting decoupled, then you can easily have two enemies that shoot different patterns but move the same way.

and on how to program waves, there was a thread in here before, i ll just skim over them:
- have lists with activation times. so at certain frame number, spawn five ships at certain positions.
- have lists with delays. so wait each wave in the list has a delay time for when it should be launched after the previous wave.
- have lists with lists of enemies to spawn after complete removal of current wave. so gotta kill all current enemies or time them out to get the next wave.
- if you have a editor (the best way to do it), triggers at certain positions in respect to global camera. each trigger when it comes under the camera spawns a bunch of enemies.
Elysian Door - Naraka (my WIP PC STG) in development hell for the moment
User avatar
laxa88
Posts: 51
Joined: Mon Mar 10, 2014 10:32 am

Re: Shmup level editor, enemy and bullet question

Post by laxa88 »

@ixmucane2
After re-reading my post, I think you're right. I was being unrealistic -- trying to combine both move and shoot events into one queue, which wasn't possible. Regarding flexibility, I've made it so that enemies can have a variable number of "weapons" which will generate different bullet patterns based on which attack method is called... so yes, I believe I'm doing what you suggested already. :D

e.g. A larger ship might have 3 weapon objects, two of them doing single-fire shots, and one in the center a spiral pattern.

@nasty_wolverine
I think I'm "hard coding" the levels right now. I don't have a separate text/binary file to store the enemy parameters. I'm still using trigger objects to "call the enemy waves", where each wave is manually coded with custom enemy movement and shooting queue actions. I believe I'm also following what you said about procedural stuff -- I have functions like such:

Code: Select all

function void ShootAtPoint(BulletType type, Vector3 position, int bullets, int cycles, float bulletCooldown, float cycleCooldown) { ... }

function void ShootByPattern(BulletType type, PatternType pattern, int bullets, int cycles, float bulletCooldown, float cycleCooldown) { ... }
Regarding FSM, I dont quite see the relevance to shmups yet. But let me try to guess what it means:
- Enemies have different states, e.g. "isMoving", "isHit", "isInSecondForm"
- Depending on each state, which (I assume) are mutually exclusive, a different function is executed

Did I get that right? Because otherwise I don't quite see how FSM works in shmups.

Regarding catmull splines, thank you so much for the mention. It's the first time I've heard of it (I might have learned that in school but it wasn't in English so I most probably wasn't aware of it). A few days back I revisited Bezier curves and considered using that for the enemy paths, but I think the concept of catmull splines is more attractive.

The only problem now is, I have no idea how it works. I'll have to google up on it as much as I can.

Regarding shooting sequence, I'm using triggers as well, rather than "shoot at xyz active frames" or "shoot at xyz time", because IMHO a visual trigger will allow me to easily adjust the timing of the enemy shots in-game.

But anyway yes, the bottom line is, I should have just went for keeping movement and shooting queues as two separate things. I was just wondering if there's any magical way to keep them together, which is silly of me.

Regarding program waves, I'll stick with the last point you mentioned -- visual triggers for now. That's what Unity is good for anyway, and I'm comfortable with it so far. I understand where you're coming from (for the first 3 points you mentioned) -- if I were coding on C#/XNA or C++/SDL I would have used the lists method you mentioned. In my current design, the subsequent waves do not get triggered even if the current wave is wiped out.
Doodle/development tumblr : http://wyleong.tumblr.com
Art (rarely updated) : http://animenifestor.deviantart.com
User avatar
nasty_wolverine
Posts: 1371
Joined: Sun Oct 09, 2011 11:44 pm

Re: Shmup level editor, enemy and bullet question

Post by nasty_wolverine »

laxa88 wrote: I think I'm "hard coding" the levels right now. I don't have a separate text/binary file to store the enemy parameters. I'm still using trigger objects to "call the enemy waves", where each wave is manually coded with custom enemy movement and shooting queue actions. I believe I'm also following what you said about procedural stuff -- I have functions like such:

Code: Select all

function void ShootAtPoint(BulletType type, Vector3 position, int bullets, int cycles, float bulletCooldown, float cycleCooldown) { ... }

function void ShootByPattern(BulletType type, PatternType pattern, int bullets, int cycles, float bulletCooldown, float cycleCooldown) { ... }
well in my game i dont make a distinction between bullets, enemies, backgrounds or triggers. they all share the same interface of a base object, which can be updated, rendered, hashed and collided with other objects, and properties can be configured and turned off. and i have a single spawn function for everything (however if required i can get access to the spawned object and change more stuff if i want), that way i just do

create(object_type, sub_type, position, trigger_at, orientation, velocity);

i would suggest have a single function to generate bullets, and change orientation and velocity to generate patterns (like in a for loop or something), and if your bullets are doing something crazy (ketsui curve balls) that should be in the bullet behaviour.
laxa88 wrote: Regarding FSM, I dont quite see the relevance to shmups yet. But let me try to guess what it means:
- Enemies have different states, e.g. "isMoving", "isHit", "isInSecondForm"
- Depending on each state, which (I assume) are mutually exclusive, a different function is executed

Did I get that right? Because otherwise I don't quite see how FSM works in shmups.
if your game has AI, even basic AI, you will need to understand FSM. even something like what cave mooks do, can be reduced to a FSM and easily coded
- come down screen till certain point.
- stop and hover around and start shooting.
- turn around and leave (while shooting optional)
laxa88 wrote: Regarding catmull splines, thank you so much for the mention. It's the first time I've heard of it (I might have learned that in school but it wasn't in English so I most probably wasn't aware of it). A few days back I revisited Bezier curves and considered using that for the enemy paths, but I think the concept of catmull splines is more attractive.

The only problem now is, I have no idea how it works. I'll have to google up on it as much as I can.
search rozyrg's post, he had a basic spline generator. it was something easy and efficient.
Elysian Door - Naraka (my WIP PC STG) in development hell for the moment
User avatar
laxa88
Posts: 51
Joined: Mon Mar 10, 2014 10:32 am

Re: Shmup level editor, enemy and bullet question

Post by laxa88 »

I never thought about bullets/enemy/background/triggers to be derived from the same base object. But now that you say that you've done it, I know it's not impossible. I think Unity has the same concept (prefabs) but it's more of a hassle to do things your way in Unity environment.

I currently use object pools for my bullets, coins and effects. I have one script (attached to all enemy weapon GameObjects) that handles generating bullets, such as "single target" or "spiral" or "ring" or etc. I'm embarassed to ask: What's a ketsui? I looked up the glossary (http://shmups.system11.org/viewtopic.php?t=1348) but there was no result.

Regarding FSM/AI -- Thanks for the info, I'll keep that in mind when I start designing/coding the enemy choreography.

I searched rozyrg's posts but ... couldn't find any thread or topic that talked about "spline" or "generator". :( But anyway I'll study up on the catmull spline and use it eventually. Thanks again for the mention.
Doodle/development tumblr : http://wyleong.tumblr.com
Art (rarely updated) : http://animenifestor.deviantart.com
User avatar
nasty_wolverine
Posts: 1371
Joined: Sun Oct 09, 2011 11:44 pm

Re: Shmup level editor, enemy and bullet question

Post by nasty_wolverine »

Well, ketsui is a kind of a cute fluffy animal, its really fun to play with, they come from caves.

well rozyrg is rozyrg, he is god sent... http://shmups.system11.org/viewtopic.ph ... 47#p946647 you will find the spline generator somewhere in there. also try out a few of his games. they are good for learning what makes a shmup a shmup.
Elysian Door - Naraka (my WIP PC STG) in development hell for the moment
Post Reply