Entities & Components

Pyxen uses an Entity-Component System (ECS). If you’ve used game engines with class hierarchies — where a Player extends Character extends GameObject — this is different. In Pyxen, there’s no inheritance. Everything is composition.

Entities

An entity is a game object. It could be a player, a wall, a bullet, a particle — anything. Under the hood, an entity is just an ID. It holds no data on its own. Instead, you attach components to it.

player = world.spawn(name="player", x=100, y=50)

This creates an entity at position (100, 50) with a name. The entity exists in the world and will be rendered if it has a sprite.

Components

Components are pieces of data attached to an entity. Pyxen has two kinds:

Built-in components

These are provided by the engine:

ComponentPurpose
TransformPosition (x, y), rotation, scale
SpriteVisual appearance — image, tile, pivot, color
CameraViewport with zoom
GridBodyCollision body on the grid
GridMapTilemap with rows, columns, and tile data
SoundSound effect playback
MusicMusic stream playback
NameString identifier for lookup
LayerRendering layer (0–255)
Parent / ChildrenScene hierarchy

You set built-in components through entity properties or at spawn time:

e = world.spawn(
    x=50, y=80,
    sprite=Sprite("hero"),
    name="player"
)

# later
e.x = 100
e.sprite = Sprite("hero", tile=(16, 0, 16, 16))

Custom components

You can attach your own components to any entity. A custom component is a dictionary with typed fields:

player.health = {"value": 100, "max": 100}
player.speed = {"value": 2.5}

Once attached, you access fields directly:

player.health.value -= 10

You can also use marker components — components with no data that act as tags:

player.alive = True
enemy.boss = True

This is useful for queries: you can find all entities with a given marker.

Field types

Component fields can be:

TypeExampleNotes
int4232-bit integer
float3.1432-bit float
boolTrueBoolean
str"hello"Max 31 characters
EntityplayerReference to another entity

These constraints exist because components are stored in a compact, cache-friendly layout inside the C++ engine. This is what makes queries fast.

Querying entities

The world lets you find entities by their components:

# all entities with a "health" component
for e in world.all("health"):
    if e.health.value <= 0:
        world.destroy(e)

# combine: has "enemy", does not have "dead"
for e in world.all("enemy", without=("dead",)):
    e.x += e.speed.value

You can also query by built-in components like "sprite", "body", "camera", "sound", "music", and "map":

# all entities with a sprite
for e in world.all("sprite"):
    e.color = (1, 1, 1, 1)

# entities with both a sprite and the "enemy" custom component
for e in world.all("sprite", "enemy"):
    e.color = (1, 0, 0, 1)

Queries are the main way you write game logic in Pyxen. Instead of each object updating itself, you write systems that iterate over entities with specific components.

See the full API: world.all(), Entity

Why ECS?

If you’re used to object-oriented game code, ECS might feel unusual at first. The benefits: