Overview
This is a self-contained, no-build-step FPS map creator. You build one or more scenes (levels) out of objects, then test them with ▶ Play, and ship the finished game with Export ZIP — a standalone HTML/JS game that runs in any browser, no editor required.
Everything lives in the browser: textures, sprites and sounds you upload are stored directly inside your project. Save JSON / Load JSON save and restore your whole project (every scene, every object, every setting) as one file.
Quick start
- Open the Place tab, tap a tool, then tap/click in the 3D viewport to drop the object.
- Tap an object (or ↖ Select then tap it) to select it — its fields appear in Inspect.
- Use the gizmo to move it, or switch tools (top toolbar, see below) to rotate/scale it.
- Check Layers any time for a flat list of everything in the current scene.
- Hit ▶ Play to test the level. ✕ Exit Play returns to editing.
- When it's ready, hit Export ZIP for a playable standalone copy of the game.
Views & moving objects
The 3D / Top / Side buttons (above the dock) switch camera angle — Top and Side are handy for precise placement. Grid sets the snap size for placement and dragging.
Once something is selected, a gizmo appears on it:
- Move — drag an axis arrow to slide it.
- Rotate — drag a ring to spin it.
- Scale — drag a handle to resize it (this is also how you resize Walls, Boxes, Trigger Zones, etc. after placing them).
Position/Rotation/Scale numbers are also editable directly at the top of Inspect for any selected object.
Object types — structure
- Floor — a large flat ground plane.
- Wall — a tall blocking slab. Collidable by default.
- Box / Cylinder / Cone / Sphere — basic collidable shapes for crates, pillars, props, obstacles.
All of these accept a Texture upload in Inspect (with X/Y repeat) so they're not just flat colors.
Object types — lighting & atmosphere
- Light — a point light. Set color, intensity and range in Inspect. Shown as a small gizmo in the editor; becomes a real light source in Play/export.
- Fog Zone — sets the scene's fog color/near/far distance. The first Fog Zone in a scene controls that scene's fog; remove it for a clear scene.
- Waypoint — an invisible-at-runtime marker used to build patrol paths for enemies. Give a group of waypoints the same Path group name and an Order number, then point an enemy's Patrol path field at that group name — it'll walk the route when it hasn't spotted the player yet.
Enemy Sprite
A textured plane that always rotates to face the camera (a classic billboard sprite) and comes with full combat AI. Fields in Inspect:
- Health, Score on kill (added to the player's score on the kill shot).
- Chase speed and an optional Patrol path (a Waypoint group name) for routes it walks before it spots the player.
- Can shoot (ranged) toggle — off makes it a melee chaser ("zombie") that closes in and hits at melee range; on makes it hold at range and damage the player from a distance with its own damage/range/fire-rate.
- Texture (static look) or Animation frames (upload several images + an FPS for an auto-cycling walk animation).
- Attack frames — a separate one-shot animation that plays whenever it actually lands a hit, then falls back to the walk-cycle.
- Left/right-side sprite frames — optional, shown automatically when the camera views it from that side instead of head-on.
🖼️ Billboard (prop or enemy, your choice)
Also always faces the camera, but its Role dropdown decides what it is:
- Prop — purely decorative: a torch, sign, tree, pickup. Upload a static Texture or multi-frame animation, and optionally tick Collidable if it should block movement (e.g. a crate).
- Enemy — instantly becomes a full enemy with the exact same Health/Chase/Melee-or-Ranged/Animation/Attack-frames/Side-sprite fields as Enemy Sprite.
One object type, two jobs — flip the dropdown instead of needing a separate prop object.
🚪 Door
A collidable slab that opens automatically when the player walks within range — and blocks the way while closed.
- Open style — Slide up (classic) or Swing open (rotates in place).
- Open distance — how close the player must get to trigger it.
- Open/close speed, and Locked if it should never open on its own.
- Auto-close + Close delay — whether/how long after the player leaves it swings/slides shut again.
- Open sound — plays the instant it starts moving.
Its collision clears naturally as it slides/swings away — no separate "passable" switch needed.
💣 Bomb
An interactive prop. Walk within its Interact range and press FIRE to start the defuse mini-game: a sequence of directional arrows fly right-to-left across the screen, and you press the matching direction on the joystick/d-pad (or arrow keys/WASD) the instant each one crosses the highlighted zone.
- Number of arrows — length of the sequence.
- Start / Fastest interval — seconds between arrows at the beginning vs. the end — they spawn about a second apart at first and speed up from there.
- Misses allowed before fail — miss this many arrows (don't press the right direction in time) and it's game over.
- Defuse success / fail sound — optional clips that play when the sequence is cleared or failed.
Clearing the whole sequence permanently defuses that bomb for the rest of the scene visit. Pair it with a Trigger Zone's "Must defuse the bomb first" exit condition to gate the level's exit on it — that condition auto-passes if the scene has no bomb at all.
🟢 Start Point
Marks where the player appears in a scene. Give it a Point name (e.g. start, back_door) and optionally tick Default spawn for this scene. If a scene has no Start Point, the player spawns at the origin.
A Trigger Zone's "Go to scene" action can target a specific named Start Point in the destination scene — useful for doors that should drop you right where you'd expect (e.g. coming back through the same doorway).
🚧 Trigger Zone
An invisible box (shown translucent pink in the editor only — resize it with the Scale gizmo) that fires an action the instant the player walks into it. Pick one action per trigger:
- Exit point → Go to scene — teleports the player into another scene, optionally landing on a named Start Point there. An Exit point or Win point can require "Must kill all enemies first" or "Must defuse the bomb first" before it'll let the player through.
- Start point → Move player here — teleports the player to a named Start Point within the current scene (a one-way door, shortcut, or checkpoint).
- Play sound — plays an uploaded sound once.
- Create enemy (jumpscare) — spawns a fresh enemy right at the trigger's position with its own health/damage/speed/sprite, plus an optional sound that fires the instant it appears.
Triggers fire once per scene visit by default — tick Repeatable to let them fire every time the player walks back in.
🧩 Shape Presets
The Nature tab's shape section holds ready-made 3D props (Car, Barrel, Gas Pump, Crate Stack, Watchtower, Barricade, Sandbag Wall, Traffic Cone) built from simple geometry with colors baked directly in — no image upload needed. Drop one in and adjust its position/rotation/scale, or Destructible settings, from the Inspector.
Any shape can be made Destructible from the Inspector: it takes damage like an enemy, and once its health hits zero the geometry itself shrinks away and disappears (optionally dealing blast damage nearby) — no destroy-animation images required.
Scenes (multi-level)
A project is one or more scenes, each with its own layout/objects/enemies. Manage them in the Scenes tab:
- Tap a scene's name to switch to it (only the active scene is shown/edited at a time — the rest keep their contents in memory).
- ✎ renames it, ✕ deletes it (can't delete the last remaining scene).
- + Add Scene starts a fresh empty level.
Link scenes together with Trigger Zones (the "Go to scene" action) and Start Points (where the player lands).
Player tab
Global settings that apply to the whole game (not per-scene): control scheme (touch joystick vs. tap-to-move/dpad), move speed, jump force, max health, gun sprite (idle image + fire animation frames), skybox colors/sprite, and uploaded sound effects (jump/shoot/hit/hurt/enemy-death/ambient).
Enemy tab
Sets the defaults that a freshly-placed Enemy Sprite starts with (health, chase speed, melee/ranged stats, animation FPS, attack animation FPS). Placing one from the Place tab pre-fills these; you can still tweak that specific enemy afterwards in Inspect.
Saving, loading & exporting
- Save JSON / Load JSON — your whole project (every scene, transforms, textures, enemy behaviour, sounds) as one self-contained
.json file you keep on your own device.
- Export ZIP — a standalone playable game:
index.html, css/, js/, data/project.json, and an assets/ folder. Every texture/sprite/sound gets pulled out of the JSON into a real file (de-duplicated by content — reusing the same upload across many objects or scenes only stores it once). Since it uses ES module imports, run it through a local server rather than double-clicking it: npx serve . or python3 -m http.server 8080.
Playing / testing controls
- Desktop — WASD to move, mouse to look (click the screen to lock the pointer), left click to fire, space to jump.
- Mobile — on-screen joystick or dpad (per your Player tab control scheme) to move, drag to look, on-screen FIRE/JUMP buttons.
- Health bar, score, hit marker and damage flash all appear automatically in the HUD. Dying shows a game-over screen with a Restart button.
Performance tips
This engine is built for tight, level-based games (a handful of linked scenes, dozens of objects/enemies each) rather than one sprawling open world. A few things to keep in mind as a scene grows:
- Every object is its own draw call — there's no instancing/merging, so hundreds of objects in one scene will cost more frame time than the same count spread across several smaller scenes.
- Player-vs-wall collision is recomputed for every collidable object each frame a Door is present in the scene — keep wall/box/door counts reasonable per scene.
- Re-using the same uploaded texture/sound across many objects is cheap (Export ZIP de-duplicates it to one file, and the engine caches it by URL so it's only decoded once) — re-uploading visually-identical files separately is not.
- Scenes stay resident in memory once visited during a play session, so a huge number of scenes visited back-to-back will accumulate memory rather than freeing it.