Update Method

Intent: Simulate a collection of independent objects by telling each to process one frame of behavior at a time.

Acron Mapping

Pattern role

Acron equivalent

update(dt) method

Task function registered with taskMgr.add()

Entity collection

Each entity owns its own task or a manager task iterates a list

Delta time

globalClock.getDt() / task.dt

Entity activation

taskMgr.add(entity.update, name)

Entity deactivation

taskMgr.remove(name) or returning task.done

Two approaches: (a) each entity has its own task — simple, but many tasks have overhead; (b) one manager task iterates a Python list of entities — efficient for hundreds of objects.

Code Sketch (Python)

class Enemy:
    def __init__(self, node):
        self.node = node
        self.dead = False
        self._dir = 1

    def update(self, dt: float):
        self.node.setX(self.node, self._dir * 4 * dt)
        if abs(self.node.getX()) > 10:
            self._dir *= -1

    def destroy(self):
        self.node.removeNode()


class EntityManager:
    def __init__(self):
        self._entities = []
        taskMgr.add(self._update_all, 'entityUpdate', sort=10)

    def add(self, entity):
        self._entities.append(entity)

    def _update_all(self, task):
        dt = globalClock.getDt()
        for e in self._entities:
            if not e.dead:
                e.update(dt)
        # Purge dead entities at end of frame
        dead = [e for e in self._entities if e.dead]
        for e in dead:
            e.destroy()
            self._entities.remove(e)
        return task.cont

    def destroy(self):
        taskMgr.remove('entityUpdate')
        for e in self._entities:
            e.destroy()
        self._entities.clear()

Pitfalls

  • Update order is not simultaneous: entities update one at a time, in list order. When entity A updates, it sees B’s state from the previous frame; when B updates next, it already sees A’s new state. This asymmetry can cause subtle bugs when entities interact. The book flags this explicitly: if order matters, either enforce a fixed canonical order or double-buffer state (see Double Buffer).

  • Modifying the list during iteration: marking entity.dead = True during update() is safe; removing from self._entities while iterating is not. Always purge after the loop (shown above).

  • Per-entity tasks for many objects: registering 500 separate tasks via taskMgr.add() adds overhead. Use the manager/list approach for large entity counts.

  • Task sort order: the entity update task must run after input processing but before rendering. Use sort=10; Acron’s render task runs at sort=50 by default.