# Konsep

## Host yang memutuskan

Logika game berjalan **di layar host**, di dalam game kamu. HP hanya mengirim input dan menampilkan apa yang diminta game. Server Ralyoo (relay) hanya meneruskan pesan antara host dan HP dalam satu room; ia tidak tahu aturan game.

Akibatnya:

- Tidak ada kode game yang berjalan di HP. Kamu tidak menulis halaman controller.
- Tidak ada server game. Keadaan game hidup di host selama game berjalan.
- Semua pemain melihat layar yang sama. Informasi rahasia per pemain dikirim ke HP masing-masing lewat [layout controller](controller.md).

## Bagian-bagiannya

| Bagian           | Siapa yang membuat | Tugas                                                   |
| ---------------- | ------------------ | ------------------------------------------------------- |
| Layar host       | Ralyoo             | Lobi, room, QR, menu jeda, layar hasil, dan memuat game |
| Controller di HP | Ralyoo             | Merender layout yang diminta game dengan widget bawaan  |
| Relay            | Ralyoo             | Meneruskan pesan per room                               |
| **Game**         | **kamu**           | Aturan, tampilan di layar host, dan layout tiap HP      |
| `@ralyoo/sdk`    | Ralyoo             | Satu-satunya pintu game ke platform                     |

## Game = bundel

Game dirilis sebagai **bundel**: satu berkas `.ralyoo` (zip) berisi `main.js`, `ralyoo.json`, dan aset. Setelah diunggah, platform menyajikannya di alamat berversi yang tidak pernah berubah, `/games/<id>/<versi>/`, dan memasukkannya ke katalog berdasarkan manifest. Web Ralyoo tidak perlu dibangun ulang untuk game baru.

Folder `dist/` hasil `npm run build` adalah isi bundel itu apa adanya.

## Sandbox

Game berjalan di dalam iframe yang terkunci:

- **Hanya bisa bicara ke platform lewat SDK.** Tidak ada akses ke halaman host, relay, cookie, atau `localStorage`. Untuk menyimpan sesuatu pakai `ctx.storage`.
- **Jaringan hanya ke folder game sendiri.** `fetch`, gambar, dan audio hanya dari bundel. Skrip hanya dari bundel dan pustaka bersama platform. Alamat di luar itu diblokir.
- **Tanpa `eval`.** WebAssembly boleh.
- Semua yang dikirim game (layout, skor, perintah audio) divalidasi ulang oleh platform sebelum dipakai.

`ralystudioo lint` memperingatkan hal yang akan ditolak sandbox sebelum kamu mengunggah.

## Dokumen game

Game menggambar ke `document.body` dokumennya sendiri, yang memenuhi layar host. Platform sudah menyiapkan:

- latar `#07060C`, tanpa margin, tinggi penuh;
- font platform lewat `@font-face`: **Manrope** (teks), **Unbounded** (judul), **JetBrains Mono** (angka).

## Pemain

Satu room berisi sampai 4 pemain. `ctx.players` selalu berisi semuanya dalam urutan slot:

```ts
{ id: 1, name: 'Sari', color: '#9E9BF7', connected: true }
```

- `id` adalah slot 1–4 dan tetap selama pemain di room.
- `color` adalah warna pemain dari platform. Pakai warna itu untuk menandai milik siapa sesuatu di layar.
- `connected` menjadi `false` saat HP terputus (layar terkunci, pindah jaringan). Slotnya ditahan dua menit; kalau HP kembali, pemainnya sama. `onPlayers` dipanggil setiap ada perubahan.

## Siapa bertanggung jawab atas performa

- **Performa game** (fps, ukuran aset, waktu muat) adalah tanggung jawab pembuat game. Ralystudioo menyediakan alat ukurnya: HUD fps dan waktu frame, ukuran bundel, dan peringatan budget.
- **Latensi input dan koneksi** (controller, relay, layar host, SDK) adalah tanggung jawab Ralyoo.

## Versi

Ada tiga nomor: versi game kamu (`version` di manifest), versi SDK yang kamu pakai, dan rentang SDK yang game kamu butuhkan (`sdk` di manifest, misalnya `">=1.1 <2"`). Game yang dibangun dengan SDK lama tetap jalan di platform yang lebih baru selama mayornya sama. Aturannya ada di [Kompatibilitas](kompatibilitas.md).
