6.0 KiB
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 real‑time runtimes.
Its core goals are:
- Didactic clarity — the language teaches how memory, data, and APIs really work.
- Game‑friendly 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 general‑purpose 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: SAFE‑Only 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
- user‑defined
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:
- cache‑friendly
- 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 SAFEborrow— temporary read‑only accessmutate— 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 onlywhen— expressionfor— 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
- singleton‑like
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
pubsymbols 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:
- frame‑based 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.