@inventure71/paddockjs 4.2.0 → 4.3.1

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 (249) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/INSTALL_AND_UPDATE.md +24 -4
  3. package/README.md +31 -2
  4. package/docs/advanced_ai_pace.md +131 -0
  5. package/docs/advanced_physics_rebuild.md +166 -0
  6. package/docs/architecture.md +109 -30
  7. package/docs/cleanup_coverage.md +284 -0
  8. package/docs/component_inventory.md +31 -15
  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/grid_walk.md +84 -0
  16. package/docs/index.md +1 -0
  17. package/docs/keyboard_driving_fix.md +118 -0
  18. package/docs/limit_driving_2026-10-14.md +88 -0
  19. package/docs/maintainability_audit_2026-09-08.md +146 -0
  20. package/docs/racing_ai_improvements.md +145 -0
  21. package/docs/rules.md +43 -13
  22. package/docs/sense_contract.md +4 -1
  23. package/docs/system_specs.md +38 -11
  24. package/docs/testing-reliability-guide.md +5 -0
  25. package/docs/v11_improvements.md +108 -0
  26. package/package.json +24 -13
  27. package/src/api/MountedSimulatorComponents.js +101 -0
  28. package/src/api/PaddockSimulatorController.js +56 -81
  29. package/src/app/BrowserExpertAdapter.js +0 -6
  30. package/src/app/BrowserExpertExternalRenderer.js +72 -50
  31. package/src/app/ExternalTrackSnapshot.js +50 -0
  32. package/src/app/F1SimulatorApp.js +242 -297
  33. package/src/app/HostLifecycleEmitter.js +93 -0
  34. package/src/app/banners/raceDataBannerController.js +9 -4
  35. package/src/app/camera/cameraConstants.js +1 -1
  36. package/src/app/camera/cameraController.js +10 -13
  37. package/src/app/camera/cameraGeometry.js +1 -1
  38. package/src/app/controls/SimulatorViewControls.js +45 -0
  39. package/src/app/controls/workbenchBindings.js +64 -0
  40. package/src/app/controls/workbenchDisclosure.js +41 -0
  41. package/src/app/domBindings.js +21 -13
  42. package/src/app/gridWalk/GridWalkController.js +180 -0
  43. package/src/app/gridWalk/gridWalkCamera.js +88 -0
  44. package/src/app/gridWalk/gridWalkControls.js +24 -0
  45. package/src/app/gridWalk/gridWalkCrew.js +246 -0
  46. package/src/app/gridWalk/gridWalkLabels.js +104 -0
  47. package/src/app/gridWalk/gridWalkLayout.js +46 -0
  48. package/src/app/gridWalk/gridWalkNavigation.js +106 -0
  49. package/src/app/gridWalk/gridWalkProjectBanner.js +43 -0
  50. package/src/app/gridWalk/gridWalkSession.js +50 -0
  51. package/src/app/layoutSupport.js +2 -0
  52. package/src/app/raceOverlayClearanceSupport.js +21 -7
  53. package/src/app/readouts/carOverviewRenderer.js +9 -4
  54. package/src/app/readouts/readoutFormatters.js +1 -8
  55. package/src/app/readouts/telemetryRenderer.js +1 -3
  56. package/src/app/readouts/timingTowerRenderer.js +48 -50
  57. package/src/app/rendering/appAssets.js +8 -10
  58. package/src/app/rendering/carRenderer.js +27 -79
  59. package/src/app/rendering/displayUtils.js +0 -6
  60. package/src/app/rendering/expertSensorRenderer.js +1 -1
  61. package/src/app/rendering/replayGhostRenderer.js +4 -1
  62. package/src/app/rendering/trackRenderer.js +2 -2
  63. package/src/app/runtime/frameLoop.js +18 -17
  64. package/src/app/runtime/pixiStartupLifecycle.js +94 -0
  65. package/src/app/runtime/runtimeTiming.js +4 -1
  66. package/src/app/runtime/runtimeVisibility.js +7 -2
  67. package/src/config/cssValues.js +1 -1
  68. package/src/config/defaultOptions.js +12 -173
  69. package/src/config/restartOptions.js +1 -0
  70. package/src/config/runtimeSeed.js +10 -0
  71. package/src/config/simulatorDefaults.js +106 -0
  72. package/src/config/telemetryModules.js +20 -0
  73. package/src/config/theme/cssTokens.js +85 -0
  74. package/src/config/theme/themeCss.js +72 -0
  75. package/src/config/theme/themeInputs.js +155 -0
  76. package/src/config/theme/themeResolver.js +172 -0
  77. package/src/config/theme/themeSelectors.js +69 -0
  78. package/src/config/theme/themeTokens.js +257 -0
  79. package/src/config/theme/themeUtils.js +15 -0
  80. package/src/config/themeOptions.js +14 -830
  81. package/src/config/timingGapMode.js +0 -2
  82. package/src/config/uiOptions.js +53 -0
  83. package/src/data/championship.js +16 -158
  84. package/src/data/championshipDefaults.js +87 -0
  85. package/src/data/driverData.js +10 -20
  86. package/src/data/entryIdentity.js +67 -0
  87. package/src/data/entryPresentation.js +23 -0
  88. package/src/data/entryTypes.d.ts +160 -0
  89. package/src/data/index.d.ts +13 -259
  90. package/src/data/ratingScale.js +14 -0
  91. package/src/data/teamTypes.d.ts +23 -0
  92. package/src/data/trackTypes.d.ts +101 -0
  93. package/src/data/vehicleData.js +12 -23
  94. package/src/environment/actions.js +3 -2
  95. package/src/environment/controllerLoop.js +57 -44
  96. package/src/environment/controllerScheduler.js +30 -0
  97. package/src/environment/driverObservations.js +260 -0
  98. package/src/environment/driverReset.js +51 -0
  99. package/src/environment/episode.js +0 -1
  100. package/src/environment/evaluation.js +6 -90
  101. package/src/environment/evaluationTracker.js +100 -0
  102. package/src/environment/events.js +23 -0
  103. package/src/environment/index.d.ts +21 -140
  104. package/src/environment/metrics.js +3 -17
  105. package/src/environment/observationSchema.js +104 -0
  106. package/src/environment/observationVector.js +16 -115
  107. package/src/environment/observations.js +16 -316
  108. package/src/environment/options.js +5 -24
  109. package/src/environment/renderFrames.js +21 -0
  110. package/src/environment/resetOptions.js +41 -0
  111. package/src/environment/results.js +125 -0
  112. package/src/environment/rewards.js +10 -16
  113. package/src/environment/runtime.js +17 -300
  114. package/src/environment/scenarioOptions.js +90 -0
  115. package/src/environment/scenarioPlacements.js +70 -0
  116. package/src/environment/scenarioPresets.js +78 -0
  117. package/src/environment/scenarios.js +5 -236
  118. package/src/environment/scratch.js +18 -0
  119. package/src/environment/sensorOptions.js +20 -0
  120. package/src/environment/sensors/index.js +2 -556
  121. package/src/environment/sensors/indexedRayBands.js +0 -18
  122. package/src/environment/sensors/nearbyCars.js +18 -15
  123. package/src/environment/sensors/opponentRadar.js +3 -2
  124. package/src/environment/sensors/pitConnectorProximity.js +20 -0
  125. package/src/environment/sensors/rayBandTrace.js +1 -37
  126. package/src/environment/sensors/rayBatch.js +81 -0
  127. package/src/environment/sensors/rayConfig.js +26 -0
  128. package/src/environment/sensors/rayGeometry.js +0 -8
  129. package/src/environment/sensors/rayGuards.js +0 -6
  130. package/src/environment/sensors/rayOutputs.js +75 -0
  131. package/src/environment/sensors/rayQuery.js +110 -0
  132. package/src/environment/sensors/rayScratch.js +146 -0
  133. package/src/environment/sensors/sensorTargets.js +12 -4
  134. package/src/environment/sensors/surfaceRays.js +6 -61
  135. package/src/environment/sensors/trackRays.js +7 -80
  136. package/src/environment/simulationSetup.js +30 -0
  137. package/src/environment/specs.js +15 -109
  138. package/src/index.d.ts +34 -259
  139. package/src/index.js +28 -6
  140. package/src/placeholder/index.js +1 -8
  141. package/src/rendering/displayLifecycle.js +6 -0
  142. package/src/rendering/proceduralTrackAsset.js +1 -1
  143. package/src/rendering/renderSnapshot.js +3 -0
  144. package/src/rendering/track/finishLineRenderer.js +1 -1
  145. package/src/rendering/track/gridRenderer.js +1 -1
  146. package/src/rendering/track/offsetStrokeSafety.js +2 -2
  147. package/src/rendering/track/pitLaneRenderer.js +1 -1
  148. package/src/rendering/track/trackMaterialRenderer.js +4 -4
  149. package/src/rendering/track/trackRenderConstants.js +0 -1
  150. package/src/rendering/track/trackRenderGeometry.js +1 -7
  151. package/src/simulation/collisionGeometry.js +5 -11
  152. package/src/simulation/driver/advancedPathControls.js +53 -0
  153. package/src/simulation/driver/advancedRacePace.js +112 -0
  154. package/src/simulation/driver/advancedRacingControls.js +61 -0
  155. package/src/simulation/driver/advancedRacingEnvelope.js +255 -0
  156. package/src/simulation/driver/advancedRacingSteering.js +76 -0
  157. package/src/simulation/driver/advancedRacingTiming.js +16 -0
  158. package/src/simulation/driver/arcadeRacePace.js +83 -0
  159. package/src/simulation/driver/arcadeRacingControls.js +111 -0
  160. package/src/simulation/driver/arcadeRacingEnvelope.js +63 -0
  161. package/src/simulation/driver/driverControlConstants.js +0 -2
  162. package/src/simulation/driver/driverController.js +14 -3
  163. package/src/simulation/driver/edgeRecovery.js +0 -1
  164. package/src/simulation/driver/racingControls.js +10 -406
  165. package/src/simulation/driver/racingDriverProfile.js +48 -0
  166. package/src/simulation/driver/racingLinePlan.js +48 -15
  167. package/src/simulation/driver/rejoinControls.js +58 -111
  168. package/src/simulation/driver/safetyCarControls.js +12 -0
  169. package/src/simulation/driver/trafficScan.js +89 -6
  170. package/src/simulation/pit/pitCarPlacement.js +29 -0
  171. package/src/simulation/pit/pitFlow.js +8 -30
  172. package/src/simulation/pit/pitIntent.js +4 -3
  173. package/src/simulation/pit/pitOccupancy.js +2 -2
  174. package/src/simulation/pit/pitQueue.js +2 -18
  175. package/src/simulation/pit/pitRouteMovement.js +1 -36
  176. package/src/simulation/pit/pitRouting.js +5 -81
  177. package/src/simulation/pit/pitService.js +3 -32
  178. package/src/simulation/pit/pitServiceConstants.js +1 -0
  179. package/src/simulation/pit/pitServiceProgress.js +34 -0
  180. package/src/simulation/pit/pitSnapshots.js +8 -4
  181. package/src/simulation/pit/pitState.js +1 -5
  182. package/src/simulation/race/classification.js +1 -8
  183. package/src/simulation/race/raceFinish.js +3 -8
  184. package/src/simulation/race/raceOrder.js +2 -13
  185. package/src/simulation/race/raceProgress.js +6 -20
  186. package/src/simulation/race/raceSetup.js +1 -1
  187. package/src/simulation/race/raceStep.js +1 -1
  188. package/src/simulation/race/redFlag.js +2 -4
  189. package/src/simulation/race/safetyCar.js +3 -8
  190. package/src/simulation/race/stalledDnf.js +2 -4
  191. package/src/simulation/raceSimulation.js +6 -38
  192. package/src/simulation/replay/replayGhosts.js +44 -32
  193. package/src/simulation/rules/collisionSteward.js +0 -14
  194. package/src/simulation/rules/penaltyActions.js +37 -0
  195. package/src/simulation/rules/penaltyLedger.js +8 -1
  196. package/src/simulation/rules/rulesReview.js +1 -7
  197. package/src/simulation/simMath.js +4 -0
  198. package/src/simulation/snapshots/raceSnapshots.js +30 -11
  199. package/src/simulation/timing/drsState.js +8 -0
  200. package/src/simulation/timing/drsTiming.js +2 -4
  201. package/src/simulation/timing/lapTelemetry.js +7 -4
  202. package/src/simulation/timing/sectorPerformance.js +3 -3
  203. package/src/simulation/timing/timingLines.js +12 -6
  204. package/src/simulation/track/pitLaneAccess.js +2 -2
  205. package/src/simulation/track/pitLaneLayout.js +4 -135
  206. package/src/simulation/track/pitLaneModel.js +70 -0
  207. package/src/simulation/track/pitLaneState.js +0 -1
  208. package/src/simulation/track/pitServiceLayout.js +121 -0
  209. package/src/simulation/track/proceduralTrack.js +77 -0
  210. package/src/simulation/track/spatialQueries.js +1 -25
  211. package/src/simulation/track/trackBuilder.js +54 -0
  212. package/src/simulation/track/trackConstants.js +0 -22
  213. package/src/simulation/track/trackMath.js +4 -29
  214. package/src/simulation/track/trackModel.js +4 -241
  215. package/src/simulation/track/trackModelCache.js +105 -0
  216. package/src/simulation/track/trackNearestQueries.js +1218 -0
  217. package/src/simulation/track/trackQueryConstants.js +3 -0
  218. package/src/simulation/track/trackQueryConstruction.js +368 -0
  219. package/src/simulation/track/trackQueryIndex.js +12 -1933
  220. package/src/simulation/track/trackQuerySegments.js +174 -0
  221. package/src/simulation/track/trackQueryStats.js +12 -0
  222. package/src/simulation/track/trackRayQueries.js +165 -0
  223. package/src/simulation/vehicle/advancedContactResponse.js +89 -0
  224. package/src/simulation/vehicle/advancedTireForces.js +92 -0
  225. package/src/simulation/vehicle/advancedVehicleModel.js +65 -0
  226. package/src/simulation/vehicle/advancedVehiclePhysics.js +127 -0
  227. package/src/simulation/vehicle/contactResolution.js +20 -6
  228. package/src/simulation/vehicle/mainTrackWheelSurface.js +2 -13
  229. package/src/simulation/vehicle/pitWheelSurface.js +0 -12
  230. package/src/simulation/vehicle/runoffResponse.js +2 -4
  231. package/src/simulation/vehicle/sampledWheelSurface.js +266 -0
  232. package/src/simulation/vehicle/vehicleGeometry.js +0 -56
  233. package/src/simulation/vehicle/vehicleKinematics.js +10 -0
  234. package/src/simulation/vehicle/vehiclePhysics.js +35 -194
  235. package/src/simulation/vehicle/vehicleSnapshots.js +13 -4
  236. package/src/simulation/vehicle/vehicleState.js +2 -1
  237. package/src/simulation/vehicle/wheelSurface.js +13 -432
  238. package/src/simulation/vehicle/wheelSurfaceCache.js +55 -0
  239. package/src/simulation/vehicle/wheelSurfaceSummary.js +101 -0
  240. package/src/styles.css +173 -19
  241. package/src/ui/bannerTemplates.js +4 -2
  242. package/src/ui/cameraControlsTemplate.js +4 -2
  243. package/src/ui/gridWalkTemplate.js +29 -0
  244. package/src/ui/htmlEscaping.js +8 -0
  245. package/src/ui/shellTemplate.js +3 -0
  246. package/src/ui/telemetryDrawerTemplate.js +4 -2
  247. package/src/ui/telemetryTemplates.js +3 -22
  248. package/src/ui/templateUtils.js +2 -8
  249. package/src/ui/viewControlsTemplate.js +21 -0
