prometeu-runtime/docs/specs/pbs/Prometeu Scripting - Language Tour.md
Nilton Constantino b3e5335deb
add PBS docs
2026-01-27 10:42:49 +00:00

6.0 KiB
Raw Blame History

Prometeu Base Script (PBS)

A didactic scripting language for game development with explicit cost, explicit memory, and predictable runtime.


0. What PBS Is (and What It Is Not)

PBS (Prometeu Base Script) is a small, explicit scripting language designed for game engines and realtime runtimes.

Its core goals are:

  • Didactic clarity — the language teaches how memory, data, and APIs really work.
  • Gamefriendly execution — predictable runtime, no hidden allocation, no tracing GC.
  • Explicit cost model — you always know when you allocate, where data lives, and who can mutate it.

PBS is not:

  • a generalpurpose application language
  • a productivity scripting language like Python or Lua
  • a language that hides runtime cost

PBS is intentionally opinionated. It is built for developers who want control, predictability, and understanding, especially in game and engine contexts.


1. The Core Philosophy

PBS is built around one rule:

If you do not allocate, you are safe. If you allocate, you are responsible.

From this rule, everything else follows.

1.1 Two Worlds

PBS has two explicit memory worlds:

World Purpose Properties
SAFE Stack / values No aliasing, no leaks, no shared mutation
HIP Storage / heap Explicit aliasing, shared mutation, refcounted

You never cross between these worlds implicitly.


2. First Contact: SAFEOnly PBS

A PBS program that never allocates lives entirely in the SAFE world.

SAFE code:

  • uses value semantics
  • copies data on assignment (conceptually)
  • cannot leak memory
  • cannot accidentally share mutable state

This makes SAFE PBS ideal for:

  • gameplay logic
  • math and simulation
  • AI logic
  • scripting without fear

Example:

let a = Vector(1, 2);
let b = a;        // conceptual copy

b.scale(2);
// a is unchanged

No pointers. No references. No surprises.


3. Values, Not Objects

PBS does not have objects with identity by default.

3.1 Value Types

All basic types are values:

  • numbers
  • bool
  • string (immutable)
  • tuples
  • userdefined struct

A value:

  • has no identity
  • has no lifetime beyond its scope
  • is safe to copy

This matches how most gameplay data should behave.


4. Structs (Data First)

Structs are pure data models.

declare struct Vector(x: float, y: float)
{
  pub fn len(self: this): float { ... }
  pub fn scale(self: mut this, s: float): void { ... }
}

Rules:

  • fields are private
  • mutation is explicit (mut this)
  • no inheritance
  • no identity

Structs are designed to be:

  • cachefriendly
  • predictable
  • easy to reason about

5. Mutability Is a Property of Bindings

In PBS, types are never mutable. Bindings are.

let v = Vector.ZERO;
v.scale();        // ERROR

let w = mut Vector.ZERO;
w.scale();        // OK

This single rule eliminates entire classes of bugs.


6. When You Need Power: Allocation (HIP World)

Allocation is explicit.

let enemies = alloc list<Enemy>();

Once you allocate:

  • data lives in Storage (heap)
  • access happens through gates (handles)
  • aliasing is real and visible

This is intentional and explicit.


7. Gates (Handles, Not Pointers)

A gate is a small value that refers to heap storage.

Properties:

  • cheap to copy
  • may alias shared data
  • managed by reference counting

7.1 Strong vs Weak Gates

  • Strong gate — keeps data alive
  • Weak gate — observes without ownership
let a = alloc Node;
let w: weak<Node> = a as weak;
let maybeA = w as strong;

This model mirrors real engine constraints without hiding them.


8. Controlled Access to Storage

Heap data is never accessed directly.

You must choose how:

  • peek — copy to SAFE
  • borrow — temporary readonly access
  • mutate — temporary mutable access
mutate enemies as e
{
  e.push(newEnemy);
}

This keeps mutation visible and scoped.


9. Errors Are Values

PBS has no exceptions.

9.1 optional<T>

Used when absence is normal.

let x = maybeValue else 0;

9.2 result<T, E>

Used when failure matters.

let v = loadTexture(path)?;

Error propagation is explicit and typed.


10. Control Flow Without Surprises

PBS favors explicit flow:

  • if — control only
  • when — expression
  • for — bounded loops only
for i in [0b..count] {
  update(i);
}

No unbounded iteration by accident.


11. Services: Explicit API Boundaries

A service is how behavior crosses module boundaries.

pub service Audio
{
  fn play(sound: Sound): void;
}

Services are:

  • explicit
  • statically checked
  • singletonlike

They map naturally to engine subsystems.


12. Contracts: Static Guarantees

Contracts define what exists, not how.

pub declare contract Gfx host
{
  fn drawText(x: int, y: int, msg: string): void;
}

Contracts:

  • have no runtime cost
  • are validated at compile time
  • define engine ↔ script boundaries

13. Modules (Simple and Predictable)

  • one directory = one module
  • only pub symbols cross modules
  • no side effects on import

This keeps build and runtime deterministic.


14. Why PBS Works for Games

PBS is designed around real engine needs:

  • framebased execution
  • explicit allocation
  • deterministic cleanup
  • predictable performance

It teaches developers why engines are written the way they are, instead of hiding reality.


15. Who PBS Is For

PBS is for:

  • game developers who want control
  • engine developers
  • students learning systems concepts
  • educators teaching memory and runtime models

PBS is not for:

  • rapid prototyping without constraints
  • general app scripting
  • hiding complexity

16. Design Promise

PBS makes one promise:

Nothing happens behind your back.

If you understand PBS, you understand your runtime.

That is the product.