1 poin oleh GN⁺ 2024-05-09 | 1 komentar | Bagikan ke WhatsApp
  • Machine dari xkcd adalah game mesin bola bergaya Rube Goldberg raksasa yang disusun dengan menyambungkan perangkat berbentuk ubin buatan para pembaca, dan idenya diwujudkan menjadi komik interaktif nyata hanya dalam waktu 3 minggu
  • Pengalaman proyek partisipatif pengguna sebelumnya mengarah pada kriteria desain bahwa kanvas bersama memerlukan konteks dan tujuan bersama agar berfungsi dengan baik
  • Sambil mempertahankan daya ekspresi pemain, batasan input dan output dibuat ketat demi kompatibilitas ubin, dan setiap perangkat dibatasi agar mencapai keadaan stabil dalam 30 detik
  • Alih-alih mensimulasikan seluruh mesin secara real time, hanya area yang terlihat yang dijalankan dengan Rapier, lalu dibuat tampak seperti perangkat yang sudah aktif menggunakan snapshot pada saat persetujuan
  • Alur persetujuan dan distribusi kiriman dijalankan dengan kombinasi React dan rendering DOM, backend Haskell, Redis, OpenAPI, TanStack Query, dan UI moderasi

Titik awal Machine

  • xkcd merilis Machine pada 5 April
  • Machine adalah pembuat Rube Goldberg machine raksasa bergaya game klasik The Incredible Machine
  • Seluruh mesin disusun dalam bentuk ubin perangkat kecil yang dibuat oleh masing-masing pembaca xkcd
  • Tim membuat Machine dalam 3 minggu, dan idenya berawal dari GIF kolaboratif tahun 2005, Blue Ball Machine
  • Pertanyaan inti dalam brainstorming awal adalah dari mana bola berasal, apakah mesin yang dilihat semua orang sama, apa tujuan mesin, bagaimana pemain berinteraksi, dan apa yang memotivasi partisipasi

Pelajaran dari xkcd partisipatif pengguna

  • Di antara komik interaktif xkcd sebelumnya yang berpusat pada konten buatan pengguna, Lorenz memungkinkan pembaca menulis teks panel untuk mengembangkan lelucon dan cerita, dan itu menjadi pengalaman yang baik
  • Pada 2020, Collector’s Edition memakai cara pemain mencari stiker di arsip xkcd lalu menempelkannya sekali ke kanvas bersama global, tetapi hasilnya tidak bekerja sebaik yang diharapkan
    • Semua pemain memulai dari tengah peta yang kosong, dan tak lama kemudian kesan pertamanya menjadi layar yang kacau
    • Insentif untuk memilih posisi stiker dengan hati-hati kurang kuat, dan sulit memajukan alur hanya lewat tindakan individu
    • Karena tidak ada cerita atau tujuan bersama, tidak jelas bagaimana tiap stiker terhubung dengan elemen lain di halaman
  • Agar kanvas kolektif bekerja baik, pengguna harus bisa belajar lewat contoh tentang apa yang menarik untuk dibuat
  • Untuk mengarahkan hasil kreasi ke satu arah, dibutuhkan konteks dan tujuan bersama yang menyelaraskan apa yang harus dibuat

