Getting started

First steps

The central object in snecs is a World.

A World is an opaque repository of all the data flowing through snecs. All the functions that let you interact with the library take an optional world argument.

If you’re only ever using one World, you don’t actually need to instantiate or pass it to functions explicitly - if you omit the world argument, snecs will use a default one. If you want to use more than one World in your code, you can create a new one just by:

from snecs import World

my_world = World()

You’d then pass my_world around explicitly to each function, by calling them with world=my_world.

Once you have a World, the next step is adding some entities to it:

from snecs import new_entity

new_id = new_entity()
# or, if you want to use a different world than the default:
new_id = new_entity(world=my_world)

new_entity returns an integer 1, uniquely identifying the newly created entity in that specific World.

Entities without components are not very useful, though, and you’ll probably want to add some data do them. You can do that by subclassing Component:

from snecs import Component, register_component

@register_component
class Position(Component):
    def __init__(self, x, y):
        self.x = x
        self.y = y

All Component classes that you intend to instantiate must be registered by decorating them with register_component 2. Otherwise, snecs won’t know about them!

Footnotes

1

If you’re using mypy and typing, you may want to use EntityID from the snecs.types module for your type annotations - it’s the return type of all the snecs functions that return… well, an entity ID. It is defined as an integer subtype, which strengthens the type safety a bit by forbidding most numeric operations on entity IDs. entity_id * 2 is pretty meaningless, after all!

If you’re not using typing, just treat all entity IDs as a normal int.

2

snecs also has a convenience class, RegisteredComponent, which automatically registers all its subclasses (and their subclasses!), so that you can avoid having to type @register_component over and over:

from snecs import RegisteredComponent

class Position(RegisteredComponent):
    def __init__(self, x, y):
        self.x = x
        self.y = y

You shouldn’t use it for classes that are abstract or have abstract subclasses.

RegisteredComponent is also usable as a mixin:

from abc import ABC
from snecs import RegisteredComponent, Component

class BaseComponent(Component, ABC):
    ...

class ConcreteComponent(BaseComponent, RegisteredComponent):
    ...