Design Questions about scrolling SHMUP design

J

J_C

Guest
Hello everyone!

I'm designing my first game (a top down shoot 'em up) in the GMS2 engine, and a question occured to me about creating the levels. I know that it is easy to set up a scrolling background for these types of games, but I plan to have more detailed, hand crafted levels for my game.

Now if I create a level, which is constatnly scrolling, I assume I should create a map (level) which is thousands (maybe tens of thousands) of pixel long so it takes several minutes (maybe 15 mins) to get to the end of it.

But isn't this too big for the engine to handle? How do people create these levels?
 
J

J_C

Guest
You can deactivate the instances outside the view. Then GM won't process them.
Thanks.

But this means that the actual room size must be many thousands pixel wide, am I correct? It's just that the actual instances will only be active when they are in view?
 

Niels

Member
Room size is always infinite. Even if you set the room size to 100x100. You can still place insances at 50000x50000.

But it's good practice to split the world into smaller sections. Use multiple rooms.
I have seen others load levels "into" a level and i'm really interested in learning how to do that. do you have any link to a tutorial that explains this?
 

YanBG

Member
To keep everything in one room you can use chunks to save/load/delete sections of land. For example World grid having 20 by 20 Chunks, each Chunk it's own grid with 30 by 30 tiles and 32 pixels for all tiles, gives you like 100 huge sized rooms combined to explore.

 
With my shmups I just load enemies as they're needed and scroll the background. I've even managed to find some sort of odd issue where the background fails to loop properly like when it loops the loop is black and then it pops in. I've struggled with it. As for levels in levels its easy enough using that load enemies as they're needed method.

Loading in enemies also lets you hold a new enemy wave until enemies are destroyed.
 
J

J_C

Guest
With my shmups I just load enemies as they're needed and scroll the background. I've even managed to find some sort of odd issue where the background fails to loop properly like when it loops the loop is black and then it pops in. I've struggled with it. As for levels in levels its easy enough using that load enemies as they're needed method.

Loading in enemies also lets you hold a new enemy wave until enemies are destroyed.
Can you load in terrain elements as well, and move them to get the illusion that the ground is scrolling?
 

Yal

🐧 *penguin noises*
GMC Elder
Can you load in terrain elements as well, and move them to get the illusion that the ground is scrolling?
Yes. Just don't forget to unload them as well when they're too far away, doing stuff to lots of objects at once can get kinda slow.
 
  • Like
Reactions: J_C
J

joqlepecheur

Guest
There is a super easy way for handcrafted schmups:
  • use a timeline to spawn ennemies and objects a little bit before they appear on screen
  • you can destroy the instances that have y > room_height (if it is from top to bottom you get the idea)
 
  • Like
Reactions: J_C
Can you load in terrain elements as well, and move them to get the illusion that the ground is scrolling?
Yeah just like enemies spawn them in as you would enemies. That way you can have a game programmed to have thousands of enemies, but they're only spawned in when needed.

Destroy them once they've scrolled past. Also if there are particles or anything like that make sure to destroy / remove them and their emitters... or just don't use particles at all. I recommend that. I've also been passed a shmup project where the previous developer deactivated things rather than destroying them.

Here is a view of thousands of enemies via an in game editor:


Every yellow line is where the enemies will spawn in. You will see I call up a radar. The gray dots are representations of where the enemies will be once they spawn in. The yellow dots are real enemies. Terrain elements are also called in, but they're only planets, black holes and simple stuff like that at the moment.
 
J

J_C

Guest
Yeah just like enemies spawn them in as you would enemies. That way you can have a game programmed to have thousands of enemies, but they're only spawned in when needed.

Destroy them once they've scrolled past. Also if there are particles or anything like that make sure to destroy / remove them and their emitters... or just don't use particles at all. I recommend that. I've also been passed a shmup project where the previous developer deactivated things rather than destroying them.

Here is a view of thousands of enemies via an in game editor:


Every yellow line is where the enemies will spawn in. You will see I call up a radar. The gray dots are representations of where the enemies will be once they spawn in. The yellow dots are real enemies. Terrain elements are also called in, but they're only planets, black holes and simple stuff like that at the moment.
Thanks, this help me a lot to sort my own game out. :)
 
J

J_C

