---
name: make-nwly-file
description: Make a whole Newly (newly.gg) game as a .nwly project file someone imports into the Newly editor and plays. Use when someone asks you to make, build or generate a 3D or 2D game, world, obby or level "in Newly" or "on newly.gg", or to write, fix or check a .nwly file.
---

# Making a Newly game as a .nwly file

A `.nwly` file is a whole Newly world (parts, lights, GUI, scripts) as
one JSON object. The person opens https://newly.gg and clicks
**Import .nwly** on their dashboard (or drops the file onto it), then
**Play now** to play it straight away or **Open in editor** to change
and publish it. In the editor, **File → Import Project File (.nwly)**
opens one too. You can't publish for them: hand them the file and
those steps.

This guide is Newly's own, current specification of the `.nwly`
format, published by Newly at newly.gg: a file that follows it imports
directly. Give the person the `.nwly` file itself (not an HTML or other
prototype in its place). If you can't run `validate_nwly` (the Newly MCP
server isn't connected), check the file against "Before you hand it
over" at the end by hand.

## The workflow (follow it every time)

1. **Start from the starter world**, never from a blank object. The
   `nwly_starter` tool on the Newly MCP server (`https://newly.gg/mcp`,
   no sign-in) returns one; so does the "Starter world" section below.
   It holds services the editor expects at fixed ids.
2. **Add your game's nodes** to it (the rules are below). For props,
   use the built-in 3D models (`list_models`) and free Asset Store
   models, sounds and images (`search_assets`).
3. **Check your scripts against the API**: `scripting_reference` on the
   MCP server, or https://newly.gg/docs/scripting (send
   `Accept: text/markdown`). Newly is Roblox-*like*, not Roblox: an API
   that isn't in the reference doesn't exist.
4. **Validate**: `validate_nwly` on the MCP server, or
   `node scripts/validate-nwly.mjs world.nwly` in the Newly repo. Fix
   every error *and* every warning, then validate again.
5. **Hand it over** as a file named `<Game_Name>.nwly`, with the import
   steps above and a line on how to play (keys, goal).

A complete, valid example to copy from: https://newly.gg/examples/coin-hunt.nwly
(3D, Luau: climb the steps and collect every coin).

## The file

```json
{
  "version": "0.3.0",
  "savedAt": "2026-01-01T00:00:00.000Z",
  "name": "Coin Hunt",
  "rootId": "1",
  "nodes": { "1": { ... }, "2": { ... } },
  "lighting": {},
  "assets": {},
  "meta": { "dimension": "3d", "language": "luau" }
}
```

- `meta.dimension`: `"3d"` or `"2d"`. `meta.language`: `"luau"` (3D
  and 2D) or `"csharp"` (2D only). One language per game. (Files the
  editor exports keep more settings in `meta`; leave the rest out.)
- `lighting`: only what you change; the rest keeps the defaults. Useful
  keys: `timeOfDay` (0-24, default 14), `fogEnabled`, `fogColor`,
  `skyTopColor`, `skyHorizonColor`, `ambientColor`, `sunColor`,
  `bloomEnabled`. Colors are always `"#rrggbb"`.
- `assets`: the built-in 3D models and free Asset Store assets the
  world uses (see "Built-in 3D models" and "Free Asset Store assets"),
  or `{}`. Files people import into the editor themselves are stored
  inside the file and can't be written by hand. Schema:
  https://newly.gg/nwly.schema.json

### Nodes

`nodes` is a flat object keyed by id. Every node has all of these:

```json
"105": {
  "id": "105", "name": "Coin1", "type": "MeshPart",
  "parentId": "103", "children": [],
  "visible": true, "locked": false, "expanded": false,
  "transform": {
    "position": { "x": 0, "y": 2, "z": -10 },
    "rotation": { "x": 90, "y": 0, "z": 0 },
    "scale":    { "x": 2, "y": 0.3, "z": 2 }
  },
  "properties": { ... },
  "scripts": []
}
```

The rules that break a file when missed:

- `id` is a string equal to its key. Give your nodes ids from `"100"` up
  (`"1"` to `"90"` belong to the starter world).
- The tree is stored **both ways**: a node's `parentId` and its parent's
  `children` must agree, and every node must lead up to the root World.
  When you add a node, push its id into the parent's `children`.
