Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

877498 Posts in 32868 Topics- by 24305 Members - Latest Member: orloff

May 19, 2013, 04:48:24 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)How do you make levels for your shmup?
Pages: [1]
Print
Author Topic: How do you make levels for your shmup?  (Read 885 times)
eiyukabe
Level 2
**



View Profile Email
« on: June 09, 2012, 11:08:19 PM »

Just curious. What tactics have any shmup developers used to create their levels? Coding enemy spawn events as time-stamp driven event arrays in your source language or xml? Placing spawners in a 2D level editor and having them automatically trigger when the top of the screen (or side if it scrolls horizontally) touches them? Magic?

I am trying to decide on a solution for making shmup levels myself, and the tradeoff seems to revolve around visualizing your "level" temporally (a sequence of spawning events) or spatially (a 2D layout of enemy formations). To get things started, I worked with a temporal scripting solution on my last project but played around with a 2D level-editing solution on a shmup that I never completed, and I feel that a 2D editor would be overkill for my current project. I am curious though to know what thoughts have been put into this dichotomy (or is there a third way of looking at it that I am not aware of), particularly for completed shmups that have provided the developer with experiential insight. Speculation is still welcome though  Beer!
Logged
Klaim
Level 10
*****



View Profile WWW
« Reply #1 on: June 10, 2012, 01:14:10 AM »

I was wondering the same question today, while thinking how to potentially produce some shmup in the coming times. My initial thinking is always to start with a timed-event system as it seems the simpler to implement, but that might be also very hard to use as a level designer in a big level, I don't know because of lack of experience.

Maybe an almost idealist way of doing it would be to make the game as an editor and allow edition on the fly (in pause) and then also allow rewinding a bit and then resume the action.
That would be perfect but I'm not sure if it's hard to implement or if it's worth it.
Logged

http://www.klaimsden.net | Game : NetRush | Digital Story-Telling Technologies : Art Of Sequence
Hima
Level 4
****


OM NOM NOM


View Profile WWW Email
« Reply #2 on: June 10, 2012, 04:22:27 AM »

I used an external text file to define my level. A syntax is something like

Code:
Time in seconds when this line should be execute, Command, Argumetn1, Argument2, ...

So a simple level file can look like this

Code:
5.0, SPAWN_ENEMY, 1, 100, 100   // EnemyID, X, Y
7.0, SPAWN_ENEMY, 1, -100, 100
10.0, START_CHANGING_BACKGROUND // Calling a function in the game

There'll be a level manager that read in the text file, parse each command into a command object and store it in an array.
Code:
void Update()
{
      totalTime += Time.deltaTime;
      if( currentIndex < commands.Count )
      {
         while( totalTime >= commands[currentIndex] )
         {
             commands[currentIndex].Execute();
             currentIndex++;
         }
      }
}

One flaw I found with this is testing a specific point in time in the game isn't really smooth, especially when you want to sync enemy sequence with background presentation and music like most shmups do. But it's simple to implement though.
Logged

eiyukabe
Level 2
**



View Profile Email
« Reply #3 on: June 11, 2012, 01:02:24 PM »

Thanks for the feedback.

Yeah, it feels like temporal sequences in text format is the "best" thing to do now, as the "level editor" (notepad++) is already made for me Smiley. Might do that, and make/find some simple 2D editor if things get more complex.
Logged
InfiniteStateMachine
Level 10
*****



View Profile WWW Email
« Reply #4 on: June 11, 2012, 01:41:07 PM »

I set up DAME to work with my game. I don't really use any timing. I have a sensor about half a screen in height above the game screen. When an enemy enters that area it awakens and starts doing it's thing.

As for the level script I have a sequence of camera nodes throughout the level I place using the DAME path tool. Each node has a couple values such as how fast it should move to the next node and some transition stuff so that the camera doesn't sharply change direction at every node.

DAME is great in that it had all the tools I need and a system for writing exporters in LUA. The problem is though that it's way too buggy as an application. I've lost my work on a level more times than I can remember. Do not trust the save function in DAME. As a result I'm now writing my own level editor ingame. The nice thing about that is people who play the game will be able to make their own levels from within the game. The not so nice thing is I tend to find excessive GUI coding to be a bit on the boring side.
Logged

BlueSweatshirt
Level 10
*****


the void


View Profile WWW
« Reply #5 on: June 11, 2012, 09:37:32 PM »

Writing out timed sequences becomes hell after about one minute of level duration, and they're incredibly painful to test. Such are my experiences.


One option that sounds good is some kind of spatial level editor that can spawn arbitrary user-defined clusters of enemies, so that when the overall bounding box of the cluster enters the screen, all enemies inside spawn. This way you can more accurately create formations and the like and have them retain their proper positioning. I think it'd be a ton easier to previsualize the level while working this way. In addition, assuming the scrolling speed is fixed, I'd include utilities to show what the timestamp of the level is at every vertical(or horizontal) point, as well as the ability to jump to a certain point based on time. In theory it sounds good to me, however I've never made such a thing.

In addition, if the editor was baked into the game itself, a useful utility would be a side panel view which simulates the level up to the current point in time, such that you can see exactly what is on the screen at the time. Yes, that would be incredibly useful. I'd even say quintessential.
Logged