Merancang batasan: ekspresivitas, kompatibilitas, dan keadaan stabil 30 detik

  • Bahkan setelah memutuskan membuat alat jatuh bola kolaboratif besar, ukuran keseluruhan mesin, cara simulasi, dan metode penyatuan ubin tetap menjadi masalah
  • Dengan asumsi mesin berukuran 100x100, target menjalankan 10.000 ubin secara real time di klien sambil memproses puluhan bola di setiap ubin dianggap terlalu berisiko
  • Mengutamakan ekspresivitas daripada ketepatan

    • Opsi menjalankan seluruh mesin di server atau memverifikasi tiap ubin lewat simulasi individual sempat dipertimbangkan
    • Saat editor prototipe dengan mudah menghasilkan pola tabrakan bola yang kacau, mereka menyimpulkan bahwa menuntut mesin yang dapat diprediksi akan mengurangi kebebasan pemain
    • Desain akhir memprioritaskan fleksibilitas pemain, bahkan sampai bisa membuat perangkat yang sangat nondeterministik atau rusak
    • Pilihan ini membuat moderasi aktif diperlukan untuk memeriksa apakah ubin memenuhi batasan dan untuk menghapus konten ofensif
  • Batasan input dan output demi kompatibilitas antarubin

    • Pada awalnya mereka mempertimbangkan pendekatan di mana pemain berikutnya bebas memperluas berdasarkan posisi output ubin sebelumnya
    • Namun jika ubin yang ditempatkan lebih awal perlu diganti belakangan, area besar yang bergantung padanya bisa ikut rusak
    • Karena itu, batasan input dan output dibuat ketat agar beberapa pemain tetap dapat menghasilkan desain yang kompatibel dalam ruang ubin yang sama
    • Pendekatan ini sejalan dengan prinsip Robustness principle: “konservatif saat mengirim, toleran saat menerima”
    • map generator buatan Kevin dimulai dari teka-teki sederhana 1 input 1 output, menjadi lebih kompleks dengan penggabungan 4 input 4 output di tengah, lalu kembali ke 2 output per ubin di bagian akhir
    • Editor memberi umpan balik real time saat pemain membuat ubin
      • Rata-rata, ubin harus mengeluarkan bola pada laju yang mirip dengan laju bola yang diterima
      • Ini dimaksudkan untuk mengurangi perangkat yang menelan bola atau membuat penundaan besar
      • Untuk mencerminkan variasi input dari hulu, editor menerapkan chaos testing dengan mengacak laju bola yang masuk
  • Harus mencapai keadaan stabil dalam 30 detik

    • Untuk mengurangi lamanya moderator harus menonton, ditetapkan aturan arbitrer bahwa perangkat harus masuk ke keadaan stabil dalam 30 detik
    • Angka itu didasarkan pada perhitungan bahwa jika 10.000 ubin masing-masing ditonton selama 30 detik, total waktu moderasi menjadi sekitar 83,3 jam
    • Bola juga dibuat kedaluwarsa setelah 30 detik
      • Tanpa kedaluwarsa, pengalaman pertama pemain pemula cenderung menjadi situasi ketika bola menumpuk di layar
      • Jumlah active rigid body meningkat dan simulasi fisika ikut melambat
    • Kedaluwarsa bola mencegah akumulasi kesalahan seiring waktu dan menyederhanakan moderasi, karena dengan observasi 30 detik saja sebagian besar lokasi kedatangan bola sudah bisa terlihat

Cara yang tidak menjalankan seluruh mesin secara real time

  • Asumsi besar pertama dalam arsitektur Machine adalah bahwa, jika batasan tadi dipatuhi, ubin-ubin berbeda bisa disambungkan dan tetap tampak seperti satu mesin utuh
  • Asumsi ini diuji dengan membuat dan memecahkan beberapa peta kecil
  • Karena seluruh mesin tidak bisa dijalankan secara real time baik di server maupun di klien, dibutuhkan pendekatan yang hanya mensimulasikan area sekitar yang sedang dilihat pengguna
  • Tujuannya adalah memungkinkan seseorang mengikuti satu bola dari bagian atas mesin hingga ke bawah
  • Dunia fisika yang hanya ada di area terlihat

    • Penampil peta awal hanya mensimulasikan area terlihat, tetapi saat menggulir, ubin yang baru masuk mulai dari keadaan kosong sehingga celah aliran terlihat
    • Agar alih-alih kosong ubin tampak sudah aktif, mereka memilih menyimpan snapshot ubin yang telah mencapai keadaan stabil lalu memuatnya tepat sebelum masuk ke layar
    • Dalam komik final, hanya ubin yang sedang dirender yang benar-benar ada dalam simulasi fisika
    • Agar tampak seolah ada lebih banyak mesin di atas layar, ubin pada baris teratas simulasi diberi suplai bola yang dihasilkan sesuai laju yang diharapkan dari batasan input
  • Snapshot saat persetujuan

    • Pembuatan snapshot dihubungkan dengan UI moderasi
    • Moderator harus menunggu setidaknya 30 detik sebelum menyetujui ubin, dan keadaan saat tombol persetujuan ditekan disimpan sebagai snapshot
    • Moderator juga diberi keleluasaan untuk menunggu sedikit lebih lama sampai perangkat berada dalam keadaan yang terlihat bagus
    • Pendekatan snapshot juga berfungsi mereset kesalahan yang menumpuk, sehingga saat pengguna pertama kali melihat ubin baru ketika menggulir, mereka melihat keadaan bersih yang dinilai baik oleh moderator
    • Jika diamati lama, banyak perangkat bisa berhenti atau rusak, tetapi dengan terus menjelajah pengguna akan menemukan snapshot baru
    • Seluruh mesin tidak pernah benar-benar disimulasikan secara penuh, dan hasilnya menjadi struktur yang mendekati hyperreality