@@ -1,262 +1,16 @@
1
- export type TireCompound = 'S' | 'M' | 'H';
2
- export type PaddockProceduralTrackProfile = 'race' | 'training-short' | 'training-medium' | 'training-technical';
3
-
4
- export interface PaddockProceduralTrackOptions {
5
- profile?: PaddockProceduralTrackProfile;
6
- minLengthMeters?: number;
7
- maxLengthMeters?: number;
8
- startStraightMeters?: number;
9
- includePitLane?: boolean;
10
- length?: {
11
- minMeters?: number;
12
- maxMeters?: number;
13
- };
14
- startStraight?: {
15
- gridMeters?: number;
16
- exitMeters?: number;
17
- blendMeters?: number;
18
- lockExtraMeters?: number;
19
- };
20
- pitLane?: {
21
- enabled?: boolean;
22
- };
23
- shape?: {
24
- scale?: number;
25
- cornerDensity?: number;
26
- variation?: number;
27
- };
28
- validation?: {
29
- minClearanceMultiplier?: number;
30
- minShapeVariation?: number;
31
- minNonAdjacentArcMeters?: number;
32
- maxLocalTurnRadians?: number;
33
- maxSampleHeadingDeltaRadians?: number;
34
- };
35
- attempts?: {
36
- primary?: number;
37
- fallback?: number;
38
- };
39
- }
40
-
41
- export interface PaddockTrackPoint {
42
- x: number;
43
- y: number;
44
- }
45
-
46
- export interface PaddockDrsZone {
47
- id: string;
48
- startRatio: number;
49
- endRatio: number;
50
- }
51
-
52
- export interface PaddockResolvedProceduralTrackOptions {
53
- profile: PaddockProceduralTrackProfile;
54
- length: {
55
- min: number;
56
- max: number;
57
- };
58
- startStraight: {
59
- grid: number;
60
- exit: number;
61
- blend: number;
62
- lockExtra: number;
63
- };
64
- pitLane: {
65
- enabled: boolean;
66
- };
67
- shape: {
68
- scale: number;
69
- cornerDensity: number;
70
- variation: number;
71
- };
72
- validation: {
73
- minClearanceMultiplier: number;
74
- minShapeVariation: number;
75
- minNonAdjacentArcDistance: number;
76
- maxLocalTurnRadians: number;
77
- maxSampleHeadingDeltaRadians: number;
78
- };
79
- attempts: {
80
- primary: number;
81
- fallback: number;
82
- };
83
- cacheKey: string;
84
- [key: string]: unknown;
85
- }
86
-
87
- export interface PaddockProceduralTrack {
88
- name: string;
89
- width: number;
90
- kerbWidth: number;
91
- gravelWidth: number;
92
- runoffWidth: number;
93
- barrierWidth: number;
94
- sampleCount: number;
95
- seed?: number;
96
- curveInterpolation?: string;
97
- centerlineControls?: readonly PaddockTrackPoint[];
98
- drsZones?: readonly PaddockDrsZone[] | null;
99
- pitLane?: { enabled?: boolean } | null;
100
- generationOptions?: PaddockResolvedProceduralTrackOptions;
101
- [key: string]: unknown;
102
- }
103
-
104
- export interface CustomField {
105
- label: string;
106
- value: string;
107
- }
108
-
109
- export type CustomFieldInput = CustomField[] | Record<string, string>;
110
- export type PaddockThemeSelector = 'default' | 'active' | 'selectedTeam' | 'team' | `team:${string}` | string;
111
-
112
- export interface PaddockPitCrewStats {
113
- speed?: number;
114
- consistency?: number;
115
- reliability?: number;
116
- }
117
-
118
- export interface TeamData {
119
- id?: string;
120
- name?: string;
121
- color?: string;
122
- icon?: string;
123
- theme?: PaddockThemeSelector;
124
- pitCrew?: PaddockPitCrewStats;
125
- pitCrewStats?: PaddockPitCrewStats;
126
- }
127
-
128
- export interface SimulatorDriver {
129
- id: string;
130
- name: string;
131
- color: string;
132
- link?: string;
133
- icon?: string;
134
- code?: string;
135
- timingName?: string;
136
- tire?: TireCompound;
137
- raceData?: string[];
138
- customFields?: CustomFieldInput;
139
- team?: TeamData | null;
140
- driverNumber?: number;
141
- }
142
-
143
- export interface DriverRatings {
144
- pace: number;
145
- racecraft: number;
146
- aggression: number;
147
- riskTolerance: number;
148
- patience: number;
149
- consistency: number;
150
- }
151
-
152
- export interface VehicleRatings {
153
- power: number;
154
- braking: number;
155
- aero: number;
156
- dragEfficiency: number;
157
- mechanicalGrip: number;
158
- weightControl: number;
159
- tireCare: number;
160
- }
161
-
162
- export interface DriverBlueprint extends Partial<DriverRatings> {
163
- customFields?: CustomFieldInput;
164
- }
165
-
166
- export interface VehicleBlueprint extends Partial<VehicleRatings> {
167
- id?: string | null;
168
- name?: string | null;
169
- customFields?: CustomFieldInput;
170
- }
171
-
172
- export interface DriverConstructorArgs {
173
- ratings: DriverRatings;
174
- customFields: CustomField[];
175
- pace: number;
176
- racecraft: number;
177
- consistency: number;
178
- personality: {
179
- aggression: number;
180
- riskTolerance: number;
181
- patience: number;
182
- };
183
- }
184
-
185
- export interface VehicleConstructorArgs {
186
- id: string | null;
187
- name: string | null;
188
- ratings: VehicleRatings;
189
- customFields: CustomField[];
190
- powerNewtons: number;
191
- brakeNewtons: number;
192
- downforceCoefficient: number;
193
- dragCoefficient: number;
194
- tireGrip: number;
195
- mass: number;
196
- tireCare: number;
197
- }
198
-
199
- export class DriverData {
200
- constructor(input?: DriverBlueprint);
201
- readonly pace: number;
202
- readonly racecraft: number;
203
- readonly aggression: number;
204
- readonly riskTolerance: number;
205
- readonly patience: number;
206
- readonly consistency: number;
207
- readonly customFields: CustomField[];
208
- ratings(): DriverRatings;
209
- toConstructorArgs(): DriverConstructorArgs;
210
- }
211
-
212
- export class VehicleData {
213
- constructor(input?: VehicleBlueprint);
214
- readonly id: string | null;
215
- readonly name: string | null;
216
- readonly power: number;
217
- readonly braking: number;
218
- readonly aero: number;
219
- readonly dragEfficiency: number;
220
- readonly mechanicalGrip: number;
221
- readonly weightControl: number;
222
- readonly tireCare: number;
223
- readonly customFields: CustomField[];
224
- ratings(): VehicleRatings;
225
- toConstructorArgs(): VehicleConstructorArgs;
226
- }
227
-
228
- export interface ChampionshipEntryBlueprint {
229
- driverId: string;
230
- driverNumber?: number;
231
- timingName?: string;
232
- driver?: DriverData | DriverBlueprint;
233
- vehicle?: VehicleData | VehicleBlueprint;
234
- team?: TeamData;
235
- }
236
-
237
- export interface NormalizedSimulatorDriver extends SimulatorDriver {
238
- code: string;
239
- timingCode: string;
240
- raceName: string;
241
- driverNumber: number;
242
- team: TeamData | null;
243
- pace: number;
244
- racecraft: number;
245
- consistency: number;
246
- personality: DriverConstructorArgs['personality'];
247
- vehicle: VehicleConstructorArgs;
248
- constructorArgs: {
249
- driver: DriverConstructorArgs;
250
- vehicle: VehicleConstructorArgs;
251
- };
252
- championship: {
253
- id: string;
254
- name: string;
255
- season: number;
256
- entryIndex: number;
257
- vehicleId: string | null;
258
- };
259
- }
1
+ import type { TeamData } from './teamTypes.js';
2
+
3
+ export type {
4
+ PaddockPitCrewStats,
5
+ PaddockThemeSelector,
6
+ TeamData,
7
+ } from './teamTypes.js';
8
+
9
+ import type { PaddockProceduralTrackProfile, PaddockProceduralTrackOptions, PaddockTrackPoint, PaddockDrsZone, PaddockResolvedProceduralTrackOptions, PaddockProceduralTrack } from './trackTypes.js';
10
+ import type { TireCompound, CustomField, CustomFieldInput, EntryPresentation, SimulatorDriver, DriverRatings, VehicleRatings, DriverBlueprint, VehicleBlueprint, DriverConstructorArgs, VehicleConstructorArgs, DriverData, VehicleData, ChampionshipEntryBlueprint, NormalizedSimulatorDriver } from './entryTypes.js';
11
+ export type { PaddockProceduralTrackProfile, PaddockProceduralTrackOptions, PaddockTrackPoint, PaddockDrsZone, PaddockResolvedProceduralTrackOptions, PaddockProceduralTrack } from './trackTypes.js';
12
+ export type { TireCompound, CustomField, CustomFieldInput, EntryPresentation, SimulatorDriver, DriverRatings, VehicleRatings, DriverBlueprint, VehicleBlueprint, DriverConstructorArgs, VehicleConstructorArgs, ChampionshipEntryBlueprint, NormalizedSimulatorDriver } from './entryTypes.js';
13
+ export { DriverData, VehicleData } from './entryTypes.js';
260
14
 
