reality-engine/README.org

11 KiB

Zirûl: A Language for Enduring Realities

Zirûl: A Language for Enduring Realities

[ᛉ  ·  ·  · 
 ·  ᚱ  ·  · 
 ·  ·  ᛇ  · 
 ·  ·  ·  ᛚ]

Zirûl (pronounced 'zi.rul) is a permacomputing oriented, statically-typed, zero-allocation programming language and virtual machine system designed for:

  • Constrained systems: microcontrollers, retro consoles (PS1, N64, Mac Classic)
  • Portable environments: Web (Emscripten), embedded, CLI
  • Permacomputing: long-term survivability, sustainability, minimalism
  • 3D world-building: built-in primitives for PS1/N64-style rendering
  • Live development: hot reloading, REPL, shadowing, symbol versioning

It runs on the Reality Engine, a minimal C89 VM inspired by Uxn, Plan 9, and Forth - but built for spatial software, deterministic execution, and software that lasts.

The Reality Engine

The Reality Engine is a register-based virtual machine designed to render not just graphics, but realities - persistent, inspectable, reproducible computational worlds.

It is:

  • Written in C89 for maximum portability
  • No dynamic allocation - memory is static, frame-managed, zero-initialized
  • Deterministic by design - identical input -> identical output, forever
  • Self-inspectable - symbol table, memory, and state are always accessible
  • Inspired by Uxn, Dis VM, Dusk OS, and Plan 9

VM Architecture

Feature Specification
Instruction Format 1-byte opcode, 3-byte operand (CISC-like)
Register Set 32 general-purpose registers (R0-R31)
Initialization ZII: Zero Is Initialization
Memory Model Frame-based arenas (function scope = frame)
Heap Behavior Copy-on-write; allocations append to frame
Frame Exit Pointer resets on return (stack-GC style)
Error Handling Returns stub pointers to zeroed memory

This ensures:

  • No malloc, no free, no GC
  • Predictable memory use
  • Perfect reproducibility
  • Safe failure modes

Zirûl Language (ZREL)

Zirûl is a statically-typed language with first-class arrays, immediate-mode semantics, and symbolic clarity - designed for game developers, artists, and preservationists.

Core Types

Type Description
int 32-bit signed integer
nat 32-bit natural number (also used for pointers)
real Q16.16 fixed-point real number
str 4-byte packed string or fat pointer
bool Compile-time flag
ref<T> Reference type for passing by reference

Array Semantics (Fortran-Style)

Arrays are first-class values:

real[3] pos = [1.0r, 2.0r, 3.0r];
real[4][4] mat = identity();
real[3] result = mat * pos;  ! compiler generates matrix-vector multiply
  • Row-major order
  • Fat pointers for slices and strings
  • No vec3=/=mat4x4 structs needed - math is generated
  • Supports composition, slicing, element-wise ops

Boolean/Enum Strategy

Flags are compiled into parallel arrays (like MultiArrayList):

bool[] player_alive;
real[3][] player_pos;
str[] player_name;

This enables:

  • Cache-friendly data layout
  • No polymorphism tax
  • High-performance iteration

Plex: The Form of Being

A plex is a Platonic form - a structured definition of a kind of being in your program.

plex Player {
  version 1;
  str name;
  real[3] pos;

  init(str name, real[3] pos) {
    this.name = name;
    this.pos = pos;
  }
  update() {}
  logout() {}
}
  • Not a class: no inheritance, no vtables
  • Methods are functions with implicit this argument
  • Instances are atoms - persistent, versioned, serializable
  • Stored in the internal graph

> "A plex defines what a thing is. An atom is its incarnation in a reality."

Versioning & Shadowing (Forth-Inspired)

When you redefine a plex, the old version is shadowed but preserved - unless explicitly discarded.

plex Counter { version 1; nat value; inc() { value += 1; } }
plex Counter { version 2; nat value; inc() { value += 2; } }  ! shadows v1

Counter c1 = Counter();        ! uses v2 (latest)
Counter c2 = Counter.v1();     ! uses v1 - still available

discard Counter.v1;            ! optional: free memory

Internally, plex versions form a linked version chain:

  • head -> latest version
  • tail -> oldest retained version
  • migrate(obj, Counter) -> converts data layout
  • versions(Counter) -> list available versions

This enables:

  • Non-destructive evolution
  • Safe refactoring
  • Historical reproducibility
  • Code archaeology

Graphics & Devices

Memory-Mapped I/O

Devices are memory-mapped:

  • SDL surface -> direct memory access
  • GPU registers -> memory addresses
  • All rendering done by writing to memory

Texture System

  • Default format: RGB332 (1 byte per pixel)
  • Tile sizes: 8x8 to 32x32
  • Automatic mipmapping for textures >128px
  • Manual override available

Immediate Mode GUI

  • Function calls are equivelent to redraws
  • Child calls define spacial location in code as well as the UI

3D Primitives Built-in support for:

  • Cube(pos, size)
  • Plane(pos, radius)
  • Model(mesh, texture)
  • Simple PS1/N64-style rendering pipeline

No shaders, no pipelines - just direct manipulation of memory and math.

Tunnels: Unified I/O (Plan 9 / 9P-Inspired)

A Tunnel unifies:

  • Files
  • Sockets
  • Web APIs
  • Devices
  • Databases
Tunnel server = Tunnel("tcp://localhost:25565");
if (server.attach(auth)) {
  Player[] players = server.read("players");
  server.write("me", me.update());
  server.clunk();
}

Tunnel Operations

Op Meaning
.attach() Authenticate and open
.open() / .create() Access/create resource
.read() / .write() Transfer data
.walk() Navigate hierarchy
.flush() Cancel long operation
.clunk() Close connection
.stat() Get metadata
.version() Get protocol version

Tunnels make I/O uniform, composable, and archival.

Development Environment

Zirûl supports live coding and temporal development:

Live Coding Features

  • Hot module reloading: inject code while VM runs
  • REPL-style interaction: inspect memory, call functions, test logic
  • Shadowing: redefine =plex=es without restarting
  • Symbol table manipulation: runtime introspection and patching

Final Binaries

  • Are snapshots of:

    • Memory state
    • Symbol table
    • Version chains
  • Can be saved, restored, or archived as .zbin files
  • Are fully deterministic and reproducible

Sustainability & Permacomputing

Zirûl embodies permacomputing principles:

Principle How Zirûl Supports It
Long-Term Survivability C89 base, no deps, text-based source
Zero Dynamic Allocation Frame arenas, copy-on-write, ZII
Energy Efficiency Fixed-point math, no GC, minimal ops
Maintenance Over Obsolescence Versioned plexes, refactorable code
Use Existing Hardware Runs on microcontrollers, old consoles
Sustainability No bloat, no planned obsolescence
Compute to Strengthen Designed for art, education, preservation

Getting Started

Build the Reality Engine

git clone https://git.alfrescocavern.com/zongor/reality-engine.git
cd reality-engine
make
./zre client.zrl

Sample Program: hello.zrl

function main(nat argc, str[] argv) {
  str name = argc > 1 ? argv[1] : "World";
  print("Hello, {name}!");
  exits("Done");
}

Run it:

./zre hello.zrl Alice
# Output: Hello, Alice!

Example: 3D Client (client.zrl)

use "common.zrl";

function main(int argc, str[] argv) {
  nat w = 800, h = 450;
  Player me(argv[1], [0.0, 1.0, 2.0], PURPLE);

  bool running = true;
  while (running) {
    window("Zirûl Client", w, h) {
      splitbox(parent.size, 0.25) {
        canvas() {
          if (button("Logout")) {
            me.logout();
            running = false;
          }
        }
      }
      splitbox(parent.size, 0.75) {
        canvas() {
          model(Floor([0,0,0], 30));
          me.update();
          model(Cube(me.pos, [0.5r,0.5r,0.5r], me.color));
          if (Player[] others = me.server.read("players")) {
            for (p in others) {
              model(Cube(p.pos, [0.5r,0.5r,0.5r], p.color));
            }
          }
        }
      }
    }
  }
  exits("Client Closed Successfully");
}

Future & Preservation

Goals

  • Run on hardware from 1980 to 2080+
  • Be hand-readable in 3024
  • Preserve digital art and games forever

Preservation Plan

  • Text-based source: no binary blobs
  • Versioned plexes: forward/backward compatibility
  • Self-documenting syntax: just enough magic
  • Open standard: no vendor lock-in
  • Archive formats: .zrl, .zbin, .zatom

License

MIT-0 - No restrictions, no warranty.

With an ethical understanding:

> This software should not be used to accelerate obsolescence, exploit users, or harm ecosystems. Compute only to strengthen what lasts.

Inspirations

  • Uxn - Minimalism, elegance
  • Plan 9 / 9P - Unified I/O, Tunnels
  • Forth - Shadowing, interactivity, immediacy
  • Lisp - Live coding, REPL, introspection
  • Fortran - Array semantics, scientific clarity
  • C / Zig - Control, minimalism
  • Permacomputing Wiki - Sustainability, longevity
  • Retro Systems - N64, PS1, Mac Classic, Windows 95, Plan9 - proof that beauty needs no bloat

Join the Effort

Zirûl is a community project. We welcome:

  • Compiler contributors
  • Port developers (Web, Game Boy, etc.)
  • Artists and game designers
  • Archivists and historians

> "We are not making programs. We are writing Ages."