• (breaking) Replace entity builder pattern with a more flexible spawn API.
    • To migrate to the new API, replace name() with the keyword argument:
      # before:
      # after:
      w.spawn(el.Body(), name="entity_name")
    • If the entity has multiple archetypes, just provide a list of archetypes as the first positional argument instead of using insert():
      # before:
      # after:
      w.spawn([el.Body(), OtherArchetype()], name="entity_name")
    • Also, spawn now returns EntityId directly instead of Entity. So, there’s no need to call id() to reference the entity in an edge component or viewport.
      a = w.spawn(...)
      b = w.spawn(...)
      # before:
      w.spawn(Rel(el.Edge(a.id(), b.id())))
      # after:
      w.spawn(Rel(el.Edge(a, b)))
  • Add multi-file support for Monte Carlo runs.
  • Add ability to use ranges in viewports for replay.


  • (breaking) Allow querying different components from the left and right entities via the new edge_fold API.
    • To migrate to the new API, move the graph query’s input components to a separate query parameter:

      # before:
      def gravity(
          graph: el.GraphQuery[GravityEdge, el.WorldPos, el.Inertia],
      # after:
      def gravity(
          graph: el.GraphQuery[GravityEdge],
          query: el.Query[el.WorldPos, el.Inertia],

      And then reference it in edge_fold:

      # before:
      return graph.edge_fold(el.Force, ...
      # after:
      return graph.edge_fold(query, query, el.Force, ...
    • To query different components from the left and right entities, use multiple queries:

      def rw_effector(
          rw_force: el.GraphQuery[RWEdge],
          force_query: el.Query[el.Force],
          rw_query: el.Query[RWForce]
      ) -> el.Query[el.Force]:
          return rw_force.edge_fold(force_query, rw_query, el.Force, ...
  • Make graph colors deterministic.
  • Drop milliseconds from the x-axis in graphs.
  • Prevent grid from changing origin.
  • Add ranges to graphs to allow zooming + panning.
  • Add support for spawning graphs and splits from code.
  • Switch to GPU based plotting.
  • Add configurable line width for graphs.


  • (breaking) Make RK4 the default integrator (can still override to use semi-implicit euler).
  • Add element names to graphs.
  • Add component priorities.
  • Components in inspector are displayed in descending order of priority.
    • Priority can be set via metadata. E.g.: metadata={"element_names": "q0,q1,q2,q3,x,y,z", "priority": 5}.
    • Default priority, if unset, is 10.
    • Components with priority of < 0 are hidden from the inspector.
  • Increase y-axis margin in graphs to prevent axis labels from getting cut off.
  • Use scientific notation for large values.
  • Prevent graph cursor modal from being cut off.
  • Add interia_diag() helper to el.SpatialInertia.
  • Fix graph data interpolation issues.


  • Reduce memory usage of plots.
  • Add rocket example with thrust curve interpolation.
  • Clear graphs on sim update.
  • Have a stable ordering of components in inspector.
  • Make decimal point stable in component inspector.
  • Add a built-in Time component + system.
  • Remember window size on restart.
  • Add configurable labels for component elements.