261
15
  export const CHAMPIONSHIP_ENTRY_BLUEPRINTS: ChampionshipEntryBlueprint[];
262
16
  export const DEMO_PROJECT_DRIVERS: SimulatorDriver[];
@@ -0,0 +1,14 @@
1
+ export const RATING_MINIMUM = 0;
2
+ export const RATING_NEUTRAL = 50;
3
+ export const RATING_MAXIMUM = 100;
4
+
5
+ export function clampRating(value, label, domain) {
6
+ const rating = Number(value);
7
+ if (!Number.isFinite(rating)) throw new Error(`Invalid ${domain} rating for ${label}: ${value}`);
8
+ return Math.min(Math.max(rating, RATING_MINIMUM), RATING_MAXIMUM);
9
+ }
10
+
11
+ export function applyRating(definition, value, direction = 1) {
12
+ const normalized = (value - definition.neutral) / (definition.maximum - definition.neutral);
13
+ return definition.base + normalized * definition.variance * direction;
14
+ }
@@ -0,0 +1,23 @@
1
+ export type PaddockThemeSelector =
2
+ | 'default'
3
+ | 'active'
4
+ | 'selectedTeam'
5
+ | 'team'
6
+ | `team:${string}`
7
+ | string;
8
+
9
+ export interface PaddockPitCrewStats {
10
+ speed?: number;
11
+ consistency?: number;
12
+ reliability?: number;
13
+ }
14
+
15
+ export interface TeamData {
16
+ id?: string;
17
+ name?: string;
18
+ color?: string;
19
+ icon?: string;
20
+ theme?: PaddockThemeSelector;
21
+ pitCrew?: PaddockPitCrewStats;
22
+ pitCrewStats?: PaddockPitCrewStats;
23
+ }
@@ -0,0 +1,101 @@
1
+ export type PaddockProceduralTrackProfile = 'race' | 'training-short' | 'training-medium' | 'training-technical';
2
+
3
+ export interface PaddockProceduralTrackOptions {
4
+ profile?: PaddockProceduralTrackProfile;
5
+ minLengthMeters?: number;
6
+ maxLengthMeters?: number;
7
+ startStraightMeters?: number;
8
+ includePitLane?: boolean;
9
+ length?: {
10
+ minMeters?: number;
11
+ maxMeters?: number;
12
+ };
13
+ startStraight?: {
14
+ gridMeters?: number;
15
+ exitMeters?: number;
16
+ blendMeters?: number;
17
+ lockExtraMeters?: number;
18
+ };
19
+ pitLane?: {
20
+ enabled?: boolean;
21
+ };
22
+ shape?: {
23
+ scale?: number;
24
+ cornerDensity?: number;
25
+ variation?: number;
26
+ };
27
+ validation?: {
28
+ minClearanceMultiplier?: number;
29
+ minShapeVariation?: number;
30
+ minNonAdjacentArcMeters?: number;
31
+ maxLocalTurnRadians?: number;
32
+ maxSampleHeadingDeltaRadians?: number;
33
+ };
34
+ attempts?: {
35
+ primary?: number;
36
+ fallback?: number;
37
+ };
38
+ }
39
+
40
+ export interface PaddockTrackPoint {
41
+ x: number;
42
+ y: number;
43
+ }
44
+
45
+ export interface PaddockDrsZone {
46
+ id: string;
47
+ startRatio: number;
48
+ endRatio: number;
49
+ }
50
+
51
+ export interface PaddockResolvedProceduralTrackOptions {
52
+ profile: PaddockProceduralTrackProfile;
53
+ length: {
54
+ min: number;
55
+ max: number;
56
+ };
57
+ startStraight: {
58
+ grid: number;
59
+ exit: number;
60
+ blend: number;
61
+ lockExtra: number;
62
+ };
63
+ pitLane: {
64
+ enabled: boolean;
65
+ };
66
+ shape: {
67
+ scale: number;
68
+ cornerDensity: number;
69
+ variation: number;
70
+ };
71
+ validation: {
72
+ minClearanceMultiplier: number;
73
+ minShapeVariation: number;
74
+ minNonAdjacentArcDistance: number;
75
+ maxLocalTurnRadians: number;
76
+ maxSampleHeadingDeltaRadians: number;
77
+ };
78
+ attempts: {
79
+ primary: number;
80
+ fallback: number;
81
+ };
82
+ cacheKey: string;
83
+ [key: string]: unknown;
84
+ }
85
+
86
+ export interface PaddockProceduralTrack {
87
+ name: string;
88
+ width: number;
89
+ kerbWidth: number;
90
+ gravelWidth: number;
91
+ runoffWidth: number;
92
+ barrierWidth: number;
93
+ sampleCount: number;
94
+ seed?: number;
95
+ curveInterpolation?: string;
96
+ centerlineControls?: readonly PaddockTrackPoint[];
97
+ drsZones?: readonly PaddockDrsZone[] | null;
98
+ pitLane?: { enabled?: boolean } | null;
99
+ generationOptions?: PaddockResolvedProceduralTrackOptions;
100
+ [key: string]: unknown;
101
+ }
@@ -1,8 +1,6 @@
1
1
  import { normalizeCustomFields } from './customFields.js';
