@inventure71/paddockjs 4.1.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/INSTALL_AND_UPDATE.md +31 -5
  3. package/README.md +34 -3
  4. package/docs/advanced_ai_pace.md +131 -0
  5. package/docs/advanced_physics_rebuild.md +166 -0
  6. package/docs/architecture.md +111 -30
  7. package/docs/cleanup_coverage.md +284 -0
  8. package/docs/component_inventory.md +32 -16
  9. package/docs/composable-layouts.md +2 -0
  10. package/docs/concepts.md +12 -1
  11. package/docs/custom_model_controller.md +1 -1
  12. package/docs/data_contract.md +33 -10
  13. package/docs/data_model.md +4 -2
  14. package/docs/efficiency_cleanup_2026-10-13.md +80 -0
  15. package/docs/getting-started.md +3 -0
  16. package/docs/grid_walk.md +80 -0
  17. package/docs/index.md +5 -2
  18. package/docs/keyboard_driving_fix.md +118 -0
  19. package/docs/limit_driving_2026-10-14.md +88 -0
  20. package/docs/loading.md +141 -0
  21. package/docs/maintainability_audit_2026-09-08.md +146 -0
  22. package/docs/racing_ai_improvements.md +145 -0
  23. package/docs/rules.md +43 -13
  24. package/docs/sense_contract.md +4 -1
  25. package/docs/system_specs.md +40 -12
  26. package/docs/testing-reliability-guide.md +67 -0
  27. package/docs/v11_improvements.md +108 -0
  28. package/package.json +23 -15
  29. package/src/api/MountedSimulatorComponents.js +101 -0
  30. package/src/api/PaddockSimulatorController.js +56 -81
  31. package/src/app/BrowserExpertAdapter.js +0 -6
  32. package/src/app/BrowserExpertExternalRenderer.js +72 -50
  33. package/src/app/ExternalTrackSnapshot.js +50 -0
  34. package/src/app/F1SimulatorApp.js +242 -297
  35. package/src/app/HostLifecycleEmitter.js +93 -0
  36. package/src/app/banners/raceDataBannerController.js +9 -4
  37. package/src/app/camera/cameraConstants.js +1 -1
  38. package/src/app/camera/cameraController.js +10 -13
  39. package/src/app/camera/cameraGeometry.js +1 -1
  40. package/src/app/controls/SimulatorViewControls.js +45 -0
  41. package/src/app/controls/workbenchBindings.js +64 -0
  42. package/src/app/controls/workbenchDisclosure.js +41 -0
  43. package/src/app/domBindings.js +21 -13
  44. package/src/app/gridWalk/GridWalkController.js +180 -0
  45. package/src/app/gridWalk/gridWalkCamera.js +88 -0
  46. package/src/app/gridWalk/gridWalkControls.js +24 -0
  47. package/src/app/gridWalk/gridWalkCrew.js +246 -0
  48. package/src/app/gridWalk/gridWalkLabels.js +104 -0
  49. package/src/app/gridWalk/gridWalkLayout.js +46 -0
  50. package/src/app/gridWalk/gridWalkNavigation.js +99 -0
  51. package/src/app/gridWalk/gridWalkProjectBanner.js +43 -0
  52. package/src/app/gridWalk/gridWalkSession.js +50 -0
  53. package/src/app/layoutSupport.js +2 -0
  54. package/src/app/raceOverlayClearanceSupport.js +21 -7
  55. package/src/app/readouts/carOverviewRenderer.js +9 -4
  56. package/src/app/readouts/readoutFormatters.js +1 -8
  57. package/src/app/readouts/telemetryRenderer.js +1 -3
  58. package/src/app/readouts/timingTowerRenderer.js +48 -50
  59. package/src/app/rendering/appAssets.js +8 -10
  60. package/src/app/rendering/carRenderer.js +27 -79
  61. package/src/app/rendering/displayUtils.js +0 -6
  62. package/src/app/rendering/expertSensorRenderer.js +1 -1
  63. package/src/app/rendering/replayGhostRenderer.js +4 -1
  64. package/src/app/rendering/trackRenderer.js +2 -2
  65. package/src/app/runtime/frameLoop.js +18 -17
  66. package/src/app/runtime/pixiStartupLifecycle.js +94 -0
  67. package/src/app/runtime/runtimeTiming.js +4 -1
  68. package/src/app/runtime/runtimeVisibility.js +7 -2
  69. package/src/config/cssValues.js +1 -1
  70. package/src/config/defaultOptions.js +12 -173
  71. package/src/config/restartOptions.js +1 -0
  72. package/src/config/runtimeSeed.js +10 -0
  73. package/src/config/simulatorDefaults.js +106 -0
  74. package/src/config/telemetryModules.js +20 -0
  75. package/src/config/theme/cssTokens.js +85 -0
  76. package/src/config/theme/themeCss.js +72 -0
  77. package/src/config/theme/themeInputs.js +155 -0
  78. package/src/config/theme/themeResolver.js +172 -0
  79. package/src/config/theme/themeSelectors.js +69 -0
  80. package/src/config/theme/themeTokens.js +257 -0
  81. package/src/config/theme/themeUtils.js +15 -0
  82. package/src/config/themeOptions.js +14 -830
  83. package/src/config/timingGapMode.js +0 -2
  84. package/src/config/uiOptions.js +53 -0
  85. package/src/data/championship.js +16 -158
  86. package/src/data/championshipDefaults.js +87 -0
  87. package/src/data/driverData.js +10 -20
  88. package/src/data/entryIdentity.js +67 -0
  89. package/src/data/entryPresentation.js +23 -0
  90. package/src/data/entryTypes.d.ts +160 -0
  91. package/src/data/index.d.ts +12 -195
  92. package/src/data/ratingScale.js +14 -0
  93. package/src/data/teamTypes.d.ts +23 -0
  94. package/src/data/trackTypes.d.ts +101 -0
  95. package/src/data/vehicleData.js +12 -23
  96. package/src/environment/actions.js +3 -2
  97. package/src/environment/controllerLoop.js +57 -44
  98. package/src/environment/controllerScheduler.js +30 -0
  99. package/src/environment/driverObservations.js +260 -0
  100. package/src/environment/driverReset.js +51 -0
  101. package/src/environment/episode.js +0 -1
  102. package/src/environment/evaluation.js +6 -90
  103. package/src/environment/evaluationTracker.js +100 -0
  104. package/src/environment/events.js +23 -0
  105. package/src/environment/index.d.ts +35 -91
  106. package/src/environment/metrics.js +3 -17
  107. package/src/environment/observationSchema.js +104 -0
  108. package/src/environment/observationVector.js +16 -115
  109. package/src/environment/observations.js +16 -316
  110. package/src/environment/options.js +5 -24
  111. package/src/environment/renderFrames.js +21 -0
  112. package/src/environment/resetOptions.js +41 -0
  113. package/src/environment/results.js +125 -0
  114. package/src/environment/rewards.js +10 -16
  115. package/src/environment/runtime.js +17 -300
  116. package/src/environment/scenarioOptions.js +90 -0
  117. package/src/environment/scenarioPlacements.js +70 -0
  118. package/src/environment/scenarioPresets.js +78 -0
  119. package/src/environment/scenarios.js +5 -236
  120. package/src/environment/scratch.js +18 -0
  121. package/src/environment/sensorOptions.js +20 -0
  122. package/src/environment/sensors/index.js +2 -556
  123. package/src/environment/sensors/indexedRayBands.js +0 -18
  124. package/src/environment/sensors/nearbyCars.js +18 -15
  125. package/src/environment/sensors/opponentRadar.js +3 -2
  126. package/src/environment/sensors/pitConnectorProximity.js +20 -0
  127. package/src/environment/sensors/rayBandTrace.js +1 -37
  128. package/src/environment/sensors/rayBatch.js +81 -0
  129. package/src/environment/sensors/rayConfig.js +26 -0
  130. package/src/environment/sensors/rayGeometry.js +0 -8
  131. package/src/environment/sensors/rayGuards.js +0 -6
  132. package/src/environment/sensors/rayOutputs.js +75 -0
  133. package/src/environment/sensors/rayQuery.js +110 -0
  134. package/src/environment/sensors/rayScratch.js +146 -0
  135. package/src/environment/sensors/sensorTargets.js +12 -4
  136. package/src/environment/sensors/surfaceRays.js +6 -61
  137. package/src/environment/sensors/trackRays.js +7 -80
  138. package/src/environment/simulationSetup.js +30 -0
  139. package/src/environment/specs.js +15 -109
  140. package/src/index.d.ts +43 -202
  141. package/src/index.js +28 -6
  142. package/src/placeholder/index.js +1 -8
  143. package/src/rendering/displayLifecycle.js +6 -0
  144. package/src/rendering/proceduralTrackAsset.js +1 -1
  145. package/src/rendering/renderSnapshot.js +3 -0
  146. package/src/rendering/track/finishLineRenderer.js +1 -1
  147. package/src/rendering/track/gridRenderer.js +1 -1
  148. package/src/rendering/track/offsetStrokeSafety.js +2 -2
  149. package/src/rendering/track/pitLaneRenderer.js +1 -1
  150. package/src/rendering/track/trackMaterialRenderer.js +4 -4
  151. package/src/rendering/track/trackRenderConstants.js +0 -1
  152. package/src/rendering/track/trackRenderGeometry.js +1 -7
  153. package/src/simulation/collisionGeometry.js +12 -20
  154. package/src/simulation/driver/advancedPathControls.js +53 -0
  155. package/src/simulation/driver/advancedRacePace.js +112 -0
  156. package/src/simulation/driver/advancedRacingControls.js +61 -0
  157. package/src/simulation/driver/advancedRacingEnvelope.js +255 -0
  158. package/src/simulation/driver/advancedRacingSteering.js +76 -0
  159. package/src/simulation/driver/advancedRacingTiming.js +16 -0
  160. package/src/simulation/driver/arcadeRacePace.js +83 -0
  161. package/src/simulation/driver/arcadeRacingControls.js +111 -0
  162. package/src/simulation/driver/arcadeRacingEnvelope.js +63 -0
  163. package/src/simulation/driver/driverControlConstants.js +0 -2
  164. package/src/simulation/driver/driverController.js +16 -5
  165. package/src/simulation/driver/edgeRecovery.js +2 -3
  166. package/src/simulation/driver/racingControls.js +10 -396
  167. package/src/simulation/driver/racingDriverProfile.js +48 -0
  168. package/src/simulation/driver/racingLinePlan.js +54 -20
  169. package/src/simulation/driver/rejoinControls.js +59 -112
  170. package/src/simulation/driver/safetyCarControls.js +12 -0
  171. package/src/simulation/driver/trafficScan.js +136 -27
  172. package/src/simulation/participants/participantInteractions.js +24 -15
  173. package/src/simulation/pit/pitCarPlacement.js +29 -0
  174. package/src/simulation/pit/pitFlow.js +8 -30
  175. package/src/simulation/pit/pitIntent.js +4 -3
  176. package/src/simulation/pit/pitOccupancy.js +2 -2
  177. package/src/simulation/pit/pitQueue.js +2 -18
  178. package/src/simulation/pit/pitRouteMovement.js +1 -36
  179. package/src/simulation/pit/pitRouting.js +5 -81
  180. package/src/simulation/pit/pitService.js +3 -32
  181. package/src/simulation/pit/pitServiceConstants.js +1 -0
  182. package/src/simulation/pit/pitServiceProgress.js +34 -0
  183. package/src/simulation/pit/pitSnapshots.js +8 -4
  184. package/src/simulation/pit/pitState.js +1 -5
  185. package/src/simulation/race/classification.js +1 -8
  186. package/src/simulation/race/raceFinish.js +3 -8
  187. package/src/simulation/race/raceOrder.js +2 -13
  188. package/src/simulation/race/raceProgress.js +6 -20
  189. package/src/simulation/race/raceSetup.js +1 -1
  190. package/src/simulation/race/raceStep.js +20 -11
  191. package/src/simulation/race/redFlag.js +2 -4
  192. package/src/simulation/race/safetyCar.js +5 -9
  193. package/src/simulation/race/stalledDnf.js +2 -4
  194. package/src/simulation/raceSimulation.js +6 -38
  195. package/src/simulation/replay/replayGhosts.js +44 -32
  196. package/src/simulation/rules/collisionSteward.js +0 -14
  197. package/src/simulation/rules/penaltyActions.js +37 -0
  198. package/src/simulation/rules/penaltyLedger.js +8 -1
  199. package/src/simulation/rules/pitLaneSpeedingSteward.js +1 -1
  200. package/src/simulation/rules/rulesReview.js +20 -16
  201. package/src/simulation/rules/trackLimitsSteward.js +2 -2
  202. package/src/simulation/simMath.js +4 -0
  203. package/src/simulation/snapshots/raceSnapshots.js +30 -11
  204. package/src/simulation/timing/drsState.js +8 -0
  205. package/src/simulation/timing/drsTiming.js +2 -4
  206. package/src/simulation/timing/lapTelemetry.js +7 -4
  207. package/src/simulation/timing/sectorPerformance.js +14 -6
  208. package/src/simulation/timing/timingLines.js +12 -6
  209. package/src/simulation/track/pitLaneAccess.js +2 -2
  210. package/src/simulation/track/pitLaneLayout.js +4 -135
  211. package/src/simulation/track/pitLaneModel.js +70 -0
  212. package/src/simulation/track/pitLaneState.js +0 -1
  213. package/src/simulation/track/pitServiceLayout.js +121 -0
  214. package/src/simulation/track/proceduralTrack.js +77 -0
  215. package/src/simulation/track/spatialQueries.js +76 -31
  216. package/src/simulation/track/trackBuilder.js +54 -0
  217. package/src/simulation/track/trackConstants.js +0 -22
  218. package/src/simulation/track/trackMath.js +4 -29
  219. package/src/simulation/track/trackModel.js +12 -240
  220. package/src/simulation/track/trackModelCache.js +105 -0
  221. package/src/simulation/track/trackNearestQueries.js +1218 -0
  222. package/src/simulation/track/trackQueryConstants.js +3 -0
  223. package/src/simulation/track/trackQueryConstruction.js +368 -0
  224. package/src/simulation/track/trackQueryIndex.js +12 -1933
  225. package/src/simulation/track/trackQuerySegments.js +174 -0
  226. package/src/simulation/track/trackQueryStats.js +12 -0
  227. package/src/simulation/track/trackRayQueries.js +165 -0
  228. package/src/simulation/vehicle/advancedContactResponse.js +89 -0
  229. package/src/simulation/vehicle/advancedTireForces.js +92 -0
  230. package/src/simulation/vehicle/advancedVehicleModel.js +65 -0
  231. package/src/simulation/vehicle/advancedVehiclePhysics.js +127 -0
  232. package/src/simulation/vehicle/contactResolution.js +23 -9
  233. package/src/simulation/vehicle/mainTrackWheelSurface.js +2 -13
  234. package/src/simulation/vehicle/pitWheelSurface.js +0 -12
  235. package/src/simulation/vehicle/runoffResponse.js +2 -4
  236. package/src/simulation/vehicle/sampledWheelSurface.js +266 -0
  237. package/src/simulation/vehicle/vehicleGeometry.js +85 -103
  238. package/src/simulation/vehicle/vehicleKinematics.js +10 -0
  239. package/src/simulation/vehicle/vehiclePhysics.js +42 -196
  240. package/src/simulation/vehicle/vehicleSnapshots.js +18 -6
  241. package/src/simulation/vehicle/vehicleState.js +5 -3
  242. package/src/simulation/vehicle/wheelSurface.js +13 -432
  243. package/src/simulation/vehicle/wheelSurfaceCache.js +55 -0
  244. package/src/simulation/vehicle/wheelSurfaceSummary.js +101 -0
  245. package/src/styles.css +173 -19
  246. package/src/ui/bannerTemplates.js +4 -2
  247. package/src/ui/cameraControlsTemplate.js +4 -2
  248. package/src/ui/gridWalkTemplate.js +29 -0
  249. package/src/ui/htmlEscaping.js +8 -0
  250. package/src/ui/raceCanvasTemplate.js +3 -2
  251. package/src/ui/shellTemplate.js +3 -0
  252. package/src/ui/telemetryDrawerTemplate.js +4 -2
  253. package/src/ui/telemetryTemplates.js +3 -22
  254. package/src/ui/templateUtils.js +2 -8
  255. package/src/ui/viewControlsTemplate.js +21 -0
  256. package/examples/train-basic-policy.mjs +0 -276
  257. package/examples/trainingData.mjs +0 -133
