- Spring Lisp Game Jam 2024 menerima 48 game dan mencetak rekor baru, dengan karya peserta terbelah jelas antara pendekatan menambahkan Lisp di atas stack yang ada dan pendekatan membangun stack itu sendiri dengan Lisp
- Pendekatan lapisan gula menempatkan Lisp sebagai lapisan scripting di atas program berbasis C/Rust/Lua untuk cepat menghasilkan sesuatu, tetapi sangat terikat pada bahasa statis dan toolchain di bawahnya
- Pendekatan kue menulis sebagian besar program dalam Lisp dan meminimalkan C FFI untuk mendapatkan kendali yang lebih dalam, tetapi biayanya lebih besar untuk implementasi library, penulisan wrapper, dan deployment web
- Dalam Game Jam, Fennel+love2d dan S7+raylib lebih dekat ke lapisan gula, Guile+Chickadee adalah kue, dan Hoot+HTML5 canvas lebih dekat ke kue berkat toolchain Wasm berbasis Scheme
- Semakin besar porsi Lisp, semakin besar pula live hacking, keamanan memori, berkurangnya batas Lisp/C, dan kemungkinan untuk diutak-atik; proyek seperti Guix, Trial, dan Pre-Scheme juga menunjukkan arah yang sama
Status pengiriman Spring Lisp Game Jam 2024
- Spring Lisp Game Jam 2024 berakhir seminggu lalu, dan 48 game dikirimkan, mencetak rekor baru untuk jam ini
- Setelah itu para peserta menghabiskan seminggu untuk memainkan dan menilai game satu sama lain
- Distribusi bahasa dari karya yang dikirim adalah sebagai berikut
- Guile: 15, 31%
- Fennel: 10, 21%
- Clojure: 5, 10%
- Common Lisp: 5, 10%
- Racket: 4, 8%
- Elisp: 4, 8%
- S7: 3, 6%
- Kawa: 1, 2%
- Owl: 1, 2%
- Porsi Guile: {p:31}
- Alasan berbagai implementasi Scheme tidak digabung ke dalam satu kategori
schemeadalah karena spesifikasi Scheme itu kecil, dan Guile, Racket, S7, serta Kawa adalah implementasi dengan tujuan yang berbeda-beda - Dalam jam kali ini, Guile untuk pertama kalinya mencatat jumlah karya terbanyak
- Dari 15 game Guile, 11 adalah game web yang dibuat dengan Hoot
- Hoot adalah compiler Scheme-to-WebAssembly yang sedang dikembangkan oleh Spritely Institute
- 2 dari 11 itu adalah proyek resmi Spritely
- Sebelum jam dimulai, Spritely Institute meminta orang untuk mencoba membuat game dengan Hoot, dan banyak peserta menanggapinya
- Biasanya bahasa paling populer di jam ini adalah Fennel, yaitu Lisp yang dikompilasi ke Lua
- Tiga game yang memakai S7 juga menjadi contoh yang terhubung dengan cara menggunakan Lisp untuk pengembangan game
Menggunakan Lisp sebagai lapisan gula
- Pola lapisan gula adalah pendekatan menaruh Lisp seperti bahasa scripting di atas “kue” yang dibuat dengan bahasa statis seperti C atau Rust
- Biasanya ini dilakukan dengan menanamkan interpreter Lisp ke dalam program yang lebih besar
- Jika ingin menulis bagian tingkat tinggi dari aplikasi dalam Lisp, ini bisa menjadi jalur tercepat
- Dibutuhkan interpreter atau compiler yang sesuai
- Juga harus ada cara untuk menambahkan hook yang dibutuhkan aplikasi
- Jika bagian utama program ditulis dalam C atau Rust, program itu bisa dikompilasi ke WebAssembly dengan emscripten lalu dideploy ke web
- Hasil yang memuaskan bisa didapat dengan cepat, tetapi pendekatan ini sangat terikat pada bahasa statis dan toolchain terkait
- Contoh yang mewakili antara lain
- S7 adalah Scheme yang bisa ditanamkan
- Guile juga bisa dipakai untuk memperluas program C, tetapi alih-alih memasukkan interpreter ke dalam executable, biasanya ia ditautkan secara dinamis ke
libguile - Fennel memanfaatkan titik ekstensi Lua pada aplikasi yang sudah ada dan mengompilasi bahasa mirip Lisp ke Lua
Menggunakan Lisp sebagai kue
- Pola kue adalah pendekatan mengimplementasikan sebanyak mungkin software stack dalam Lisp
- Alih-alih menaruh Lisp di dalam program non-Lisp, sebagian besar program ditulis dalam Lisp
- Jika perlu, shared library dipanggil lewat foreign function interface (FFI), tetapi sebaiknya penggunaannya dibuat seminimal mungkin
- Butuh waktu lebih lama sampai hasilnya terlihat
- Library yang tidak ada pada implementasi Lisp yang dipilih harus diimplementasikan sendiri
- Wrapper harus ditulis untuk shared library C yang tidak bisa dihindari
- Proyek tidak mudah menjadi target emscripten, sehingga deployment web menjadi lebih sulit
- Pendekatan ini bersinggungan dengan perdebatan klasik embed vs. extend
- Guile bisa dipakai sebagai lapisan gula, tetapi lebih kuat saat dipakai sebagai kue
- Visi awal Guile adalah menambahkan interpreter Scheme untuk membuat program lain menjadi seperti Emacs
- Praktik yang baik saat ini adalah menulis program dalam Scheme sejak awal
- Common Lisp juga merupakan contoh bagus dari pendekatan kue
- Implementasi seperti SBCL menyediakan C FFI yang baik
- Bisa dikompilasi menjadi executable native yang efisien, sehingga mengurangi situasi di mana orang ingin memakai C demi performa
Lapisan gula dan kue dilihat dari contoh Game Jam
-
Fennel + love2d
- love2d sudah lama menjadi pilihan populer untuk pengembangan game solo atau tim kecil
- love2d adalah program C++ dengan interpreter Lua tertanam, sehingga menjadi target yang bagus untuk Fennel
- Karena sebagian besar distro Linux memaketkan love2d, file
.lovemudah dijalankan secara native - Berkat emscripten, game love2d juga bisa dideploy ke web
- Karena itu, sebagian besar game Fennel memakai love2d
- ./soko.bin dan Gnomic Vengeance memakai stack ini
- Fennel+love2d adalah contoh utuh dari Lisp sebagai lapisan gula
- Fennel berada di puncak stack, dan praktis tidak ada jalur untuk menyebarkan Lisp ke lapisan di bawahnya
- Sejauh ini ini adalah stack pengembangan game Lisp yang paling sukses
-
S7 + raylib
- Dalam jam kali ini, dua game yaitu GhostHop dan Life Predictor memakai stack S7+raylib
- Raylib adalah library C dengan binding untuk banyak bahasa tingkat tinggi dan popularitasnya meningkat dalam beberapa tahun terakhir
- S7 juga diimplementasikan dalam C dan mudah ditanamkan, sehingga kombinasi ini mudah dideploy ke web dengan emscripten
- S7+raylib juga merupakan contoh Lisp sebagai lapisan gula, dan menarik untuk dilihat apakah nanti akan menjadi lebih populer di jam mendatang
-
Guile + Chickadee
- Chickadee adalah library game untuk Guile, dan hampir semua bagian menarik termasuk rendering diimplementasikan dalam Scheme
- Dalam jam-jam terbaru, dua game Turbo Racer 3000 dan Bloatrunner dibuat dengan Chickadee
- Guile+Chickadee adalah contoh Lisp sebagai kue
- Chickadee memang membungkus beberapa library C untuk tugas tingkat rendah seperti memuat gambar, audio, dan font, tetapi kodenya sendiri ditulis dalam Scheme murni
- Matematika matriks dan vektor juga semuanya diimplementasikan dalam Scheme
- Ia menyediakan sekumpulan rendering primitive yang sebanding dengan love2d dan raylib, dan ini juga diimplementasikan dalam Scheme
- Sementara banyak library game Lisp lain memakai library C seperti nanosvg, Chickadee juga telah membuat kemajuan dalam mengimplementasikan rendering grafis vektor dalam Scheme
- Chickadee mendorong batas compiler dan virtual machine Guile, dan dalam proses itu Guile juga ikut membaik
- Namun, karena pengembangannya sebagian besar dilakukan oleh satu orang di waktu luang yang terbatas, butuh waktu lama untuk menyamai kelengkapan fitur library pengembangan game yang lebih populer
- Bahkan dalam kondisi sekarang, ia sudah bekerja cukup baik untuk tujuan tersebut
-
Hoot + HTML5 canvas
- Hoot adalah compiler Scheme-to-WebAssembly
- Hoot tidak mengompilasi Guile VM yang ditulis dalam C ke Wasm dengan emscripten
- Sebaliknya, Hoot mengimplementasikan toolchain Wasm lengkap dan backend baru untuk compiler Guile yang mengekspor Wasm secara langsung
- Hoot ditulis seluruhnya dalam Scheme
- Tidak seperti program C yang dikompilasi dengan emscripten dan menargetkan Wasm 1.0 berbasis linear memory, Hoot menargetkan Wasm 2.0 dengan heap type yang dikelola GC
- Berkat struktur ini, biner Hoot tidak menyertakan garbage collector saat didistribusikan
- Karena itu ukurannya jauh lebih kecil daripada runtime Lisp yang dikompilasi dengan emscripten
- Biner Wasm untuk salah satu game Hoot berukuran kurang dari 2MiB, sementara
love.wasmdari game love2d yang diperiksa hampir 6MiB - Program Hoot bisa berinteroperasi dengan JavaScript dengan mudah
- Objek Scheme dapat dengan mudah dikirim ke JavaScript
- Objek JavaScript juga dapat dikirim ke Scheme
- Karena objek di kedua sisi dikelola pada heap yang sama
- API browser dapat diakses sebagai Wasm import, sehingga untuk game, API HTML5 canvas bawaan menjadi pilihan rendering 2D yang mudah
- Dalam jam kali ini ada 11 game yang memakai Hoot, termasuk Cirkoban dan Lambda Dungeon
- Hoot+HTML5 canvas sebagian besar adalah kue tebal dengan sedikit campuran lapisan gula
- Booting Hoot memakan waktu satu tahun dan pendanaan yang cukup besar
- Tanpa memakai emscripten, proyek ini membangun toolchain sendiri dan juga memperluas compiler Guile
- Ada juga interpreter Wasm yang berjalan di atas Guile VM
- Di sisi lain, API canvas sangat tingkat tinggi
- Pendekatan yang lebih dekat ke kue adalah memanggil WebGL atau WebGPU lewat JS FFI milik Hoot
- Rencana ke depan mengarah ke WebGL/WebGPU, dan agar itu memungkinkan dibutuhkan peningkatan pada Wasm GC
- Tujuan lain adalah mem-porting Chickadee ke Hoot agar game Chickadee bisa dimainkan dengan mudah di native maupun browser seperti game love2d
Batasan dan keunggulan pendekatan kue
- Pendekatan kue juga jelas punya batasan
- Lingkungan modern bukan dunia mesin Lisp, dan bahkan kue Lisp tertinggi pun kebanyakan tetap diletakkan di atas kue yang lebih besar yang terbuat dari C
- Sistem Lisp modern pada titik tertentu tetap mencapai lapisan di bawahnya
- Emacs berada di atas inti C
- Guile VM ditulis dalam C
- Hoot berjalan di atas mesin JavaScript besar berbasis C++ seperti V8
- Game Hoot saat ini dirender dengan HTML5 canvas, bukan WebGL/WebGPU
- Penggunaan OpenGL membutuhkan
libGL - Chickadee memakai
guile-openglyang memanggillibGLlewat C FFI - Ada juga
libpng, FreeType, dan lain-lain
- Menulis ulang semuanya dalam Lisp menghadapi kendala sumber daya yang besar
- Meski begitu, merebut kembali sebagian stack dari bahasa seperti C tetap merupakan kemenangan kecil
- Bagian yang ditulis dalam Lisp lebih mudah diutak-atik, dan sebagian bahkan memungkinkan live hacking saat program berjalan
- Berkat runtime yang dikelola GC, secara umum didapat keamanan memori
- Jika panggilan FFI berkurang, overhead melintasi batas Lisp/C ikut berkurang dan keamanan juga meningkat
- Semakin besar porsi Lisp dalam stack, semakin dekat posisinya ke kue daripada lapisan gula
Contoh kue di luar game
- Guix adalah contoh bagus yang menunjukkan seberapa kuat pendekatan kue bisa menjadi
- Guix mengambil model packaging fungsional dari proyek Nix lalu mengimplementasikannya ulang dengan mengganti bahasa Nix menjadi Guile
- Alasannya adalah code staging, berbagi kode, dan peningkatan kemampuan untuk diutak-atik
- Guix juga memakai init system yang ditulis dalam Guile sebagai pengganti systemd, dan pilihan ini berangkat dari alasan yang sama
- Pada awalnya Guix mudah dikritik karena dianggap menemukan ulang roda tanpa alasan, tetapi setelah 10 tahun, keteguhan untuk memaksimalkan penggunaan Lisp justru menjadi inti keberhasilan proyek ini
- Pengguna yang mempelajari idiom Guix dan sedikit Guile mendapatkan kemampuan kuat untuk mengonfigurasi sistem operasi sesuai keinginan mereka
- Guix dapat dilihat sebagai pengalaman yang paling mendekati mesin Lisp di perangkat keras modern
- Di sisi Common Lisp, game engine Trial adalah contoh implementasi banyak bagian dalam Common Lisp alih-alih hanya membungkus library C
- Proyek seperti Pre-Scheme memberi harapan bahwa bahkan lapisan di bawah runtime yang dikelola GC suatu hari juga bisa diimplementasikan dalam Lisp
- Pre-Scheme dikembangkan di Scheme 48 dan telah berhasil digunakan
- Berkat NLnet grant, kebangkitan modernnya diharapkan terjadi
Arah untuk membangun lebih banyak stack dengan Lisp
- Arah ini lebih dekat ke kue
- Harus ada lebih banyak proyek yang terus mendorong batas dari apa yang bisa dilakukan Lisp
- Hal paling menarik dari Lisp Game Jam bukan game-nya sendiri, melainkan kemajuan kecil dalam merebut kembali sepotong kue dari C yang tua dan kering
- Dalam pengembangan game Guile, upaya mendorong batas itu akan terus dilakukan lewat proyek Chickadee
- Kesimpulannya bukan menulis ulang dengan Rust, melainkan menulis ulang dengan Lisp
1 komentar
Opini Hacker News
Secara objektif, belakangan ini hampir tidak pernah melihat tulisan yang membandingkan pendekatan perangkat lunak, jadi tulisan ini terasa makin menyenangkan
Bahkan ketika mencoba mencari tulisan seperti itu, sekarang hasil pencarian sering kali tidak bisa melewati spam SEO
Janet tampaknya dibuat untuk game, dan secara tak terduga juga terlihat punya cukup banyak unsur “batteries included” seperti server web atau grafis, jadi saya agak terkejut tidak melihat game yang memakai Janet
Menurut saya, di ranah Lisp dan game, bahasa ini layak dilihat
Senang melihat s7 mendapat perhatian
Saya memakainya untuk menulis Scheme for Max, ekstensi open source yang memasukkan interpreter Scheme ke lingkungan musik komputer Max/MSP; posisinya seperti berada di antara Guile, Clojure, dan Common Lisp, tetapi sangat kecil dan mudah di-embed
Saya juga suka karena lisensinya BSD yang jauh lebih permisif daripada Guile
Jika Anda menyukai makro Common Lisp dengan lingkungan kelas satu, besar kemungkinan Anda juga akan menyukai s7
Di WASM pun sangat mudah digunakan, dan saya memakainya seperti itu dalam proyek pendidikan musik
Membuat fungsi umum untuk memanggil fungsi JS dari Scheme dan sebaliknya memanggil Scheme dari JS juga tidak sulit, sehingga keseluruhan alurnya mulus
Kami berhasil meng-embed s7 dan SQLite sebagai engine selain grafis di aplikasi native iOS dan Android
Sangat cepat, FFI-nya bagus, stabil, kecil, dan kami mendapat banyak manfaat dari code sharing antar-aplikasi mobile, unit test yang luar biasa cepat, serta toolchain yang rapi
Pada akhirnya, di mobile kami pindah ke Fennel, Lisp yang lebih praktis
Hampir hanya tim kami yang memakai s7 di mobile, sementara Lua jauh lebih umum sebagai bahasa ekstensi mobile, dan status kompatibilitas r7rs Scheme juga berpengaruh
Karena untuk pengembangan desktop kami memakai Guile lalu distribusinya memakai s7, kami sering tersandung inkompatibilitas halus, misalnya urutan evaluasi parameter
Baik s7 maupun Fennel adalah proyek dan komunitas yang luar biasa
Saya sangat menyarankan melihat Spritely Institute, terutama sampai blognya
Saya tidak ingin membocorkan apa yang mereka lakukan, tetapi ini topik dan institusi yang layak digali dalam-dalam
Saya menghabiskan lebih dari 10 jam hanya untuk membaca blog, tautan terkait, dan proyeknya
https://spritely.institute/archive/
Ringkasan “kita tidak hidup di dunia mesin Lisp, melainkan di dunia PDP-11 yang dimuliakan” terasa berkesan
Namun saya penasaran apakah ada “icing” yang dipakai bersama sdl
Memang mirip dalam arti sama-sama mesin von Neumann dengan memori tanpa tag, tetapi sejak sekitar pertengahan 80-an, ketika mikroprosesor 32-bit menjadi umum dan teknologi compiler Lisp berkembang menyesuaikannya, CPU tradisional mulai melampaui mesin Lisp
Bagian “memori tanpa tag” itu pun mungkin tidak akan terus bertahan jika melihat arus seperti CHERI, dan ada peluang arsitektur gaya LispM kembali secara besar
Selama beberapa tahun saya menaruh PDP-11/45 di ruang tamu, lalu belakangan menggantinya dengan beberapa H-11 LSI-11/2 yang dilengkapi dua floppy 8 inci untuk menghemat ruang
PDP-11 bukan hanya semacam protoplasma Unix, tetapi juga dirancang dengan baik secara konseptual
Seperti kita lebih menyukai routine yang “muat dalam satu layar”, ruang alamat langsung PDP-11 yang kecil mendorong modul yang tidak terlalu besar dan menganjurkan modularitas
Apakah kurang memadai hari ini? Tentu saja, terutama menyakitkan untuk big data
Meski begitu, ada alasan konseptual mengapa PDP-11 sukses dan jejaknya masih tersisa sampai sekarang
Karena tidak ada cara lain untuk memperbaiki C, dan terlalu banyak kode yang tidak akan ditulis ulang
Lisp terutama menangani list, dan list dapat mengikuti pointer yang tersebar di seluruh memori
Pada CPU lama, memori umumnya punya waktu akses acak yang sama sehingga ini bukan masalah, tetapi CPU modern tidak bisa mengikuti pointer memori dengan kecepatan yang sama dan harus mengikuti aturan locality demi performa
Karena itu, algoritme yang memakai sesuatu seperti array C atau Fortran pasti selalu lebih cepat daripada versi berbasis list Lisp
Kemajuan terbaru Guile Scheme membuat saya antusias
Tidak seperti terakhir kali saya melihatnya, ia sudah berubah dari bahasa interpreter menjadi bahasa dengan compiler yang layak, dan sekarang bahkan bisa dikompilasi ke WASM dengan Hoot
Saya familier dengan Clojure, uLisp, dan Common Lisp, tetapi Guile Scheme terasa seperti mengurangi banyak embel-embel Common Lisp, dan terutama jika Guix dan Shepard makin mapan, saya ingin punya Lisp yang bisa dikompilasi
Saya penasaran apakah ada materi bagus untuk mempelajari Guile Scheme secara efektif selain Little Lisper dan SICP
Saya sedang mempertimbangkan memakai Guile untuk sesuatu yang akan saya buat ke depan, jadi ini menarik dibaca
Pekerjaan di sisi WASM juga tampaknya berjalan baik
https://wingolog.org/archives/2024/05/16/on-hoot-on-boot
Baru-baru ini saya membuat prototipe boss fight 3D dengan Clojure: https://prototype-game.pages.dev
Dulu saya membenci semua bentuk pengembangan web, tetapi ClojureScript benar-benar membuatnya menyenangkan, dan saya berharap lebih banyak digunakan
Nanti akan saya coba lagi saat berada di depan PC
Penasaran library apa yang dipakai
Salah satu game yang benar-benar saya sukai saat kecil
https://www.youtube.com/watch?v=dcJFldES9dg
Saya memang sempat meminta agar dimasukkan ke tabel, tapi mungkin sekarang sudah jadi berita lama
Referensi:
https://lispy-gopher-show.itch.io/logos-lisp-legend/devlog/7...
https://itch.io/post/10013482
Janet tidak masuk, padahal ada https://ianthehenry.com/posts/janet-game/
Tahun hak cipta tulisannya tercantum 1899–1907, tapi sayang tampilannya tidak terasa vintage
Untuk scripting, saya kembali lagi ke Fennel, karena bisa langsung memakai jauh lebih banyak library Lua dan berjalan tanpa masalah hampir di mana saja, bahkan di a-Shell di iPad
Ada referensi berguna di thread ini, dan mungkin nanti bisa saya coba lagi: https://janet.zulipchat.com/#narrow/stream/409517-help/topic...
Walau sudah ada jalur produksi yang terbukti, saya nyaris tidak berhasil membuat sesuatu yang playable tepat waktu, dan sebutan “playable” pun rasanya agak murah hati
Saya sangat penasaran game seperti apa yang dibuat dengan Emacs Lisp
Itu bukan pilihan pertama yang terlintas saat memikirkan pemrograman game
Dunnet awalnya ditulis oleh Ron Schnell pada 1982 sebagai program Maclisp yang berjalan di TOPS-20
Pada 1992, ia di-porting ke Emacs Lisp, tetapi lebih dari sekadar porting sederhana: ditambahkan ruangan, item, dan puzzle baru, sementara konten yang berpusat pada MIT dihapus
Misalnya, komputer “endgame” di bagian akhir game awalnya bernama MIT-SALLY, berada di MIT, dan diakses lewat Chaosnet, tetapi referensi MIT yang usang seperti ini dihilangkan dalam versi GNU Emacs
Sebagai gantinya, konten seperti VAX 11/780—lebih mudah dikenali secara luas tetapi tetap terasa dari zamannya—sengaja dimasukkan
https://en.wikipedia.org/wiki/Dunnet_(video_game)
Versi aslinya ada di sini: https://github.com/Quogic/DunnetPredecessor/blob/master/foo....
https://lcolonq.itch.io/slgj2024-game-boy-gizmo
https://asquared31415.itch.io/disassembly
https://grindingstone.itch.io/pendulum