Skip to main content

Project 04: Vehicle spawner

In Project 03, you built an allied bodyguard who follows on foot. In Project 04, you tackle motorized vehicles. Your objective is to build a reliable vehicle spawner that queries the navigation mesh, snaps an empty car to the nearest legal road node ahead of the player, settles its tires on the asphalt using physical ground alignment, and cleans up properly.


The mission

Build an empty vehicle spawner fulfilling five core technical deliverables:

  1. Query the game's road navigation grid to locate the nearest valid street node ahead of the player.
  2. Gracefully handle off-road terrain where no street node exists without throwing exceptions.
  3. Stream a vehicle model asynchronously into memory with timeout safety.
  4. Spawn an empty vehicle at the snapped road coordinates and stabilize its suspension via PlaceOnGround.
  5. Maintain single-vehicle ownership to prevent multiple cars spawning on top of each other.
  6. Cleanly delete the vehicle when reloading the script.

Specifications, constraints

  • Empty vehicle exclusively: Do not spawn an AI driver in this project; AI driving navigation is taught in Lesson 48 before the Complete Mod.
  • Road node snapping: Always query candidate positions using World.GetNextPositionOnStreet and test against Vector3.Zero.
  • Ground collision settling: Invoke PlaceOnGround() immediately after vehicle creation to avoid physics glitches or vehicles falling through the world.
  • Persistence flag: Set _car.IsPersistent = true to protect the vehicle from ambient culling when walking away.
  • Zero orphan vehicles: Enforce complete entity deletion in OnAborted.

Implementation steps

  1. Declare vehicle tracking: Define a private field private Vehicle _car; in your script class.
  2. Wire lifecycle events: In the constructor, attach event handlers to Tick and Aborted.
  3. Check active ownership: In OnTick, check if _car is non-null and exists. If so, return immediately to enforce single-car ownership.
  4. Locate the nearest street: Calculate a candidate position 25 meters forward (player.Position + player.ForwardVector * 25f) and query World.GetNextPositionOnStreet.
  5. Handle off-road fallback: If the returned coordinate equals Vector3.Zero, exit the method cleanly without spawning.
  6. Stream vehicle model: Create a Model with VehicleHash.Dominator and call model.Request(2000). Abort if streaming fails.
  7. Instantiate and settle: Inside a try-finally block, call World.CreateVehicle, assign IsPersistent = true, and execute _car.PlaceOnGround().
  8. Release model handle: In the finally block, call model.MarkAsNoLongerNeeded().
  9. Implement teardown: In OnAborted, verify that _car exists and call _car.Delete().

APIs, tools to explore

  • GTA.World.GetNextPositionOnStreet(Vector3 position): Scans the game's navigation network to find the closest road node coordinate.
  • GTA.Vehicle: High-level wrapper representing motor vehicles, planes, helicopters, and watercraft.
  • GTA.World.CreateVehicle(Model model, Vector3 position, float heading): Spawns a physical vehicle entity in the world.
  • Vehicle.PlaceOnGround(): Snaps the vehicle's wheels and collision chassis firmly onto the underlying terrain mesh.
  • Entity.IsPersistent: Informs the ambient garbage collector that this entity must remain loaded regardless of camera distance.
  • GTA.VehicleHash.Dominator: Model hash representing the Vapid Dominator muscle car.

Validation checklist

Your mod is validated when:

  • Standing on or near a roadway causes the Dominator to spawn directly on the asphalt ahead of the player.
  • The vehicle sits stable on its wheels with zero bouncing, clipping, or chassis deformation.
  • Standing in deep mountains or open water far from roads prevents spawning without generating script errors.
  • Walking away from the vehicle does not cause the engine to despawn it prematurely.
  • Reloading the script with Insert deletes the vehicle cleanly.

Solution, explanations

Partner
Verified solution and code explanations

The mission, specifications, and guided steps remain 100% free and open for everyone. The complete verified reference code and production explanations are reserved for Partner members.