# @tiptap/vehicle@0.1.0

<!-- Generated by scripts/gen-package-reference.mts from the package source.
     Do not edit: §15.4 — package docs are generated, nobody writes them. -->

**Spec §7.1: `@tiptap/vehicle`** — contact between two things that point
where they are going.

Extracted from `racer/src/contact.rs`. §7.1's entry is "tire model, drift
threshold, car-to-car contact"; this is the last of those, and it comes out
first because it is the part with a *decision* in it rather than a curve to
tune. The tire model is still inside `racer/src/step.rs`, tangled with the
orchestration, and separating it is the same cut phase 4 makes anyway.

## The decision, unchanged by the move

> **Contact separates the two bodies and exchanges the sideways part of the
> impulse. It never changes either body's heading, and it never changes either
> body's forward speed. The share of the separation each absorbs is
> proportional to how hard it was driving *into* the contact.**

Three of those clauses are worth restating because they are counter-intuitive
and they are why this is a package rather than a physics textbook.

**Never changes heading.** A yaw correction is the one a player cannot
survive: `racer::feel` measures corrections in terms of the driver's own
steering authority, and an injected rotation the driver did not ask for reads
as the car being taken away from them. Position can be corrected; facing
cannot.

**Never changes forward speed.** Each body keeps only the component of the
impulse across its *own* body axis. Two vehicles nose to tail keep nothing —
rear-ending somebody does not slow you down and does not speed them up.
Side by side, they keep all of it, which is the door-to-door shove that makes
contact fun.

**The separation is shared by blame.** Whoever was closing harder absorbs
more of it. When nobody is closing — two bodies overlapping from a respawn or
a previous tick — there is nobody to charge, so it splits evenly.

## What is not here

The **event and the flag**. `resolve_pair` reports what happened and mutates
two bodies; whether that fires a `Contact` event, sets a `CAR_CONTACT` bit or
plays a sound is the game's business. That is the seam: a package says what
physics did, the game says what it means.

## Types

```rust
pub struct Body
```

What contact needs to know about a body.

Four fields. `racer` passes a `Car`'s; the extraction was largely the work of
finding out that the `&Car` the old functions took was almost entirely unread.

```rust
pub struct Shape
```

The body's extent, as a two-disc capsule.

```rust
pub struct Contact
```

One contact, before it is resolved.

## Functions

```rust
pub fn discs(shape: Shape, body: &Body) -> [Vec2; 2]
```

The two disc centres a body's capsule is built from.

```rust
pub fn between(shape: Shape, a: &Body, b: &Body) -> Option<Contact>
```

The deepest overlap between two bodies, if they are touching at all.

Also the kernel behind a "am I touching anybody" query, so a game asking gets
the answer the simulation acted on rather than a second implementation of
nearly the same test.

```rust
pub fn resolve_pair(
```

Separate one touching pair and exchange the sideways impulse.

Returns the contact it acted on, so the caller can fire whatever the game
thinks a collision means. Returns `None` and touches nothing if the two are
not overlapping.
