Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
treeform
marked this pull request as draft
September 25, 2026 15:02
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes GotA training faster in two ways: the simulation runs about 1.55x faster per core with identical results, and a new lockstep training API lets trainers use every CPU.
Simulation speedups (game results unchanged)
A full 28,800-tick match with fixed actions gives the same state hash before and after (
5CD704D815D34746), at 1,274 ticks/s on main and 1,972 ticks/s on this branch (Apple M-series, one core).for x in world.footmenandlet x = world.footmen[i]copied eachFootman, including itsmovePathseq, many times per tick. Those read-only locals are now{.cursor.}over indexed loops.ensureScriptObjectsrebuilt and sorted the visible-object list for every hero, but during a decision frame it only depends on the team. It is now cached per team while observations are frozen.revealVisionCachedcompared two height grids element by element every rebuild; that is now oneequalMem, and the blocker grid is copied withcopyMem.navigationRevision, which already bumps whenever building occupancy changes, so results are the same.visible()unrolled over its up to four sight cells instead of going through thesightTilesiterator; it runs for every unit pair.Bug fix in
training.nimA lane releases the process lock mid-tick while it waits for the trainer's action. Another lane then ticks and repoints the
navigationWorldglobal at its own match, and when the first lane resumed, its heroes pathed against the other match's buildings. The lane now callsbindNavigation(game.world)after it wakes, next to the existingactiveGame = game. Single-lane results are unchanged; multi-lane results change because of the fix.Lockstep training API (
lockstep.nim)training.nimgives each lane a worker thread that blocks insidechooseAction, and all lanes share one process lock, so a trainer gets one core per process and one lane decision at a time.lockstep.nimis a second API alongside it:chooseActionrecords the hero's newest features and returns the action the trainer last set, so scripts never block and no threads are needed.stepapplies one action per agent, runsactionTicksticks of every lane, and returns rewards, terminals, and per-lane stats. Finished lanes restart inside the step.selfPlayruns the policy on both teams (10 agents per lane); otherwise one team plays a bundled opponent (5 per lane).gota_create/agents/reset/step/close.Library state is still process-global, so the external PufferLib env loads one copy of the library per env to run envs in parallel. With that, a PufferLib 5 trainer measured 33–36K steps/s on 128 CPUs of a b300 node, against about 370 with
training.nim.Testing
tests/test_gota_lockstep.nim(added to CI): agent counts, seats, determinism, lane restarts, and every reward mode.POLYWORLD_DEPS=tmp/coworld/deps:tests/tests.nimand every GotA step inbuild.ymlpass (events, controls, camps, phases, portals, potions, progression, drafts,gen_replays gota,test_gota_sim,test_gota_training,test_gota_lockstep,test_recordings -d:recordGota).🤖 Generated with Claude Code