Files
cell/docs/cell.md

3.8 KiB

Cell Language

Cell is a JavaScript variant used in the Prosperon game engine. While very similar to JavaScript, it has several important differences that make it more suitable for game development and actor-based programming.

Key Differences from JavaScript

Null vs Undefined

  • Cell has only null, no undefined
  • Idiomatic null checking: if (object.x == null)
  • Uninitialized variables and missing properties return null

Equality Operators

  • Only == operator exists (no ===)
  • == is always strict (no type coercion)
  • != for inequality (no !==)

Variable Declarations

  • def keyword for constants (replaces const)
  • var works like let (block-scoped)
  • No let keyword

Compilation

  • All code is compiled in strict mode
  • No need for "use strict" directive

Removed Features

Cell removes several JavaScript features for simplicity and security:

  • No Proxy objects
  • No ES6 module syntax (use use() function instead)
  • No class syntax (use prototypes and closures)
  • No Reflect API
  • No BigInt
  • No WeakMap, WeakSet, WeakRef
  • No document.all (HTMLAllCollection)
  • No with statement
  • No Date intrinsic (use time module instead)

Language Features

Constants

def PI = 3.14159
def MAX_PLAYERS = 4
// PI = 3.14 // Error: cannot reassign constant

Variables

var x = 10
{
  var y = 20  // Block-scoped like let
  x = 15      // Can access outer scope
}
// y is not accessible here

Null Checking

var obj = {name: "player"}
if (obj.score == null) {
  obj.score = 0
}

Functions

// Function declaration
function add(a, b) {
  return a + b
}

// Function expression
var multiply = function(a, b) {
  return a * b
}

// Arrow functions work normally
var square = x => x * x

Objects and Prototypes

// Object creation
var player = {
  x: 0,
  y: 0,
  move: function(dx, dy) {
    this.x += dx
    this.y += dy
  }
}

// Prototype-based inheritance
function Enemy(x, y) {
  this.x = x
  this.y = y
}
Enemy.prototype.attack = function() {
  // Attack logic
}

Module System

Cell uses a custom module system with the use() function:

var math = use('math')
var draw2d = use('prosperon/draw2d')

Time Handling

Since there's no Date object, use the time module:

var time = use('time')
var now = time.number()     // Numeric timestamp
var record = time.record()   // Structured time
var text = time.text()       // Human-readable time

Best Practices

  1. Prefer def for values that won't change

    def TILE_SIZE = 32
    var playerPos = {x: 0, y: 0}
    
  2. Always check for null explicitly

    if (player.weapon == null) {
      player.weapon = createDefaultWeapon()
    }
    
  3. Use prototype patterns instead of classes

    function GameObject(x, y) {
      this.x = x
      this.y = y
    }
    GameObject.prototype.update = function(dt) {
      // Update logic
    }
    
  4. Leverage closures for encapsulation

    function createCounter() {
      var count = 0
      return {
        increment: function() { count++ },
        getValue: function() { return count }
      }
    }
    

Common Gotchas

  1. No undefined means different behavior

    var obj = {}
    console.log(obj.missing)  // null, not undefined
    
  2. Strict equality by default

    "5" == 5   // false (no coercion)
    null == 0  // false
    
  3. Block-scoped var

    for (var i = 0; i < 10; i++) {
      setTimeout(() => console.log(i), 100)  // Works as expected
    }
    

See Also