Usage
Decoder simulator
ammc-sim pretends to be a timing decoder, so you can develop and test your
application without a physical decoder on the desk. It ships in the AMMC zip
next to ammc-amb.
It is not a complete decoder emulator. It generates passing traffic and answers the handful of requests AMMC itself sends; a third-party timing application that expects the full protocol will most likely not work with it.
How it works
The simulator opens a TCP server and waits for clients — the opposite of a
real decoder only in that you connect to localhost instead of the track. The
port is fixed by decoder type and cannot be changed:
| Decoder type | Port | Protocol |
|---|---|---|
AMB (default) | 5403 | P3 binary |
Vostok | 8899 | text lines |
Inside, three independent tasks run at the same time:
A passing generator. Every --passing-delay milliseconds — a fresh random
value in the given range for each passing — it builds one passing, encodes it in
the decoder's wire format and pushes it to all connected clients. The passing
number counts up from the low end of --passing-numbers; the transponder (and
the transponder code, if you gave one) is picked at random from your list on
every passing. --hits, --strength and --decoder-id are copied into every
message unchanged. The timestamp is the current local time of the machine,
taken at the moment the passing is generated.
A status timer. Every 3 seconds it sends a status message, the same keep-alive a real decoder emits. AMMC logs it and carries on.
A request responder. Anything a client sends is fed through the same P3
parser AMMC uses, and known requests are answered: VERSION gets a version
message, PING is echoed back with its payload, a time-sync request gets a time
message, and a request to resend passings is accepted and logged. Unknown
requests are ignored. This is what makes ammc-amb -t (time sync) and the
WebSocket PING round-trip work against the simulator.
Two things regularly surprise people:
- The generator does not wait for a client. It starts at the configured passing number and keeps ticking whether or not anything is connected, and it does not replay what it missed. Connect a few seconds late and the first passing you see is number 4 or 5, not 1.
- It stops on its own. When the passing number passes the top of
--passing-numbersthe simulator waits--shutdown_delay_secsand exits. With the default1-3000and the default delay that is roughly two hours; use a range like-n 1-50for a short, repeatable test.
Every connected client gets the same passings, so you can point several applications at one simulator.
Auto-discovery
A real AMB decoder answers a UDP broadcast so AMMC's -a can find it. The
simulator does this only when you tell it which address to advertise:
.\ammc-sim.exe -m 192.168.1.10
It then listens for discovery requests on UDP port 5403 and answers with a
broadcast to port 5303 carrying that address and the decoder ID. Without -m it
logs Use '-m <IP address>' to enable auto-discovery mode and simply ignores
discovery traffic.
Note that the simulator holds UDP port 5403 while it does this, and AMMC's -a
wants the same port. Running both on one machine will not work — use
ammc-amb <ip> with the address instead of -a when the simulator is local.
Examples
Start a simulator and read it with AMMC, in two terminals:
cd windows64
.\ammc-sim.execd windows64
.\ammc-amb.exe 127.0.0.1[2026-08-09T08:17:07Z INFO common] >>> {"decoder_id":"0A87E5","gps_locked":false,"hits":100,"low_battery":false,"modified":false,"msg":"PASSING","passing_number":4,"resend":false,"rtc_time":"2026-08-09 10:17:07.376639 +02:00","strength":300.0,"transponder":12345}
[2026-08-09T08:17:07Z INFO common] >>> {"decoder_id":"0A87E5","gps_locked":false,"hits":100,"low_battery":false,"modified":false,"msg":"PASSING","passing_number":5,"resend":false,"rtc_time":"2026-08-09 10:17:07.684126 +02:00","strength":300.0,"transponder":7777}
Fifty passings, three known transponders, about three per second:
.\ammc-sim.exe -n 1-50 -d 300-400 -t 12345,23456,4554444
A steady one-second beat from a single transponder, for a scoreboard demo:
.\ammc-sim.exe -d 1000-1001 -t 232323 -c ID:232323
Load test — as fast as the simulator will go:
.\ammc-sim.exe -n 1-100000 -d 1-2
Vostok instead of AMB:
.\ammc-sim.exe Vostok
.\ammc-vostok.exe 127.0.0.1Options
Usage: ammc-sim [OPTIONS] [DECODER_TYPE]
Arguments:
[DECODER_TYPE] Decoder type; AMB or Vostok [default: AMB]| Option | Default | Description |
|---|---|---|
-n, --passing-numbers <from-to> | 1-3000 | Range of passing numbers to generate. The simulator exits after the last one |
-d, --passing-delay <from-to> | 1000-3000 | Delay between passings in milliseconds, picked at random from the range for each passing |
-t, --transponder <list> | 123456,87654321 | Transponder numbers, comma separated. One is chosen at random per passing |
-c, --tran_code <list> | Transponder codes, comma separated, e.g. x-1,d-345,aa-199. Setting either -t or -c replaces the default transponders | |
--decoder-id <hex> | 0A87E5 | Decoder ID sent in every message. Must be a hex number |
-s, --strength <n> | 300 | Signal strength in every passing |
--hits <n> | 100 | Hit count in every passing |
-m, --my_ip <ip> | IP address to advertise in auto-discovery replies. Off when not given | |
-x, --startup_delay_secs <n> | 0 | Wait before generating the first passing |
-y, --shutdown_delay_secs <n> | 0 | Wait after the last passing before exiting |
-v, --verbose | Log every message, including the raw bytes on the wire | |
-q, --quite | Errors and warnings only | |
--skip_telemetry_upload | Do not send the runtime telemetry ping | |
-V, --version | Print the version | |
-h, --help | Print all options |
Passings always carry the local time of the machine that runs the simulator.