Catatan pengembangan "Machine" dari xkcd
Konsep awal
- Sampai akhir Maret masih memikirkan idenya, lalu memutuskan ide ini pada awal April
- "Bisakah kita membuat perangkat raksasa berbentuk ubin seperti GIF Blue Ball yang dibuat para pengguna Something Awful? Semua orang menyumbang satu persegi kecil masing-masing"
- Awalnya idenya terasa sudah terbentuk utuh, tetapi saat benar-benar mulai membicarakannya, mereka menyadari masih banyak keputusan yang harus dibuat
- Mereka punya bayangan berbeda soal bagian-bagian penting, seperti dari mana bola keluar, apakah semua orang melihat mesin yang sama, apa tujuannya, dan bagaimana pemain berinteraksi
Pelajaran dari percobaan sebelumnya
- Ada pengalaman membuat komik interaktif yang berpusat pada konten buatan pengguna
- Lorenz: exquisite corpse tempat pembaca menulis teks panel untuk mengembangkan lelucon dan cerita (sangat menyenangkan)
- Collector's Edition: permainan di mana pembaca mencari stiker tersembunyi di arsip xkcd lalu menempelkannya secara permanen pada kanvas bersama (tidak menghasilkan hasil yang diinginkan)
- Jika dimulai dari peta tengah yang kosong pada tahap awal, semuanya jatuh ke dalam kekacauan
- Insentif untuk penempatan stiker kurang, sehingga tindakan individual sulit mendorong alur maju dan yang muncul hanya pola sederhana
- Tidak ada cerita atau tujuan keseluruhan, dan hubungan antarstiker juga tidak jelas
- Agar kanvas kolektif berhasil, pengguna harus diberi contoh tentang apa yang bisa dibuat, serta memiliki konteks dan tujuan bersama
Merancang batasan
- Setelah memutuskan untuk membuat mesin jatuh-bola besar, mereka dihadapkan pada terlalu banyak pilihan
- Diputuskan untuk menyusunnya sebagai grid berukuran 100x100
- Menyimulasikan 10 ribu ubin secara real-time di klien tampak berisiko
- Tidak ada kepastian bahwa pemain bisa membuat subbagian mesin yang kompleks tanpa berkomunikasi langsung, lalu tetap berfungsi saat ubin-ubin terpisah itu digabungkan
- Setelah berbagai eksperimen pikiran, ditetapkan 3 prinsip inti:
1. Memaksimalkan daya ekspresi pemain meski harus mengorbankan akurasi
- Seberapa dapat diprediksi mesin ini seharusnya?
- Mereka juga mempertimbangkan menjalankan semuanya di server atau memverifikasi tiap ubin, tetapi dari editor prototipe terlihat bahwa pola tabrakan bola yang kacau bisa dibuat dengan mudah
- Jika bola tidak bergerak lurus tanpa gangguan, sangat mudah menciptakan mesin yang tak dapat diprediksi
- Meningkatkan prediktabilitas mesin bertentangan dengan kebebasan pemain
- Tenggat pengembangan yang ketat juga membuat pendekatan dengan prediksi/simulasi minimal lebih disukai
- Akhirnya diputuskan memberi kebebasan kreasi yang sangat fleksibel kepada pemain, termasuk mesin yang sangat nondeterministik atau bahkan rusak
- Perlu moderasi aktif untuk memastikan batasan dipenuhi dan konten yang tidak pantas dihapus
2. Memberikan batasan ketat yang mendorong mesin kompatibel dan dapat saling menggantikan
- Penerimaan melalui moderasi dan mesin pemain yang tidak bisa diprediksi justru menuntut lebih banyak keteraturan
- Pada awalnya input/output dipertimbangkan sebagai format yang sepenuhnya bebas, tetapi selama proses moderasi mereka menyadari bahwa jika ubin awal perlu diganti, hal itu bisa menyebabkan gangguan besar
- Mereka merancang batasan yang cukup kuat agar banyak pemain bisa membuat desain yang kompatibel dalam ruang ubin yang sama
- Menerapkan prinsip Robustness: "bersikap konservatif pada data yang dikirim, dan toleran pada data yang diterima"
- Untuk menetapkan batasan input/output, peta seluruh mesin diperlukan sejak awal
- Pembuatan peta juga dipakai untuk mengatur tingkat kesulitan mesin, dari 1 input 1 output yang sederhana hingga penggabungan 4 input 4 output yang kompleks
- Untuk memberi umpan balik real-time, ubin dibatasi agar mengeluarkan bola dengan laju yang mirip dengan yang diterimanya
- Mesin yang menelan atau menunda bola dibatasi
- Ubin diuji dalam kondisi kacau dengan laju input acak
- Lalu ditetapkan prinsip: "jalankan mesin untuk sementara waktu dan cek apakah secara rata-rata batasannya terpenuhi"
3. Mesin harus mencapai keadaan stabil dalam 30 detik pertama
- Muncul pertanyaan berapa lama moderator harus mengamatinya
- Mereka menghitung waktu yang dibutuhkan untuk memoderasi seluruh mesin (83,3 jam untuk 10 ribu ubin)
- Diputuskan secara arbitrer bahwa mesin harus masuk ke keadaan stabil dalam 30 detik
- Bola diatur menghilang setelah 30 detik
- Pada awalnya tidak ada waktu kedaluwarsa, sehingga saat pemain masih belajar memainkan game, bola menumpuk dan memenuhi layar
- Saat rigid body aktif bertambah banyak, simulasi fisika menjadi lebih lambat
- Bola akhirnya lebih mengganggu daripada menyenangkan
- Dengan kedaluwarsa bola, mesin tidak lagi menumpuk kesalahan seiring waktu
- Moderator cukup melihat selama 30 detik untuk memahami ke mana sebagian besar bola bisa pergi
Simulasi dan hiperrealitas
- Ada dua tantangan besar dalam arsitektur Machine:
- Apakah menyambungkan ubin-ubin yang heterogen menjadi satu mesin utuh dengan batasan desain di atas akan benar-benar bekerja?
- Mereka memverifikasi ini dengan membuat dan menyelesaikan beberapa peta kecil
- Jika mesin raksasa itu tidak bisa dijalankan secara real-time di server maupun klien, bagaimana cara menampilkannya?
Tujuannya adalah memungkinkan orang menggulir sambil mengikuti satu bola tunggal
- Walau seluruh mesin tidak disimulasikan, area di sekitar wilayah yang dilihat pemain tetap harus disimulasikan
- Pada awalnya mereka menguji simulasi hanya pada area yang terlihat di peta tak terbatas
- Ini bekerja cukup baik, tetapi saat menggulir, ubin masuk ke simulasi dalam keadaan awal yang kosong sehingga muncul celah pada aliran
- Alih-alih ubin kosong, ubin harus tampak seolah sudah memiliki aktivitas
Tantangan kedua: hanya mengambil snapshot ubin setelah mencapai keadaan stabil, agar ubin itu baru "ada" tepat sebelum terlihat saat digulir
- Dalam komik final, tampilan dengan clipping display dimatikan (
CSS overflow:hidden, contain:paint dinonaktifkan):
- Apakah Anda menyadari adanya snapshot? Tanpa perhatian khusus, ini sulit disadari
- Hanya ubin yang dirender yang benar-benar ada dalam simulasi fisika
- Optimasi tampilan: hanya bola di dalam viewport yang terlihat, tetapi simulasi tetap berjalan di seluruh rentang ubin
- Untuk meniru bagian atas mesin, bola dibuat dan dipasok dari baris teratas simulasi berdasarkan laju yang diharapkan dari batasan input
- Pembuatan snapshot dihubungkan ke UI moderasi
- Moderator harus menunggu setidaknya 30 detik sebelum menyetujui ubin
- Saat tombol persetujuan diklik, snapshot dibuat
- Sesuai penilaian moderator, mereka bisa menunggu sedikit lebih lama sampai mesin tampak dalam kondisi yang bagus
- Pendekatan snapshot bekerja jauh lebih baik dari yang diharapkan
- Efek samping yang bagus: kesalahan yang terakumulasi di mesin ikut ter-reset
- Kesan pertama dari ubin yang dilihat saat menggulir adalah kondisi bersih dan bagus yang memang disukai moderator
- Pada kenyataannya, jika diamati lama, banyak mesin bisa rusak atau hancur, tetapi itu tidak akan terlihat karena saat terus menjelajah, pemain masuk ke snapshot baru
- Mesin yang digulir dalam komik itu bukanlah sesuatu yang nyata. Itu adalah hiperrealitas
- Seluruhnya tidak pernah disimulasikan sekaligus, tetapi justru menghasilkan hasil yang lebih baik
Merender ribuan bola dengan React dan DOM
- Dibangun di atas engine fisika Rapier
- Dokumentasinya sangat baik, API elemen dasarnya rapi dan berguna, dan implementasinya dalam Rust (berjalan sebagai WASM di browser) memberi performa yang mengesankan
- Pada awalnya mereka tertarik pada jaminan determinisme Rapier, tetapi simulasi sisi server tidak digunakan
- Mereka menulis konteks React khusus
<PhysicsContext> di atas Rapier
- Membuat objek fisika Rapier dan mengelolanya dalam siklus hidup komponen React
- Memudahkan pengembangan komponen "widget" untuk tiap objek yang bisa ditempatkan dan memiliki fisika atau permukaan tumbukan
- React berfungsi sebagai scene graph yang sederhana dan agak kotor
- Menyederhanakan pemuatan/pembongkaran ubin saat tampilan digulir: ketika ubin di-unmount, semua fisika dan DOM ikut dibersihkan
- Bonusnya, hot reloading jadi mudah dihubungkan dengan fast refresh (sangat bagus untuk menyetel bentuk tumbukan)
- Keuntungan lain dari pendekatan konteks React:
- Jika hook fisika tidak berada di dalam
<PhysicsContext>, ia akan menjadi noop
- Ini digunakan untuk merender pratinjau ubin statis di UI moderasi
- Mereka merasa seharusnya menggunakan komponen, bukan hook, untuk membuat objek Rapier (seperti pendekatan react-three-rapier)
- Ini lebih cocok dengan React diffing (jika dependensi berubah,
useEffect menghapus instance lama lalu membuat ulang)
- Machine dirender sepenuhnya dengan DOM
- Pada awal pengembangan mereka khawatir batas performa rendering DOM akan tercapai
- Jika terlalu lambat, mereka memperkirakan akan beralih ke PixiJS atau canvas, tetapi ingin melihat sejauh mana DOM bisa dimanfaatkan
- Optimasi performa rendering:
- Frame loop menerapkan style langsung ke widget yang memiliki simulasi fisika
- React diff hanya berjalan saat ada perubahan struktural pada scene graph
- Pada awalnya bola dirender dengan React,
1 komentar
Komentar Hacker News
Jika berbagai komentar dirangkum, isinya kira-kira sebagai berikut:
"The Incredible Machine"dari XKCD, yang merupakan event April Mop mereka, adalah game puzzle kolaboratif yang berlangsung selama satu hari pada 1 April"The Incredible Machine"Rapier, tetapi sempat terjadi crash akibat error rekursif