@inventure71/paddockjs 1.0.0 → 2.0.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 (203) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/INSTALL_AND_UPDATE.md +4 -3
  3. package/README.md +219 -12
  4. package/docs/architecture.md +126 -45
  5. package/docs/concepts.md +9 -5
  6. package/docs/custom_model_controller.md +329 -0
  7. package/docs/data_contract.md +317 -22
  8. package/docs/data_model.md +1 -1
  9. package/docs/index.md +10 -0
  10. package/docs/learnings.md +22 -0
  11. package/docs/rules.md +71 -14
  12. package/docs/sense_contract.md +59 -0
  13. package/docs/system_specs.md +75 -13
  14. package/docs/training.md +280 -32
  15. package/examples/python/README.md +62 -0
  16. package/examples/python/base_policy_server.py +191 -0
  17. package/examples/python/requirements.txt +2 -0
  18. package/package.json +12 -4
  19. package/src/api/PaddockSimulatorController.js +6 -33
  20. package/src/app/BrowserExpertAdapter.js +76 -9
  21. package/src/app/BrowserExpertExternalRenderer.js +303 -0
  22. package/src/app/F1SimulatorApp.js +291 -1630
  23. package/src/app/banners/bannerFormatters.js +55 -0
  24. package/src/app/banners/raceDataBannerController.js +141 -0
  25. package/src/app/banners/stewardMessageController.js +99 -0
  26. package/src/app/camera/cameraConstants.js +21 -0
  27. package/src/app/camera/cameraController.js +265 -0
  28. package/src/app/camera/cameraGeometry.js +176 -0
  29. package/src/app/domBindings.js +4 -0
  30. package/src/app/readouts/carOverviewRenderer.js +109 -0
  31. package/src/app/readouts/controlStateRenderer.js +37 -0
  32. package/src/app/readouts/raceStatusRenderer.js +133 -0
  33. package/src/app/readouts/readoutFormatters.js +58 -0
  34. package/src/app/readouts/telemetryRenderer.js +113 -0
  35. package/src/app/readouts/timingTowerRenderer.js +177 -0
  36. package/src/app/rendering/appAssets.js +38 -0
  37. package/src/app/rendering/carRenderer.js +286 -0
  38. package/src/app/rendering/displayUtils.js +22 -0
  39. package/src/app/rendering/drsTrailRenderer.js +90 -0
  40. package/src/app/rendering/expertSensorRenderer.js +126 -0
  41. package/src/app/rendering/pitLaneStatusRenderer.js +50 -0
  42. package/src/app/rendering/replayGhostRenderer.js +124 -0
  43. package/src/app/rendering/trackRenderer.js +25 -0
  44. package/src/app/runtime/frameLoop.js +66 -0
  45. package/src/app/runtime/runtimeTiming.js +34 -0
  46. package/src/app/runtime/runtimeVisibility.js +45 -0
  47. package/src/config/defaultOptions.js +20 -0
  48. package/src/config/restartOptions.js +34 -0
  49. package/src/environment/actions.js +13 -5
  50. package/src/environment/controllerLoop.js +261 -0
  51. package/src/environment/episode.js +98 -2
  52. package/src/environment/evaluation.js +54 -32
  53. package/src/environment/index.d.ts +376 -10
  54. package/src/environment/index.js +1 -0
  55. package/src/environment/metrics.js +159 -0
  56. package/src/environment/observationOptions.js +22 -1
  57. package/src/environment/observationVector.js +200 -0
  58. package/src/environment/observations.js +199 -141
  59. package/src/environment/options.js +37 -5
  60. package/src/environment/recorder.js +13 -6
  61. package/src/environment/rewards.js +13 -2
  62. package/src/environment/runtime.js +272 -23
  63. package/src/environment/scenarios.js +57 -9
  64. package/src/environment/sensors/bodySenses.js +23 -0
  65. package/src/environment/sensors/boundarySenses.js +17 -0
  66. package/src/environment/sensors/carRays.js +75 -0
  67. package/src/environment/sensors/contactSenses.js +32 -0
  68. package/src/environment/sensors/index.js +157 -0
  69. package/src/environment/sensors/indexedRayBands.js +103 -0
  70. package/src/environment/sensors/nearbyCars.js +52 -0
  71. package/src/environment/sensors/opponentRadar.js +75 -0
  72. package/src/environment/sensors/rayConfig.js +110 -0
  73. package/src/environment/sensors/rayDefaults.js +6 -0
  74. package/src/environment/sensors/rayGeometry.js +60 -0
  75. package/src/environment/sensors/rayGuards.js +19 -0
  76. package/src/environment/sensors/sensorTargets.js +66 -0
  77. package/src/environment/sensors/surfaceRays.js +360 -0
  78. package/src/environment/sensors/trackRays.js +424 -0
  79. package/src/environment/sensors.js +1 -367
  80. package/src/environment/specs.js +159 -26
  81. package/src/environment/workerProtocol.js +13 -1
  82. package/src/index.d.ts +171 -6
  83. package/src/index.js +6 -32
  84. package/src/rendering/proceduralTrackAsset.js +20 -823
  85. package/src/rendering/renderSnapshot.js +38 -12
  86. package/src/rendering/track/finishLineRenderer.js +34 -0
  87. package/src/rendering/track/gridRenderer.js +47 -0
  88. package/src/rendering/track/offsetStrokeSafety.js +136 -0
  89. package/src/rendering/track/pitLaneRenderer.js +248 -0
  90. package/src/rendering/track/trackMaterialRenderer.js +326 -0
  91. package/src/rendering/track/trackRenderConstants.js +38 -0
  92. package/src/rendering/track/trackRenderGeometry.js +94 -0
  93. package/src/simulation/collisionGeometry.js +1 -1
  94. package/src/simulation/driver/driverControlConstants.js +28 -0
  95. package/src/simulation/driver/driverController.js +47 -0
  96. package/src/simulation/driver/driverInput.js +28 -0
  97. package/src/simulation/driver/driverMath.js +6 -0
  98. package/src/simulation/driver/driverPersonality.js +25 -0
  99. package/src/simulation/driver/edgeRecovery.js +48 -0
  100. package/src/simulation/driver/racingControls.js +399 -0
  101. package/src/simulation/driver/racingLinePlan.js +166 -0
  102. package/src/simulation/driver/recoveryDynamics.js +38 -0
  103. package/src/simulation/driver/rejoinControls.js +213 -0
  104. package/src/simulation/driver/safetyCarControls.js +35 -0
  105. package/src/simulation/driver/trafficScan.js +51 -0
  106. package/src/simulation/driverController.js +4 -619
  107. package/src/simulation/participants/participantInteractions.js +120 -0
  108. package/src/simulation/pit/pitFlow.js +239 -0
  109. package/src/simulation/pit/pitIntent.js +92 -0
  110. package/src/simulation/pit/pitKinematics.js +24 -0
  111. package/src/simulation/pit/pitOccupancy.js +47 -0
  112. package/src/simulation/pit/pitPenaltyService.js +71 -0
  113. package/src/simulation/pit/pitQueue.js +60 -0
  114. package/src/simulation/pit/pitRouteMovement.js +167 -0
  115. package/src/simulation/pit/pitRouting.js +319 -0
  116. package/src/simulation/pit/pitService.js +43 -0
  117. package/src/simulation/pit/pitServiceConstants.js +21 -0
  118. package/src/simulation/pit/pitServiceProfile.js +45 -0
  119. package/src/simulation/pit/pitSnapshots.js +61 -0
  120. package/src/simulation/pit/pitState.js +113 -0
  121. package/src/simulation/pit/pitTireService.js +94 -0
  122. package/src/simulation/race/classification.js +104 -0
  123. package/src/simulation/race/gridPenalties.js +37 -0
  124. package/src/simulation/race/raceControlState.js +38 -0
  125. package/src/simulation/race/raceDistance.js +32 -0
  126. package/src/simulation/race/raceFinish.js +65 -0
  127. package/src/simulation/race/raceLifecycle.js +67 -0
  128. package/src/simulation/race/raceOrder.js +113 -0
  129. package/src/simulation/race/raceProgress.js +129 -0
  130. package/src/simulation/race/raceSetup.js +93 -0
  131. package/src/simulation/race/raceStep.js +80 -0
  132. package/src/simulation/race/redFlag.js +15 -0
  133. package/src/simulation/race/retirements.js +44 -0
  134. package/src/simulation/race/safetyCar.js +92 -0
  135. package/src/simulation/race/stalledDnf.js +77 -0
  136. package/src/simulation/raceSimulation.js +231 -2817
  137. package/src/simulation/replay/replayGhosts.js +128 -0
  138. package/src/simulation/rules/moduleConfig.js +72 -0
  139. package/src/simulation/rules/penaltyConfig.js +99 -0
  140. package/src/simulation/rules/penaltyEvents.js +18 -0
  141. package/src/simulation/rules/penaltyStats.js +26 -0
  142. package/src/simulation/rules/ruleConfigMerge.js +41 -0
  143. package/src/simulation/rules/ruleDefaults.js +85 -0
  144. package/src/simulation/rules/rulesReview.js +144 -0
  145. package/src/simulation/rules/rulesetPresets.js +47 -0
  146. package/src/simulation/rules/trackLimitsSteward.js +1 -1
  147. package/src/simulation/rulesConfig.js +5 -323
  148. package/src/simulation/snapshots/raceSnapshots.js +193 -0
  149. package/src/simulation/timing/drsTiming.js +87 -0
  150. package/src/simulation/timing/gapEstimation.js +38 -0
  151. package/src/simulation/timing/lapTelemetry.js +182 -0
  152. package/src/simulation/timing/raceTiming.js +15 -0
  153. package/src/simulation/timing/sectorPerformance.js +60 -0
  154. package/src/simulation/timing/timingConstants.js +5 -0
  155. package/src/simulation/timing/timingHistory.js +46 -0
  156. package/src/simulation/timing/timingLines.js +79 -0
  157. package/src/simulation/track/centerlineSpline.js +59 -0
  158. package/src/simulation/track/drsZones.js +67 -0
  159. package/src/simulation/track/pitLaneAccess.js +103 -0
  160. package/src/simulation/track/pitLaneLayout.js +395 -0
  161. package/src/simulation/track/pitLaneState.js +160 -0
  162. package/src/simulation/track/proceduralCenterline.js +237 -0
  163. package/src/simulation/track/sampleGeometry.js +49 -0
  164. package/src/simulation/track/spatialQueries.js +154 -0
  165. package/src/simulation/track/startStraight.js +141 -0
  166. package/src/simulation/track/trackConstants.js +109 -0
  167. package/src/simulation/track/trackGenerationOptions.js +283 -0
  168. package/src/simulation/track/trackMath.js +241 -0
  169. package/src/simulation/track/trackModel.js +240 -0
  170. package/src/simulation/track/trackQueryGrid.js +94 -0
  171. package/src/simulation/track/trackQueryIndex.js +659 -0
  172. package/src/simulation/track/trackQueryPitIndex.js +140 -0
  173. package/src/simulation/track/trackQueryScratch.js +46 -0
  174. package/src/simulation/track/trackQueryStats.js +28 -0
  175. package/src/simulation/track/trackSectors.js +19 -0
  176. package/src/simulation/track/trackStatePolicy.js +24 -0
  177. package/src/simulation/track/trackValidation.js +98 -0
  178. package/src/simulation/trackModel.js +1 -1706
  179. package/src/simulation/vehicle/contactResolution.js +181 -0
  180. package/src/simulation/vehicle/mainTrackWheelSurface.js +82 -0
  181. package/src/simulation/vehicle/pitWheelSurface.js +69 -0
  182. package/src/simulation/vehicle/runoffResponse.js +87 -0
  183. package/src/simulation/vehicle/surfacePriority.js +28 -0
  184. package/src/simulation/vehicle/vehicleGeometry.js +247 -0
  185. package/src/simulation/vehicle/vehicleKinematics.js +37 -0
  186. package/src/simulation/vehicle/vehiclePhysics.js +364 -0
  187. package/src/simulation/vehicle/vehicleSnapshots.js +327 -0
  188. package/src/simulation/vehicle/vehicleState.js +220 -0
  189. package/src/simulation/vehicle/wheelSurface.js +152 -0
  190. package/src/simulation/vehicleGeometry.js +1 -247
  191. package/src/simulation/vehiclePhysics.js +1 -136
  192. package/src/simulation/warmup/runtimeWarmup.js +224 -0
  193. package/src/simulation/wheelSurface.js +1 -338
  194. package/src/styles.css +42 -0
  195. package/src/ui/cameraControlsTemplate.js +20 -0
  196. package/src/ui/carOverviewTemplate.js +33 -0
  197. package/src/ui/componentTemplates.js +14 -360
  198. package/src/ui/raceCanvasTemplate.js +69 -0
  199. package/src/ui/raceControlsTemplate.js +36 -0
  200. package/src/ui/shellTemplate.js +5 -4
  201. package/src/ui/telemetryDrawerTemplate.js +55 -0
  202. package/src/ui/telemetryTemplates.js +136 -0
  203. package/src/ui/timingTowerTemplate.js +34 -0