Guest
I reached a point in prototyping when I have to make a decision about handling the scrolling bit of the game. What do you think is the better (easier) way of handling a shmup, which as lot of scrolling elements? Not just enemies, but terrain elements and other objects as well.

a) the player ship and the camera is not moving, it is the background and every other object that is scrolling towards the player. Basicly the room is scrolling, not the player.
b) the room and every object is fixed, it is the player ship and the camera which is moving forward.

I started development using option a) but I'm thinking that since there will be many moving objects in the room, using this would mean more work (and more way to mess it up).
 

Electros

Member
It's an interesting topic - I am currently working with two approaches:

1) The level is laid out, player and camera move through it, enemies are spawned (via timelines) and disposed of (by position checks) when required
2) The player and camera are fixed, the level (layers) scroll downwards, enemies are spawned (via timelines) and disposed of (by position checks) when required

I am using option 1) for the standard shmup go through the level & complete at the finish, and option 2) for the boss battles. Scrolling the layers for 2) also allows for fairly straightforward looping, which I think may be trickier with option 1) (though certainly doable).

It kind of feels like there are advantages to both, it may more come down to the type of shmup you are building, and which you feel more comfortable implementing.
 
J

J_C

Guest
I'm leaning towards your number 1), just because that way you don't have to manage the scrolling of all the other objects (enemies, terrain), just the player and the camera. Of course all of that scrolling might be handled with just one variable, and changing that can effect all other objects, so it is not that number 2) is that difficult to code. Spawning in enemies (with timelines) and disposing them are needed for both of them, so on the basic level the main difference is that how many object's movement you have to code.

A question though: when you are scrolling a layer, you are just scrolling a background, or is it possible to scroll all the objects which are placed on that layer?
 

Yal

