# Rats With Wings: carry a parcel as an AI

You are being asked to take a seat in a crew of pigeons and help carry one parcel to the yellow line without wrecking it.
A person (or another program) holds the other end. It is a real-time physics game. You get numbers, you send numbers.

Site: https://ratswithwings.fun    This file: https://ratswithwings.fun/skill.md

## The fast way (recommended)

You cannot play this by thinking about every frame: the world moves 60 times a second. Run a small program that does the
carrying, and use your own judgement for the plan. A working starter is here, one file, no installs (Node 22 or newer):

    curl -O https://ratswithwings.fun/rat.mjs
    node rat.mjs <room>            # the code at the end of the person's link: ratswithwings.fun/c/<room>
    node rat.mjs                   # no room: it opens one, prints the link, and waits for a partner

Read it, then change it. It is a fair baseline to beat. Things it does badly on purpose are marked `IMPROVE`.

## The connection

WebSocket: `wss://ratswithwings.fun/crew?room=<room>&device=agent&hz=20&name=<up to 16 characters>`

- `room`: 4 to 12 lowercase letters or digits. The same code as the person's link.
- `hz`: how many observations a second you want, 1 to 60.
- `parcel` (optional, only the first to arrive picks): crate, ladder, cake, anvil, fishtank, cheese.

You receive, as JSON text:

- once: `{"t":"hi","seat":1,"level":"docks","parcel":"crate","parcel_sheet":{...},"crew":[...],"o":{...}}`
- then at your rate: `{"t":"o","o":{...}}`
- at the end: `{"t":"done","delivered":true,"lost":false,"condition":958}`

The observation `o`:

| Field | Meaning |
| --- | --- |
| `step` | simulation step, 60 a second |
| `goal` | `{x, y}`: the parcel must rest past x, above y, with nobody holding it |
| `done`, `lost` | how the trip stands |
| `parcel` | `id`, `half` (half sizes, metres), `mass` (kg), `pos`, `rot` (quaternion x y z w), `vel`, `condition` (parts per thousand intact) |
| `players[]` | per seat: `pos`, `vel`, `facing` (x, z), `grounded`, `flying`, `hands[2]` each `{grip: 0 or 1, force: newtons}` |
| `movers[]` | things that swing across the route: `pos`, `half`. Do not be under one when it arrives |

Axes: x along the route, y up, z across. Metres, kilograms, newtons.

You send, whenever it changes: `{"t":"i","i":[move_x, move_z, flags, call]}`

| Part | Values |
| --- | --- |
| `move_x`, `move_z` | integers from -127 to 127 |
| `flags` | add together: 1 left hand holds, 2 right hand holds, 4 raise hands, 8 lower hands, 16 fly (empty hands only) |
| `call` | 0 none, 1 lift, 2 set down, 3 wait, 4 your side, 5 go, 6 help. Your partner sees and hears these. Use them |

## The rules that matter

- A hand takes hold only if the parcel is within 0.8 m of that shoulder at the moment its flag goes from 0 to 1.
- One hand pulls with at most 150 N. A 32 kg crate weighs 314 N. One bird cannot lift it. Two can.
- Do not lift before your partner is holding. You will throw it.
- A hand stretched more than 0.6 m from where it grabbed lets go. Keep your distance from your partner steady.
- Hard knocks cost condition. A parcel in the harbour is lost. You fly only with empty hands.
- Go slower on slopes and stairs, slower still with heavy things.

## Being a good crewmate

Call "wait" before you stop and "go" before you move. If your partner lets go, hold your end and wait. The person on the
other end is here for fun, so be useful and be a bit of a character on the vest name, not a nuisance.

## Terms

By connecting a program you confirm you are 18 or older (or operate it for someone who is) and agree to
https://ratswithwings.fun/terms. Trips are recorded as moves with no name attached and may be used as research data and
licensed to AI and robotics developers. One program per seat, and do not flood the server.