package/src/index.d.ts CHANGED
@@ -1,8 +1,76 @@
1
- import type { PaddockActionSpec, PaddockObservationSpec } from './environment/index.js';
2
-
3
- export type { PaddockActionSpec, PaddockObservationSpec } from './environment/index.js';
1
+ import type {
2
+ PaddockActionSpec,
3
+ PaddockDriverControllerLoop,
4
+ PaddockDriverControllerLoopOptions,
5
+ PaddockObservationSpec,
6
+ PaddockParticipantInteraction as EnvPaddockParticipantInteraction,
7
+ PaddockParticipantInteractionsOptions as EnvPaddockParticipantInteractionsOptions,
8
+ PaddockParticipantInteractionOverride as EnvPaddockParticipantInteractionOverride,
9
+ PaddockParticipantInteractionProfile as EnvPaddockParticipantInteractionProfile,
10
+ PaddockReplayGhostOptions as EnvPaddockReplayGhostOptions,
11
+ PaddockReplayGhostSnapshot as EnvPaddockReplayGhostSnapshot,
12
+ PaddockReplayGhostTrajectorySample as EnvPaddockReplayGhostTrajectorySample,
13
+ } from './environment/index.js';
14
+
15
+ export type {
16
+ PaddockActionSpec,
17
+ PaddockControllerRuntime,
18
+ PaddockDriverController,
19
+ PaddockDriverControllerContext,
20
+ PaddockDriverControllerLoop,
21
+ PaddockDriverControllerLoopOptions,
22
+ PaddockObservationSpec,
23
+ } from './environment/index.js';
4
24
 
