# BG Lands UI protocol 1.0

Transport: canal Bukkit `bglands:ui`, objet JSON UTF-8 brut, 30 KiB maximum.
Le serveur reste autoritaire : un libellé, une position ou un token fourni par
le client ne doit jamais remplacer la validation Paper.

## Handshake et changement de backend

Client vers serveur :

```json
{"type":"hello","protocolMajor":1,"protocolMinor":0,"modVersion":"1.0.0","capabilities":["screen-v1","form-v1"]}
```

Serveur vers client :

```json
{"type":"hello_ack","protocolMajor":1,"protocolMinor":0,"serverVersion":"1.0.0","accepted":true,"reason":""}
```

Après chaque transfert Velocity, le nouveau backend envoie `probe`. Le client
ferme tout écran de l'ancien backend, oublie ses révisions et répond par un
nouveau `hello`.

## Écran d'actions

`open.controls[]` accepte `id`, `label`, `description`, `icon`, `token`,
`color`, ainsi que `x`, `y`, `width`, `height`. Si toute la page possède les
quatre valeurs géométriques, elles sont projetées depuis le canvas 400×300 du
Studio. Le transport tolère les bornes larges du serveur (x/y 0..2048,
taille 1..1024), mais une géométrie hors canvas repasse en grille pour ne pas
dessiner une interaction inaccessible. Sinon la page entière utilise la grille
responsive.

Un clic renvoie :

```json
{"type":"action","instanceId":"uuid","controlId":"c0","token":"uuid","requestId":"uuid"}
```

## Formulaire

Le serveur envoie `open_form` avec `instanceId`, `route`, `title`,
`instruction`, un `submitToken` et 1 à 8 champs `{id,label,placeholder,maxLength}`.
Le client répond :

```json
{"type":"submit","instanceId":"uuid","submitToken":"uuid","requestId":"uuid","values":{"name":"BG Team"}}
```

Le serveur termine une action ou soumission par `result`. `accepted` consomme
l'interaction et ferme l'écran correspondant; `ok` et `success` restent positifs.
Les autres statuts réactivent le contrôle pour permettre une correction.