- `name` is how scripts find a node (`workspace.Coins`,
  `hud:WaitForChild("Score")`): keep names unique among siblings and
  free of spaces when scripts use them.
- `transform` is in **world space**, even for a node inside a Folder or
  Model. Units are studs (the player is 3.4 studs tall); `rotation` is
  in degrees; **a part's size is its `scale`**.
  +Y is up; the starter ground's top is at y = 0.
- `scripts` is always `[]`. Code lives in Script nodes.

## Starter world (3D)

What `nwly_starter` returns, in short (it fills in every field above):

| id | type | name | parent |
|---|---|---|---|
| 1 | World | World | (none) |
| 2 | Workspace | Workspace | 1 |
| 3 | Camera | Camera | 2 |
| 4 | Terrain | Baseplate (flat grass, 512 × 512, top at y = 0) | 2 |
| 5 | SpawnLocation | SpawnLocation (where players start) | 2 |
| 10 | Lighting | Lighting | 1 |
| 20 / 21 | ReplicatedStorage / ReplicatedFirst | | 1 |
| 30 / 31 | ServerScriptService / ServerStorage | | 1 |
| 40 | StarterGui | StarterGui | 1 |
| 41 | ScreenGui | ScreenGui (put HUD elements here) | 40 |
| 50 | StarterPack | StarterPack | 1 |
| 60 | StarterPlayer | StarterPlayer | 1 |
| 61 / 62 | StarterCharacterScripts / StarterPlayerScripts | | 60 |
| 65, 70, 80, 90 | Player, SoundService, Teams, Chat | | 1 |

Keep all of them. Change the Baseplate's or SpawnLocation's position,
size or color rather than adding second ones. A 2D starter is just a
`World` named "Canvas" (id `"1"`) with a `Folder` "Frame" (id `"100"`);
in 2D everything, scripts included, goes straight under the root, and
the 3D services don't exist.

## 3D building blocks

Put everything visible in **Workspace** (`"2"`), grouped in Folders or
Models as you like.

### MeshPart: every solid shape

```json
"properties": {
  "shapeType": "Cube", "color": "#8a93a6", "material": "Concrete",
  "castShadow": true, "receiveShadow": true
}
```

- `shapeType` (required): Cube, Sphere, Wedge, Cylinder, Cone, Torus,
  Capsule, Prism, TreeTrunk, TreeLeaves. A Cylinder's round faces point
  along ±Y (rotate x 90 to stand it on edge like a coin).
- `material`: Default, Plastic, Wood, Stone, Brick, Concrete, Marble,
  Metal, BrushedMetal, Chrome, Gold, Copper, Glass, TintedGlass, Neon
  (glows), Grass, Lawn, Turf, Sand, Ice, Ground, Asphalt, Pavement,
  Fabric, Rubber, CarPaint, Bark, Leaves.
- Optional: `opacity` (0-1), `bevelEnabled`, `text` (writes on the part).

**Physics, the part that's easy to get wrong:**

| You want | Properties |
|---|---|
| A still floor, wall or platform the player stands on | nothing extra (the player collides with every visible part) |
| A still part whose `Touched` fires (kill brick, checkpoint, button pad) | `"physicsEnabled": true, "physicsType": "static"` |
| A pickup or zone the player walks *through* and `Touched` fires (coin, finish line) | `"physicsEnabled": true, "physicsType": "static", "isTrigger": true` |
| A loose object that falls and can be pushed | `"physicsEnabled": true, "physicsType": "dynamic"` (+ `mass`, `friction`, `restitution`) |
| Decoration the player passes through | `"canCollide": false` |

`Touched` only fires on parts with `physicsEnabled`; a part without it
is solid but never reports a touch. `physicsEnabled` alone means
"dynamic": the part drops through the world at Play.

### Built-in 3D models

Newly ships 45 free (CC0) models from Poly Haven: street furniture,
trees, rocks, shrubs, furniture, boxes. Use them for detail; build the
level itself (floors, walls, platforms) from MeshParts. A model takes
two things:

1. Its **asset entry** in the file's `assets`, keyed by its asset id
   (`list_models` on the MCP server returns each one ready to copy):

   ```json
   "assets": {
     "builtin-ph-street_lamp_01": {
       "id": "builtin-ph-street_lamp_01", "name": "street_lamp_01.glb", "ext": "glb", "category": "mesh",
       "url": "/models/polyhaven/street_lamp_01.glb", "builtin": true,
       "credit": "\"street_lamp_01\" by Poly Haven (https://polyhaven.com/a/street_lamp_01), CC0",
       "license": "CC0-1.0", "createdAt": 0
     }
   }
   ```

2. A **MeshPart** that shows it, one per copy:

   ```json
   "type": "MeshPart",
   "transform": {
     "position": { "x": 6, "y": 1.935, "z": -4 },
     "rotation": { "x": 0, "y": 90, "z": 0 },
     "scale":    { "x": 3.87, "y": 3.87, "z": 3.87 }
   },
   "properties": { "assetId": "builtin-ph-street_lamp_01", "assetName": "street_lamp_01.glb",
     "keepAssetColors": true, "shapeType": "Cube", "color": "#ffffff", "material": "Default",
     "castShadow": true, "receiveShadow": true }
   ```

The two rules that make a model look right:

- **`scale` is the same on x, y and z: the model's longest side** (the
  "scale" column below). A model is drawn shrunk to fit 1 stud, then
  stretched by `scale`, so the longest side gives its real size and
  any other numbers squash it. Bigger or smaller: multiply all three by
  the same factor.
- **`position` is the middle of the model**: to stand it on ground at
  height `g`, `y = g + height / 2` (height is the middle size number,
  times your factor). Turn it with `rotation.y`.

