T4: Add movement harness + oscillator module #182
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
#165 (ModularBot wayfinder map)
What to build
Movement trait and harness, plus first movement module:
common_libs/movement_harness/):MovementModuleconcept withcomputeMove(state) → (speed, turnRate). Harness calls module every tick, applies to bot. No fitness selector yet — single module only. Interface designed for future selector.common_libs/movements/oscillator.nim): Perpendicular strafing relative to enemy bearing, periodic direction reversal.Wire into ModularBot. The bot now dodges instead of sitting still.
Acceptance criteria
Blocked by
#179 (T1)
Movement harness implemented and wired. Build passes.
Files created:
common_libs/movement_harness/movement_interface.nim—MoveCommandtuple type +isMovementModuleconcept, re-exportsWorldStatefrom gun_interfacecommon_libs/movements/oscillator.nim—OscillatorModule: perpendicular strafing (enemy bearing + 90°), reverses every 40 ticks or on wall proximity (<60px), speed ±8, turnRate clamped ±10°/tickModularBot.nim changes:
import movements/oscillatormover: OscillatorModulefieldonRoundStarted: resetsbot.mover = initOscillator()run(): replacessetTargetSpeed(0)/setTurnRate(0)withcomputeMove(lastState)output when contact is established; stationary while searchingNote: file was concurrently modified by another agent (radar harness already landed), changes merged on top of that state.
Done. Created
/common_libs/movements/phantom_meteor.nim— full gravity engine (danger histogram, phantom bullets, waves, wall forces) adapted as aMovementModule.Changes:
gun_interface.nim: addedenemyEnergyfield toWorldStatecommon_libs/movements/phantom_meteor.nim: new file —PhantomMeteorModulewithinitPhantomMeteor(),resetRound(),computeMove(state) → (speed, turnRate)ModularBot.nim: swapped oscillator → phantom_meteor;buildStatepassese.energy;onRoundStartedcallsbot.mover.resetRound()(histogram survives rounds, transients reset);isMainModuleinit updatedBuild: clean (
nimble buildexits 0).