NEOLearn

Samples and templates

The NEO engine's GASP template that every new project starts from, the sample projects you can learn from, and how to start a project from a template.

Updated October 17, 2026

On this page

You don't start a NEO game from an empty folder. Every new project is a copy of a template, a small game that already works, and NEO ships sample projects you can open, play and read to see how things are done.

The GASP template#

The NEO engine's GASP template is the default template and the one every project starts from. A project made from it is a complete, playable third-person game:

What you getDetails
A third-person characterWalk, run, sprint, crouch, jump, strafe, and traversal moves: vault, mantle and hurdle. The character has physical animation and can ragdoll and get back up.
A course to play onA traversal course built from boxes, with other characters on it. You can move its start points and boxes in the Studio.
A cameraA third-person orbit camera that follows the player, with mouse and stick look and zoom.
ControlsKeyboard and mouse and gamepad, ready to use. Click to capture the mouse, Esc to release it, Backspace to reset.
SoundFootsteps, landings and ambient sound, and a sun for lighting.
ScriptingA [script] manifest in neo.toml, so you can add JavaScript or Python scripts.
MultiplayerPlayers in the same session see each other, with no code. See Multiplayer.

The character, input, camera and audio come from the engine's gameplay kit rather than being copied in, so your project keeps getting engine fixes. See Gameplay kit.

Default controls#

ActionKeyboard and mouseGamepad
MoveW, A, S, D or the arrow keysLeft stick (push further to run)
LookMouse (while captured)Right stick
ZoomMouse wheel
SprintShift (hold)Click the left stick (until you let go of the stick)
JumpSpaceBottom face button
Crouch (toggle)CRight face button
Walk (toggle)Left Ctrl or V
StrafeRight mouse button (hold)Left trigger (hold), or click the right stick to toggle
InteractELeft or top face button
TakedownF, or left click while capturedRight trigger
RagdollR or GClick both sticks together

GASP Playground#

On the platform you may see a game called GASP Playground. It is an internal test build of the GASP template, showing its movement: walking, running, sprinting, crouching, vaulting, mantling and getting shoved. Play it to try the template's movement before you start a project.

Sample projects in the Studio#

The GASP project#

When you first open the Studio, it opens the GASP project: the template in its full form, with its own menus and HUD. It runs a script too, so it's a good place to see scripting in a real game: choose Play, then open Project ▾ ▸ Scripts… to see the running script, Edit it, change something and save. It hot-reloads in the running game.

The script playground#

The script playground is the smallest scripted NEO game: a JavaScript file moves a platform around a square, drops a cube every 2 seconds (five at most) and boosts the platform when the player touches it. Everything the script can reach is declared by the game and granted in its neo.toml:

KindWhat scripts may do
PlayerRead its position and name.
PlatformSet its position, read its speed and label, and call boost(by).
CubeSpawn cubes and set their position and size.

Its script, platform.js, is a compact example of the World API: a tick handler, a timed handler with every, spawning, emitting events, and a touch handler that waits with sleep:

platform.js
import { World, on, sleep } from "neo";
import { square } from "./paths";

export default class PlatformMover extends World {
  state = { lap: 0, spawned: 0, touches: 0, boosts: 0, playerX: 0 };

  @on("tick")
  move(dt) {
    const platform = this.query("Platform")[0];
    if (!platform) return;
    this.state.lap += (dt / 1000) * platform.speed;
    platform.position = square(this.state.lap);
    const player = this.query("Player")[0];
    if (player) this.state.playerX = Math.round(player.position.x * 100) / 100;
  }

  @on("tick", { every: 2 })
  drop() {
    if (this.state.spawned >= 5) return;
    const n = this.state.spawned;
    const cube = this.spawn("Cube", { size: 0.25 + 0.125 * n, position: { x: -4 + 2 * n, y: 3, z: 0 } });
    this.state.spawned = n + 1;
    this.emit("cube_spawned", { id: cube.id, n: n + 1 });
  }

  @on("touch", { tag: "Platform" })
  async touched(player, platform) {
    this.state.touches += 1;
    if (this.state.boosts < 3) {
      platform.boost(0.05);
      this.state.boosts += 1;
    }
    await sleep(0.5);
    this.emit("touch_settled", { by: player.name, touches: this.state.touches });
  }
}

square comes from the sample's own module, paths.js; see Modules. The script playground isn't in the browser Studio's project list; it is a sample of the NEO engine that runs on the desktop.

Start a project from a template#

  1. In the Studio, open Project ▾ and choose New Project….
  2. Enter a Name (lowercase letters, digits and _, such as my_game) and, if you like, a Title.
  3. Under Template, leave GASP selected (it's marked "default").
  4. Choose Create, then Switch to it.

The new project has its own neo.toml, its own assets/ folder for your content and scripts, and reads the template's content by reference. See Projects and templates for the details and the name rules, or follow Make your first game end to end.

See also#