Skip to content

6. Creating a New Room or Stage

Triangly edited this page Dec 18, 2024 · 7 revisions

When creating a room, much like creating an object, specific conditions must be met, particularly regarding the instance_creation_order. Incorrect ordering can lead to crashes in some cases. The most critical rule is that the c_framework object must be the first instance in the room.

Let's go through an example where we create a new level.

Room Creation

  1. Create a new room and add an instance layer for your controllers (name it however you like). This layer should be first in the list, ensuring that you don’t accidentally modify the instance_creation_order later.
  2. Place the c_framework controller outside the visible room bounds.
  3. Next, place the controller for your room alongside the c_framework on the same layer. For stages, this would be c_stage; for other rooms, it would be a custom controller that you create.

You should now have something that looks like this:
chapter6_image1

Finally, lock the layer as there’s no need to use it again. You can safely forget about it.

If you're not creating a new stage (meaning you didn't place the c_stage controller), you’re done. However, since we’re making a playable stage, we need to set it up.

Setting Up the Stage

Open the scr_stage_setup() script and navigate to the switch room block. Add a case for your new room:

case rm_myroom:

break;

Now, let's configure c_stage specifically for rm_myroom. Start by calling the m_stage_set() function. Here’s the breakdown:

  • stage_index - Real - a unique number from 0 to 255. This will be stored in the save file to determine which room to load on save load.
  • name - String - the stage name to be displayed on the Title Card.
  • act_id - Real - the act number, where 0 is Act 1, 1 is Act 2, and 2 is Act 3. Use ACT_SINGLE to hide the act number.
  • bgm - Asset.GMSound - the main background music for the stage.
  • animals - Array<Asset.GMSprite> - an array of animal sprites for the stage. At least one animal must be listed.
  • bottom_bound - Real - the initial bottom boundary of the stage.
  • water_level - Real - the starting water level. Use -1 if there should be no water.
  • next_room - Asset.GMRoom - the room to transition to after the stage is complete.
  • do_save - Bool - whether or not the game should save after completing the stage.

For our stage, the setup would look like this:

m_stage_set(99, "HELLO GITHUB", 0, bgm_woofle, [spr_obj_animal_flicky, spr_obj_animal_pocky], room_height, -1, rm_devmenu, false);

Next, spawn the player using the player_spawn() function. Note that we don’t place the player object directly in the room but spawn it in code to ensure correct instance_creation_order:

player_spawn(32, 176, global.player_main, "Instances");

Make sure the layer you type into the function above exists in the room!

You can place the player manually in the room, but make sure to adjust the added instance’s Variable Definitions to set the desired player type. By default, it's set to PLAYER_NOONE, which will delete the object on initialisation.

Collisions

Finally, set up collisions. Allocate two layers in the room for tilesets, link them to the same collision tileset, and load the data using the collision_load() or collision_load_binary() functions. Collision creation is discussed in this chapter.

Here’s an example loading the Sonic 3 collision data:

collision_load_binary("widths_s3", "heights_s3", "angles_s3", "CollisionA", "CollisionB");

chapter6_image3

Final Setup Code

Here’s the final stage setup code, which takes just a few lines:

case rm_myroom:
        
    m_stage_set(99, "HELLO GITHUB", 0, bgm_woofle, [spr_obj_animal_flicky, spr_obj_animal_pocky], room_height, -1, rm_devmenu, false);    
    player_spawn(32, 176, global.player_main, "Instances");
    collision_load_binary("widths_s3", "heights_s3", "angles_s3", "CollisionA", "CollisionB");
        
break;

Launch the game and ensure everything works as expected:

chapter6_image4