🐧 *penguin noises*
GMC Elder
I would go for option B personally if terrain itself is interactible (e.g. Gradius, Deathsmiles, Raiden, Ikaruga) and option A only if anything non-enemy/non-bullet is just decoration (e.g. Touhou, Galaxy Squadron EX, Crimzon Clover). If terrain objects need to form an obstacle course for you to go through, it's MUCH easier to get things right if you can actually see them. For this approach, I'd even put enemies into the room manually (but use instance activation or something to make them stay at their initial positions until they're on-screen) to make sure they sync properly with the level. We've got the view system for precisely this reason, not having to move the entire level around all the time, so not using this helpful abstraction for what it's intended for is... kinda wasteful and just gonna make things harder for you.
 
  • Like
Reactions: J_C
J

J_C

Guest
I would go for option B personally if terrain itself is interactible (e.g. Gradius, Deathsmiles, Raiden, Ikaruga) and option A only if anything non-enemy/non-bullet is just decoration (e.g. Touhou, Galaxy Squadron EX, Crimzon Clover). If terrain objects need to form an obstacle course for you to go through, it's MUCH easier to get things right if you can actually see them. For this approach, I'd even put enemies into the room manually (but use instance activation or something to make them stay at their initial positions until they're on-screen) to make sure they sync properly with the level. We've got the view system for precisely this reason, not having to move the entire level around all the time, so not using this helpful abstraction for what it's intended for is... kinda wasteful and just gonna make things harder for you.
Yes, I think that will be my choice. Especially since there will be interactable object in the terrain.
 
J

J_C

Guest
In my game different instances of the same object might to different things at different points of the map, at different times. What do you think would be the easiest solution for doing this? The only thing which comes to mind is doing a lot of if statements, but maybe you guys and gals know a better solution.
 

Yal

🐧 *penguin noises*
GMC Elder
Depends a lot on whether you want your game to be scalable, fast to make, and a lot of other factors. I personally advocate having a separate object for each behavior for small games, but it can give you problems if you need to update the base object's behavior (since all the children needs to be updated too). You could also give the objects a script in a variable and have them run that each step, that is a lot more scalable (base functionality is unchanged, you can put ANYTHING in the script, you can reuse scripts to give multiple objects the same new behavior...). A bit more complex to set up, but definitely worth the effort.
 
  • Like
Reactions: J_C
J

J_C

Guest
Depends a lot on whether you want your game to be scalable, fast to make, and a lot of other factors. I personally advocate having a separate object for each behavior for small games, but it can give you problems if you need to update the base object's behavior (since all the children needs to be updated too). You could also give the objects a script in a variable and have them run that each step, that is a lot more scalable (base functionality is unchanged, you can put ANYTHING in the script, you can reuse scripts to give multiple objects the same new behavior...). A bit more complex to set up, but definitely worth the effort.
I was thinking about making a separate object for each behaviour, but it could get pretty crowded on the long run, because I'd like to have many ships and behaviours. I will probably write scripts as you suggested. How would you implement it so two instances at different points of the map use different scripts? Maybe somethings like this?
if object.x == 1000 {
use script 1
}

if object.y == 2000 {
use script2
}
and so on.

My problem would be that if I change something on the map, e.g. the placement of the objects, I would have to go through all these if statements to change the check for the x value.
 

sylvain_l

Member
My problem would be that if I change something on the map, e.g. the placement of the objects, I would have to go through all these if statements to change the check for the x value.
depend how you generate your level, by hand in room editor or procedurally generated.
and if you want it to work, so you could have the same object, with 2 instances with differents behaviour at the same point of the map too ?

In any case, I would be more tempted to go with an instance variable (and you use the instance creation code to alter it to your desired behaviour)
Code:
behaviourScript = cEnemyBehave_attack_1;
and then in step event
Code:
//call behaviour script
script_execute(behaviourScript);
 
  • Like
Reactions: J_C
J

J_C

Guest
In any case, I would be more tempted to go with an instance variable (and you use the instance creation code to alter it to your desired behaviour)
Code:
behaviourScript = cEnemyBehave_attack_1;
and then in step event
Code:
//call behaviour script
script_execute(behaviourScript);
Thank you so much, this is exactly what I was looking for. Somehow I never noticed before that there is such a things as a creation code. Using this, I can give individual instances a variable which I can use to trigger different behaviours.
 
J

J_C

Guest
I'm thinking about the correct resolution of my game, and I would happily listen to your feedback on this matter. In my 2D shoot em up, I'm planning to make pixel art. What should be the base resolution of the game so the pixelart looks good even if it is stretched fullscreen on a 1080p monitor? Should I do half res? So maybe 960x540 or is it still too big for a pixelart game? Also, what is the optimal sprite size for the objects? 64x64 or bigger? I'm not a good artist, so I assume I would be able to do better pixel art if it is low res.
 

Yal

🐧 *penguin noises*
GMC Elder
I've done several 640x360 games (one-third-res) based around 16x16 sprites, I kinda like that setup. 640 width in particular works both with the smallest PC screen resolution still in use and with widescreens, and 16x16 graphics gives you a pretty big area to put stuff in without it being TOO big. And 16x16 is a really nice grid size when you're new to pixelart, you can leave a lot to the player's imagination. Also most old systems used 16x16 graphics so it looks authentic if you're going for a NES vibe. (bosses and stuff can use bigger sprites of course, and in fact having more than one sprite size adds variety that usually look nice)
 
I'm thinking about the correct resolution of my game, and I would happily listen to your feedback on this matter. In my 2D shoot em up, I'm planning to make pixel art. What should be the base resolution of the game so the pixelart looks good even if it is stretched fullscreen on a 1080p monitor? Should I do half res? So maybe 960x540 or is it still too big for a pixelart game? Also, what is the optimal sprite size for the objects? 64x64 or bigger? I'm not a good artist, so I assume I would be able to do better pixel art if it is low res.
If you're not a good artist, stick to 16 x 16 at first and a NES resolution of 256 x 240 (or something else that is 16:19). Once you're done with this game you can move on to a grander scale.
 

Retrotoast

Member
Yeah just like enemies spawn them in as you would enemies. That way you can have a game programmed to have thousands of enemies, but they're only spawned in when needed.

Destroy them once they've scrolled past. Also if there are particles or anything like that make sure to destroy / remove them and their emitters... or just don't use particles at all. I recommend that. I've also been passed a shmup project where the previous developer deactivated things rather than destroying them.

Here is a view of thousands of enemies via an in game editor:


Every yellow line is where the enemies will spawn in. You will see I call up a radar. The gray dots are representations of where the enemies will be once they spawn in. The yellow dots are real enemies. Terrain elements are also called in, but they're only planets, black holes and simple stuff like that at the moment.
This looks like a very smart solution to building your enemy waves but possibly even the entire background layout with tiles.

I'm in the early stages for a shmup prototype and doing my head in with which way to generate waves. I'm currently scrolling the background and generate waves with timelines and paths to control enemies' movements.
Am always wondering if this is the best way, I find working with Timelines super fiddley and inconvenient, would really be time to update the timelines feature for usability. Better yet a proper level/wave editor built into GM.

Anyway, I meant to ask how hard it is to build that level editor? The mere thought of it gives me an aneurysm .
 

Yal

🐧 *penguin noises*
GMC Elder
Am always wondering if this is the best way, I find working with Timelines super fiddley and inconvenient, would really be time to update the timelines feature for usability. Better yet a proper level/wave editor built into GM.
In this engine I'm using a system where I put scripts function variables in a queue, whenever there's 0 enemies left (or optionally a timer expires) the next one is executed. If you extend this to function + argument pairs you can do all sorts of crazy stuff, like having scripts for spawning each type of pattern (lines, random swarms, single enemies, etc) and being able to adjust things like positions and enemy type by passing arguments to customize them. (And you can even do things like starting cutscenes or ending the level by having a script for that!)


Also why the heck did you revive a 6 year old topic lol
 

Retrotoast

Member
I've had a look at this. Is the engine based on your game Road Warriors 2?

I was hoping to get some comment from @sitebender about his in game level / wave editor. I find this the ultimate way to build your levels to cut down on production time and for convenience.
 

Yal

🐧 *penguin noises*
GMC Elder
I've had a look at this. Is the engine based on your game Road Warriors 2?
No, RW2 started as a GM8 project and uses timelines. (It was a pain to finish it). YDE is built from the ground up, it was meant to be used in a game project but after it got cancelled I repurposed it into an asset pack (so a bunch of things are kinda sloppy and I probably would've done them better today... but ah well).
 

Retrotoast

Member
Thanks for your feedback. What was the worst thing for you working with Timelines and what are the biggest drawbacks/restrictions using them?
 

Yal

🐧 *penguin noises*
GMC Elder
What was the worst thing for you working with Timelines and what are the biggest drawbacks/restrictions using them?
There's basically just drawbacks, really:
  • You need to visualize the order/timing of events in your head
  • Changing things if you realize something is wrong is a massive pain
  • The time when timeline moments occur relative to the step event / alarm ordering is undefined so it's hard to synchronize a timeline with regular game timing
For cutscenes in particular, Sequences is infinitely better than Timelines and I would recommend a custom approach for anything wave-based (have a graze timer to next event, because it's easier to judge how much time the player needs for one wave than it is to compute the absolute time each wave should spawn at, but spawn the wave immediately if the player manages to kill the previous wave to keep things flowing). You can generate timelines programmatically though, this could have some uses when you don't want to hardcode things.
 

Retrotoast

Member
Okay, that's essentially describing what I called fiddly and I generally agree with it. About visualizing waves, how is any other programming method better though if we're talking about straight up coding? You still have to work with co-ordinates and numbers, nothing to look at?
Unless you program a level editor like @sitebender who seems to be away from making games now?

In my book defeating a wave should not trigger the next wave immediately though. That is certainly one way of doing it but its not what the majority of shmups are doing/not what I'm looking to do, especially when you have a purpose built background scrolling then waves need to be in sync with that, rather than a infinitely scrolling / same background. IMO with proper overall balancing and good wave design this is a non issue.
 
I've had a look at this. Is the engine based on your game Road Warriors 2?

I was hoping to get some comment from @sitebender about his in game level / wave editor. I find this the ultimate way to build your levels to cut down on production time and for convenience.
Road Warriors 2? Never heard of it. Is that the Mad Max Sequel?

I am not away from making games, but yes, I have been away from YoyoGames forum, which seems like it's now gamemaker.io.

About defeating a wave triggering the next, it's all up to you. In that level editor, you can make 1 super long wave.

Just set tiles as you would enemies. Other shmups set background changes for certain waves.
 

Retrotoast

Member
RW2 is a shmup Yal made, it's on her itch.io page, guess she was infact inspired by Mad Max.
Since you have eyes on this now, my biggest question is how hard it is to make that level/wave editor that you have showed in your video?

It seems the best way to be able to properly visualize and design your levels, but I'm only a hobbyist programmer so was wondering how feasible it is to program this.

I'm using a mix of timelines, paths and other ways to generate waves at the moment, doable but not convenient and can get messy.
 
Top