Skip to content

Architecture

Reinfors separates reusable rules, search, record generation, and user-owned learning.

CALLER-OWNED PYTHON

┌──────────────────────────────────────────────────────────────────────┐
│ Training loop calls Engine.collect(...) or reads a CollectStream     │
└──────────────────────────────────┬───────────────────────────────────┘
                                   │
══════════════════════ RUST / PYTHON BOUNDARY ═════════════════════════
                                   ▼
RUST: ENGINE AND COMPOSED COMPONENTS

┌──────────────────────────────────────────────────────────────────────┐
│ Engine                                                               │
│ owns active game slots, component instances, cache, batching,        │
│ record floor, stream queue, snapshots, and telemetry                 │
└──────────────────────────────────┬───────────────────────────────────┘
                                   ▼
              ┌───────────────────────────────┐
              │ Game                          │
              │ state · rules · legal actions │
              │ chance · terminal status      │
              └───────┬───────────────▲───────┘
      state + player  │               │ selected action / transition
      perspective     │               │
                      ▼               ├──────────────────────────┐
              ┌───────────────┐       │                  ┌───────┴────────┐
              │ Encoder       │       │                  │ Policy/search  │
              │ observation + │       └──────────────────│ uses Game +    │
              │ action view   │                          │ network data   │
              └───────┬───────┘                          └───────┬────────┘
                      │ encoded evaluation request               │
                      ▼                                          │
              ┌───────────────────────────────┐                  │
              │ Engine inference pool         │◄─────────────────┘
              │ batches requests from games,  │
              │ players, and search leaves    │
              └───────────────────┬───────────┘
                                  │ pooled observation array
══════════════════════ RUST / PYTHON BOUNDARY ═════════════════════════
                                  ▼
CALLER-OWNED PYTHON

              ┌──────────────────────────────────────────┐
              │ infer callback                           │
              │ NumPy → arbitrary network/device/RPC →   │
              │ policy values, action values, or logits  │
              └───────────────────┬──────────────────────┘
                                  │ prediction arrays
══════════════════════ RUST / PYTHON BOUNDARY ═════════════════════════
                                  ▼
RUST

              ┌──────────────────────────────────────────┐
              │ Engine routes each prediction row back   │
              │ to the policy/search that requested it   │
              └───────────────────┬──────────────────────┘
                                  │
                         search continues, or
                         an action is selected
                                  │
              ┌───────────────────▼──────────────────────┐
              │ Game applies actions and chance          │
              │ transitions, producing ordered events    │
              └──────────────┬────────────────┬──────────┘
                             │                │ events
                transition / │                ▼
                search data  │       ┌───────────────────┐
                             │       │ Reward            │
                             │       │ events → rewards  │
                             │       └─────────┬─────────┘
                             ▼                 ▼
              ┌──────────────────────────────────────────┐
              │ Learner                                  │
              │ Engine-supplied trajectory, decision,    │
              │ and search data + rewards → records      │
              └───────────────────┬──────────────────────┘
                                  │ records accumulate to requested floor
              ┌───────────────────▼──────────────────────┐
              │ completed Engine batch                   │
              │ (direct return or CollectStream queue)   │
              └───────────────────┬──────────────────────┘
                                  │
══════════════════════ RUST / PYTHON BOUNDARY ═════════════════════════
                                  ▼
CALLER-OWNED PYTHON

              replay/buffer → loss → optimizer → updated network
                                  │
                                  └──────────────► next collection cycle

The primary execution surfaces

Engine owns many active episodes. A policy asks for evaluations, the engine pools those requests, and a learner converts completed decisions or trajectories into training records. Use it for policy-driven, learner-shaped data generation, including direct value learning and search-guided methods (for example, DQN, TreeStrap, and AlphaZero).

Env owns one game instance and lets the caller supply each decision. Use it for evaluation, interactive play, custom agents, and Gymnasium/PettingZoo adapters. It exposes observations, legal actions, active agents, event traces, rewards, snapshots, and forks.

Arena owns concurrent, paired evaluation games. It pools native policy search across ready games and can place one external contestant on bounded worker lanes. Use it when the deployed agent includes search or when a subprocess engine must play alongside searched contestants.

Algorithms whose traversal does not fit policy-driven episode collection use standalone solvers (e.g. CFR).

Component responsibilities

Component Responsibility
Game State transitions, active agents, legal actions, explicit chance distributions, terminal state, and information-state identity.
Encoder Convert a valid game state and agent perspective into a fixed observation and action-head view.
Reward Map ordered transition events to per-agent scalar rewards.
Policy Choose decisions and define any search/evaluation process used to do so.
Learner Decide which training records a policy trajectory produces.
Engine Run games concurrently, batch inference, assemble records, cache evaluations, and report telemetry.
Arena Run paired evaluation games, pool searched inference, and schedule external agents.
Env Expose one caller-controlled game instance.
Solver Own algorithm-specific traversals and persistent state outside the policy/learner engine model.

The native component contracts describe the implementation contracts in detail.

Why the inference boundary uses arrays

The engine needs evaluated rows, not a particular model object. NumPy is the stable Python ABI at that boundary and lets callers wrap PyTorch, JAX, ONNX Runtime, a custom accelerator, or RPC. Legal actions remain a property of the game and are enforced around inference by search, selection, and loss construction; masks are not model inputs.

This keeps the single performance-critical seam small while leaving model architecture and deployment open.

Next steps