How do *you* organize level data and shot patterns?

A place for people with an interest in developing new shmups.
Post Reply
User avatar
Pixel_Outlaw
Posts: 2636
Joined: Sun Mar 26, 2006 3:27 am

How do *you* organize level data and shot patterns?

Post by Pixel_Outlaw »

There are many ways you can organize level data (aka enemies spawning) and also shot bursts.

Quite a lot of this approach heavily depends on the language you choose to write in.

So for people who have made shmups in the past, how did you store and execute your:
Level data (timer based? create all instances at once and scroll them/player? tile/trigger based?)
Enemy data (hard coding each one, base class inheritence?, dynamic functions bound to instances?)
Shot patterns (list of burst pattern instances with pointer? hard coding? queue of actions?)
Edit Enemy Paths (bezier patches?, other curve types?, waypoints and homing?)

The system I'm currently working on:

One of the solutions I'm currently toying with is a single game object type that so far sufficiently encompasses all shots, players and enemies.
All of these things mostly are a sprite bound to a hitbox with speed direction HP movement paths etc.

As it stands they are differentiated by the container they're stored in. enemies, enemy shots, player shots and players all get stored in different semi global containers.
They get an iterated int step counter which they pass to a dynamically bound script at runtime as a parameter.
This means each instance, though being the same C++ class gets a dynamically bound Common Lisp update function at runtime.
The bound Lisp function receiving the int from the C++ side is free to do anything it wishes depending on the value of the step variable passed.
This means I can actually change in game behaviors without needing to recompile the project through ECL.
I can edit the source scripts then tell C++ to reload them while the game is running. This means I have a live testing environment for shot bursts.
Also I might leave the scripts exposed so players can make their own "arrange" versions without needing my source code.
(Yeah they can delete files and harm their computer but that's not my problem)

But enough about my current approach, how are you or how have you stored and executed your data?
Last edited by Pixel_Outlaw on Sun Dec 18, 2016 11:25 pm, edited 2 times in total.
Some of the best shmups don't actually end in a vowel.
No, this game is not Space Invaders.
User avatar
Squire Grooktook
Posts: 5969
Joined: Sat Jan 12, 2013 2:39 am

Re: How do *you* organize level data and shot patterns?

Post by Squire Grooktook »

-Level data is entirely timer based for me. I do this because the games scoring system is based around Dangun Feveron's "kill enemies faster for extra enemy waves" system, so spawns are handled dynamically based on timers and time based checks (ie if enemy1 is dead before stage_time > 1000 then spawn enemy2).

-Enemies inherit from a parent object for basic stuff like hp and hit detection, but everything from movement to bullet patterns are scripted from scratch per-enemy.
RegalSin wrote:Japan an almost perfect society always threatened by outsiders....................

Instead I am stuck in the America's where women rule with an iron crotch, and a man could get arrested for sitting behind a computer too long.
Aeon Zenith - My STG.
User avatar
Pixel_Outlaw
Posts: 2636
Joined: Sun Mar 26, 2006 3:27 am

Re: How do *you* organize level data and shot patterns?

Post by Pixel_Outlaw »

Hard coding enemies will probably get you the fastest results for the CPU I'd imagine. :P
I kind of shudder to think what XML parsing in real time is like (BulletML) unless you convert it after loading to an internal structure.
How are you storing your derived enemies? Using a pointer of the base class type in a single list then casting as needed?
Some of the best shmups don't actually end in a vowel.
No, this game is not Space Invaders.
User avatar
Squire Grooktook
Posts: 5969
Joined: Sat Jan 12, 2013 2:39 am

Re: How do *you* organize level data and shot patterns?

Post by Squire Grooktook »

Pixel_Outlaw wrote: How are you storing your derived enemies? Using a pointer of the base class type in a single list then casting as needed?
Though I do know how to use pointers, I'm using Game Maker for this project (originally Unity), so most of that low level stuff like that is taken care of.
RegalSin wrote:Japan an almost perfect society always threatened by outsiders....................

Instead I am stuck in the America's where women rule with an iron crotch, and a man could get arrested for sitting behind a computer too long.
Aeon Zenith - My STG.
User avatar
trap15
Posts: 7835
Joined: Mon Aug 31, 2009 4:13 am
Location: 東京都杉並区
Contact:

Re: How do *you* organize level data and shot patterns?

Post by trap15 »

Level data is a list of commands, a sort of assembly language. Commands include "spawn object" "wait time" "wait for enemies to be dead" "call subroutine" "return from subroutine" "jump to position" and "end stage". Every stage has two "threads", one for ground enemies (on fixed placements, so everything is separated by "wait time"), and one for air enemies (on wave style formations, so a lot of "wait for enemies to be dead"). Spawn object commands give an ID number for the object type, and the object spawn handler returns how many bytes of data follow the spawn command, so that parameters can just be placed directly next to the spawn command.

Enemies are handled by an enemy manager, which is essentially just a fixed length list of Enemy structs, that gets iterated through and runs the update function. The enemy manager will take care of all the "common" behavior of enemies, and each enemy definition (a const struct) contains information such as base HP, init/kill/dying/main/draw callbacks (enemymgr has defaults for each of these if unspecified), points, sprite information/palette, and hitbox info.

Shot data is (again) a bytecode that is written as a sort of assembly language and interpreted. To improve turnaround on creating new patterns, I wrote a simulator in JavaScript (mostly took my interpreter in C and copy-pasted and hacked around stuff to work in JS) that takes the bytecode as a hexdump in a textbox and executes it with some dummy positions for the source and player. This is what that looks like: https://i.imgur.com/ZA9uxcX.png
@trap0xf | daifukkat.su/blog | scores | FIRE LANCER
<S.Yagawa> I like the challenge of "doing the impossible" with older hardware, and pushing it as far as it can go.
User avatar
Pixel_Outlaw
Posts: 2636
Joined: Sun Mar 26, 2006 3:27 am

Re: How do *you* organize level data and shot patterns?

Post by Pixel_Outlaw »

@trap15

I thought about doing some bytecode based stuff myself at some point.
Looks like you're planning an engine that can produce a series shmups by simply loading different externally defined patterns and bytecode scripts.
That's my goal too to some extent. To get all the damned boilerplate out of the way and focus on loadable behaviors. 8)

It's nice that most shmups boil down the the same handful of shots, enemies, players, obstacles and powerups.
Change the behaviors of those and you get entirely new games in a series.

Your editor looks pretty cool. Currently I have to edit behaviors in a text editor then hit a button to reload them kind of clunky but OK if I'm very careful with syntax before loading.
Some of the best shmups don't actually end in a vowel.
No, this game is not Space Invaders.
User avatar
trap15
Posts: 7835
Joined: Mon Aug 31, 2009 4:13 am
Location: 東京都杉並区
Contact:

Re: How do *you* organize level data and shot patterns?

Post by trap15 »

Pixel_Outlaw wrote:Looks like you're planning an engine that can produce a series shmups by simply loading different externally defined patterns and bytecode scripts.
That's my goal too to some extent. To get all the damned boilerplate out of the way and focus on loadable behaviors. 8)
Not even close :P Anything that's not super stupid implementation-wise is because it makes things easier in some other way. And most of it is evolutions of stupider and simpler implementations I did before.

Like the enemymgr stuff used to not even exist, I had to implement it to improve performance and decrease code size. Bullet stuff used to be all in code but I needed to decrease code size so I implemented a bytecode. Stage data was always a bytecode (couldn't think of a better or simpler way to do it that would be good on code size), though it used to be generated by a tool I had to compile and run every time I changed data; switched to an assembly to make that less painful.
@trap0xf | daifukkat.su/blog | scores | FIRE LANCER
<S.Yagawa> I like the challenge of "doing the impossible" with older hardware, and pushing it as far as it can go.
User avatar
MsK`
Posts: 42
Joined: Tue Jun 28, 2016 12:36 pm
Location: Bordeaux, France
Contact:

Re: How do *you* organize level data and shot patterns?

Post by MsK` »

I can give not one but two answers!

Shogun Rise of the Renegade : iOS/Android/Mobile... custom engine

In shogun rise of the renegade, all the enemies and bullet patterns were running a micro virtual machine running the bytecode compiled from a custom scripting language. It was kind of a super simple assembly language designed for shoot'em ups. You had a set of free purpose registers and 3 special ones : speed, angle and orientation. By setting speed = 10, angle = 90 and orientation = 180, you would have an enemy or bullet move at 10 pixels / frame, downwards and looking at the left. It was all made with polar coordinates.

The instructions where really simple like "add", "subtract", "multiply"... Some a little bit more evolved like "distance" and "target". But the really cool ones were the "wait" and "emit" instructions. The first one holds script execution for any number of frames. It makes most enemy and pattern coding dead simple because you most of the time don't need to code any kind of state machine anymore.

The emit instruction would duplicate the current VM (kind of like the unix fork() syscall) and would
replace the script pointer to a new one and all associated metadata (sprite, animations...). The advantage of duplicating the VM is that you can use all the free purpose registers to pass info from one VM to another. So most of the time, before doing "emit laser" we would set r0 to 40 and the first instruction of the laser script would be speed = r0. Voila, you get a laser going in the same direction as your enemy and 4 times faster with just two lines of script. This is really flexible because you could freely spawn enemies from enemies, bullets from enemies or even enemies from bullets :twisted:

Code: Select all

[General]
Health = 425
Timeout = 600
Drop = "worlds/ocean/scripts/badguy10explosion"
MinRank = 8
Deadtime = 40

[Metadata]
Score = 950

[Collision]
Radius = 35
Hitbox = { -18 -30 18 30 }

[Graphic]
Sprite = "worlds/ocean/badguys/lvl1-badguy010b.tga"
Shadow = "common/shadows/VrectangularshadowL.tga"
AnimationSpeed = 2
AnimationRegister = 18
Animation0 = { 0 }
Animation1 = { 0 1 2 3 4 5 6 }
Animation2 = { 6 7 8 7 }
Animation3 = { 6 5 4 3 2 1 0 }

[Script]
	Angle = 90°
	Speed = 3.0
	r6 = 0
	r0 = 2
	r18 = 0
	Define Bullet 2
	Wait 15
	
	
Ral	Speed -= 0.1
	Wait 2
	Jump Ral Speed > 0
	Speed = 0
	r6 = 0
	r18 = 1
	wait 15
	r18 = 2
P4	Angle += 8
	Counter = Bullet
P5	R6 += 1
	R17 = 1
	Emit common/bullets/scripts/disk 5 270°
	Angle += (16 / Bullet)
	Loop P5
	Wait 2
	Jump P4 R6 < 60
	
	Angle = 90°
	
	r18 = 3
	wait 10
	r18 = 0
Acc	Speed += 0.1
	Wait 2
	Jump Acc Speed < 2
    Wait infinity
The level editing was really simple also. We had a weird editor where most of script was a big grid. Below you would find all the sprites of all the enemies. On the top right, a view of the game. On the bottom right, settings of the currently set "block". By drag & dropping an enemy from the enemy tab to the big grid, you would add a new block. The position on the grid on the horizontal axis would tell when to instantiate the enemy and and the vertical axis would be where *around* the screen. Shogun had in his design support for many screen resolutions and for some reason, people didn't want to just use x/y and stretch that value to the screen... So it's kind of rectangulary polar coordinates!

So all in all, it was quite pleasant to work with because we could do stuff really quickly! The downside was that we could not put any enemies on the ground with that (but the background was just a scrolling 3D mesh so who cares !) and making complicated enemies could sometimes be tricky with the simple asm like language. Complex math formulas had to break down manually onto many instructions and we sometime ran out of registers...

PAWARUMI : PC/Consoles Unity3D

For Pawarumi, things are quite different! I wanted to be able to put enemies on the ground, everything is in 3D and I think I could leverage some C#/unity features to have most of what I liked of my vm/asm scripting.

So all enemies derive from one Enemy class that has 3 Speed, Angle and Orientation variables and are expected to override a coroutine called Script. This way, I'm not bound to any kind of special registers and I can still wait for some time with yield instructions and avoid writing boring state machine code. To spawn new enemies, I use a pooled version of the Instantiate method of unity and just pass data by assigning public variables on the enemies.

For bullets it's different. They also have the Speed/Angle/Orientation and a coroutine but the coroutine is selected with reflection to find the method between all the methods in the (partial) bullet class. And the coroutine is run with any kind of parameters that are passed by the vararg of the Fire() method.
All the 3D->2D projection math is hidden in the system to make enemy scripting really easy and fun. It's not the most efficient way of doing it but this is far from being the performance bottleneck of the game so it's fine :D

Here is a sample

Code: Select all

using UnityEngine;
using System.Collections;

public class SimpleLinearEnemy : Enemy
{
// thanks to unity, all there public variables are customizable in the editor's inspector
    public float Delay = 0f;
    public float MainSpeed = 30f;
    public float RotationSpeed = 0f;
    public float BulletSpeed = 30f;
    public float FireStartTime = 1f;
    public float FireRate = 0.1f;
    public int BulletCount = 3;
    public float Spread = 10f;

    protected override IEnumerator Script()
    {
        yield return Wait.Seconds(Delay);

        Speed = MainSpeed;
        float rotation = RotationSpeed * Time.fixedDeltaTime;
        float timer = FireStartTime;
        int count = BulletCount;
        while (count > 0 && FireStartTime < 100f)
        {
            Angle += rotation;
            Orientation = Aim(PlayerPosition, 180f);
            timer -= Time.fixedDeltaTime;
            if (timer < 0f)
            {
                Fire("Simple", BulletSpeed, Random.Range(-Spread, Spread));
                count--;
                timer += FireRate;
            }
            yield return Wait.Frame;
        }

        timer = 0.5f;
        while (timer > 0f)
        {
            Angle += rotation;
            timer -= Time.fixedDeltaTime;
            yield return Wait.Frame;
        }

        while (true)
        {
            Angle += rotation;
            Orientation += Mathf.DeltaAngle(Orientation, Angle) * 0.05f;
            yield return Wait.Frame;
        }
    }
}
Level editing is completely different. We have one or several big splines in the level which the "playspace" area follows. We put triggers along the way to start execution of the different kind of enemies that are dormant in the level. Enemies are automatically destroyed when they get out of the screen. (unless told not to do so) Some enemy triggers are conditional: they only trigger if a certain group of enemies has been killed. This is useful to fill out some areas if the player gets down the previous ones too quickly.

Image
Dodge the bullet, save the world.
Working on Pawarumi, check it out!
My twitter | Manufacture 43's Twitter
Image
User avatar
Pixel_Outlaw
Posts: 2636
Joined: Sun Mar 26, 2006 3:27 am

Re: How do *you* organize level data and shot patterns?

Post by Pixel_Outlaw »

That's some really good information.
It is always nice to see how different programmers tackle making games within the same genre.

I might have to make an editor too. I don't mind putting a lot of time into the boiler plate stuff as long as eventually I can get to making shmups by mostly placing and editing enemies and their paths.
That's my long term goal I suppose. In the past I've hard coded each game and found out that they could almost all be the same basic engine with edited enemy and level data.
I think that thing is especially evident in some of the doujin stuff from X.X Game Room though I'm not sure if they have an engine per se.

As much as I love programming I'd like to focus on making a 1 time engine that only gets tweaked between releases.
I would prefer it be my engine though, running my routines as I understand them.
The meat of the game being in external files defining behaviors, levels, and shot patterns.

This might be a good thread for people of different ability levels. Also some great ideas on how to store and execute routines.
Some of the best shmups don't actually end in a vowel.
No, this game is not Space Invaders.
User avatar
Xonatron
Posts: 658
Joined: Fri Aug 29, 2008 7:01 pm
Location: Yarmouth, Nova Scotia, Canada
Contact:

Re: How do *you* organize level data and shot patterns?

Post by Xonatron »

For our Duality ZF engine, that both the Duality ZF and Score Rush series uses:

Level data:

It is tile based. So the entire background level of tiles is loaded into memory and is scrolled along automatically. Left and right scrolling is controlled by the player of course.

Enemy data:

The enemy data is essentially stored in world (x,y) coordinates, with each having a path also store in multiple local (x,y) coordinates. The engine reads all of this from text files (some text files are created from excel files and formulas) and then sorts it. As the level scrolls, it waits for the next enemy to be instantiated.

At first there was no sorting, but when I made a 10,000 enemy stage it slowed it down. The sorting fixed it all. Amazing what optimizations can do.

Shot patterns:

I will have to let Jason explain this one. He created a bullet language that I coded the shot patterns in. It's one of the few area of the Duality ZF engine (that Score Rush also uses) that I do not know.
Matthew Doucette, Xona Games
Score Rush Extended [PS4]: viewtopic.php?t=55520
User avatar
Pixel_Outlaw
Posts: 2636
Joined: Sun Mar 26, 2006 3:27 am

Re: How do *you* organize level data and shot patterns?

Post by Pixel_Outlaw »

Xonatron wrote: Enemy data:
The enemy data is essentially stored in world (x,y) coordinates, with each having a path also store in multiple local (x,y) coordinates.
Paths are another topic that you can use quite a few approaches for. Some people use simple homing behavior (moving toward the next waypoint when "close enough" to the target) and then I've used things like bezier patches myself. (Though moving smoothly along those at a consistent speed was something I never did work out, especially with multiple bezier patches per path)

I'm thinking about doing waypoints in my current project. Seems a bit less of a hassle. Possibly more trial and error involved as "close enough" is found while limiting over shooting and under shooting destinations due to movement speed. There is also some danger of falling into "orbit" as limited turning angle tries to get close to the waypoint but constant speed doesn't allow it to get closer.
Some of the best shmups don't actually end in a vowel.
No, this game is not Space Invaders.
User avatar
jandrogo
Posts: 254
Joined: Thu Feb 07, 2008 11:51 pm
Location: Spain

Re: How do *you* organize level data and shot patterns?

Post by jandrogo »

Thanks for the thread and comments.
Very interesting to know the way people code stuff in shmups.

We should have more threads like this with knowledge and sharing creative thoughts.

I am on my way to code my first shmup in GM, just to learn, nothing to show.
Working in the japanese language achievement
User avatar
Jason
Posts: 211
Joined: Thu Oct 23, 2008 7:45 pm
Location: Canada
Contact:

Re: How do *you* organize level data and shot patterns?

Post by Jason »

I know Matt already replied, but here's my quick take on each one for the Duality engine, which also powers Score Rush:

Level data

- Tile based engine. No special sorting of graphics used, but it does make sure a single frame doesn't repeatedly swap textures when multiples are needed (i.e. tiles are rendered out of order, if needed).
- Enemies are stored in (x,y) delta starting positions from the screen position they should appear on. Y is included to allow for the same enemy path to occur in different locations relative to the player. There's more to it than this, but that's the start.
- Enemies are sorted in order of appearance, meaning checking to see if an enemy should spawn is literally a single element check per frame. Note that the shadow of an enemy means it's visible, so shadow sizes need to be taken into account. Trigger is the scrolling of the level. Could easily be a dynamic trigger though.

Enemy data

- I use the "Type Object" pattern (recently found out there was a word for this). I stay away from inheritance, it complicates with little gain. Don't always listen to your Comp Sci prof. A basic enum that states what the enemy is. Also another enum for the enemy 'class' or caliber. Staying the same means identical code running, just with different graphics/paths/shot patterns, which are other systems anyway.

Shot patterns

- Bullet language. You have default variables, and can even make your own. You set the pace. Spreads and lasers and randomized shots can all be made with a couple of variables. You can change the timing to overlap if desired. This produces byte code: at run time, anything that could be pre-calculated already is (on load). Anything not (such as randomness in shot angle, shot appearance, or angle at player) is computed on the spot and combined with the pre-calculated shot data.
- Enemies have guns that have patterns, which are really collections of patterns. The code automatically sets timing between shots, and handles the progress based on enemy health to move through different shooting personalities.
- Bullets are computed in position sub-frame, to easily allow time dilation for easier modes without quantization ruining the pattern.
- Care is taken to both optimize the bullet handling without damaging the draw order, required when bullets overlap in impressive spread/laser arcs: overlap must remain constant and in-order.

Enemy Paths

- Enemies are simple motions, going through (x,y) waypoints using Catmull-Rom splines, pre-calculated and divided to allow traversal in constant spline relative speed (not waypoint speed) -- very optimized. The waypoints include speed, to easily allow for fake acceleration/deceleration, which works well; Score Rush doesn't showcase this much, but it's there. Note the speed traversal handling allows for a chaotic motion when the spline produces a tiny quick arc; so care must be taken to use the system properly -- i.e. (x,y) dictates the curve, not the speed from point to point, so you can use many points to adjust a curve and not affect the speed.

All data is text file driven, which can allow for tools to easily modify it, and hand modification is trivial. Tools would be the way to go here for quick iteration times.
Jason Doucette / Xona Games
- Score Rush Extended
- Decimation X3
- Duality ZF
User avatar
Pixel_Outlaw
Posts: 2636
Joined: Sun Mar 26, 2006 3:27 am

Re: How do *you* organize level data and shot patterns?

Post by Pixel_Outlaw »

Jason wrote:I know Matt already replied, but here's my quick take on each one for the Duality engine, which also powers Score Rush:

Enemy data
- I use the "Type Object" pattern (recently found out there was a word for this). I stay away from inheritance, it complicates with little gain. Don't always listen to your Comp Sci prof. A basic enum that states what the enemy is. Also another enum for the enemy 'class' or caliber.
Looked it up, yeah seems like a lot of people have fought the impulse to create too many classes while making games.

I think this is a hallmark problem of trying to adhere to "good" OOP practices while writing a system of 20 or so Enemy objects that only change in behavior at runtime. ;)
In fact, how many shmup objects are just a moving hitbox, HP, a runtime action and a sprite? The only difference many times is the container they're stored in "bullets" "players" "enemies" etc.
They Engine knows how to treat items in each container in my case. C++'s static typing often gets in my way. That's sort of what my approach tries to solve by creating highly customized instances rather than sub classes or composite classes. Hence the script binding to an update event passing a step value. You'd think it'd be really slow but I can belch out 1000 enemy shots with no noticeable slowdown on a low end machine. Granted the scripts are compiled when loaded at runtime. :)
Some of the best shmups don't actually end in a vowel.
No, this game is not Space Invaders.
User avatar
Jason
Posts: 211
Joined: Thu Oct 23, 2008 7:45 pm
Location: Canada
Contact:

Re: How do *you* organize level data and shot patterns?

Post by Jason »

I still make different classes for the different objects, because there are enough significant differences (bullets don't need score, for example). I even have the enemy and player bullets different (because one animates and the other doesn't). Static type checking doesn't impact this, because they only get used where they need to. There's no "foreach x in all_objects do { x.update() }"

Now that they are separate, I can handle updating them individually in optimized ways. This is so powerful that for the particle systems I even have multiple classes for each type of particle. Some live a constant amount so I can have a cyclic array that is always accessed in order. Others die by a random amount of time, so I have to work harder to keep them close to each other (and thus all in cache).

Highly recommended book: Game Programming Patterns
Recommended chapter: Data Locality
Jason Doucette / Xona Games
- Score Rush Extended
- Decimation X3
- Duality ZF
User avatar
MintyTheCat
Posts: 2023
Joined: Sat Jun 19, 2010 3:46 am
Location: Germany, Berlin

Re: How do *you* organize level data and shot patterns?

Post by MintyTheCat »

I work on older platforms and as such my decisions reflect the means :)

I have a blob of code that acts as my 'engine' which is a set of tasks that run on the old hardware. This is tied to my utility that generates the data, converts it, compresses, etc. I then add in maps for the levels made in Pro-Motion (bit buggy but ok for now) and then I wrote my own command-line based tools to convert it all and recently added a GUI app in Visual C++ which is my level editor. Everything is my own.