5
25
  export type TireCompound = 'S' | 'M' | 'H';
26
+ export type PaddockPhysicsMode = 'arcade' | 'simulator';
27
+ export type PaddockWarmupPolicy = 'config-change' | 'always' | 'never';
28
+ export type PaddockProceduralTrackProfile = 'race' | 'training-short' | 'training-medium' | 'training-technical';
29
+
30
+ export interface PaddockWarmupOptions {
31
+ enabled?: boolean;
32
+ policy?: PaddockWarmupPolicy;
33
+ steps?: number;
34
+ }
35
+
36
+ export interface PaddockProceduralTrackOptions {
37
+ profile?: PaddockProceduralTrackProfile;
38
+ minLengthMeters?: number;
39
+ maxLengthMeters?: number;
40
+ startStraightMeters?: number;
41
+ includePitLane?: boolean;
42
+ length?: {
43
+ minMeters?: number;
44
+ maxMeters?: number;
45
+ };
46
+ startStraight?: {
47
+ gridMeters?: number;
48
+ exitMeters?: number;
49
+ blendMeters?: number;
50
+ lockExtraMeters?: number;
51
+ };
52
+ pitLane?: {
53
+ enabled?: boolean;
54
+ };
55
+ shape?: {
56
+ scale?: number;
57
+ cornerDensity?: number;
58
+ variation?: number;
59
+ };
60
+ validation?: {
61
+ minClearanceMultiplier?: number;
62
+ minShapeVariation?: number;
63
+ minNonAdjacentArcMeters?: number;
64
+ maxLocalTurnRadians?: number;
65
+ maxSampleHeadingDeltaRadians?: number;
66
+ };
67
+ attempts?: {
68
+ primary?: number;
69
+ fallback?: number;
70
+ };
71
+ }
72
+
73
+ export type PaddockStabilityState = 'stable' | 'understeer' | 'oversteer' | 'spin-risk' | 'destroyed';
6
74
  export type PaddockPitIntent = 0 | 1 | 2;