@@ -1,276 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { createPaddockEnvironment, createProgressReward } from '@inventure71/paddockjs/environment';
4
- import { TRAINING_DEMO_DRIVERS, TRAINING_DEMO_ENTRIES } from './trainingData.mjs';
5
-
6
- const DEFAULT_OPTIONS = Object.freeze({
7
- generations: 4,
8
- candidates: 5,
9
- episodes: 1,
10
- steps: 240,
11
- frameSkip: 4,
12
- seed: 71,
13
- traffic: false,
14
- evalOnly: false,
15
- });
16
-
17
- const INITIAL_POLICY = Object.freeze({
18
- steeringHeading: -1.2,
19
- steeringOffset: -0.35,
20
- steeringRayBalance: 0.45,
21
- throttleBias: 0.72,
22
- throttleFrontClearance: 0.28,
23
- throttleSpeedDamping: 0.18,
24
- brakeBias: 0,
25
- brakeFrontDanger: 0.65,
26
- brakeOffTrack: 0.2,
27
- });
28
-
29
- const POLICY_KEYS = Object.keys(INITIAL_POLICY);
30
-
31
- main();
32
-
33
- function main() {
34
- const options = parseCliArgs(process.argv.slice(2));
35
- if (options.help) {
36
- printHelp();
37
- return;
38
- }
39
-
40
- const driverId = TRAINING_DEMO_DRIVERS[0].id;
41
- const rng = createSeededRandom(options.seed);
42
- const reward = createProgressReward();
43
- const evaluate = (policy, seedOffset = 0) => evaluatePolicy({
44
- policy,
45
- driverId,
46
- reward,
47
- options,
48
- seedOffset,
49
- });
50
-
51
- if (options.evalOnly) {
52
- const baseline = evaluate(INITIAL_POLICY);
53
- printSummary({ options, driverId, bestPolicy: INITIAL_POLICY, best: baseline });
54
- return;
55
- }
56
-
57
- let bestPolicy = { ...INITIAL_POLICY };
58
- let best = evaluate(bestPolicy);
59
-
60
- console.log(formatGenerationLine(0, best));
61
-
62
- for (let generation = 1; generation <= options.generations; generation += 1) {
63
- const mutationScale = 0.45 / Math.sqrt(generation);
64
- const candidates = [{ policy: bestPolicy, scoreSeedOffset: generation * 1000 }];
65
-
66
- for (let index = 1; index < options.candidates; index += 1) {
67
- candidates.push({
68
- policy: mutatePolicy(bestPolicy, rng, mutationScale),
69
- scoreSeedOffset: generation * 1000 + index * 100,
70
- });
71
- }
72
-
73
- for (const candidate of candidates) {
74
- const score = evaluate(candidate.policy, candidate.scoreSeedOffset);
75
- if (score.averageReward > best.averageReward) {
76
- best = score;
77
- bestPolicy = candidate.policy;
78
- }
79
- }
80
-
81
- console.log(formatGenerationLine(generation, best));
82
- }
83
-
84
- printSummary({ options, driverId, bestPolicy, best });
85
- }
86
-
87
- function evaluatePolicy({ policy, driverId, reward, options, seedOffset = 0 }) {
88
- let totalReward = 0;
89
- let totalDistanceMeters = 0;
90
- let totalCollisions = 0;
91
- let totalOffTrackSteps = 0;
92
- let completedEpisodes = 0;
93
-
94
- for (let episode = 0; episode < options.episodes; episode += 1) {
95
- const env = createTrainingEnvironment({ driverId, reward, options, episode, seedOffset });
96
- let result = env.reset();
97
- let episodeReward = 0;
98
-
99
- for (let step = 0; step < options.steps && !result.done; step += 1) {
100
- const observation = result.observation[driverId];
101
- const action = chooseAction(policy, observation);
102
- result = env.step({ [driverId]: action });
103
- episodeReward += result.reward?.[driverId] ?? 0;
104
- totalCollisions += result.events.filter((event) => event.type === 'collision').length;
105
- if (result.observation[driverId]?.object?.self?.onTrack === false) totalOffTrackSteps += 1;
106
- }
107
-
108
- const car = result.state.snapshot.cars.find((entry) => entry.id === driverId);
109
- totalReward += episodeReward;
110
- totalDistanceMeters += Number(car?.distanceMeters ?? 0);
111
- completedEpisodes += 1;
112
- env.destroy();
113
- }
114
-
115
- return {
116
- averageReward: totalReward / Math.max(1, completedEpisodes),
117
- averageDistanceMeters: totalDistanceMeters / Math.max(1, completedEpisodes),
118
- collisions: totalCollisions,
119
- offTrackSteps: totalOffTrackSteps,
120
- };
121
- }
122
-
123
- function createTrainingEnvironment({ driverId, reward, options, episode, seedOffset }) {
124
- const drivers = options.traffic ? TRAINING_DEMO_DRIVERS.slice(0, 8) : TRAINING_DEMO_DRIVERS.slice(0, 1);
125
- return createPaddockEnvironment({
126
- drivers,
127
- entries: TRAINING_DEMO_ENTRIES,
128
- controlledDrivers: [driverId],
129
- seed: options.seed + seedOffset + episode,
130
- trackSeed: options.seed + 2026 + seedOffset + episode,
131
- totalLaps: 3,
132
- frameSkip: options.frameSkip,
133
- scenario: {
134
- participants: options.traffic ? 'all' : 'controlled-only',
135
- nonControlled: 'ai',
136
- },
137
- episode: {
138
- maxSteps: options.steps,
139
- endOnRaceFinish: true,
140
- },
141
- rules: {
142
- standingStart: false,
143
- },
144
- reward,
145
- });
146
- }
147
-
148
- function chooseAction(policy, observation) {
149
- const self = observation.object.self;
150
- const frontRay = getRayDistance(observation, 0);
151
- const leftRay = getRayDistance(observation, -60);
152
- const rightRay = getRayDistance(observation, 60);
153
- const frontDanger = clamp01((35 - frontRay) / 35);
154
- const rayBalanceMeters = rightRay - leftRay;
155
-
156
- const steering = clamp(
157
- policy.steeringHeading * self.trackHeadingErrorRadians +
158
- policy.steeringOffset * (self.trackOffsetMeters / 12) +
159
- policy.steeringRayBalance * (rayBalanceMeters / 120),
160
- -1,
161
- 1,
162
- );
163
- const throttle = clamp01(
164
- policy.throttleBias +
165
- policy.throttleFrontClearance * (frontRay / 120) -
166
- policy.throttleSpeedDamping * (self.speedKph / 320) -
167
- (self.onTrack ? 0 : 0.35),
168
- );
169
- const brake = clamp01(
170
- policy.brakeBias +
171
- policy.brakeFrontDanger * frontDanger +
172
- (self.onTrack ? 0 : policy.brakeOffTrack),
173
- );
174
-
175
- return { steering, throttle, brake };
176
- }
177
-
178
- function getRayDistance(observation, angleDegrees) {
179
- const ray = observation.object.rays.find((entry) => entry.angleDegrees === angleDegrees);
180
- return Number(ray?.track?.distanceMeters ?? ray?.lengthMeters ?? 120);
181
- }
182
-
183
- function mutatePolicy(policy, rng, scale) {
184
- return Object.fromEntries(POLICY_KEYS.map((key) => [
185
- key,
186
- policy[key] + randomNormal(rng) * scale,
187
- ]));
188
- }
189
-
190
- function parseCliArgs(argv) {
191
- const options = { ...DEFAULT_OPTIONS };
192
-
193
- for (const arg of argv) {
194
- const [name, rawValue] = arg.split('=');
195
- if (name === '--help' || name === '-h') options.help = true;
196
- else if (name === '--eval-only') options.evalOnly = true;
197
- else if (name === '--traffic') options.traffic = true;
198
- else if (name === '--no-traffic') options.traffic = false;
199
- else if (name === '--generations') options.generations = parsePositiveInt(rawValue, name);
200
- else if (name === '--candidates') options.candidates = parsePositiveInt(rawValue, name);
201
- else if (name === '--episodes') options.episodes = parsePositiveInt(rawValue, name);
202
- else if (name === '--steps') options.steps = parsePositiveInt(rawValue, name);
203
- else if (name === '--frame-skip') options.frameSkip = parsePositiveInt(rawValue, name);
204
- else if (name === '--seed') options.seed = parsePositiveInt(rawValue, name);
205
- else throw new Error(`Unknown option: ${name}`);
206
- }
207
-
208
- return options;
209
- }
210
-
211
- function parsePositiveInt(value, optionName) {
212
- const parsed = Number.parseInt(value, 10);
213
- if (!Number.isFinite(parsed) || parsed <= 0) {
214
- throw new Error(`${optionName} requires a positive integer value.`);
215
- }
216
- return parsed;
217
- }
218
-
219
- function createSeededRandom(seed) {
220
- let state = seed >>> 0;
221
- return function random() {
222
- state += 0x6D2B79F5;
223
- let value = state;
224
- value = Math.imul(value ^ (value >>> 15), value | 1);
225
- value ^= value + Math.imul(value ^ (value >>> 7), value | 61);
226
- return ((value ^ (value >>> 14)) >>> 0) / 4294967296;
227
- };
228
- }
229
-
230
- function randomNormal(rng) {
231
- const a = Math.max(Number.EPSILON, rng());
232
- const b = Math.max(Number.EPSILON, rng());
233
- return Math.sqrt(-2 * Math.log(a)) * Math.cos(2 * Math.PI * b);
234
- }
235
-
236
- function clamp(value, min, max) {
237
- return Math.min(max, Math.max(min, value));
238
- }
239
-
240
- function clamp01(value) {
241
- return clamp(value, 0, 1);
242
- }
243
-
244
- function formatGenerationLine(generation, score) {
245
- return [
246
- `generation=${generation}`,
247
- `reward=${score.averageReward.toFixed(2)}`,
248
- `distanceMeters=${score.averageDistanceMeters.toFixed(1)}`,
249
- `collisions=${score.collisions}`,
250
- `offTrackSteps=${score.offTrackSteps}`,
251
- ].join(' ');
252
- }
253
-
254
- function printSummary({ options, driverId, bestPolicy, best }) {
255
- console.log(JSON.stringify({
256
- driverId,
257
- options,
258
- best,
259
- bestPolicy,
260
- }, null, 2));
261
- }
262
-
263
- function printHelp() {
264
- console.log(`Usage: node examples/train-basic-policy.mjs [options]
265
-
266
- Options:
267
- --generations=N Random-search generations. Default: ${DEFAULT_OPTIONS.generations}
268
- --candidates=N Candidate policies per generation. Default: ${DEFAULT_OPTIONS.candidates}
269
- --episodes=N Episodes per policy evaluation. Default: ${DEFAULT_OPTIONS.episodes}
270
- --steps=N Maximum manual environment steps per episode. Default: ${DEFAULT_OPTIONS.steps}
271
- --frame-skip=N Simulator frames advanced by each step(action). Default: ${DEFAULT_OPTIONS.frameSkip}
272
- --seed=N Deterministic random seed. Default: ${DEFAULT_OPTIONS.seed}
273
- --traffic Keep built-in AI traffic on track during training.
274
- --eval-only Evaluate the starter policy without training.
275
- `);
276
- }
@@ -1,133 +0,0 @@
1
- export const TRAINING_DEMO_DRIVERS = [
2
- {
3
- id: 'budget',
4
- code: 'BUD',
5
- icon: 'BB',
6
- name: 'Budget Buddy',
7
- color: '#ff2d55',
8
- tire: 'M',
9
- raceData: ['AI finance coach', 'Python + LLM', 'Budget guardrails'],
10
- },
11
- {
12
- id: 'noir',
13
- code: 'NOI',
14
- icon: 'NN',
15
- name: 'Neural Noir',
16
- color: '#ffb000',
17
- tire: 'M',
18
- raceData: ['Procedural mystery', 'Gemini storytelling', 'Unreal loop'],
19
- },
20
- {
21
- id: 'vinyl',
22
- code: 'HOL',
23
- icon: 'HV',
24
- name: 'HoloVinyl',
25
- color: '#00c2a8',
26
- tire: 'H',
27
- raceData: ['Touchless DJ control', 'Computer vision', 'Hand tracking'],
28
- },
29
- {
30
- id: 'drsorriso',
31
- code: 'DRS',
32
- icon: 'DR',
33
- name: 'DrSorrisoDonations',
34
- color: '#e10600',
35
- tire: 'S',
36
- raceData: ['Donation intake', 'Database workflow', 'Automation tool'],
37
- },
38
- {
39
- id: 'victoria',
40
- code: 'VIC',
41
- icon: 'VI',
42
- name: 'VictorIA',
43
- color: '#00a3ff',
44
- tire: 'M',
45
- raceData: ['Game AI sandbox', 'Robotics ideas', 'Vision systems'],
46
- },
47
- {
48
- id: 'reminderz',
49
- code: 'REM',
50
- icon: 'RZ',
51
- name: 'ReminderZ',
52
- color: '#a3e635',
53
- tire: 'H',
54
- raceData: ['Knowledge workflow', 'Personal graph', 'Capture tool'],
55
- },
56
- {
57
- id: 'clipclop',
58
- code: 'CLP',
59
- icon: 'CC',
60
- name: 'ClipClop',
61
- color: '#f97316',
62
- tire: 'S',
63
- raceData: ['Mac + Android sync', 'Local clipboard', 'Productivity app'],
64
- },
65
- {
66
- id: 'core',
67
- code: 'COR',
68
- icon: 'AI',
69
- name: 'Core Conflict',
70
- color: '#38bdf8',
71
- tire: 'M',
72
- raceData: ['Runtime AI agents', 'Multiplayer state', 'Game systems'],
73
- },
74
- ];
75
-
76
- export const TRAINING_DEMO_ENTRIES = [
77
- {
78
- driverId: 'budget',
79
- driverNumber: 71,
80
- timingName: 'Budget',
81
- driver: { pace: 52, racecraft: 74, aggression: 38, riskTolerance: 47, patience: 81, consistency: 86 },
82
- vehicle: { id: 'budget-bb01', name: 'BB-01 Ledger', power: 48, braking: 72, aero: 55, dragEfficiency: 66, mechanicalGrip: 63, weightControl: 58, tireCare: 82 },
83
- },
84
- {
85
- driverId: 'noir',
86
- driverNumber: 13,
87
- timingName: 'Noir',
88
- driver: { pace: 68, racecraft: 83, aggression: 61, riskTolerance: 72, patience: 57, consistency: 64 },
89
- vehicle: { id: 'noir-nn13', name: 'NN-13 Shadow', power: 64, braking: 60, aero: 73, dragEfficiency: 57, mechanicalGrip: 69, weightControl: 54, tireCare: 51 },
90
- },
91
- {
92
- driverId: 'vinyl',
93
- driverNumber: 33,
94
- timingName: 'HoloVinyl',
95
- driver: { pace: 71, racecraft: 66, aggression: 52, riskTolerance: 59, patience: 62, consistency: 58 },
96
- vehicle: { id: 'vinyl-hv33', name: 'HV-33 Groove', power: 70, braking: 49, aero: 58, dragEfficiency: 74, mechanicalGrip: 52, weightControl: 68, tireCare: 46 },
97
- },
98
- {
99
- driverId: 'drsorriso',
100
- driverNumber: 55,
101
- timingName: 'DrSorriso',
102
- driver: { pace: 46, racecraft: 69, aggression: 44, riskTolerance: 43, patience: 76, consistency: 73 },
103
- vehicle: { id: 'sorriso-ds55', name: 'DS-55 Intake', power: 54, braking: 67, aero: 62, dragEfficiency: 49, mechanicalGrip: 71, weightControl: 45, tireCare: 69 },
104
- },
105
- {
106
- driverId: 'victoria',
107
- driverNumber: 11,
108
- timingName: 'VictorIA',
109
- driver: { pace: 78, racecraft: 79, aggression: 58, riskTolerance: 65, patience: 55, consistency: 68 },
110
- vehicle: { id: 'victoria-vi11', name: 'VI-11 Vector', power: 76, braking: 58, aero: 65, dragEfficiency: 63, mechanicalGrip: 61, weightControl: 60, tireCare: 48 },
111
- },
112
- {
113
- driverId: 'reminderz',
114
- driverNumber: 7,
115
- timingName: 'ReminderZ',
116
- driver: { pace: 41, racecraft: 61, aggression: 34, riskTolerance: 39, patience: 85, consistency: 80 },
117
- vehicle: { id: 'reminderz-rz07', name: 'RZ-07 Recall', power: 42, braking: 76, aero: 50, dragEfficiency: 72, mechanicalGrip: 58, weightControl: 63, tireCare: 88 },
118
- },
119
- {
120
- driverId: 'clipclop',
121
- driverNumber: 14,
122
- timingName: 'ClipClop',
123
- driver: { pace: 73, racecraft: 88, aggression: 76, riskTolerance: 78, patience: 48, consistency: 61 },
124
- vehicle: { id: 'clipclop-cc14', name: 'CC-14 Sync', power: 68, braking: 63, aero: 59, dragEfficiency: 61, mechanicalGrip: 78, weightControl: 56, tireCare: 44 },
125
- },
126
- {
127
- driverId: 'core',
128
- driverNumber: 91,
129
- timingName: 'Core',
130
- driver: { pace: 82, racecraft: 85, aggression: 67, riskTolerance: 74, patience: 53, consistency: 72 },
131
- vehicle: { id: 'core-ai91', name: 'AI-91 Core', power: 80, braking: 61, aero: 72, dragEfficiency: 59, mechanicalGrip: 75, weightControl: 51, tireCare: 50 },
132
- },
133
- ];