All docs

Playground

Visual level editor for .vplay files — place objects, paint walkable areas, configure enemies, hotspots, scroll limits, and test with live physics simulation.

The Playground is a full visual level editor. Open it from the activity bar and use ✨ New / 💾 Save / 📁 Load to manage .vplay files. Levels saved here are referenced in VPy code with LOAD_LEVEL("scene_name").

Playground open — canvas with platforms placed, asset palette on the left, properties panel on the right


Canvas

The canvas shows the Vectrex world in Vectrex units (−128 to +127 on a single screen). Use scroll wheel to zoom and middle-mouse drag to pan.

Visual reference elements:

  • Green grid — 32×32 unit tiles
  • Dashed grey lines — screen boundaries (each screen is 192×256 units)
  • Orange dashed line — ground floor Y per screen (driven by the Ground Bottom Offset setting)
  • S1, S2… labels — screen index (S1 = bottom)

World size

Set how many screens the level spans using the W and H inputs in the toolbar (1–8 each). Each screen tile is 192 units wide and 256 units tall.


Asset palette (left panel)

Vectors

Lists every .vec file in the project. Drag one onto the canvas to place a background object.

Enemies

Lists every .venemy file. Click an enemy type to select it, then click on the canvas to place a spawn point. The selected enemy type is highlighted in magenta.

Ground Bottom Offset

Sets the Y distance (in units) from the bottom edge of each screen to the floor. Default is 42. This value is read by GET_LEVEL_FLOOR_Y() in VPy code.


Tools

ToolUse
SelectClick to select; drag to move; drag on empty canvas for rubber-band multi-select
HotspotClick canvas to place a trigger zone
EnemyClick canvas to place the selected enemy type
PatrolWith an enemy selected, click canvas to add patrol waypoints

Placing and editing objects

Drag a vector from the palette to place it. Click to select it — the right panel shows its properties:

PropertyDescription
LayerBackground / Gameplay / Foreground — controls draw order
X, YWorld position; drag on canvas or type directly
ScaleSize multiplier (0.1–5.0)
Physics typegravity, bounce, projectile, or static
CollidableMarks the object as solid; exposes custom collision segments

Select multiple objects by shift-clicking or rubber-band dragging, then move them as a group.

Object selected — right panel showing position, scale, layer and physics options


Enemies

Click an enemy in the palette, switch to the Enemy tool, then click the canvas to place it. Select the placed enemy to configure it in the right panel:

PropertyDescription
AI typepatrol / wander / chase / flee / static
SpeedUnits per frame (0.1–20)
Mirror on turnFlip sprite horizontally when reversing direction
Default facingWhich direction the enemy faces at spawn
WaveSpawn wave group (0 = always present)
RespawnRespawn after being defeated

Patrol waypoints

With the enemy selected, switch to the Patrol tool and click the canvas to add waypoints. The enemy will walk between them in sequence. Drag individual waypoint markers to reposition them.

Wander — walkable areas

Wander enemies bounce between a walkable area's x_min and x_max boundaries at the area's Y level. By default they inherit the level-wide walkable areas (see below). Click Override in the right panel to define custom areas for just this enemy.

Each area has:

  • Y — shelf height in world units
  • x_min / x_max — left and right bounds

Enemy properties panel — wander AI, walkable areas list with one area, transitions section below


Level-wide walkable areas

When no object is selected, the right panel shows level settings including Level Walkable Areas. These are inherited by all wander enemies that do not define their own areas.

Click + Add area to create a new area, then click and drag on the canvas to paint the shelf (Y from the click row, X range from the drag).

Auto-transitions

The compiler automatically derives jump and drop connections between areas based on proximity. You can tune three parameters:

ParameterDefaultDescription
Min X overlap4Minimum horizontal overlap (units) to generate a vertical jump/drop
Max ΔY8Maximum Y difference to consider areas on the same row (lateral jumps)
Max gap60Maximum horizontal gap (units) for a lateral jump_across connection

Enable Isolate screens to prevent auto-transitions from crossing screen boundaries — useful for multi-floor games where each floor is an independent level.

Level walkable areas panel — two areas defined, auto-transition tuning visible


Hotspots

Switch to the Hotspot tool and click the canvas to place a trigger zone. Select it to configure:

FieldDescription
LabelText shown in-game when the player interacts
Triggerplayer_near, player_on, projectile, or auto
W / HHalf-width and half-height of the trigger zone

Hotspots appear as dashed orange rectangles on the canvas.


Scroll limits

Click the L, R, T, B buttons in the toolbar to add scroll limit markers. Drag the coloured lines on the canvas to set the exact boundary. The camera will not scroll past these limits.

Read them in VPy code with:

camera_x = clamp(target, GET_SCROLL_LIMIT_LEFT(), GET_SCROLL_LIMIT_RIGHT())
SET_CAMERA_X(camera_x)

Canvas showing cyan left and right scroll limit lines


Screen backgrounds

For multi-screen levels, the right panel (with nothing selected) shows a Screen Backgrounds section. Assign a PNG or JPG from your project's assets/ folder to each screen as a tracing or reference overlay. Images are shown at 25% opacity and are editor-only — they are not included in the compiled ROM.


Play simulation

Click ▶ Play to run a live physics and AI simulation directly in the editor. Enemies patrol and wander, physics objects fall and bounce. Click ⏹ Stop to restore the level to its saved state.

This is useful for checking platform positions, patrol routes, and walkable area coverage before building.


Save and load

ActionBehaviour
✨ NewClears the canvas and resets all settings. Asks for confirmation if there is unsaved content.
💾 SaveQuick-saves if the level has a name; otherwise opens a dialog to enter one. Saved as assets/playground/{name}.vplay. Also triggered with Ctrl+S / Cmd+S.
📁 LoadOpens the scene list. Click a scene to load it; levels are auto-migrated from v1.0 format if needed.
🗑️ ClearRemoves all objects and hotspots but keeps level metadata.

Using the level in VPy

def main():
    LOAD_LEVEL("world_1")      # load geometry and enemies
    SPAWN_ENEMIES("world_1")   # initialise enemy pool (call once)
 
def loop():
    UPDATE_ENEMIES()           # advance AI each frame
    SHOW_LEVEL()               # draw all objects in the level
    DRAW_ENEMIES()             # draw all enemies (applies camera offset)