Python and Go bridge scaffolding for AI-controlled ATC experiments in the Vice ATC simulator.
This repository is intentionally an overlay, not a full copy of Vice. It keeps the large simulator source, resources, generated datasets, trained models, and local toolchains out of GitHub. To use it on another PC, clone upstream Vice separately, then apply this overlay.
python/vice_ai/: Python environment wrapper, schemas, action masks, synthetic policies, JSONL episode processing, behavior-cloning trainer, and eval tools.cmd/vice-ai-bridge/: a small Go JSON-lines bridge that loads Vice scenarios, steps the simulator, emits observations, and applies typed ATC actions.server/demo_recorder.go: support code for human demonstration recording.patches/vice_ai_integration.patch: the small patch needed for existing Vice files such as the UI recorder toggle and server command hooks.docs/ai_controller_plan.md: architecture and training notes.
These are ignored on purpose:
- Vice source folders such as
sim,client,server,resources,radar,stars,panes, and other upstream game directories. - Generated datasets under
data/. - Trained model runs under
runs/. - Built binaries under
bin/. - Local compiler/toolchain folders and downloaded dependencies.
The commands below assume PowerShell and an E: drive layout. Adjust paths if
you use a different drive.
cd E:\
git clone --recursive https://github.com/mmp/vice.git ViceBaseIf you already cloned without submodules:
cd E:\ViceBase
git submodule update --init --recursivecd E:\
git clone https://github.com/Daboss57/VICEAI.git VICEAIrobocopy E:\VICEAI\python E:\ViceBase\python /E
robocopy E:\VICEAI\docs E:\ViceBase\docs /E
robocopy E:\VICEAI\cmd\vice-ai-bridge E:\ViceBase\cmd\vice-ai-bridge /E
New-Item -ItemType Directory -Force E:\ViceBase\server | Out-Null
Copy-Item E:\VICEAI\server\demo_recorder.go E:\ViceBase\server\demo_recorder.go -Force
Copy-Item E:\VICEAI\requirements-training.txt E:\ViceBase\requirements-training.txt -Force
Copy-Item E:\VICEAI\pytest.ini E:\ViceBase\pytest.ini -Force
Copy-Item E:\VICEAI\pyrightconfig.json E:\ViceBase\pyrightconfig.json -ForceApply the integration patch from inside the Vice checkout:
cd E:\ViceBase
git apply E:\VICEAI\patches\vice_ai_integration.patchIf git apply reports conflicts, the upstream Vice code changed. Open the patch
and apply the same small edits manually, then continue.
cd E:\ViceBase
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements-training.txt
$env:PYTHONPATH = "E:\ViceBase\python"Check CUDA if you want GPU training:
python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'no cuda')"Vice's Go bridge uses CGO, so Go needs a C/C++ compiler. Keep the compiler outside both repos. For example:
$env:PATH = "E:\Toolchains\ViceAI\mingw64-15.2.0-ucrt\mingw64\bin;$env:PATH"
$env:CGO_ENABLED = "1"
$env:CC = "gcc"
$env:CXX = "g++"
$env:GOMODCACHE = "E:\ViceBase\.gomodcache"If SDL DLLs are required at runtime, also add the Vice SDL folder:
$env:PATH = "E:\ViceBase\ext\SDL2-2.24.0\x86_64-w64-mingw32\bin;$env:PATH"cd E:\ViceBase
python -m vice_ai.build_bridge --repo-root E:\ViceBase --out E:\ViceBase\bin\vice-ai-bridge.exepython -m vice_ai.eval `
--policy noop `
--repo-root E:\ViceBase `
--bridge-command E:\ViceBase\bin\vice-ai-bridge.exe `
--facility SBA `
--scenario "SBA 07/15" `
--episodes 1 `
--steps 10 `
--step-seconds 5 `
--device cpuGenerated data and models are intentionally ignored by Git. Keep them local or upload them to a separate artifact store.
Collect the v4 candidate-ranking dataset with --include-valid-actions so each
row records the safe action set that the teacher picked from:
python -m vice_ai.collect_parallel `
--repo-root E:\ViceBase `
--bridge-command E:\ViceBase\bin\vice-ai-bridge.exe `
--scenario-manifest docs\curricula\zla_sba_v4.json `
--dataset-key ZLA_SBA_mix_v4_candidates `
--policy synthetic_full `
--episodes 3000 `
--workers 6 `
--steps 300 `
--step-seconds 5 `
--include-valid-actions `
--flush-every-steps 64 `
--progress-every 50 `
--out data\episodesFor better dataset diversity without hand-writing giant command lists, use a
weighted scenario curriculum manifest. This repository includes a SBA-focused
mix at docs/curricula/zla_sba_v4.json:
python -m vice_ai.collect_parallel `
--repo-root E:\ViceBase `
--bridge-command E:\ViceBase\bin\vice-ai-bridge.exe `
--scenario-manifest docs\curricula\zla_sba_v4.json `
--dataset-key ZLA_SBA_mix_v4 `
--policy synthetic_full `
--episodes 5000 `
--workers 6 `
--steps 360 `
--step-seconds 5 `
--flush-every-steps 64 `
--progress-every 50 `
--out data\episodesThat manifest mixes the real Vice scenarios SBA 07/15 and KSBA 25/15, with
time jitter baked in so the teacher sees more than one narrow traffic slice.
Build the v4 full-game tensor cache only if you need the older hierarchical heads for comparison:
python -m vice_ai.build_dataset_cache `
--episodes data\episodes\ZLA_SBA_mix_v4 `
--out data\cache\sba_mix_v4_full.pt `
--progress-every 25000The candidate-ranking path processes the collected JSONL files directly. There is no separate candidate cache build between collection and training.
--label-mode executable remains the default because it filters to actions the
bridge actually executed. If you want the fastest path and trust the stored
valid_actions, use --label-mode oracle; that avoids recomputing the
conservative executable action set while processing JSONL episodes.
The training CLI defaults are tuned for this v4 setup: the active
candidate-ranking model uses a 512-wide, 8-head, 3-layer traffic transformer
with 4x feedforward layers, 0.02 dropout, AdamW, 1e-3 learning rate, 0.01
weight decay, cosine decay after 5 warmup epochs, gradient clipping at 1.0,
and an effective batch size of 2048. The older full-game comparison path uses a
1024-wide, 8-head, 2-layer transformer.
Train the v4 full-game policy only if you are comparing against the candidate-ranking model:
python -m vice_ai.train_full_bc `
--cache data\cache\sba_mix_v4_full.pt `
--out runs\bc_full_sba_mix_v4 `
--epochs 220 `
--hidden 1024 `
--dropout 0.02 `
--batch-size 1024 `
--effective-batch-size 2048 `
--device cuda `
--precision bf16 `
--num-workers 6 `
--max-noop-ratio 1.0 `
--seed 1337 `
--log-every 1 `
--log-head-losses `
--checkpoint-every 10Train the candidate-ranking policy:
python -m vice_ai.train_candidate_bc `
--episodes data\episodes\ZLA_SBA_mix_v4_candidates `
--label-mode executable `
--out runs\bc_candidate_sba_mix_v4 `
--epochs 180 `
--hidden 512 `
--attention-heads 8 `
--encoder-layers 3 `
--feedforward-multiplier 4 `
--dropout 0.02 `
--batch-size 768 `
--effective-batch-size 1536 `
--device cuda `
--precision bf16 `
--num-workers 6 `
--max-noop-ratio 1.0 `
--seed 1337 `
--log-every 1 `
--checkpoint-every 10--batch-size is the micro-batch. --effective-batch-size uses gradient
accumulation when it is larger than the micro-batch. For example,
--batch-size 8 --effective-batch-size 64 accumulates 8 mini-batches before
one optimizer update. The candidate BC trainer now splits collected JSONL files
into 90% train and 10% eval by default and runs held-out eval every epoch. Use
--val-ratio 0 to disable the held-out split or --no-shuffle only for
debugging.
Do not select checkpoints by training loss alone. Keep the model that wins the simulator comparison, not the one with the prettiest training curve.
Compare no-op, synthetic teacher, and model:
python -m vice_ai.eval_compare `
--model runs\bc_candidate_sba_mix_v4\candidate_policy.pt `
--repo-root E:\ViceBase `
--bridge-command E:\ViceBase\bin\vice-ai-bridge.exe `
--facility SBA `
--scenario "SBA 07/15" `
--episodes 30 `
--workers 6 `
--steps 360 `
--step-seconds 5 `
--device cpuAfter applying the patch, normal Vice can toggle human-demo recording from the
UI. Use Ctrl+Shift+R or the square recorder button in the menu bar. The
recorder writes JSONL demonstration rows locally. Do not commit those files.
The v4 path is the active training path. It uses the weighted SBA curriculum and candidate-ranking JSONL processing so the model learns to compare whole valid actions directly instead of reconstructing a decision from separate offline heads during eval.