v0.3.0 · open source, Apache 2.0

A tiny decision model that keeps up with real time.

It reads one short sentence about the situation and picks an action in about 2 ms on one CPU core. No GPU, not even for training.

pip install simthinkd
Fits inside the deadline

Decide before the world moves on.

A game or a machine does not wait. Each bar is the time you have. The orange part is the time SimThink D used.

Doom, one tick at 35 ticks per second1.9 ms of 28.6 ms
28.6 ms
Inspection conveyor, before the part reaches the diverter20 ms of 400 ms
400 ms
SimThink D decision time (median)time available

Medians measured on our test PCs. In the conveyor run the decider is called over HTTP. Your numbers will differ, so measure them: simthinkd bench · reproduce

On a simulated inspection line

Internet down. The line kept going.

A cloud service decides first. When its answer is not back in 0.33 seconds, SimThink D on the factory PC decides. Then we cut the network for 15 seconds.

59 / 63parts right during the outage
54% → 94.7%parts handled correctly, whole run
0late decisions

A simulated line, and the decider learned this line's own rules, so it has a home advantage. The simulator is in examples/factory_twin.

Live demo

Try it right here.

The two Doom deciders from the paper run in this page, in plain JavaScript. Change the situation and press Decide.

What you get

Small, fast and easy to own.

One CPU core

About 2 ms per decision with 265,665 parameters. No GPU and no network needed. One call can carry several questions, and one batch many situations.

Train in seconds

Write your rules as a normal function. The toy task in the README trains on a CPU in about 8 seconds.

NumPy only

Making decisions needs only NumPy. Training adds PyTorch, and the CPU build is fine.

Plugs into your stack

An HTTP server, an MCP server and a LangChain tool come with the package, and a plain Java 8 runtime runs the same model inside JVM games.

Measure your own model

simthinkd bench replays 1,050 recorded Doom states and tells you if a decider answers within one tick. --batch compares one at a time with batches.

Checkable

The two bundled deciders are the ones evaluated in the paper. Their SHA-256 hashes are listed so you can check.

Where it fits

Best as one part of a bigger system.

Use it when the situation fits in one short line, the answer is small (one of up to 8 actions, or one number), and the answer has to be fast, cheap or offline.

First filter

SimThink D answers every case first. Only the cases it is not sure about go to a large model or a person.

Local backup

A cloud model answers first. When it is late or the network fails, SimThink D on the local machine answers instead.

Game characters

Moment-to-moment moves on every tick from SimThink D. Rare planning or dialogue from a large model.

Risk or priority score

fit_score returns one number per item, in well under a millisecond. See examples/risk_score.py.

A rule you already have

It learns your rule from examples, then runs it in about 2 ms with no network.

Not a fit

Judging long text, answers that depend on history the line does not contain, and open-ended writing.

Quickstart

One call is one decision.

from simthinkd import Decider

d = Decider("doom-defend")
print(d.decide("seen: Demon left a30 d5 | enemies 1 | sway left | gun ready | ammo25"))
# TURN_LEFT (100%, 1.1 ms)

# train your own from rules, on a CPU
import simthinkd
from simthinkd import toy
d = simthinkd.fit(toy.examples(3000), toy.ACTIONS, goal=toy.GOAL, out="inspection")
Paper

Decision time and decision quality, measured apart.

Separating Decision Time from Decision Quality in the Real-Time Gap of Distilled Deciders: Evidence from a Game and a Conveyor Simulator

Shin, Lee, Jeong and Kwon · preprint