7
75
  export type PaddockPitIntentRequest = PaddockPitIntent | {
8
76
  intent?: PaddockPitIntent;
@@ -23,6 +91,13 @@ export type CameraControlsMode = 'embedded' | 'external' | false;
23
91
  export type PaddockPresetName = 'dashboard' | 'timing-overlay' | 'compact-race' | 'full-dashboard';
24
92
  export type TelemetryModuleName = 'core' | 'sectors' | 'lapTimes' | 'sectorTimes';
25
93
  export type SectorPerformanceStatus = 'overall-best' | 'personal-best' | 'slower';
94
+ export type PaddockParticipantInteractionProfile = EnvPaddockParticipantInteractionProfile;
95
+ export type PaddockParticipantInteraction = EnvPaddockParticipantInteraction;
96
+ export type PaddockParticipantInteractionOverride = EnvPaddockParticipantInteractionOverride;
97
+ export type PaddockParticipantInteractionsOptions = EnvPaddockParticipantInteractionsOptions;
98
+ export type PaddockReplayGhostTrajectorySample = EnvPaddockReplayGhostTrajectorySample;
99
+ export type PaddockReplayGhostOptions = EnvPaddockReplayGhostOptions;
100
+ export type PaddockReplayGhostSnapshot = EnvPaddockReplayGhostSnapshot;
26
101
 
27
102
  export interface CustomField {
28
103
  label: string;
@@ -208,6 +283,10 @@ export interface F1SimulatorUiOptions {
208
283
  timingTowerVerticalFit?: TimingTowerVerticalFit;
209
284
  }
210
285
 
286
+ export interface F1SimulatorDebugOptions {
287
+ physicsModeIndicator?: boolean;
288
+ }
289
+
211
290
  export interface TrackTextureAssets {
212
291
  asphalt?: string;
213
292
  }
@@ -437,6 +516,16 @@ export interface PaddockTireStrategyRules {
437
516
  mandatoryDistinctDryCompounds?: number | null;
438
517
  }
439
518
 
519
+ export interface PaddockTireDegradationRules {
520
+ enabled?: boolean;
521
+ }
522
+
523
+ export interface PaddockStalledDnfRules {
524
+ enabled?: boolean;
525
+ maxStoppedSeconds?: number;
526
+ speedThresholdKph?: number;
527
+ }
528
+
440
529
  export interface PaddockPenaltySubsectionRules {
441
530
  strictness?: number;
442
531
  timePenaltySeconds?: number;
@@ -484,6 +573,8 @@ export interface PaddockPenaltyRules {
484
573
  export interface PaddockRaceModules {
485
574
  pitStops?: PaddockPitStopRules;
486
575
  tireStrategy?: PaddockTireStrategyRules;
576
+ tireDegradation?: PaddockTireDegradationRules;
577
+ stalledDnf?: PaddockStalledDnfRules;
487
578
  penalties?: PaddockPenaltyRules;
488
579
  weather?: { enabled?: boolean };
489
580
  reliability?: { enabled?: boolean };
@@ -549,19 +640,30 @@ export interface WheelSurfaceSnapshot {
549
640
 
550
641
  export interface CarSnapshot {
551
642
  id: string;
552
- rank: number;
643
+ rank: number | null;
553
644
  code: string;
554
645
  timingCode: string;
555
646
  name: string;
556
647
  color: string;
557
648
  tire: TireCompound;
649
+ interaction?: PaddockParticipantInteraction;
558
650
  lap: number;
651
+ velocityX?: number | null;
652
+ velocityY?: number | null;
559
653
  speedKph: number;
560
654
  finishRank?: number | null;
561
- status?: 'racing' | 'waved-flag' | string;
562
- raceStatus?: 'racing' | 'waved-flag' | string;
655
+ status?: 'racing' | 'waved-flag' | 'destroyed' | string;
656
+ raceStatus?: 'racing' | 'waved-flag' | 'destroyed' | string;
563
657
  wavedFlag?: boolean;
564
658
  finished?: boolean;
659
+ destroyed?: boolean;
660
+ destroyReason?: string | null;
661
+ destroyedAt?: number | null;
662
+ dnf?: boolean;
663
+ dnfReason?: string | null;
664
+ dnfAt?: number | null;
665
+ dnfOrder?: number | null;
666
+ outOfRace?: boolean;
565
667
  finishTime?: number | null;
566
668
  penaltySeconds?: number;
567
669
  adjustedFinishTime?: number | null;
@@ -573,6 +675,12 @@ export interface CarSnapshot {
573
675
  leaderGapLaps?: number;
574
676
  lapTelemetry?: LapTelemetrySnapshot;
575
677
  surface?: string;
678
+ lateralG?: number;
679
+ longitudinalG?: number;
680
+ gripUsage?: number;
681
+ slipAngleRadians?: number;
682
+ tractionLimited?: boolean;
683
+ stabilityState?: PaddockStabilityState;
576
684
  signedOffset?: number;
577
685
  crossTrackError?: number;
578
686
  inPitLane?: boolean;
@@ -593,6 +701,10 @@ export interface RaceClassificationEntry {
593
701
  lap: number;
594
702
  finished: boolean;
595
703
  finishTime?: number | null;
704
+ dnf?: boolean;
705
+ dnfReason?: string | null;
706
+ dnfAt?: number | null;
707
+ dnfOrder?: number | null;
596
708
  penaltySeconds?: number;
597
709
  adjustedFinishTime?: number | null;
598
710
  gapLaps?: number;
@@ -604,6 +716,7 @@ export interface RaceClassificationEntry {
604
716
 
605
717
  export interface RaceSnapshot {
606
718
  time: number;
719
+ physicsMode: PaddockPhysicsMode;
607
720
  world: {
608
721
  width: number;
609
722
  height: number;
@@ -646,6 +759,7 @@ export interface RaceSnapshot {
646
759
  events: RaceEvent[];
647
760
  penalties: PaddockPenaltyEntry[];
648
761
  cars: CarSnapshot[];
762
+ replayGhosts: PaddockReplayGhostSnapshot[];
649
763
  }
650
764
 
651
765
  export interface LifecycleErrorContext {
@@ -679,6 +793,8 @@ export interface F1SimulatorExpertOptions {
679
793
  frameSkip?: number;
680
794
  visualizeSensors?: boolean | {
681
795
  rays?: boolean;
796
+ drivers?: 'selected' | 'all' | string[];
797
+ selectedDriverId?: string;
682
798
  };
683
799
  }
684
800
 
@@ -691,13 +807,51 @@ export interface F1SimulatorExpertAction {
691
807
  pitTargetCompound?: TireCompound | string;
692
808
  }
693
809
 
810
+ export interface PaddockExternalRenderFrame {
811
+ snapshot: RaceSnapshot;
812
+ observation: Record<string, unknown>;
813
+ meta?: Record<string, unknown> | null;
814
+ }
815
+
816
+ export interface PaddockExternalRendererSource {
817
+ subscribe(onFrame: (frame: PaddockExternalRenderFrame) => void): () => void;
818
+ }
819
+
820
+ export interface PaddockExternalRendererState {
821
+ attached: boolean;
822
+ lastMeta: Record<string, unknown> | null;
823
+ lastFrameAt: number | null;
824
+ lastError: string | null;
825
+ }
826
+
827
+ export interface PaddockScenarioPlacement {
828
+ distanceMeters?: number;
829
+ startDistanceMeters?: number;
830
+ offsetMeters?: number;
831
+ speedKph?: number;
832
+ headingErrorRadians?: number;
833
+ }
834
+
835
+ export interface PaddockEnvironmentResultOptions {
836
+ stateOutput?: 'full' | 'minimal' | 'none';
837
+ observationScope?: 'all' | 'reset';
838
+ resetDriversObservationScope?: 'all' | 'reset';
839
+ }
840
+
694
841
  export interface F1SimulatorExpertApi {
695
842
  reset(options?: unknown): unknown;
696
843
  step(actions: Record<string, F1SimulatorExpertAction>): unknown;
844
+ resetDrivers?(
845
+ placements: Record<string, PaddockScenarioPlacement>,
846
+ resultOptions?: PaddockEnvironmentResultOptions
847
+ ): unknown;
697
848
  getObservation(): unknown;
698
849
  getState(): unknown;
699
850
  getActionSpec(): PaddockActionSpec;
700
851
  getObservationSpec(): PaddockObservationSpec;
852
+ attachExternalRenderer(source: PaddockExternalRendererSource): void;
853
+ detachExternalRenderer(): void;
854
+ getExternalRendererState(): PaddockExternalRendererState;
701
855
  destroy(): void;
702
856
  }
703
857
 
@@ -707,8 +861,14 @@ export interface F1SimulatorOptions extends F1SimulatorCallbacks {
707
861
  entries?: ChampionshipEntryBlueprint[];
708
862
  seed?: number;
709
863
  trackSeed?: number;
864
+ trackGeneration?: PaddockProceduralTrackOptions;
865
+ trackQueryIndex?: boolean;
866
+ warmup?: PaddockWarmupOptions | boolean;
710
867
  totalLaps?: number;
868
+ physicsMode?: PaddockPhysicsMode;
711
869
  rules?: PaddockRaceRules;
870
+ participantInteractions?: PaddockParticipantInteractionsOptions;
871
+ replayGhosts?: PaddockReplayGhostOptions[];
712
872
  initialCameraMode?: CameraMode;
713
873
  theme?: F1SimulatorTheme;
714
874
  title?: string;
@@ -717,6 +877,7 @@ export interface F1SimulatorOptions extends F1SimulatorCallbacks {
717
877
  backLinkLabel?: string;
718
878
  showBackLink?: boolean;
719
879
  ui?: F1SimulatorUiOptions;
880
+ debug?: F1SimulatorDebugOptions;
720
881
  assets?: F1SimulatorAssets;
721
882
  expert?: F1SimulatorExpertOptions;
722
883
  }
@@ -754,6 +915,7 @@ export interface F1MountedSimulator {
754
915
  setPitIntent(driverId: string, intent: PaddockPitIntentRequest, targetCompound?: TireCompound | string): boolean;
755
916
  getPitIntent(driverId: string): PaddockPitIntent;
756
917
  getPitTargetCompound(driverId: string): TireCompound | string | null;
918
+ getSimulationSpeed(): number;
757
919
  servePenalty(penaltyId: string): PaddockPenaltyEntry | null;
758
920
  cancelPenalty(penaltyId: string): PaddockPenaltyEntry | null;
759
921
  getSnapshot(): RaceSnapshot | null;
@@ -790,6 +952,7 @@ export interface PaddockSimulatorController {
790
952
  setPitIntent(driverId: string, intent: PaddockPitIntentRequest, targetCompound?: TireCompound | string): boolean;
791
953
  getPitIntent(driverId: string): PaddockPitIntent;
792
954
  getPitTargetCompound(driverId: string): TireCompound | string | null;
955
+ getSimulationSpeed(): number;
793
956
  servePenalty(penaltyId: string): PaddockPenaltyEntry | null;
794
957
  cancelPenalty(penaltyId: string): PaddockPenaltyEntry | null;
795
958
  getSnapshot(): RaceSnapshot | null;
@@ -826,6 +989,8 @@ export function simSpeedToMetersPerSecond(simSpeed: number): number;
826
989
 
827
990
  export function createPaddockSimulator(options: F1SimulatorOptions): PaddockSimulatorController;
828
991
  export function mountF1Simulator(root: Element, options: F1SimulatorOptions): Promise<F1MountedSimulator>;
992
+ export function createProceduralTrack(seed?: number | string, options?: PaddockProceduralTrackOptions): unknown;
993
+ export function createPaddockDriverControllerLoop(options: PaddockDriverControllerLoopOptions): PaddockDriverControllerLoop;
829
994
 
830
995
  export function mountRaceControls<T extends Element>(root: T, simulator: PaddockSimulatorController): T;
831
996
  export function mountCameraControls<T extends Element>(root: T, simulator: PaddockSimulatorController): T;
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import './styles.css';
2
2
  import { F1SimulatorApp } from './app/F1SimulatorApp.js';
3
3
  import { resolveF1SimulatorOptions } from './config/defaultOptions.js';
4
+ import { mergeRestartOptions } from './config/restartOptions.js';
4
5
  import { createF1SimulatorShell } from './ui/shellTemplate.js';
5
6
  export {
6
7
  createPaddockSimulator,
@@ -30,7 +31,9 @@ export {
30
31
  export { DEMO_PROJECT_DRIVERS } from './data/demoDrivers.js';
31
32
  export { DEFAULT_F1_SIMULATOR_ASSETS } from './config/defaultAssets.js';
32
33
  export { PADDOCK_SIMULATOR_PRESETS } from './config/defaultOptions.js';
34
+ export { createPaddockDriverControllerLoop } from './environment/controllerLoop.js';
33
35
  export { normalizeSimulatorDrivers } from './data/normalizeDrivers.js';
36
+ export { createProceduralTrack } from './simulation/track/trackModel.js';
34
37
  export {
35
38
  REAL_F1_CAR_LENGTH_METERS,
36
39
  SIM_UNITS_PER_METER,
@@ -49,38 +52,6 @@ function assertMountRoot(root) {
49
52
  }
50
53
  }
51
54
 
52
- function mergeRestartOptions(previousOptions, nextOptions) {
53
- const resetFromPreset = Object.hasOwn(nextOptions, 'preset');
54
- const previousUi = resetFromPreset ? {} : previousOptions.ui;
55
- const previousTheme = resetFromPreset ? {} : previousOptions.theme;
56
- return {
57
- ...previousOptions,
58
- ...nextOptions,
59
- ui: {
60
- ...previousUi,
61
- ...(nextOptions.ui ?? {}),
62
- raceDataBanners: {
63
- ...(previousUi.raceDataBanners ?? {}),
64
- ...(nextOptions.ui?.raceDataBanners ?? {}),
65
- },
66
- },
67
- theme: {
68
- ...previousTheme,
69
- ...(nextOptions.theme ?? {}),
70
- },
71
- assets: {
72
- ...previousOptions.assets,
73
- ...(nextOptions.assets ?? {}),
74
- trackTextures: {
75
- ...previousOptions.assets.trackTextures,
76
- ...(nextOptions.assets?.trackTextures ?? {}),
77
- },
78
- },
79
- drivers: nextOptions.drivers ?? previousOptions.drivers,
80
- entries: nextOptions.entries ?? previousOptions.entries,
81
- };
82
- }
83
-
84
55
  export async function mountF1Simulator(root, options = {}) {
85
56
  assertMountRoot(root);
86
57
 
@@ -134,6 +105,9 @@ export async function mountF1Simulator(root, options = {}) {
134
105
  getPitTargetCompound(driverId) {
135
106
  return app.getPitTargetCompound(driverId);
136
107
  },
108
+ getSimulationSpeed() {
109
+ return app.simulationSpeed;
110
+ },
137
111
  servePenalty(penaltyId) {
138
112
  return app.servePenalty(penaltyId);
139
113
  },