The player bumps into a model's real shape; set `"canCollide": false`
for things to walk through (shrubs, a tree's leaves). Don't give a
model `physicsEnabled` (its physics body would be the whole scale cube):
for a Touched zone, put an invisible MeshPart (`"visible": false`) with
the sensor properties where the model is. `keepAssetColors` keeps the
model's own textures; without it, `color` tints the whole model.

Sizes in studs (1 stud = 1 metre):

| id | size (x × y × z) | scale |
|---|---|---|
| street_lamp_01 | 0.7 × 3.87 × 0.39 | 3.87 |
| fire_hydrant | 0.87 × 0.8 × 0.32 | 0.87 |
| shrub_02 | 6.05 × 3.77 × 2.46 | 6.05 |
| street_lamp_02 | 0.39 × 1.68 × 0.81 | 1.68 |
| concrete_road_barrier | 1.54 × 0.83 × 0.64 | 1.54 |
| concrete_road_barrier_02 | 1.56 × 1.11 × 0.44 | 1.56 |
| metal_trash_can | 1.78 × 1.1 × 0.5 | 1.78 |
| utility_box_01 | 0.52 × 1.12 × 0.43 | 1.12 |
| utility_box_02 | 0.92 × 1.12 × 0.43 | 1.12 |
| security_camera_01 | 0.17 × 0.28 × 0.55 | 0.55 |
| security_light | 0.32 × 0.53 × 0.42 | 0.53 |
| exterior_aircon_unit | 1.8 × 0.93 × 0.37 | 1.8 |
| modular_street_seating | 4.34 × 0.95 × 0.77 | 4.34 |
| water_manhole_cover | 0.69 × 0.07 × 0.69 | 0.69 |
| old_tyre | 0.6 × 0.6 × 0.17 | 0.6 |
| trashbag | 0.53 × 0.57 × 0.46 | 0.57 |
| cardboard_box_01 | 0.39 × 0.34 × 0.52 | 0.52 |
| wooden_picnic_table | 2.24 × 0.75 × 3.02 | 3.02 |
| planter_box_01 | 0.91 × 0.42 × 0.41 | 0.91 |
| potted_plant_01 | 0.58 × 1.35 × 0.63 | 1.35 |
| shrub_03 | 1.37 × 0.4 × 0.15 | 1.37 |
| shrub_04 | 0.58 × 0.22 × 0.15 | 0.58 |
| boulder_01 | 1.27 × 1 × 1.83 | 1.83 |
| rock_07 | 0.17 × 0.14 × 0.32 | 0.32 |
| stone_01 | 0.15 × 0.07 × 0.09 | 0.15 |
| tree_stump_01 | 1.43 × 0.57 × 1.59 | 1.59 |
| korean_fire_extinguisher_01 | 0.28 × 0.66 × 0.37 | 0.66 |
| WetFloorSign_01 | 0.3 × 0.63 × 0.36 | 0.63 |
| metal_office_desk | 2 × 0.79 × 0.95 | 2 |
| modern_arm_chair_01 | 0.82 × 1.02 × 0.99 | 1.02 |
| mounted_fluorescent_lights | 0.91 × 0.04 × 0.65 | 0.91 |
| wall_clock | 0.32 × 0.32 × 0.05 | 0.32 |
| jacaranda_tree | 24.36 × 19.59 × 19.11 | 24.36 |
| GothicCabinet_01 | 1.72 × 2.36 × 1.12 | 2.36 |
| ArmChair_01 | 0.85 × 1.06 × 0.77 | 1.06 |
| Rockingchair_01 | 0.71 × 0.99 × 0.83 | 0.99 |
| gothic_coffee_table | 1.44 × 0.56 × 1.44 | 1.44 |
| WoodenTable_01 | 1.8 × 0.55 × 0.66 | 1.8 |
| dining_chair_02 | 0.43 × 0.97 × 0.58 | 0.97 |
| brass_candleholders | 1.05 × 0.83 × 0.36 | 1.05 |
| wooden_candlestick | 0.1 × 0.22 × 0.1 | 0.22 |
| marble_bust_01 | 0.27 × 0.52 × 0.3 | 0.52 |
| fancy_picture_frame_01 | 0.6 × 0.46 × 0.02 | 0.6 |
| vintage_oil_lamp | 0.22 × 0.8 × 0.22 | 0.8 |
| potted_plant_02 | 0.7 × 0.84 × 0.66 | 0.84 |

### Free Asset Store assets

Creators share models, sounds and images in Newly's Asset Store
(https://newly.gg/assets). A .nwly can use the **free** ones: find them
with `search_assets` (`price: "free"`, `category: "mesh"`, `"audio"` or
`"decal"`). Each free result has an `asset` entry: copy it into the
file's `assets` under its `id`, exactly as given:

```json
"assets": {
  "store-1b2c3d4e-0000-4000-8000-00000000abcd": {
    "id": "store-1b2c3d4e-0000-4000-8000-00000000abcd", "name": "Wooden Crate",
    "ext": "glb", "category": "mesh", "storeAssetId": "1b2c3d4e-0000-4000-8000-00000000abcd"
  }
}
```

The file only names the listing. When the person imports the world,
the editor gets each one for them (it lands in their asset library, as
"Get it free" does); they need to be **signed in**, so tell them to
sign in before importing. Never use a paid asset: it won't come in.
Credit the creators (`creator` in the result) in what you tell the
person.

Use them like this:

- **Model** (`mesh`): a MeshPart with `"assetId": "<the asset's id>"`,
  `"keepAssetColors": true`, `"shapeType": "Cube"`, `"color": "#ffffff"`,
  and a **scale that's the same on x, y and z**, as for built-in models.
  Store models don't list their size: the scale is how long the model's
  longest side will be, so pick it from what the thing is (a crate about
  1.5, a car about 4.5), and set `position.y` to the ground plus about
  half its height. Tell the person they may want to nudge its size.
- **Sound** (`audio`): a Sound with `"assetId": "<the asset's id>"`, plus
  `volume`, `loop` and `autoplay` (music: in SoundService, `loop` and
  `autoplay` true, `volume` about 0.4). A script plays one with
  `sound:Play()`.
- **Image** (`decal`): on a MeshPart, `"decalAssetId": "<the asset's id>"`.
  It becomes the part's texture on every face, tinted by its color, so
  give the part `"color": "#ffffff"` and make it thin, like a sign or a
  poster (scale z 0.1). Don't write `decalUrl`: the import fills it in.

### How far the player jumps

Lay out obbies and platforms to these, or the game can't be finished:

- A jump rises about **1.8 studs**: each platform's top at most
  **1.5** above the last. Ledges up to 0.5 are stepped up without
  jumping.
- A jump crosses about **4 studs** walking and **8** sprinting (Shift):
  keep gaps (edge to edge) at **4 or less**, or tell the player to sprint.
- Walking speed is 7 studs a second, sprinting 14.
- A script can change these with the Humanoid's `JumpPower` and
  `WalkSpeed` (Roblox numbers); say so in the instructions if you do.

### Other 3D nodes

- **SpawnLocation**: the starter one (`"5"`) is enough; move it to
  where players should start. Same properties as a MeshPart plus
  `"isSpawn": true`.
- **Light**: `{ "lightType": "Point", "skyColor": "#ffd36b", "brightness": 2, "range": 24, "enabled": true }`.
  `skyColor` is the light's color. `"lightType": "Spot"` shines along its
  -Z (rotate to aim), with `spotAngle` (degrees).
- **Sound**: `{ "url": "/sounds/music/adventure.wav", "volume": 0.4, "loop": true, "autoplay": true }`
  in SoundService. Built-in music: `/sounds/music/adventure.wav`,
  `cozy-morning.wav`, `spooky-night.wav`.
- **Water**: a pool; its surface is its `position.y`.
  `{ "width": 40, "depth": 40, "volumeDepth": 6, "color": "#1c6f8c", "deepColor": "#0b3350", "opacity": 0.86, "waveHeight": 0.35, "waveSpeed": 1, "waveScale": 1, "buoyancy": true, "shape": "pool" }`
- **ParticleEmitter**: emits along its own +Y. `{ "enabled": true, "rate": 20, "lifetimeMin": 1, "lifetimeMax": 2, "speedMin": 2, "speedMax": 4, "spreadAngle": 15, "startSize": 0.5, "endSize": 0.1, "startColor": "#ffffff", "endColor": "#ffffff", "startTransparency": 0, "endTransparency": 1, "acceleration": { "x": 0, "y": 0, "z": 0 }, "maxParticles": 200 }`
- **ProximityPrompt** (inside a part; press E near it):
  `{ "ActionText": "Open", "ObjectText": "Door", "KeyCode": "E", "HoldDuration": 0, "MaxActivationDistance": 10, "Enabled": true }`
- **BillboardGui** (inside a part; a floating label):
  `{ "Text": "Shop", "TextColor": "#ffffff", "TextSize": 14, "BackgroundColor": "#1b1d24", "BackgroundTransparency": 0.25, "StudsOffset": 2.5, "MaxDistance": 120, "Enabled": true }`
- **RemoteEvent / RemoteFunction / BindableEvent**: in ReplicatedStorage, `properties: {}`.
- **IntValue / NumberValue / StringValue / BoolValue**: `{ "Value": 0 }`.

## Screen GUI (HUD, menus)

GUI elements go **inside a ScreenGui inside StarterGui**: use the
starter's `"41"` (rename it, e.g. "HUD") or add more. Position and size
are **percent of the parent** (`x`, `y`, `w`, `h`), plus pixel offsets
(`xo`, `yo`, `wo`, `ho`) and an anchor point (`ax`, `ay`, 0-1).

```json
"type": "TextLabel",
"properties": {
  "x": 35, "y": 3, "w": 30, "h": 8, "xo": 0, "yo": 0, "wo": 0, "ho": 0, "ax": 0, "ay": 0,
  "bg": "#1e2230", "bgOpacity": 0.7, "radius": 10, "borderW": 0, "borderColor": "#3a4158",
  "text": "Coins: 0", "textColor": "#ffffff", "fontSize": 22, "bold": true,
  "textScaled": false, "align": "center", "valign": "center"
}
```

Types: Frame, TextLabel, TextButton, TextBox (`placeholderText`),
ImageLabel, ImageButton, ScrollingFrame (`scroll: "y"`, `layout: "list"`,
`gap`). Frames hold other elements. Scripts set `.Text`, `.Visible`,
`.BackgroundColor3`, and listen to `MouseButton1Click`.

## Scripts (Luau)

A script is a node with its code in `properties.source`:

```json
{ "id": "112", "name": "CoinCollector", "type": "LocalScript", "parentId": "62", ...,
  "properties": { "source": "print(\"hi\")" } }
```

| Type | Runs | Put it in |
|---|---|---|
| `LocalScript` | on each player's computer | StarterPlayerScripts (`"62"`), or a ScreenGui |
| `Script` | on the server (one player hosts in multiplayer) | ServerScriptService (`"30"`), or inside a part (`script.Parent` is the part) |
| `ModuleScript` | when `require`d; must `return` a table | ReplicatedStorage (`"20"`) |

Scripts in ServerStorage, ReplicatedStorage and StarterPack don't start
by themselves. In JSON, `source` is one string: escape `"` as `\"`,
newlines as `\n`, tabs as `\t`.

**Newly differences that trip up Roblox code:**

- **The player touching a part:** `hit` is the player's character
  itself, and `hit.Parent` is Workspace. Check `hit:IsA("Player")` (or
  `Players:GetPlayerFromCharacter(hit)`), not
  `hit.Parent:FindFirstChild("Humanoid")`.
- Most single-player game logic (score, pickups, HUD) is simplest as one
  **LocalScript**: it sees the player, the parts and the GUI. Reach the
  HUD with `game:GetService("StarterGui"):WaitForChild("HUD")`.
- Each player's progress belongs in their LocalScript (a server Script's
  DataStore is the host's). Talk between them with RemoteEvents.
- A script is stopped after 1 s without yielding, an event handler after
  150 ms: loop with `task.wait()`, or `RunService.Heartbeat:Connect`.
- `part.Position`, `part.Orientation` (degrees), `part.Size`,
  `part.Color` (`Color3.fromRGB`), `part.Transparency`, `part:Destroy()`,
  `part:Clone()`, `TweenService:Create(...)`, `leaderstats` (Folder +
  IntValue under the player) all work as on Roblox.
- Anything else: look it up in `scripting_reference` first.

```lua
local coins = workspace:WaitForChild("Coins")
local score = game:GetService("StarterGui"):WaitForChild("HUD"):WaitForChild("Score")
local got = 0
for _, coin in ipairs(coins:GetChildren()) do
	coin.Touched:Connect(function(other)
		if not other:IsA("Player") or coin.Parent == nil then return end
		coin:Destroy()
		got += 1
		score.Text = "Coins: " .. got
	end)
end
```

## 2D games

`"meta": { "dimension": "2d" }`. Nodes go under the root `"1"`. Shapes: Rectangle,
Ellipse, Text (`text`), Sprite. `transform.position` x/y place the
shape's center (+y is up, z stays 0), `scale` x/y are its width and
height, `rotation.z` turns it. Properties:

- `color`, `opacity`
- `body`: `"static"` (ground, walls), `"dynamic"` (falls), `"kinematic"`
  (moved by script), or leave it out (scenery)
- `controller`: `"platformer"` (arrows/WASD run, Space jumps) or
  `"topdown"` (moves in four directions, no gravity), with `moveSpeed`
  (8) and `jumpPower` (16). The player needs no code to move.
- `cameraFollow: true` on the player; `isTrigger` (touch-only), `oneWay`
  (jump up through), `climbable` (ladder), `gravityScale`, `bounce`, `tag`
- The root's properties: `background2D` (a color), `cameraBounds2D: "level"`,
  `gravity2D`

Build the ground from static Rectangles (Tilemaps need a palette the
editor makes). A 2D player:

```json
"properties": { "color": "#ffd36b", "opacity": 1, "body": "dynamic", "controller": "platformer",
  "moveSpeed": 8, "jumpPower": 16, "cameraFollow": true, "tag": "Player" }
```

2D scripts are `Script` nodes inside the shape they control, with
`"language": "csharp"` and `source` in a C# game. In C#, `me` is that
shape; use `me.Touched += hit => { ... }`, `hit.Is("Coin")` (name or
tag), `OnFrame(dt => ...)`, `Find(name)`. Full API:
`scripting_reference` with `language: "csharp"`. Luau works in 2D too.

## Before you hand it over

- [ ] Built on the starter world; every starter node is still there.
- [ ] Every `parentId` matches a `children` entry and the reverse.
- [ ] Ids are unique strings, `"100"` and up for yours.
- [ ] Every part is inside Workspace, has a `shapeType`, a positive size,
      and sits on or above the ground (y > 0).
- [ ] Parts with `Touched` handlers have `physicsEnabled` with
      `physicsType: "static"` (plus `isTrigger` to walk through).
- [ ] Every model has its asset entry, a scale that's the same on x, y
      and z, and sits on the ground (y = ground + half its height).
- [ ] Asset Store assets are free ones, copied exactly from
      `search_assets`, and you've told the person to sign in before
      importing.
- [ ] GUI is inside a ScreenGui in StarterGui.
- [ ] Every script's API is in the scripting reference.
- [ ] `validate_nwly` shows no errors and no warnings.
- [ ] The player can reach everything (see "How far the player jumps").