2
2
 
3
- const RATING_MINIMUM = 0;
4
- const RATING_NEUTRAL = 50;
5
- const RATING_MAXIMUM = 100;
3
+ import { RATING_MINIMUM, RATING_NEUTRAL, RATING_MAXIMUM, clampRating, applyRating } from './ratingScale.js';
6
4
 
7
5
  export const VEHICLE_STAT_DEFINITIONS = {
8
6
  power: { minimum: RATING_MINIMUM, neutral: RATING_NEUTRAL, maximum: RATING_MAXIMUM, base: 43000, variance: 3200, output: 'powerNewtons' },
@@ -14,18 +12,6 @@ export const VEHICLE_STAT_DEFINITIONS = {
14
12
  tireCare: { minimum: RATING_MINIMUM, neutral: RATING_NEUTRAL, maximum: RATING_MAXIMUM, base: 1, variance: 0.12, output: 'tireCare' },
15
13
  };
16
14
 
17
- function clampRating(value, label) {
18
- const rating = Number(value);
19
- if (!Number.isFinite(rating)) throw new Error(`Invalid vehicle rating for ${label}: ${value}`);
20
- return Math.min(Math.max(rating, RATING_MINIMUM), RATING_MAXIMUM);
21
- }
22
-
23
- function applyRating(definition, value) {
24
- const normalized = (value - definition.neutral) / (definition.maximum - definition.neutral);
25
- const direction = definition.direction ?? 1;
26
- return definition.base + normalized * definition.variance * direction;
27
- }
28
-
29
15
  export class VehicleData {
30
16
  constructor({
31
17
  id = null,
@@ -38,17 +24,19 @@ export class VehicleData {
38
24
  weightControl = RATING_NEUTRAL,
39
25
  tireCare = RATING_NEUTRAL,
40
26
  customFields = [],
27
+ driverModel = null,
41
28
  } = {}) {
42
29
  this.id = id;
43
30
  this.name = name;
44
- this.power = clampRating(power, 'power');
45
- this.braking = clampRating(braking, 'braking');
46
- this.aero = clampRating(aero, 'aero');
47
- this.dragEfficiency = clampRating(dragEfficiency, 'dragEfficiency');
48
- this.mechanicalGrip = clampRating(mechanicalGrip, 'mechanicalGrip');
49
- this.weightControl = clampRating(weightControl, 'weightControl');
50
- this.tireCare = clampRating(tireCare, 'tireCare');
31
+ this.power = clampRating(power, 'power', 'vehicle');
32
+ this.braking = clampRating(braking, 'braking', 'vehicle');
33
+ this.aero = clampRating(aero, 'aero', 'vehicle');
34
+ this.dragEfficiency = clampRating(dragEfficiency, 'dragEfficiency', 'vehicle');
35
+ this.mechanicalGrip = clampRating(mechanicalGrip, 'mechanicalGrip', 'vehicle');
36
+ this.weightControl = clampRating(weightControl, 'weightControl', 'vehicle');
37
+ this.tireCare = clampRating(tireCare, 'tireCare', 'vehicle');
51
38
  this.customFields = normalizeCustomFields(customFields);
39
+ this.driverModel = driverModel;
52
40
  }
53
41
 
54
42
  ratings() {
@@ -67,7 +55,7 @@ export class VehicleData {
67
55
  const ratings = this.ratings();
68
56
  const values = Object.fromEntries(Object.entries(VEHICLE_STAT_DEFINITIONS).map(([key, definition]) => [
69
57
  definition.output,
70
- applyRating(definition, ratings[key]),
58
+ applyRating(definition, ratings[key], definition.direction ?? 1),
71
59
  ]));
72
60
 
73
61
  return {
@@ -75,6 +63,7 @@ export class VehicleData {
75
63
  name: this.name,
76
64
  ratings,
77
65
  customFields: this.customFields,
66
+ driverModel: this.driverModel,
78
67
  ...values,
79
68
  };
80
69
  }
@@ -1,5 +1,6 @@
1
1
  import { clamp } from '../simulation/simMath.js';
2
2
  import { VEHICLE_LIMITS } from '../simulation/vehicle/vehiclePhysics.js';
3
+ import { normalizePitIntent } from '../simulation/pit/pitIntent.js';
3
4
 
4
5
  export function resolveActionMap(actions = {}, controlledDrivers = [], { policy = 'strict' } = {}) {
5
6
  const errors = [];
@@ -52,8 +53,8 @@ function finiteActionValue(value, message, policy, errors) {
52
53
 
53
54
  function normalizePitIntentAction(action, driverId, policy, errors) {
54
55
  if (!Object.hasOwn(action, 'pitIntent')) return null;
55
- const number = Number(action.pitIntent);
56
- if (Number.isInteger(number) && number >= 0 && number <= 2) {
56
+ const number = normalizePitIntent(action.pitIntent);
57
+ if (number != null) {
57
58
  const pitCompound = normalizePitCompoundAction(action, driverId, policy, errors);
58
59
  if (pitCompound === false) return null;
59
60
  return pitCompound == null ? number : { intent: number, targetCompound: pitCompound };