Deep Dive

Entity-Centric Design

Every object in a Planetary Processing world is an entity, and every entity’s behaviour is just a script. Here’s why that one decision makes complex multiplayer games so much easier to reason about.

12 September 2024  •  Planetary Processing

Entity-Centric Design Explained | Planetary Processing

Ask three engineers how to architect a multiplayer game and you’ll get three sprawling diagrams. We wanted something simpler — a single concept flexible enough to model a player, a bullet, a door, a weather system or a quest, while still being predictable to synchronise across the network. That concept is the entity.

Everything is an entity


In our engine there are no special cases for “players” versus “objects” versus “the world.” There are only entities. Each one has a type, a bag of state, and a script that defines how it behaves. A type is the template; an entity is a living instance of it.

  • Type — what kind of thing this is (player, tree, projectile).
  • State — the data that makes this particular instance unique (position, health, owner).
  • Behaviour — the Lua functions that run on the server to update that state.

Behaviour lives in scripts


An entity’s logic is plain Lua in a repository we host for you. The engine calls well-known lifecycle functions — such as an initialiser when the entity is created and an update each tick — and your script does the rest. Because the script runs on the server, it is the single source of truth for that entity’s state.

-- door.lua
function init(self)
  self.data.open = false
end

function on_interact(self, actor)
  if distance(self, actor) < 2 then
    self.data.open = not self.data.open
  end
end

Notice what isn’t here: no networking code, no serialization, no “if I’m the host” branches. You describe the door’s rules; the platform handles getting that state to every player who can see it.

Server owns state, client renders it


This split is the heart of the design. The server-side entity holds authoritative state. The client — through the SDK — holds a synchronised mirror it uses purely for presentation: meshes, animations, particles, sound. When the server says the door is open, every client shows it open. Clients can’t lie about state they don’t own, which removes a whole class of cheating and desync bugs.

Why this matters

Separating authority from presentation means your game logic exists in exactly one place. There is no “host” copy and “guest” copy to keep reconciled — there is the server’s entity, and everyone else is watching it.

Composition over inheritance


Because behaviour is just code attached to a type, building variety is a matter of composing small, focused scripts rather than wrestling with deep inheritance trees. A flammable crate and a flammable barrel can share the same “catches fire” logic without pretending to be the same kind of object.

Entities and the wider engine


Entity-centric design dovetails with the rest of the platform. Entities live inside chunks, which is how the world scales horizontally across servers. With dimensions, the same entity types populate many independent worlds at once. And the SDKs know how to sync any entity to any client regardless of which engine that client is built in.

The payoff


When everything is an entity and every entity is a script, a multiplayer game stops being a tangle of networking concerns and becomes a collection of small, testable behaviours. You spend your time on what your game does, not on the machinery that keeps it consistent across the wire — which is exactly where an indie team’s time should go.

← Back to all articles

We do the heavy lifting, so you don’t have to

Try the Planetary Processing platform for free today

Planetary Processing
©2024 Planetary Processing. All rights reserved