Vectrex Studio has two compiler backends, both selectable from the IDE Settings panel. They share the same VPy input but differ in architecture and capabilities.
Why Two Backends?
The Core compiler was the original implementation — stable and well-tested. When PDB debug symbol generation was added it caused enough structural issues that a clean-room rewrite was started. The new Buildtools compiler is a modular 9-phase Rust pipeline that properly supports multibank ROMs, source-level debugging, and tree shaking.
Backend 1 — Core (Legacy)
Status: ✅ Stable · Single-bank only (32 KB ROM)
Single-pass pipeline: lexer → parser → AST → optimizer → codegen → MC6809 assembly → binary. The assembler is built-in; no external toolchain required.
Optimizations
- Constant folding and propagation
- Dead code elimination
- Dead store elimination
- Peephole patterns (power-of-two mul/div → shifts)
Limitations
- Always outputs a fixed 32 KB ROM
- No PDB debug symbol generation
- No source-level breakpoints in VPy files
Use Core if your game fits in 32 KB and you need maximum reliability.
Backend 2 — Buildtools (New)
Status: ⚠️ Partial — multibank works, some edge cases remain
A modular multi-crate Rust pipeline with one crate per phase.
| Phase | Crate | Responsibility |
|---|---|---|
| 1 | vpy_loader | Load .vpyproj project file (TOML) |
| 2 | vpy_parser | Parse VPy source to AST |
| 3 | vpy_unifier | Merge multi-file ASTs, resolve imports |
| 4 | vpy_bank_allocator | Assign functions/data to ROM banks |
| 5 | vpy_codegen | AST → MC6809 assembly (with tree shaking) |
| 6 | vpy_assembler | MC6809 assembly → machine code (two-pass) |
| 7 | vpy_linker | Symbol resolution, inter-bank references |
| 8 | vpy_binary_writer | Emit final .bin ROM image |
| 9 | vpy_debug_gen | Generate .pdb debug symbol file |
Use Buildtools if you need multibank support or source-level debugging (breakpoints in .vpy files).
Multibank ROMs
Games bigger than 32 KB are supported with zero code changes. Add two META directives:
META ROM_TOTAL_SIZE = 524288 # 512 KB total
META ROM_BANK_SIZE = 16384 # 16 KB per bank (default)The compiler calculates bank count, assigns functions via call graph analysis, and generates all bank-switching wrappers automatically. Your VPy code stays the same.
Memory map
$0000-$3FFF Banked window (16 KB) — changes based on register
$4000-$7FFF Fixed bank (16 KB) — last bank, always visible
$4000 ROM_BANK_REG (write) — select active bank
The fixed bank always contains main(), interrupt handlers, and the bank-switching runtime.
Project File Format (.vpyproj)
[project]
name = "mygame"
version = "0.1.0"
entry = "src/main.vpy"
description = "My Vectrex game"
author = "Your Name"
[build]
output = "build/mygame.bin"
target = "vectrex"
optimization = 2
debug_symbols = true # required for source-level debugging
[sources]
vpy = ["src/**/*.vpy"]
[resources]
vectors = ["assets/vectors/*.vec"]
music = ["assets/music/*.vmus"]
sfx = ["assets/sfx/*.vsfx"]| Field | Required | Description |
|---|---|---|
project.entry | Yes | Main .vpy file |
build.output | Yes | Output .bin path |
build.debug_symbols | No | Enable PDB generation (Buildtools only) |
build.optimization | No | 0–2, default 2 |
Building from the Command Line
# Build with Buildtools
cargo run --bin vectrexc -- build program.vpy --bin
# Run tests
cargo test --all -p vectrex_emulator