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. Create a project
Section titled “1. Create a project”- Choose File → New project…. A new project starts with a procedural meadow landscape and a player start.
- Alternatively, keep the Shred & Sort starter the editor opens by default and edit that.
2. Place objects
Section titled “2. Place objects”- Click Add in the toolbar and choose a built-in object: Group, Tree, Rock, Cottage, Crystal, Cube, Sphere or Plane.
- To use your own model, click Import (or File → Import GLB model…) and choose a
.glbfile. See Assets for what the importer accepts. - Select objects in the viewport or the Outliner.
- 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.
- 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.
3. Add physics
Section titled “3. Add physics”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.
4. Add behaviour
Section titled “4. Add behaviour”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 |
-
For a collectible, add a Crystal, open Details → Behaviours, turn on Collectible and set Score per item. Walking into it during Play collects it.
-
For code, click Add script in Details → Script. The default script rotates the object:
fn update(dt) {rotate(0.0, dt, 0.0);} -
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.
5. Play and stop
Section titled “5. Play and stop”- 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.
- 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.
- 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.
6. Save
Section titled “6. Save”- Press Cmd/Ctrl+S, or choose File → Save project.
- Choose a folder and file name. The project is saved as a
.feather.jsonfile with anassets/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.
7. Build
Section titled “7. Build”- Choose File → Build for this computer, or File → Build game… to pick platforms and settings.
- Feather validates the project and builds a standalone copy of your game, with the native player, the project and its assets.
- 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.
- Choose File → New project…. The player start sits at X 0, Z 8, facing towards negative Z.
- Choose Add → Crystal. In Details → Transform, set Location to
0,1,2and name itSeed. - Open Details → Behaviours. Set Spin °/s to
0,90,0, turn on Collectible and set Score per item to10. - Choose Add → Cube and set its Location to
3,5,0. - In the cube’s Details → Physics, set Body to Dynamic.
- 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:
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.jsonCheck it worked by holding W for three seconds of simulated play:
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.
Automate it
Section titled “Automate it”Every step above is also a command. This builds and checks a small scene without opening a 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.