1 poin oleh GN⁺ 2024-05-09 | 1 komentar | Bagikan ke WhatsApp

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:
    1. 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
    2. 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

 
GN⁺ 2024-05-09
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
    • Pengguna bisa memecahkan puzzle dengan memanfaatkan elemen mesin yang diimplementasikan dengan physics engine, serta membuat puzzle mereka sendiri dan mengirimkannya
    • Namun, tampaknya cukup banyak pengguna yang kebingungan karena penjelasan tentang cara bermainnya kurang memadai
  • Format game puzzle ini mirip dengan game DOS lama "The Incredible Machine"
    • Caranya adalah mencapai tujuan tertentu dengan menggunakan komponen mesin yang terbatas
  • Dalam proses pengembangannya digunakan physics engine Rapier, tetapi sempat terjadi crash akibat error rekursif
  • Ada juga pendapat bahwa akan bagus jika setelah event berakhir tetap ada fitur permalink untuk membagikan puzzle yang telah dibuat
    • Karena masalah ruang penyimpanan bisa menjadi kendala, ada usulan untuk mengenkode JSON ke Base64 lalu mengirimkannya sebagai parameter URL
  • Menyelesaikan proyek sebesar ini hanya dalam waktu 3 minggu dinilai sebagai pencapaian yang luar biasa
  • Ada juga yang merasa heran karena mengira XKCD dijalankan oleh Randall Munroe seorang diri, padahal tampaknya ada beberapa orang yang terlibat
  • Informasi lebih lanjut tentang event ini bisa ditemukan di Reddit, Explain XKCD, GitHub repository, dan lain-lain