Your First Project
Create a New Project
Section titled “Create a New Project”- Launch the editor:
./run-editor.ps1from the repo root (see Installation) - On the Start Screen, click Create New Project
- Choose a folder; the project takes its name
- The editor writes a starter project and opens its scene: a camera, a title, and a square you can move with the arrows, WASD or a gamepad stick. Press Play to try it.
Without the editor, the same starter project comes from the command line:
cargo run -p jengine-builder --bin jengine -- project new projects/my-game --name "My Game"Both write the files in templates/project/.
Project File Structure
Section titled “Project File Structure”my-game/├── project.jengine # Project settings (JSON)├── assets/│ ├── scenes/main.scene # The starter scene│ ├── scripts/player.lua # The starter player script│ ├── sprites/ # Images (.png, .jpg)│ ├── sounds/ # Audio clips (.ogg, .wav, .mp3)│ ├── prefabs/ # Entity templates (.prefab)│ └── ui/ # GUI documents (.gui)project.jengine Format
Section titled “project.jengine Format”{ "name": "My Game", "default_scene": "scenes/main.scene", "settings": { "title": "My Game", "width": 1280, "height": 720, "background_color": [0.1, 0.1, 0.15, 1.0], "target_fps": 60, "entry_scene": "scenes/main.scene", "physics": { "gravity_x": 0.0, "gravity_y": -9.81, "backend": "rapier2d", "fixed_timestep": 0.016666668, "length_unit": 100.0 }, "input_actions": [ { "name": "move_left", "keys": ["A", "Left"] }, { "name": "move_right", "keys": ["D", "Right"] }, { "name": "jump", "keys": ["Space", "W", "Up", "Pad0_A"] } ] }, "packages": [], "component_definitions": []}Scene paths are relative to assets/. gravity_y is multiplied by length_unit, so -9.81 with a
length unit of 100 is about 981 units per second squared - one world unit is roughly a centimetre.
"packages" lists the Rust packages the project links; most settings have a field in
Project Settings in the editor, which is the easier way to change them.
Add an Entity
Section titled “Add an Entity”- In the Scene Tree panel, right-click and select Add Entity
- Name it “Player”
- In the Inspector, click Add Component and add:
- Transform — set position to
(0, 0) - Sprite — select a texture from assets
- Script — create a new Lua or JS script
- Transform — set position to
Write a Script
Section titled “Write a Script”Create assets/scripts/player.lua:
local speed = 200
function init(entity) log("Player initialized!")end
function update(entity, dt) local x, y = Transform.get_position(entity)
if Input.is_key_pressed("D") then x = x + speed * dt end if Input.is_key_pressed("A") then x = x - speed * dt end
Transform.set_position(entity, x, y)endLua scripts call the engine through capitalised namespaces - Transform, Input, Physics,
Sprite and so on; see the Scripting API.
Or in JavaScript (assets/scripts/player.js), which keeps the flat function names and runs on desktop builds only:
var speed = 200;
function init(entity) { log("Player initialized!");}
function update(entity, dt) { var pos = get_position(entity); var x = pos[0], y = pos[1];
if (is_key_pressed("D")) { x += speed * dt; } if (is_key_pressed("A")) { x -= speed * dt; }
set_position(entity, x, y);}Save and Run
Section titled “Save and Run”- Press Ctrl+S to save the scene
- Click the Play button in the toolbar
- The game runs in the viewport — test your controls!
Build for Distribution
Section titled “Build for Distribution”Open Build Settings and pick a target. Each build streams its compiler output into the Build panel at the bottom of the editor.
- Windows — a standalone
.exewith its assets. - Web — an HTML + WASM + JS bundle for any static web server.
- Android — an APK (debug-signed) or a Google Play bundle, identity from Project Settings → Mobile App. Lua scripts only.
A project with Rust packages gets its own runtime crate generated for each target, so its packages are
linked in. The same builds run from the command line: jengine web-build projects/<name>,
jengine android-build projects/<name>.
To keep a build small, name asset packs in Project Settings → Asset Pipeline → Asset Packs:
each takes asset paths (a later world’s scenes, sprites and music, say), and a build moves them out
of the game into packs/<name>-<hash>.jpak. Upload that folder, set its URL, and fetch a pack from a
script when it is needed with Packs.download("name") - see
Asset packs in the scripting API.
Next Steps
Section titled “Next Steps”- Editor Overview — Learn the full editor interface
- Scripting Guide — Deep dive into Lua and JS scripting
- ECS & Components — Understand the entity-component system