Skip to content

Tutorials · Crypt Knight · Chapter 10

Levels

40 minutes Uses: Area, Shape, CharacterBody, complete, keep_number, kept_number, set_number, hide, pulse_colour

By the end

  • The Levels list, with The Gate as its first level and the castle loop as its music
  • A relic on an altar, a sign that says what it does, and a knight that jumps once more in the air once he has taken it
  • An exit, an Area that wins the level
  • What winning and losing a level do in the game, and in the editor’s Play
On this page

The Levels list

A level is a scene with a name and a place in an order. The Levels panel lists them, and the game follows the list: a level that is won opens the next one, a level that is lost opens itself again, and a level can have music that plays as it opens. The Levels and endings guide has the whole of it. Crypt Knight has three levels, in this order: The Gate, The Crypt and The Beast’s Hall. Chapter 11 adds the second; for now the list has one.

The level’s music is the castle loop: a track that plays, on the one channel the game has for music, as the level opens.

  1. In your file manager, open the crypt-knight folder and make a folder in it called audio. Copy the music in, from where the list above says it is, under its own name.
  2. Back in the editor, press Refresh in the bar of the Assets panel. audio appears.
  3. Click the Levels tab, at the bottom right of the editor, beside Build. If it is not there, choose View → Panels → Levels. It says No levels yet.
  4. Type The Gate into the box in the panel’s bar and press Add level. The new row names a scene for it, scenes/the_gate.ron, and warns that the file does not exist.
  5. With the row selected, press Scene and choose gate.ron. The warning goes, and the row says startup: it is the scene the project opens on.
  6. Open audio in Assets, and drag abandoned_castle_music_-_starninjas_6.ogg onto the Music button in the row’s lower line. The button names the file. The triangle beside it plays it.
The Levels panel: 1 in order, and one row, The Gate, scenes/gate.ron, startup, with Up, Down, Open, Play, Scene and Remove under it, the Music button naming abandoned_castle_music_-_starninjas_6.ogg and Then open: (none) under the row

Every change in the panel is written to project.rengy at once: there is nothing to save. The panel’s Then open is the scene the game goes to after the last level. It is empty until chapter 15, where the victory screen goes in it.

A relic on an altar

The knight finds a power on the way: a Double Jump relic, on an altar near the end of the Gate. Taking it lets him jump a second time in the air. Past it is a gap, the one you made in chapter 9, that only a double jump crosses; past the gap is the exit.

The altar is two more pedestals on the tilemap’s back layer, as chapter 8’s: one for the relic, and one for a sign that says what it does.

  1. Select ground, open the Tilemap tab, turn on Paint mode, and choose Brush. Under Layers, click back.
  2. In the picker, hover until the tooltip reads #48, and click it. Click once inside cell (68, 8) and once inside cell (76, 8).
  3. Pick #69, and click once inside cell (68, 9) and once inside cell (76, 9), under them.
  4. Press Save at the top of the Tilemap panel.

Cell 68 is the sign’s pedestal, and cell 76 the relic’s. The relic is a pale circle that glows.

  1. Click the Viewport tab. Select Gate, press + Add node, choose Shape, and rename it relic. Set its Position to 1224 and 120.
  2. In its Shape, set Kind to Circle, Size to 10 and 10, Anchor to 0.5 and 0.5, Outline to 0 and Color to 0.6, 0.85, 1.0 with an alpha of 1: a pale blue. Set its Sort Layer to 6.
  3. Press Add component and choose AreaComponent. In its Shape, set Size to 16 and 48, and Offset to 0 and 16: a column that stands the knight’s height over the floor and takes in the circle above it. Leave its Layer and Mask as they are: it is on layer 0 and looks for layer 0, where the knight is.
  4. Press Ctrl+S.

The relic hangs 3 units over its pedestal, and the column reaches down to the floor, so he takes it by walking past. The relic’s script is a short one, shared with the sword in chapter 11, so its name is the power it hands over.

  1. In Assets, press Create, choose New script, type relic, and press Enter.
  2. In the Code tab’s Scripts list, click relic.rgs, replace everything in it with the script below, and press Ctrl+S.
rgs relic.rgs
/// A relic on an altar: it glows, and the knight takes it by walking into it.
/// Taking it keeps 1 under `power` for the rest of the game, and the relic is
/// gone.
component Relic : Area {
    /// The kept value that taking it sets to 1.
    power: String = "double_jump",

    fn on_create() {
        pulse_colour("ShapeComponent", "color", vec4(1.0, 1.0, 1.0, 0.4), 0.6, .InOutSine);
    }

    fn on_enter(other: NodeId) {
        if in_group(other, "knight") {
            keep_number(power, 1.0);
            // A hidden Area meets nothing, so it cannot be taken twice.
            hide();
        }
    }
}
The Code panel open on relic.rgs, the Relic component’s nineteen lines, with its power field, its on_create glow and its on_enter that keeps the power and hides the relic, and Up to date in its status line
  1. Click the Viewport tab, select relic, press Add component, and choose Relic. Its Power is double_jump already, and stays.
  2. Press Ctrl+S.
