https://cleoselene.com/ [?][?] Active Development: Cleoselene is currently in an early preview stage. Please reach out to help@cleoselene.com before using it for any serious projects or production work. Cleoselene Logo Cleoselene A Multiplayer-First Server-Rendered Game Engine with Lua Scripting. Play Demo: Astro Maze curl -fsSL https://cleoselene.com/install | bash Supported: macOS (Universal: M1/M2/M3 & Intel), Linux (x64). Windows soon. Why Cleoselene? [?] Multiplayer as Simplicity Code multiplayer games as simple as single-player. No more worrying about client-server state sync or lag compensation. Just one loop, everywhere. [?] Primitive Streaming We stream drawing primitives instead of heavy pixels or complex state objects. It's faster than cloud gaming and lighter than traditional networking. High Performance All performance-critical logic (Physics, Pathfinding) runs in Native Rust. Communication is powered by WebRTC for sub-frame latency. [?] Impossible to Cheat Since the game is entirely server-rendered, the client has zero knowledge of the game state. No wallhacks, no aimbots, no compromise. Hide Your Secrets Keep your game's internal logic and secrets safe. Since your script never leaves the server, players can't reverse-engineer your code or find hidden content. Host Anywhere Total freedom. This version of the engine is free for personal or commercial use on your own infrastructure. No lock-in, no per-player fees. Features * Native Performance: Physics and Pathfinding in Rust. * Lua Scripting: Hot-reloadable game logic. * Web Ready: WebRTC & WebSocket multiplayer out of the box. Get Started Download the binary and run: cleoselene my_game.lua API Reference Cleoselene Manual A Multiplayer-First Server-Rendered Game Engine with Lua Scripting. Game Structure A minimal game script (main.lua) must implement these callbacks: -- Called once when the server starts function init() -- Initialize physics, load assets, setup state db = api.new_spatial_db(250) phys = api.new_physics_world(db) api.load_sound("jump", "assets/jump.wav") end -- Called every server frame (typically 30 TPS) function update(dt) -- Advance physics simulation phys:step(dt) -- Handle collisions local events = phys:get_collision_events() for _, pair in ipairs(events) do -- Handle game logic (damage, score) end end -- Called for EACH connected client to generate their frame function draw(session_id) api.clear_screen(20, 20, 30) -- Draw player-specific view (camera, HUD) local p = players[session_id] if p then api.set_color(255, 255, 255) api.draw_text("HP: " .. p.hp, 10, 10) -- Use db:query_rect to draw visible entities end end -- Network Events function on_connect(session_id) print("Player joined: " .. session_id) -- Spawn player entity end function on_disconnect(session_id) print("Player left: " .. session_id) -- Despawn entity end function on_input(session_id, key_code, is_down) -- Handle input (key_code is JS key code) -- 37=Left, 38=Up, 39=Right, 40=Down, 32=Space, 90=Z if players[session_id] then players[session_id].inputs[key_code] = is_down end end API Reference Display & Coordinates The engine uses a fixed virtual coordinate system of 800x600. All drawing commands (api.fill_rect, api.draw_line, etc.) use these coordinates. The engine automatically scales the output to fit the user's screen while maintaining the logical resolution and aspect ratio. Graphics & Sound Method Description api.clear_screen(r, g, b) Clears the frame with a background color. api.set_color(r, g, b, [a]) Sets the current drawing color. api.fill_rect(x, y, w, h) Draws a filled rectangle. api.draw_line(x1, y1, x2, Draws a line. y2, [width]) api.draw_text(text, x, y) Draws text at position. api.load_sound(name, url) Preloads a sound from a URL/path (relative to script). api.play_sound(name, [loop]) Plays a loaded sound. api.stop_sound(name) Stops a sound. api.set_volume(name, volume) Sets volume (0.0 to 1.0). Spatial DB (Geometry) The engine provides a high-performance Spatial Hash Grid for broadphase queries. Creation local db = api.new_spatial_db(cell_size) -- e.g., 250 Object Management Method Description Returns db:add_circle(x, y, radius, Registers a circular entity. id tag) (int) db:add_segment(x1, y1, x2, Registers a line segment id y2, tag) (wall). (int) db:remove(id) Removes an entity from the DB. nil db:update(id, x, y) Manually updates position nil (teleport). db:get_position(id) Returns x, y of the entity. x, y Queries (Sensors) Method Description Returns db:query_range(x, y, r, Finds entity IDs within {id1, id2...} [tag]) radius r. db:query_rect(x1, y1, Finds entity IDs within {id1, id2...} x2, y2, [tag]) AABB (Culling). db:cast_ray(x, y, angle, Casts a ray. id, frac, hit_x, dist, [tag]) hit_y or nil Physics Engine (Simulation) Handles rigid body dynamics, integration, and collision resolution. Creation local phys = api.new_physics_world(db) Body Management Method Description phys:add_body(id, props) Adds physics to an entity. Props: {mass= 1.0, restitution=0.5, drag=0.0}. phys:set_velocity(id, vx, Sets velocity. vy) phys:get_velocity(id) Returns vx, vy. phys:set_gravity(x, y) Sets global gravity vector. phys:step(dt) Advances simulation. Resolves collisions and updates db. phys:get_collision_events Returns list of collisions since last step: () {{idA, idB}, ...}. Graph Navigation (Pathfinding) Native A* implementation on a custom graph. Method Description nav = api.new_graph() Creates a new navigation graph. nav:add_node(id, x, y) Adds a node to the graph. nav:add_edge(u, v) Adds an edge (connection) between nodes. nav:find_path(start, Returns a list of node IDs forming the end) shortest path.