VPy is a Python-inspired language that compiles to MC6809 assembly for the Vectrex console. All values are 16-bit integers. No floats, no booleans, no runtime exceptions.
Program Structure
Every VPy program has two special functions:
def main():
# Called once at startup — initialization only
SET_INTENSITY(127)
def loop():
# Called every frame — game logic goes here
draw_player()main()runs once when the cartridge starts.loop()runs every frame (~50 fps). All drawing and input goes here.WAIT_RECAL()is automatically injected at the start ofloop()by the compiler — do not write it yourself.
Minimal example
META TITLE = "HELLO"
def main():
SET_INTENSITY(100)
def loop():
PRINT_TEXT(-50, 0, "HELLO WORLD")Variables and Constants
Global variables
Declared at the top level, persisted across frames:
player_x = 0
player_y = 0
score = 0Local variables
Declared inside a function, scoped to that call:
def update_player():
dx = joy_x * 2 # local
player_x = player_x + dx # player_x is globalConstants
const declares a compile-time constant stored in ROM, not RAM:
const MAX_ENEMIES = 8
const GROUND_Y = -70
const LEVEL_NAMES = ["LEVEL 1", "LEVEL 2", "LEVEL 3"]Types and Values
VPy has a single type: 16-bit integer.
- All arithmetic is 16-bit (values wrap modulo 65536).
0is false, any non-zero value is true.- No floating point. No booleans — use
1and0.
x = 42 # decimal
x = 0xFF # hexadecimal
x = 0b1010 # binary
x = -7 # negative (compiled as 0 - 7)Operators
| Category | Operators |
|---|---|
| Arithmetic | + - * / % |
| Bitwise | & | ^ ~ << >> |
| Comparison | == != < <= > >= |
| Logical | and or not |
| Compound | += -= *= |
Chained comparisons work: 0 < x < 100 expands to (0 < x) and (x < 100).
Control Flow
# if / elif / else
if score > 100:
level = 2
elif score > 50:
level = 1
else:
level = 0
# while loop
while lives > 0:
lives -= 1
# for loop
for i in range(8):
draw_enemy(i)
# switch / case
switch state:
case 0:
draw_title()
case 1:
draw_game()
# break, continue, return work as expectedFunctions
def fire_bullet(x, y, direction):
bullet_x = x
bullet_y = y
bullet_dir = direction- Up to 4 positional parameters.
- Variables declared in
main()are not accessible inloop()and vice versa — each function has separate scope.
Arrays
Arrays are declared with const (stored in ROM) or as globals (stored in RAM):
const coords = [10, 20, 30, 40]
val = coords[1] # read by index
scores = [0, 0, 0] # mutable array in RAM
scores[0] = 999META Directives
META TITLE = "PANG" # ROM header title (max 16 chars)
META MUSIC = music1 # background music asset
META ROM_TOTAL_SIZE = 65536 # enable multibank (optional)
META ROM_BANK_SIZE = 16384 # bank size (optional, default 16KB)Key Built-in Functions
| Function | Description |
|---|---|
SET_INTENSITY(n) | Set beam brightness (0–127) |
DRAW_LINE(x0, y0, x1, y1) | Draw a line |
DRAW_VECTOR("name", x, y) | Draw a .vec asset at position |
PRINT_TEXT(x, y, "text") | Print text on screen |
J1_X() / J1_Y() | Joystick 1 axes (-128 to 127) |
J1_BUTTON_1() | Joystick 1 button (0 or 1) |
PLAY_MUSIC("name") | Start playing a .vmus asset |
PLAY_SFX("name") | Play a .vsfx sound effect |
ANALOG_X() / ANALOG_Y() | Raw analog joystick input |
DEBUG_PRINT(val) | Print value to IDE debug panel |