The Viewport framed on the safe strip after the spike pit: two stone pedestals on a floor, the left under the tall outline of a sign’s Area and the right under the relic, a pale blue circle floating above it, with the strip’s Area in the Inspector
power
The name the relic keeps a 1 under. A string field, so one script serves every relic: chapter 11’s sword is another node with another power.
pulse_colour
Eases the Shape’s colour toward a see-through white and back, 0.6 seconds each way, for as long as the node exists: the glow. It is the pulse the knight’s blink uses in chapter 9, slow.
keep_number and hide
keep_number("double_jump", 1.0) keeps the 1 for the rest of the game: a kept value outlasts a change of scene, which is how the power carries from level to level. hide() hides the node, and a hidden node’s Area meets nothing, so the relic cannot be taken twice.

The sign beside the altar is chapter 8’s, copied.

  1. Right-click sign_walk in the Hierarchy and choose Duplicate. Rename the copy sign_air.
  2. Set its Position to 1096 and 114, the Text of its World Text to You can jump once more in the air., and the Size of its Shape to 212 and 13.
  3. Press Ctrl+S.

The panel is the text’s width, six for each character, with a margin of eight: 34 characters make 212.

The knight jumps once more

Taking the relic keeps a 1 under double_jump. The knight’s Character Body has a field, Air Jumps, that says how many more jumps it may make before it lands, and a script writes only its own node’s fields, so the knight reads the kept value and writes the field, on every step. Open knight.rgs. First, the comment at the top, which now says so: replace its first seven lines with these.

rgs part of knight.rgs
/// The knight: runs where `move` points, jumps on `jump`, jumps lower when
/// `jump` is let go early, drops through a ledge when `down` is held as it
/// jumps, jumps once more in the air once the relic is taken, faces the way it
/// last moved, and shows the clip for what it is doing. It keeps where it last
/// stood on safe ground. A spike or a pit costs it a heart and puts it back
/// there; the hurt shakes the camera and blinks the knight, and nothing can
/// hurt it while it blinks. With no hearts left, the level is lost.

Then, at the top of loop, three lines before let x:

rgs part of knight.rgs
    fn loop() {
        // One more jump in the air once the relic is taken: double_jump is
        // kept as 0 or 1.
        set_number("CharacterBodyComponent", "air_jumps", kept_number("double_jump", 0.0));
        let x = direction("move").x;

kept_number reads the kept value, with 0 as its answer until anything has kept one. set_number writes it into the body’s air_jumps, a whole number: a number with no fraction lands in a whole-number field as that whole number. A second press of Space in the air, with a jump left, jumps again, and each press is a fresh one: holding Space does not spend it. Press Ctrl+S.

The way out

The exit is a dark doorway against the right wall, and an Area that wins the level when the knight walks into it. complete ends a level as won.

  1. In Assets, press Create, choose New script, type exit, and press Enter.
  2. In the Code tab’s Scripts list, click exit.rgs, replace everything in it with the script below, and press Ctrl+S.
rgs exit.rgs
/// The way out of a level: walking into it wins the level.
component Exit : Area {
    fn on_enter(other: NodeId) {
        if in_group(other, "knight") {
            complete();
        }
    }
}
  1. Click the Viewport tab. Select Gate, press + Add node, choose Shape, and rename it exit. Set its Position to 1584 and 160: the foot of the right wall’s inner face.
  2. In its Shape, keep Kind on Rectangle, set Size to 20 and 36, Anchor to 0.5 and 1, Outline to 0, Color to 0.02, 0.02, 0.04 with an alpha of 1, and Sort Layer to 1.
  3. Press Add component and choose AreaComponent. In its Shape, set Size to 24 and 36, and Offset to 0 and -18. Leave its Layer and Mask.
  4. Press Add component again and choose Exit.
  5. Press Ctrl+S.
The exit node selected and framed in the Viewport: a dark slab on the floor against a wall of stone, under the outline of its Area, a small dot at the Area’s centre for its Offset, with its Inspector showing Position 1584 and 160 and an Area of Size 24 by 36 and Offset 0 and -18

What happens when a level ends

A level ends when a script calls complete(), which is a win, or fail(), which is a loss. What happens next is the Levels list’s business:

  • `complete()` opens the next level on the list, and after the last, the scene named in Then open. With neither, as now, with The Gate alone and Then open empty, the run ends: the picture stays, and no script runs again.
  • `fail()` opens the same level again, fresh: the knight back at the start with five hearts. The knight’s on_create keeps them again.
  • What carries over is the kept values. The relic’s double_jump is not forgotten when the Gate opens again: powers carry. The hearts do not: they are the knight’s own, kept again at every level’s start.
  • In the editor, Play started on a level, as now, stops when the level ends, and the status bar says how it ended, how long it took, and the next level. Play started on a scene that is not a level, such as the title of chapter 15, follows the list as the game does.

The Levels and endings guide has what an exported game does with the list.

Check it works

The relic is a long way from the start. To skip the walk, set the knight’s Position to 1160 and 160, press Ctrl+S, and set it back to 72 and 160, and save again, when you have seen it.