Struktur rendering React, DOM, dan Rapier

  • Machine dibangun di atas mesin fisika Rapier
  • Rapier dipilih karena dokumentasi, API, elemen dasar yang berguna, dan performa browser WASM berkat implementasi Rust
  • Pada awalnya mereka juga tertarik pada jaminan determinisme Rapier, tetapi akhirnya simulasi sisi server tidak digunakan
  • Di atas Rapier, mereka menulis React context kustom <PhysicsContext>
    • Ini membuat objek fisika Rapier bisa dibuat dan dikelola di dalam siklus hidup komponen React
    • Setiap objek yang dapat ditempatkan dan permukaan tabrakan menjadi lebih mudah dikembangkan sebagai komponen “widget”
    • React bekerja seperti scene graph yang cepat dan kasar
    • Saat ubin di-unmount, objek fisika terkait dan DOM ikut dibersihkan
    • Hot reloading lewat refresh cepat memudahkan penyesuaian bentuk tabrakan
  • Hook fisika dibuat tidak berfungsi jika berada di luar <PhysicsContext>, dan ini dimanfaatkan untuk pratinjau statis di UI moderasi
  • Belakangan mereka merasa pendekatan membuat objek Rapier sebagai komponen, bukan hook, akan lebih baik
    • react-three-rapier memakai pendekatan ini dan lebih cocok dengan React diffing
    • Pendekatan berbasis useEffect membuat instans lama dihapus dan instans baru dibuat saat dependensi berubah
  • Rendering khusus DOM

    • Machine dirender sepenuhnya dengan DOM
    • Pada awalnya mereka mengira jika mentok soal performa, rendering bisa dipindah ke PixiJS atau canvas, tetapi mereka mendorong sejauh mungkin pendekatan DOM yang lebih sedikit kebutuhan pembangunannya
    • Demi performa rendering, frame loop langsung menerapkan style ke widget yang menjadi objek simulasi fisika
    • React diff hanya dijalankan saat struktur scene graph berubah
    • Pada awalnya bola juga dirender dengan React, tetapi karena pembuatan dan penghapusan yang sangat sering menambah biaya diff, mereka membuat optimized renderer terpisah
    • Draw culling diterapkan pada bola dan widget yang berada di luar layar
    • Pendekatan ini bekerja baik untuk 4.000 bola yang sedang disimulasikan dan ratusan bola di layar, sehingga rendering khusus DOM dipertahankan

API, moderasi, dan operasional kiriman

  • Backend ditulis oleh davean dan Kevin dengan Haskell, dan Redis dipakai sebagai penyimpanan
  • Untuk berbagi tipe antarkodebase, mereka menggunakan OpenAPI dan OpenAPI fetch
    • Awalnya ada ketidaknyamanan dalam menyesuaikan dengan tipe Haskell
    • Namun ini membantu menyelaraskan perubahan API di tahap akhir
  • TanStack Query berguna untuk menangani cache dan penyegaran otomatis tanpa server push
  • UI moderasi dan prioritas

    • UI moderasi rancangan Ed White menjadi titik bottleneck yang harus dilalui semua kiriman sebelum dipublikasikan
    • Moderator mungkin harus memilih dari ratusan desain kandidat untuk ubin tertentu
    • Prioritas antrean ditentukan dengan memberi interestingness score per jenis widget lalu menghitung tiap instans untuk mengurutkan ubin kandidat
    • Cara ini condong ke solusi dengan banyak elemen, tetapi moderator mengimbanginya dengan meninjau bagian tengah daftar untuk mencari solusi yang lebih minimalis
    • Ketimpangan besar antara jumlah desain yang dikirim dan jumlah desain yang benar-benar dipasang di mesin menjadi salah satu penyesalan
    • Sebelum peluncuran mereka mencari cara menampilkan lebih banyak backlog, tetapi tidak menemukan kompromi yang baik dalam batasan waktu moderasi
    • Setelah kiriman live berakhir, mereka ingin mencari cara berbagi lebih banyak dari dataset kiriman
  • Cooldown persetujuan dan pengaturan kecepatan

    • Karena kualitas snapshot ubin penting, tombol persetujuan moderator dinonaktifkan sampai simulasi berjalan setidaknya 30 detik
    • Cooldown ini membantu menghasilkan snapshot keadaan stabil dan memeriksa apakah output menerima bola pada laju yang diharapkan
    • Awalnya ini diperkirakan akan terasa merepotkan bagi moderator, tetapi justru diterima positif karena mencegah keputusan yang tergesa-gesa
    • Setelah peluncuran, ditambahkan slider agar moderator dapat menjalankan simulasi jauh lebih cepat daripada waktu nyata
    • Fitur ini memungkinkan 30 detik pertama kiriman dilihat dalam kurang dari 5 detik, dan juga memudahkan peninjauan perilaku dalam durasi yang lebih panjang

