Skip to content

Make your first game

This walkthrough covers the full authoring loop in Feather 2: add objects, configure physics, attach behaviour, play-test in the viewport, save a portable project and export a native player. It takes about ten minutes and uses only built-in content.

Before you start, install and run the editor.

  1. Choose File → New project…. A new project starts with a procedural meadow landscape and a player start.
  2. Alternatively, keep the Shred & Sort starter the editor opens by default and edit that.
  1. Click Add in the toolbar and choose a built-in object: Group, Tree, Rock, Cottage, Crystal, Cube, Sphere or Plane.
  2. To use your own model, click Import (or File → Import GLB model…) and choose a .glb file. See Assets for what the importer accepts.
  3. Select objects in the viewport or the Outliner.
  4. Press W, E or R to move, rotate or scale with the viewport gizmo, or type exact values in Details → Transform. A root object’s height is measured in metres above the terrain.
  5. Press F to frame the selection and Cmd/Ctrl+D to duplicate it.

You can also drag a card from the Content Browser into the viewport; it lands on the ground under the cursor.

Select an object and open Details → Physics.

Setting What it does
Preset Applies a ready-made body setup in one step
Body None, Static, Dynamic or Kinematic. Dynamic bodies fall and collide during Play
Collider Box, Sphere, Capsule, Hull (convex hull) or Mesh (exact triangles; Static and Kinematic only)
Half extents and Centre offset The collider’s size and offset in metres. Fit box sizes it to an imported model
Friction, Bounce, Mass Surface and body properties. Mass is in kilograms
Sensor The collider reports overlaps but blocks nothing

For a quick test, add a Cube, raise it a few metres, and set Body to Dynamic.

Feather offers three ways to make an object do something. They can be combined on one object.

Option Where Use it for
Behaviours Details → Behaviours Spin, bobbing and collectibles, with no code
Script Details → Script, or Tools → Script editor Rhai code with start() and update(dt)
Blueprint Tools → Blueprints A visual node graph compiled to the same runtime
  1. For a collectible, add a Crystal, open Details → Behaviours, turn on Collectible and set Score per item. Walking into it during Play collects it.

  2. For code, click Add script in Details → Script. The default script rotates the object:

    fn update(dt) {
    rotate(0.0, dt, 0.0);
    }
  3. Press Cmd/Ctrl+Enter or click Apply script to commit the change. Applying creates an undo step.

See Scripting and Blueprints for the full APIs.

  1. Click Play in the centre of the toolbar. The Play in dropdown beside it can run the game in the viewport or in its own window instead.
  2. Walk with WASD, look with the mouse — Play captures the cursor when it starts; press Shift+F1 to free it — jump with Space and run with Shift.
  3. Press Stop or Escape to return to editing.

Editing is locked during Play, so the simulation cannot change your saved project. Stop restores every object to its authored state. Script messages and errors appear in the Output Log tab.

  1. Press Cmd/Ctrl+S, or choose File → Save project.
  2. Choose a folder and file name. The project is saved as a .feather.json file with an assets/ folder beside it containing every imported file it uses.

Keep the project file and its assets/ folder together when you move or share the project. See Projects.

  1. Choose File → Build for this computer, or File → Build game… to pick platforms and settings.
  2. Feather validates the project and builds a standalone copy of your game, with the native player, the project and its assets.
  3. Run it to play the game outside the editor.

See Build a game for every platform and setting.

Example: a spinning crystal worth 10 points

Section titled “Example: a spinning crystal worth 10 points”

You’ll put a collectible crystal in front of the player start and a cube that falls when Play begins, starting from a new project.

  1. Choose File → New project…. The player start sits at X 0, Z 8, facing towards negative Z.
  2. Choose Add → Crystal. In Details → Transform, set Location to 0, 1, 2 and name it Seed.
  3. Open Details → Behaviours. Set Spin °/s to 0, 90, 0, turn on Collectible and set Score per item to 10.
  4. Choose Add → Cube and set its Location to 3, 5, 0.
  5. In the cube’s Details → Physics, set Body to Dynamic.
  6. Press Play and walk forward with W. The cube drops onto the grass, and the crystal disappears when you walk into it.

Do the same from the command line:

Terminal window
feather-cli --workspace ./crystal-hunt command project.create \
--json '{"name":"Crystal Hunt"}' --save project.feather.json
feather-cli --workspace ./crystal-hunt --project project.feather.json command scene.add \
--json '{"kind":"Crystal","name":"Seed","position":[0,1,2]}' --save project.feather.json
# rotate_speed is in radians per second: 1.5708 is 90°/s.
feather-cli --workspace ./crystal-hunt --project project.feather.json command scene.update \
--json '{"id":1,"patch":{"gameplay":{"collectible":true,"score":10,"rotate_speed":[0,1.5708,0]}}}' \
--save project.feather.json
feather-cli --workspace ./crystal-hunt --project project.feather.json command scene.add \
--json '{"kind":"Cube","name":"Falling cube","position":[3,5,0]}' --save project.feather.json
feather-cli --workspace ./crystal-hunt --project project.feather.json command scene.update \
--json '{"id":2,"patch":{"physics":{"body":"Dynamic"}}}' --save project.feather.json

Check it worked by holding W for three seconds of simulated play:

Terminal window
feather-cli --workspace ./crystal-hunt --project project.feather.json command game.simulate \
--json '{"frames":180,"inputs":[{"frame":0,"key":"W","pressed":true}]}'

The report should contain "score": 10 and the log entry Collected Seed (+10).. The crystal’s final.visible is false, and the cube’s final.position is lower than its initial.position.

Every step above is also a command. This builds and checks a small scene without opening a window:

Terminal window
feather-cli --workspace ./my-game command scene.add \
--json '{"kind":"Cube","name":"Falling cube","position":[0,4,0]}' \
--save game.feather.json
feather-cli --workspace ./my-game --project game.feather.json command scene.update \
--json '{"id":1,"patch":{"physics":{"body":"Dynamic"}}}' --save game.feather.json
feather-cli --workspace ./my-game --project game.feather.json \
command game.simulate --json '{"frames":120}'

The simulation report lists each object’s initial and final position, so you can confirm the cube fell. See Command-line control and Play-testing with simulation.