Compression, deltas, all are handled and calculated using my tools which are packed into the ROM which when ran under the target is consumed.

I have something fairly standard that is like a little language that describes actions, events and updates, e.g. load in level sequence, load in enemy ID at slot N, alter the scroll-rate, change scroll direction, change background, load in new Sprite asset - that sort of thing. This is then parsed, determined, then turned into data for the engine to interpret. Presently no support for sound but will add it in once I get the time.

The data generated can also be used for other purposes.

I have direct control of the interrupt ratios and I can tell the engine to alter it for timing.
I have a block of variables that are given over for use by the game engine that the level-editor provides.

All is based on a sequence tick with a level being a set of sequences with each sequence having a set of tiles, sprites, enemy-table and palettes. This is so that my tick never gets to be too big. The level editor is instructed as to what is required, it knows what is in memory at any given time and for an update elects to either swap all out or parts which become update actions so imagine pieces of graphic, sprite data being swapped out or a palette being swapped out in part due to game events.
A comparison with current tick-time against the slots' "activate-time" is made periodically with anything at the point being acted on and the status of that slot changing to "active".

To be honest, most of the intelligence really is in the tools, the game engine itself is fairly simple and plays it fast and loose :D
I also have some useful bench-marking services added in too which requires the designer to execute the sequence once and then compares loading stress to which the designer can then tune as necessary. The GUI level editor came much later for me and instead I used my own tools to handle the level data and events but it gets to be too much work to keep changing often so I chose to have a GUI on top - all code uses exisiting code though and I use a mix of C and C++ which builds under Linux and Windows.

The enemy table is simply a block of objects, the enemy list is a simple list with the enemy manager adding in and swapping out enemies as they as placed in ready to be used, made active then either die due to losing all health or their life expires and to which they are set as being "expired" and the manager then knows to use that slot in the list.

I can also tell the engine to do nothing and switch control directly over to a Routine for something heavy if I need it - eg. a massive boss encounter but I have not required this as yet but it is there if I need it.

I studied some Shmups and how they designed their enemy and object control software and worked it out from that but tailored it to my own situation.

I read somewhere in a japanese STG dev book that you should "decide what is the main feature of your game and design around that".
More Bromances = safer people
Post Reply