# Writing Multiple Scripts

This tutorial builds off the Simple Runner game introduced in Your First Extension and will introduce you to working with multiple scripts and interacting with Godot’s existing signals to teleport the player, creating an infinite runner.

Writing Multiple Scripts.tutorial

## Handle vertical movement

The player currently only moves along the horizontal axis, but remains in place vertically. Let’s adjust the player code to include vertical motion.

1. In `PlayerController.swift`, find the `movementVector` computed property and update its y value to include a constant speed of one.

`PlayerController.swift`
``````//
//  PlayerController.swift
//
//
//  Created by Marquis Kurt on 7/19/23.
//

import SwiftGodot

@Godot
class PlayerController: CharacterBody2D {
var acceleration: Float = 100
var friction: Double = 100
var speed: Double = 200

var movementVector: Vector2 {
var movement = Vector2.zero
movement.x = Float(
Input.getActionStrength(action: "move_right") - Input.getActionStrength(action: "move_left"))
movement.y = 1.0
return movement.normalized()
}

override func _physicsProcess(delta: Double) {
if Engine.isEditorHint() { return }
if movementVector != .zero {
let acceleratedVector = Vector2(x: acceleration, y: acceleration)
let acceleratedMovement = movementVector * acceleratedVector
self.velocity = acceleratedMovement.limitLength(speed)
} else {
velocity = velocity.moveToward(to: .zero, delta: friction)
}
self.moveAndSlide()
super._physicsProcess(delta: delta)
}
}``````
PlayerController-multiscript-2.swift
2. In the terminal, navigate to the SimpleRunnerDriver package and run `swift build` to build the package.

3. Open the `.build/{arch}/debug` directory in the Finder using the `open` command, replacing `arch` with your Mac’s architecture folder.

4. Copy the `libSimpleRunnerDriver.dylib` file into the `bin` directory of the SimpleRunner Godot project.

5. Open the project in the Godot editor and open the `main.tscn` scene file.

6. Run the project by pressing the Play button in the toolbar. The player should now be moving down the screen, past the edges of the level.

## Teleport the player

Now that the player can run down the screen, let’s allow the player to teleport to the top of the level when they reach the bottom.

To do so, you will create a new node class that represents the main level logic and detect when the player has reached the bottom and teleport them to the top.

1. Create a new Swift file called MainLevel in the SimpleRunnerDriver package and import the SwiftGodot library.

`MainLevel.swift`
``````//
//  MainLevel.swift
//
//
//  Created by Marquis Kurt on 7/22/23.
//

import SwiftGodot``````
MainLevel-multiscript-init.swift
2. Write a new `MainLevel` class that inherits from `Node2D` and has the `@Godot` attribute

`MainLevel.swift`
``````//
//  MainLevel.swift
//
//
//  Created by Marquis Kurt on 7/22/23.
//

import SwiftGodot

@Godot
class MainLevel: Node2D {
}``````
MainLevel-multiscript-2.swift
3. Add the `player`, `spawnpoint`, and `teleportArea` properties to `MainLevel`, using the `@SceneTree` macro to list their names in the scene tree.

Note that these properties are marked optional, as they may not exist in the scene tree.

`MainLevel.swift`
``````//
//  MainLevel.swift
//
//
//  Created by Marquis Kurt on 7/22/23.
//

import SwiftGodot

@Godot
class MainLevel: Node2D {
@SceneTree(path: "CharacterBody2D") var player: PlayerController?
@SceneTree(path: "Spawnpoint") var spawnpoint: Node2D?
@SceneTree(path: "Telepoint") var teleportArea: Area2D?

}``````
MainLevel-multiscript-3.swift
4. Create a new `teleportPlayerToTop()` method and add a guard statement to check that the player and spawn point exist.

`GD.pushWarning(_:)` allows us to send warning messages to Godot’s console.

`MainLevel.swift`
``````//
//  MainLevel.swift
//
//
//  Created by Marquis Kurt on 7/22/23.
//

import SwiftGodot

@Godot
class MainLevel: Node2D {
@SceneTree(path: "CharacterBody2D") var player: PlayerController?
@SceneTree(path: "Spawnpoint") var spawnpoint: Node2D?
@SceneTree(path: "Telepoint") var teleportArea: Area2D?

private func teleportPlayerToTop() {
guard let player, let spawnpoint else {
GD.pushWarning("Player or spawnpoint is missing.")
return
}

}
}``````
MainLevel-multiscript-4.swift
5. Set the player’s position so that their horizontal coordinate is kept, but the vertical coordinate is that of the spawn point.

This will effectively teleport the player to the top of the map, preserving where the player was on the horizontal axis.

`MainLevel.swift`
``````//
//  MainLevel.swift
//
//
//  Created by Marquis Kurt on 7/22/23.
//

import SwiftGodot

@Godot
class MainLevel: Node2D {
@SceneTree(path: "CharacterBody2D") var player: PlayerController?
@SceneTree(path: "Spawnpoint") var spawnpoint: Node2D?
@SceneTree(path: "Telepoint") var teleportArea: Area2D?

private func teleportPlayerToTop() {
guard let player, let spawnpoint else {
GD.pushWarning("Player or spawnpoint is missing.")
return
}

player.position = Vector2(x: player.position.x, y: spawnpoint.position.y)
}
}``````
MainLevel-multiscript-5.swift
6. In the `_ready()` method, connect the teleport area’s `bodyEntered` signal method to check if the player has entered the area and teleport them when necessary.

`MainLevel.swift`
``````//
//  MainLevel.swift
//
//
//  Created by Marquis Kurt on 7/22/23.
//

import SwiftGodot

@Godot
class MainLevel: Node2D {
@SceneTree(path: "CharacterBody2D") var player: PlayerController?
@SceneTree(path: "Spawnpoint") var spawnpoint: Node2D?
@SceneTree(path: "Telepoint") var teleportArea: Area2D?

override func _ready() {
teleportArea?.bodyEntered.connect { [self] enteredBody in
if enteredBody.isClass("\(PlayerController.self)") {
teleportPlayerToTop()
}
}

}

private func teleportPlayerToTop() {
guard let player, let spawnpoint else {
GD.pushWarning("Player or spawnpoint is missing.")
return
}

player.position = Vector2(x: player.position.x, y: spawnpoint.position.y)
}
}``````
MainLevel-multiscript-6.swift
7. Register the class type in `SimpleRunnerDriver.swift` to expose it to Godot.

`SimpleRunnerDriver.swift`
``````// The Swift Programming Language
// https://docs.swift.org/swift-book

import SwiftGodot

let allNodes: [Wrapped.Type] = [PlayerController.self, MainLevel.self]

#initSwiftExtension(cdecl: "swift_entry_point", types: allNodes)``````
SimpleRunnerDriver-multiscript-2.swift

## Using the new main level node

Now that the main level code has been added, let’s replace the current main level node with its new instance provided by your extension.

1. Rebuild the extension and copy over `libSimpleRunnerDriver.dylib` as before.

2. Open the project in the Godot editor and open the `main.tscn` scene file.

3. Right click on the Main Level node and select Change Type.

4. Search for “MainLevel” and set the node’s type to the new MainLevel node you created.

If the node doesn’t appear in the search results, retry the steps for registering the class, rebuilding the extension, and re-opening Godot.

5. Run the project by pressing the Play button in the toolbar. The player should now be moving down the screen, teleporting to the top of the screen once the player reaches the bottom. 🎉