FemtoKitten
Level 0
**


Everyone deserves a cuddle or two!


View Profile Email
« Reply #6 on: June 11, 2012, 10:24:50 PM »

In a shot-em-up awhile ago I used the "Time label" method, it was a pain to test and get just right. In the end I combined the idea of Waves and Time, the less enemies on the screen the faster the time passes. This way a poor player would get extra time, and one who was great would quickly have the screen filled with enemies/bullets and would also have no shortage of enemies until the end.

Of course I just had a repeating background in this one (I was trying to test out ships with linked pieces, the background wasn't my concern), so the background didn't matter. For a game with set-pieces and paths it would be more difficult.
Logged

Lonely Girl in Denver, I like making  games that require thought (Puzzles, 4Xs, Strategy, Turn-Based board games). Currently working on a Cute Collectible Card Game for Console and Mobile devices
Azure Lazuline
Level 2
**



View Profile WWW
« Reply #7 on: June 12, 2012, 07:57:59 AM »

I use scripting for my shmup, in a separate (synced) thread. Pseudocode:
Code:
SpawnEnemy(type,x,y,parameters);
Wait(60); //wait 60 frames
for(i=0;i<5;i++){
SpawnEnemy(type,x,y,parameters); //do something with i to make the enemies line up or form a pattern
Wait(5); //each enemy is spawned 5 frames apart
}
Wait(80);
SpawnMidboss();
WaitUntilAllEnemiesDead(); //only continue when the midboss is dead

//etc, more enemies, then a boss, then it sets a clear flag

It's basically time-label, but everything is relative instead of absolute. Also, it becomes very easy to comment out the first chunk of the stage to skip that part in testing!
Logged

Copy Kitty - a platformer/shooter with 200 weapons! Blow up robots and destroy the world!
VSRI
Manbaby
*


Dirty Web Hippy


View Profile WWW
« Reply #8 on: June 12, 2012, 05:18:00 PM »

I use data-driven timelines and triggers. The triggers make the game progress to the next timeline when a condition occurs, for example if all the enemies are destroyed. With triggers you can control the overlap between timelines and even partition the stage into stand-alone pieces like waves. It's only necessary then to test the timeline you're currently working on without having to simulate from the very beginning of the stage. This also makes the timelines modular so you can reuse them as patterns in other stages if need be.

If you do roll timelines, you really need to make a timeline editor so they're easy to modify. Notepad++ won't cut it. You should be able to scale segments and insert/remove arbitrary amounts of time as if manipulating image data. Otherwise you'll go on a rampage when it comes to fine tuning. (Try rescaling 100+ events in a text editor. Evil)
Logged

Until next time, live dementedly.
a_citizen_erased
Level 0
**


View Profile WWW
« Reply #9 on: June 13, 2012, 01:49:29 AM »

To throw some ideas out there, here's what I'm currently doing:
* Levels are scripted using Lua.
* Use coroutines so logic can wait and resume.
* Can have many coroutines running at once.

Example level:

Code:
function background0(script, args)
    setBackground("image.png")
    setBackgroundSpeed(100)
    wait(1000)
    setBackgroundSpeed(200)
end

function spawnWave(script, args)
    for i=1,10 do
        spawn("enemy1", position={args.x, 100}, path="path_name")
        wait("milli", 200)
    end
end

function spawnBoss(scripts, args)
    spawn("boss")
    wait("second", 10)
    spawn("boss2")
end

function run(script, args)
    script(background0)
    script(spawnWave, {x = 0})
    script(spawnWave, {x = 100})
    wait("all enemies dead")
    script(spawnBoss)
    wait("all enemies dead")
    nextStage("stage2")
end

return run

The above script will spawn two waves of enemies at the same time. Each wave will spawn a single enemy every 200 milliseconds, and finish when 10 enemies have been spawned. When all those enemies die, a boss will be spawned. After 10 a second boss enemy is spawned. When they're dead the level is complete.

* The script() call starts a new coroutine.
* The wait() call yields the coroutine.
* The game will resume a coroutine when its wait condition is met.
* You can have many scripts running "concurrently". By concurrently here I mean each time the game's logic is updated, each coroutine will be run sequentially until it waits or finishes.
* Can add in whatever different wait conditions you like.
* Whatever the script returns is the first coroutine that gets run.

This allows scripting levels temporally but does not tie things to real time. Wait conditions such as "wait for all enemies to die" is useful in many situations. It's easy enough to skip parts of levels by commenting stuff out (this will depend on how well you organise the scripts). Since it's in lua, pretty much everything is done already, except the logic to run and check coroutine wait conditions.
Logged
Skomakar'n
Level 10
*****


Vąutah


View Profile WWW Email
« Reply #10 on: June 14, 2012, 01:37:23 PM »

I have never made a shmup, specifically, but for this kind of scrolling and fairly simple and almost repetitive kind of level, unless the game will be too big, I tend to just hardcode and test stuff the hard way. If you're going to be working on it for an extended time, though, I would at least recommend making a simple editor where you can scroll through the level and place different objects easily and then save that to a level file.
Logged

mak gam
Geisha Novia: Out now!
Bottoms Up!: Devlog

Royal Railway on Twitter.

Adam Emil
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic