A pen or eraser does not need VRChat's pickup. Its `holding` field picks what holds it:

| `holding` | What holds it |
|---|---|
| `VrcPickup` | The `VRCPickup` on the same object: picking it up holds it, its Use draws, R on desktop and the holding hand's upper face button in VR undo. The default |
| `Custom` | Your code. VRChat's pickup events are ignored, so a `VRCPickup` may stay on the object or go |

## Three calls

With `holding` set to `Custom`, tell the pen what your system already knows:

| Call | When |
|---|---|
| `SetHeld(true)` | The local player took it |
| `SetUse(true)` | They pressed Use |
| `SetUse(false)` | They let go of Use |
| `Undo()` | They asked to undo their newest stroke |
| `SetHeld(false)` | They put it down |

Call them on the client of the player holding it; every other client hears the ink through the
network as usual. A press made before `SetHeld(true)` does not count, and Use already down when the
pen is taken has to be let go before it draws, so the trigger that grabbed a pen never also starts a
stroke.

## Where it still draws by itself

Holding is yours; where the ink goes stays the pen's. In VR it draws from its `tip`, so move the
pen object with the hand as your pickup already does. On desktop and phones it draws from the
player's view, so your pickup does not need to aim it at all, or from the `tip` as in VR when
`desktopAim` is `Tip`, for a pickup that carries it in the hand.

## An adapter

Most pickup systems raise events. A small behaviour beside the pen forwards them:

```csharp
public class PenGrip : UdoniteBehaviour
{
    public Pen pen;

    public void OnGrabbed() => pen.SetHeld(true);
    public void OnReleased() => pen.SetHeld(false);
    public void OnUseDown() => pen.SetUse(true);
    public void OnUseUp() => pen.SetUse(false);
    public void OnAlternate() => pen.Undo();
}
```

Wire those to your system's events, set the pen's `holding` to `Custom`, and nothing else changes:
ink styles, boards, erasing and the late-joiner copy all work the same.