Interaksi ubin yang tidak disengaja

  • Jamslunt Interfoggle” adalah perangkat yang diunggah dalam beberapa jam pertama setelah rilis, dengan mekanisme yang memanfaatkan rentang sempit kipas
  • Perangkat ini mengumpulkan bola biru di lorong lalu menumpahkannya ke dua sisi ketika bobotnya sudah cukup
  • Bouncy” yang ditempatkan di atasnya adalah mesin chaos yang menembakkan bola lewat jalur persimpangan bercabang tiga
  • Bouncy kadang mengirim bola hijau ke output yang salah, dan bola ini memecah tumpukan bola biru yang macet sehingga menciptakan aliran berantai ke Interfoggle
  • Di editor, hanya warna yang benar yang disuplai agar input mudah dipahami, sehingga Interfoggle tidak mungkin dirancang dengan mempertimbangkan perilaku bola hijau ini
  • Kombinasi tak disengaja semacam ini menjadi kesenangan besar proyek, karena menunjukkan cara orang memakai alat secara kreatif di kanvas bersama

Kode dan eksperimen yang tersisa

  • Kode sumber Machine tersedia di repositori GitHub
  • Implementasi yang mensimulasikan seluruh mesin secara penuh pada skala global tetap menjadi tugas hacking yang menarik
  • Tautan untuk langsung menambahkan desain ke Machine ada di xkcd 2916

1 komentar

 
GN⁺ 2024-05-09
Komentar Hacker News
  • Yang lucu setelah membaca tulisan ini adalah, waktu itu aku sama sekali tidak tahu kalau hal seperti ini sedang terjadi
    Sepertinya tidak ada penjelasan tentang apa yang sedang terjadi, aku juga tidak tahu bahwa ini adalah pengalaman bersama yang dilakukan semua orang, dan hanya merasa ada banyak hal acak yang terjadi dengan kacau
    Aku menyelesaikan beberapa tile lalu mengirimkannya, mengira itu cara untuk masuk ke “tahap berikutnya”, jadi aku memberinya nama bodoh seperti “test 1b”. Karena kupikir ini single-player, aku mengira hanya aku yang bisa melihat namanya
    Setelah membuat beberapa, aku bosan, lalu berkeliling dan melihat hal-hal yang rumit, tetapi aku tidak sadar bahwa itu adalah karya kiriman dan hanya menganggapnya sebagai titik awal untuk menyelesaikan level. Pada akhirnya aku memang kena lelucon April Mop

    • Aku bahkan tidak tahu kalau itu bisa diinteraksikan, cuma melihatnya dan berpikir, “keren juga”
    • Seharusnya sejak awal ditunjukkan contoh yang bisa diedit, atau hasil akhirnya diperlihatkan dulu lalu fokus diarahkan ke slot kosong sebagai bentuk ajakan bertindak
    • Sebagai informasi, pengiriman masih dibuka
    • Aku bahkan lebih parah. Setelah mengutak-atik sekitar 2 menit, aku sama sekali tidak paham apa yang terjadi lalu menyerah
      Mungkin karena aku belum pernah memainkan game mesin yang jadi inspirasi aslinya :-)
    • Lain kali, akan bagus kalau tulisan penjelasan diposting dulu sebelum dibuka ke publik
  • Sepertinya aku membunuh rapier setelah menambahkan banyak sekali elemen “bonk”
    Uncaught Error: recursive use of an object detected which would lead to unsafe aliasing in rust
    at jt (rapier_wasm2d_bg.js:4836:11)
    at 4ea5626ea4b1e4145572.module.wasm:0xf061c
    at 4ea5626ea4b1e4145572.module.wasm:0xf0638
    at 4ea5626ea4b1e4145572.module.wasm:0xb5e7b
    at H.remove (rapier_wasm2d_bg.js:1051:14)
    at l.remove (collider_set.js:87:18)
    at y.removeCollider (world.js:343:28)
    at PhysicsContext.tsx:258:15
    Tetap saja ini sangat menyenangkan, dan sayang aku tidak tahu saat ini dibuka secara real-time. Akan sangat bagus kalau tiap mesin buatan orang juga bisa punya tautan permanen
    Aku paham mungkin ada masalah penyimpanan, tapi apakah tidak bisa JSON di-encode ke base64 lalu dimasukkan ke parameter URL? Aku ingin membuat peta aneh dan membagikannya ke orang lain

    • Masih dibuka. https://xkcd.com/2916/
      Mesin yang masuk ke versi publik final bisa punya tautan permanen, tetapi karya individual yang tidak terpilih dari antrean kurasi tidak punya tautan permanen
      Itu memang keputusan yang sengaja diambil untuk menghindari risiko meng-host konten buatan pengguna yang belum ditinjau di domain komik
  • Sebagai catatan, topik ini juga pernah muncul di HN pada 6 April dan ada 14 komentar
    https://news.ycombinator.com/item?id=39953514

  • “Tidak ada dorongan untuk berpikir matang tentang di mana stiker harus ditempatkan. Pemain tidak punya cukup kendali untuk mendorong alur maju lewat tindakan individual. Akibatnya, kreativitas terbatas pada pola sederhana seperti mengulang stiker yang mirip seperti tile atau membuat garis.”
    Ah, jadi game ini berubah menjadi kehidupan kerja di perusahaan besar

  • Aku ikut saat ini dirilis. Kurasa aku menghabiskan sekitar satu jam untuk membuatnya seandal mungkin agar bola yang benar menuju keluaran yang benar
    Setelah mengirimnya, aku me-refresh halaman dan di tempat itu sudah ada perangkat milik orang lain. Harus kuakui memang lebih cantik, tapi keandalannya lebih rendah
    Akan lebih baik kalau cara kerjanya diberi tahu lebih awal. Dan sepertinya aku bukan satu-satunya yang tidak sadar bahwa daftar blok bangunan itu bisa di-scroll

    • Aku baru saja mengirim dua buah, dan sama sekali tidak tahu kalau daftarnya bisa di-scroll
      Sekarang aku sudah tidak punya tenaga untuk kembali dan memeriksanya :(
  • Wah, aku dan temanku juga memikirkan ide yang sama pada 2014 lalu mengimplementasikannya untuk Ludum Dare. https://nickfa.ro/wiki/CoinSlot
    Keren melihat ide itu hadir dalam bentuk yang lebih matang dan bekerja lebih baik

  • Ini mengingatkanku pada masa muda. Aku membuang sangat banyak waktu dengan sangat menyenangkan
    https://www.myabandonware.com/game/the-incredible-machine-1m...

    • Di tulisannya juga disebut bahwa proyek ini terinspirasi dari itu
  • Rasanya aku melewatkan sesuatu, tapi kenapa elemen tertentu di dalam mesin tampaknya hanya memengaruhi bola warna tertentu?
    Tebakanku itu untuk mencegah warna bercampur total, tetapi sepertinya tidak dijelaskan dalam tulisan ini

    • Setiap bola diberi karakteristik fisik yang berbeda
      Bola kuning ringan dan punya hambatan udara besar, bola hijau berat, dan bola merah memantul sangat baik
      Jadi kamu bisa merancang penyortir yang bersifat fisik
  • Aku berharap ada cara mudah untuk mengecek apakah ada mesin buatanku yang masuk ke versi final
    Dalam desain berikutnya, mungkin bagus kalau judul kiriman sebelumnya disimpan di semacam local storage lalu ditampilkan notifikasi