1 poin oleh GN⁺ 5 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Catlantean 3D adalah proyek sampingan untuk membuat first-person shooter lengkap dengan batasan ala game PC awal 1990-an, dengan target rendering berbasis resolusi 320x240 dan palet 256 warna
  • Karena renderer hanya menangani indeks palet, proyek ini menghitung sebelumnya colormap 32 tingkat untuk efek penggelapan berbasis jarak, lalu saat runtime memilih warna gelap lewat lookup O(1)
  • Pembuatan aset dibagi menjadi sprite pra-render berbasis Blender, sprite dan tekstur gambar tangan, serta tekstur prosedural yang dibuat dengan skrip Python
  • HUD gambar tangan dan aturan skala per piksel adalah batasan kunci untuk menjaga ketajaman dan keterbacaan pada resolusi kecil, dengan 1 unit dunia disetel setara 64 piksel
  • Alih-alih memakai Tiled, pembuatnya membuat editor peta sendiri dan berencana memberikan editor yang sama kepada pemain setelah rilis, sementara source code game akan dibuka sebagai open source di GitHub

Tujuan dan batasan proyek

  • Catlantean 3D adalah proyek sampingan yang dikembangkan perlahan selama lebih dari setahun di waktu luang, dengan target rilis di Steam tahun depan
  • Tujuannya adalah membuat first-person shooter yang selesai dan layak dirilis menggunakan teknik yang umum pada awal 1990-an
  • Kompiler modern dan lapisan abstraksi platform diperbolehkan, tetapi lapisan abstraksinya dibatasi pada framebuffer untuk menulis piksel, input keyboard dan mouse, buffer audio untuk menulis sampel, dan I/O filesystem
  • Game ini harus dibuat sepenuhnya dari nol termasuk asetnya, dan rendering serta sound mixing juga harus diimplementasikan sendiri
  • Resolusi targetnya adalah 320x240, dan setiap piksel di layar hanya boleh memakai salah satu dari 256 warna
  • Logika game memakai fixed-point untuk menjamin perilaku deterministik, sedangkan rendering memakai floating-point karena determinisme kurang penting di sana
  • Hasil akhirnya harus berupa game lengkap yang menyenangkan dimainkan, bukan sekadar demo teknologi, dan tidak menggunakan hasil dari AI
  • Semua materi yang ditampilkan masih dalam proses pengerjaan dan dapat berubah besar

Rendering palet

  • Grafik VGA

    • Mode 13h pada hardware VGA adalah mode grafis 320x200 256 warna yang terkenal dan mendefinisikan satu generasi game PC
    • Dari sudut pandang programmer, Mode 13h menyediakan framebuffer linear yang merepresentasikan tiap piksel sebagai 1 byte, yaitu indeks ke palet 256 warna
    • Untuk menggambar piksel, cukup menulis 1 byte ke alamat tertentu, tanpa perlu menangani konsep seperti shader atau VRAM
    • Aset game modern bisa memakai jutaan warna dalam gambar, tetapi dengan batas 256 warna, setiap pemilihan warna harus hati-hati dan disengaja
    • Game seperti Doom dan Duke Nukem disebut sebagai contoh bagaimana keterbatasan teknis justru menghasilkan grafis yang tajam dan jelas
    • Catlantean 3D mencoba menghadirkan kembali nuansa itu, tetapi memilih 320x240 yang lebih dekat ke VGA Mode-X alih-alih 320x200
    • Jika 320x200 ditampilkan pada layar 4:3, pikselnya menjadi tidak persegi; cara ini lebih autentik, tetapi sengaja dihindari sesuai preferensi
  • Palet

    • Palet dimulai dari 768 byte dan dipilih melalui banyak percobaan dan iterasi
    • Palet ini masing-masing mencadangkan satu warna merah muda terang untuk transparansi, putih murni, dan hitam murni
    • Banyak nuansa merah dibutuhkan untuk menampilkan darah, dan nuansa hijau serta biru juga diperlukan untuk kunci merah-hijau-biru dan pintu pembeda warna
    • Latar dunianya adalah Catlantis, negeri parodi mirip Mesir kuno karena pemujaan kucing, sehingga membutuhkan banyak warna gurun bernuansa kuning dan cokelat
    • Karena latarnya juga menceritakan Catlantis yang diduduki manusia-anjing sibernetik, banyak nuansa abu-abu dibutuhkan untuk menampilkan fasilitas teknologi
    • Nuansa beige juga dimasukkan untuk memecah monoton abu-abu dan dipakai sebagai alternatif hangat saat warna digelapkan
    • Sisa warna diisi sesuai kebutuhan selama proses pembuatan tekstur, berdasarkan penilaian subjektif bahwa warnanya “terlihat pas”
    • Palet tidak selesai sekaligus, melainkan terus disesuaikan sepanjang proses pembuatan aset, pengujian, dan iterasi

colormap dan pencahayaan

  • Struktur raycaster

    • Catlantean 3D adalah raycaster tradisional, dan peta seluruhnya tersusun dari tile berukuran sama
    • Beberapa tile adalah dinding, sementara tile lain adalah ruang kosong yang hanya memiliki lantai dan langit-langit
    • Untuk tiap kolom layar, renderer menelusuri tilemap dengan algoritme DDA guna mencari posisi tabrakan dengan geometri peta
    • Berdasarkan posisi tabrakan itu, renderer menggambar kolom dinding yang diambil dari koordinat tekstur yang sesuai ke layar
    • Lantai dan langit-langit kemudian dirender setelahnya dengan scanline horizontal untuk mengisi sisa layar
    • Jika dunia game dirender hanya dengan palet tanpa apa pun lagi, hasilnya akan tampak datar dan kurang berkesan
    • Kesan kedalaman muncul jika cahaya berkurang saat menjauh dari pemain, dan jika satu sisi tile peta sedikit lebih gelap daripada sisi lainnya
  • Penggelapan berbasis palet

    • Pada renderer modern yang dipercepat hardware, warna bisa dengan mudah digelapkan di shader dengan mengalikan vektor warna menggunakan koefisien floating-point berdasarkan jarak vertex
    • Renderer palet tidak menangani konsep warna, melainkan hanya indeks palet, jadi untuk mencari versi lebih gelap dari suatu warna perlu menelusuri seluruh palet
    • Menelusuri palet 256 warna untuk setiap piksel render akan terlalu lambat, jadi dibuat lookup warna cepat lewat pra-perhitungan sebelum runtime
    • Jika palet disusun dalam satu baris dan dipilih 32 tingkat kecerahan, maka tiap warna memerlukan 31 variasi yang lebih gelap selain versi aslinya
    • Nilai RGB dan indeks kecerahan tiap warna dipakai untuk menghitung target warna gelap, tetapi warna itu belum tentu benar-benar ada di dalam palet
    • Untuk membangun colormap, palet lalu ditelusuri guna mencari warna palet yang paling dekat dengan warna target tersebut
    • Awalnya digunakan jarak Euclidean, tetapi banyak warna cenderung tertarik ke arah abu-abu, sehingga warna gelap terlihat dingin dan tidak hidup
    • Setelah itu, warna diubah ke ruang warna Oklab dan digunakan rumus jarak perseptual yang lebih dekat dengan cara manusia melihat perbedaan warna
    • Juga diterapkan hue shifting, konsep pixel art yang sedikit menggeser warna ke arah yang lebih hangat saat makin gelap
    • colormap adalah matriks dua dimensi berisi indeks palet yang merepresentasikan tingkat kecerahan tiap warna, dan karena tetap hanya bisa memakai warna palet, gradasinya tidak sempurna
  • Mengurangi biaya runtime

    • Setelah indeks baris colormap berbasis jarak ditentukan, item ke-N pada baris tingkat kecerahan itu dipilih untuk memperoleh indeks palet dari warna N yang telah digelapkan
    • Dengan cara ini, pemilihan warna yang lebih gelap saat runtime menjadi lookup O(1)
    • Pada rendering dinding, karena kolom dinding sepenuhnya vertikal dan semua piksel dalam kolom itu memiliki jarak yang sama ke kamera, indeks baris colormap cukup dihitung sekali per kolom layar
    • Pada rendering lantai, karena semua piksel pada satu baris horizontal memiliki jarak yang sama, perhitungan cukup dilakukan sekali per baris layar
    • Sprite adalah billboard datar yang semua pikselnya memiliki jarak yang sama ke kamera, jadi perhitungan cukup sekali untuk tiap sprite yang terlihat
    • Artinya, dinding cukup dihitung 320 kali, lantai paling banyak 240 kali, dan tiap sprite yang terlihat hanya sekali, sementara raycasting sekaligus memberi penghapusan objek tertutup secara gratis
    • Doom dan banyak game lain juga memakai pendekatan serupa

Cara pembuatan aset

  • Tiga kategori aset

    • Tekstur dan sprite Catlantean 3D dibagi ke dalam tiga kategori
    • Kategori pertama adalah sprite pra-render dari model 3D yang dibuat di Blender lalu dirender menjadi tekstur
    • Kategori kedua adalah sprite dan tekstur yang digambar tangan
    • Kategori ketiga adalah tekstur prosedural yang dihasilkan oleh skrip Python khusus yang menggabungkan seni gambar tangan
  • Sprite pra-render

    • Sprite animasi yang rumit sulit dan memakan waktu untuk diulang pengerjaannya karena perlu mengubah banyak frame
    • Cara yang lebih efisien adalah membuat model 3D di Blender, melakukan rigging dan animasi, lalu memakai skrip berbasis Blender Python API untuk merender banyak tekstur
    • Perubahan dilakukan pada model, dan skrip render menangani sisanya, sehingga waktu iterasi berkurang drastis
    • Kesulitan utamanya adalah sprite hasil render terlihat sangat buram dan seperti pudar
    • Metode merender pada resolusi tinggi lalu mengecilkannya dengan filtering memberi hasil campuran, karena detail bisa hilang oleh filtering dan ketajaman tepi bisa lenyap
    • Cara yang paling efektif dan bisa digunakan ulang adalah memanfaatkan compositing di Blender untuk mendapatkan kontras dan ketajaman yang sesuai
    • Setelah gambar siap, skrip Python khusus melakukan kuantisasi palet untuk menghasilkan gambar piksel 1 byte yang dipakai engine
    • Untuk setiap piksel pada gambar asli, skrip mencari warna palet yang paling dekat secara perseptual menurut Oklab, lalu memakai indeks warna itu sebagai nilai piksel
    • Array indeks dan informasi ukuran kemudian dipaketkan ke format TEX sederhana yang digunakan game
    • Sprite musuh dapat memiliki banyak animasi, dan setiap animasi harus memiliki frame untuk 8 arah hadap sprite
    • Skrip Python memutar sprite untuk tiap animasi, merender semua frame, lalu mengulang proses itu setelah rotasi berikutnya
    • Nama file sprite disimpan menurut konvensi yang menunjukkan nama sprite, nama aksi, arah, dan indeks frame
    • Sprite hasil render tidak disimpan di repositori dan dimasukkan ke .gitignore; di komputer lain, skrip kompilasi akan merender semua model untuk menghasilkan sprite
    • Pada RTX 3070, memproses sekitar 15 model membutuhkan kira-kira 10 detik
  • Sprite dan tekstur gambar tangan

    • Pada awal pengembangan, pembuatnya membuat kepala berbentuk kucing bertekstur kucing Vilko di Blender untuk dipakai sebagai wajah status bar
    • Hasilnya terlihat malas dan minim usaha, tidak menyampaikan emosi dengan baik, dan menjadi hal pertama yang ditunjukkan orang saat memberi umpan balik soal suasana
    • Beberapa elemen memang harus digambar tangan, dan versi gambar tangan yang dianimasikan dinilai jauh lebih baik
    • Karena ukuran sprite kecil, setiap piksel harus sengaja ditempatkan, dan ini tidak bisa diserahkan ke renderer Blender
    • Logika yang sama juga berlaku pada sebagian besar item pickup, dan hasil pra-render sebelumnya tidak konsisten menghasilkan kualitas bagus pada skala kecil lewat compositor Blender
    • Setelah dikerjakan dengan tangan, ketajaman dan keterbacaan item pickup meningkat besar
    • Resolusi sprite memang bisa dinaikkan dan dirasterisasi game bisa menskalakannya, tetapi hasilnya buruk karena skala piksel menjadi tidak konsisten
    • Secara bawah sadar, orang berharap ukuran piksel tetap sama saat bergerak maju-mundur pada baris atau kolom layar yang sama, jadi skala piksel yang berbeda antar-sprite terasa janggal
    • Di Catlantean 3D, 1 unit dunia setara 64 piksel, dan semua sprite dibuat mengikuti skala ini
    • Sprite dengan tinggi seperempat unit dunia harus memiliki tinggi 64/4=16 piksel

HUD dan pipeline generasi prosedural

  • HUD

    • HUD dan komponennya hampir semuanya ditempatkan dan digambar secara manual
    • Status bar di bagian bawah layar, berbagai panel dan layar transisi, serta font termasuk dalam kategori HUD gambar tangan
    • Alih-alih mengecat semua elemen langsung, banyak digunakan efek layer dan compositing dari Affinity Photo
    • Efek yang dipakai mencakup emboss untuk memberi kesan 3D pada permukaan datar, pembuatan dan overlay noise untuk tekstur kasar, color overlay, blending mode, dan efek glow
    • Karena elemen HUD sering direvisi berulang kali, kemudahan penataan ulang berbasis layer juga penting
    • Umumnya pengerjaan dimulai dalam truecolor di Affinity Photo, dan banyak elemen hanya berupa persegi panjang warna solid yang diberi efek khusus dan blending
    • Gambar hasil ekspor dari Affinity Photo mengandung artefak aneh yang tampaknya terkait anti-aliasing, dan ini tidak bisa dimatikan secara andal
    • Karena kurang cocok untuk pekerjaan yang presisi per piksel, pekerjaan tambahan dilakukan di Aseprite seperti teks pixel-perfect, memotong artwork, dan menimpa garis batas agar lebih tajam
  • Tekstur generasi prosedural

    • Beberapa tekstur cukup sederhana atau spesifik untuk digambar langsung, tetapi banyak tekstur berbagi pola keausan, debu, dan variasi detail permukaan di atas material dasar
    • Jika setiap variasi digambar tangan, hasilnya membosankan dan kurang konsisten, jadi semuanya dihasilkan dengan skrip Python
    • Pipeline generasi menerima input berupa heightmap yang mendefinisikan relief permukaan, noise map untuk variasi, grime map untuk debu dan keausan, dua warna dasar, dan brightmap
    • Heightmap sebenarnya dipakai untuk membuat normal map, dan normal map digunakan untuk memanggang pencahayaan dan bayangan sederhana
    • Brightmap menentukan bagian yang harus mempertahankan warna terlepas dari parameter lain
    • Skrip membuat tekstur final dan sekaligus melakukan kuantisasi palet agar bisa langsung dipakai di engine
    • Mengubah tekstur lalu menjadi soal menyesuaikan parameter, bukan menggambar ulang piksel, dan ini sangat menghemat waktu saat bekerja sendirian

gibs dan efek pra-render

  • Gibs

    • Gibbing biasanya terjadi ketika musuh menerima damage berlebihan seperti point-blank shotgun blast atau ledakan
    • Untuk menyampaikan dampak dari kerusakan besar, digunakan animasi musuh meledak menjadi potongan berdarah
    • Pipeline ini dipimpin skrip Python yang menerima sprite, palet, dan kumpulan parameter, lalu menghasilkan frame animasi yang masuk ke data game
    • Pada tahap pertama, Voronoi decomposition, K piksel seed dipilih secara acak dari tubuh sprite yang opak, lalu setiap piksel ditugaskan ke seed terdekat
    • Setiap cell yang terbentuk dengan cara ini menjadi satu potongan yang terlempar
    • Pada tahap kedua, wound bleeding, piksel batas yang bersebelahan dengan potongan lain ditandai sebagai luka dengan kedalaman 0, lalu BFS menyebar ke dalam dan memberi nilai kedalaman
    • Saat dirender, piksel dekat batas dicampur ke arah warna darah dari ramp yang diturunkan dari palet game, dan semakin ke dalam potongan, warna asli sprite makin dipertahankan
    • Pemilihan ramp palet bersifat terparameterisasi, sehingga “darah” hijau atau biru juga bisa dipakai untuk musuh tertentu
    • Pada tahap ketiga, physics, tiap potongan diberi titik pusat, kecepatan sebar acak yang mengarah keluar dari pusat sprite, kecepatan rotasi, gravitasi, dan drag
    • Tidak ada deteksi tabrakan, tetapi potongan akan berhenti saat menyentuh lantai, dan hasil kasarnya dianggap cukup baik
    • Jumlah potongan, kekuatan ledakan, gravitasi, drag, sebaran, dan kedalaman luka dapat diatur sebagai parameter
    • Perlu sedikit trial and error untuk menemukan seed yang terlihat bagus, tetapi tetap lebih cepat daripada menggambar animasi dengan tangan
    • Teknik yang sama juga dipakai untuk objek lingkungan yang bisa dihancurkan seperti pot bunga, barrel, dan peti
    • Seperti animasi pra-render, hasil gibs juga tidak disimpan di repositori, melainkan dibuat ulang setelah checkout, dan waktu eksekusinya bisa diabaikan
  • Sistem partikel pra-render

    • Sebagian besar efek partikel digambar tangan di Aseprite, tetapi beberapa dihasilkan dan dipanggang dengan cara yang sama seperti gibs
    • Skrip Python menjalankan simulasi untuk membuat urutan frame PNG, lalu mengkuantisasikannya ke TEX
    • Tidak ada sistem partikel runtime; semua efek dipanggang sebelumnya agar software rasterizer dapat merender secepat mungkin
    • Di sini kata “particle” agak menyesatkan, karena sebenarnya tidak ada partikel yang benar-benar disimulasikan
    • Setiap frame menghitung radial energy field per piksel lalu menggabungkan beberapa layer independen
    • core adalah cakram lembut yang mengembang ke luar sepanjang animasi
    • rays adalah semburat cahaya tajam di sekitar core; sharpness dan length dapat diatur, dan tiap ray diberi variasi panjang berbasis RNG agar terlihat tidak teratur
    • ring adalah shockwave mengembang opsional, sementara noise mengalikan seluruh energi dengan value noise agar bentuk yang tadinya bersih menjadi kasar dan tidak beraturan
    • Energi per piksel yang telah diakumulasikan lalu dikuantisasi sesuai ramp palet yang ditentukan lewat parameter skrip
    • Karena desain palet memperlakukan tiap baris sebagai gradasi dari terang ke gelap, piksel dapat digelapkan hanya dengan aritmetika indeks palet tanpa blending atau perhitungan alfa
    • Di atas ambang tertentu, piksel didorong ke arah putih untuk memberi kesan white-hot core
    • Secara opsional, sparkle kecil bisa ditebar di atasnya; bentuk silang ini bergerak ke luar dan memudar selama masa hidupnya masing-masing
    • Animasi mendukung mode one-shot yang membesar lalu menghilang, seperti ledakan atau teleport flash, serta mode loop mulus di mana frame pertama dan terakhir saling cocok
    • Mode loop berguna untuk efek berulang yang terus aktif seperti plasma bolts dan energy projectiles

Editor peta dan ekosistem alat

  • Pengeditan peta awalnya dimulai di Tiled, yang secara umum merupakan alat masuk akal, tetapi kekurangan fitur spesifik yang dibutuhkan game
  • Tiled tidak memiliki light level painting per sel, cell flags, maupun konsep properti khusus game, sehingga pada awalnya hal itu diakali dengan terlalu mengandalkan object properties
  • Juga dibutuhkan skrip Python untuk mengubah output JSON dari Tiled menjadi format biner yang dipakai engine, yang menjadi komponen tambahan untuk menutupi ketidakcocokan antara alat dan kebutuhan game
  • Jika pemain harus memasang Tiled, mempelajari antarmukanya, dan menyiapkan skrip konversi untuk membuat peta, bebannya akan terlalu besar sampai praktis menghilangkan peluang editor itu benar-benar dipakai
  • Editor buatan sendiri mendukung light level painting, cell flags, dan semua tipe entity serta properti yang dikenali game secara native
  • Saat game dirilis, pemain juga akan menerima editor yang sama dengan yang dipakai saat pengembangan
  • Editornya bersifat plug and play, dan level bisa langsung dijalankan dari dalam editor
  • Pembuatnya sadar bahwa ikon toolbar terlihat buruk, dan justru karena itulah mereka dibiarkan apa adanya
  • Editor dibuat dengan wxPython, yang dinilai lebih cocok daripada tkinter dalam hal widget, event handling, dan layout
  • Hasil dari wxPython juga terlihat lebih native dan membuat iterasi berlangsung cepat
  • Struktur yang berfokus pada pola MVP memisahkan logika UI dan data peta dengan rapi, dan ini penting karena format peta belum stabil sehingga kedua sisi sering berubah
  • Tidak semua bagian editor ditulis dalam Python; banyak bagian model bergantung pada library pybast
  • pybast adalah binding Python ke bagian internal engine melalui pybind yang menyediakan pembacaan game data archive, pembacaan game textures, fixed point class untuk koordinat entity, dan serialization
  • Ini dipilih agar fungsi yang sudah diimplementasikan dalam C++ tidak perlu ditulis ulang di Python, dan engine serta alat membentuk ekosistem kecil yang rapat

Rencana rilis dan cara publikasi

  • Catlantean 3D diperkirakan akan dirilis pada kuartal pertama 2027
  • Fokus saat ini adalah desain level, penambahan musuh dan senjata, serta pekerjaan polish yang masih berlangsung
  • Target harganya berada di kisaran 5–8 dolar
  • Source code game direncanakan akan dirilis sebagai open source di GitHub
  • Arsip data aktual yang berisi grafis, level, suara, musik, dan sebagainya hanya bisa didapat dengan membeli game
  • Transparansi proses dianggap sebagai salah satu dari sedikit hal yang membangun kepercayaan berkelanjutan
  • Berbeda dari AAA, game indie bergantung pada audiens yang lebih kecil, tetapi audiens itu lebih mau mengikuti proyek, mendukungnya, dan memberi tahu orang lain
  • Menunjukkan proses pengerjaan diposisikan sebagai cara paling jujur untuk memperlihatkan bahwa pembuatnya benar-benar peduli pada apa yang sedang dibuat

1 komentar

 
GN⁺ 5 jam lalu
Komentar Hacker News
  • Jika ingin bermain-main dengan software rendering, ada contoh yang nyaris merupakan kode tersingkat untuk secara efisien menampilkan array 2D ARGB8888 di memori utama ke layar di semua platform dengan SDL2 dan C: https://gist.github.com/CoryBloyd/6725bb78323bb1157ff8d4175d...
    Konversi framebuffer palet 320x200x8-bit ke ARGB harus dilakukan sendiri ;)
    Jika ingin mencari inspirasi tentang apa yang bisa dilakukan dengan framebuffer palet, tekan Show Options di http://www.effectgames.com/demos/canvascycle/ atau lihat presentasi GDC dari artis tersebut di https://youtu.be/aMcJ1Jvtef0
    Lalu jika ingin nuansa klasik Deluxe Paint IIe, buka https://github.com/mriale/PyDPainter, atau jika ingin alat yang lebih modern, buka https://www.aseprite.org/

    • Setidaknya di SDL3, renderer atau texture tidak lagi diperlukan. Ambil surface dengan SDL_GetWindowSurface lalu tampilkan dengan SDL_UpdateWindowSurface
      Sejauh pemahaman saya tentang library ini, ini adalah cara yang paling dekat dengan grafis software, dan SDL tetap menangani double buffering

    • Ini jelas cara yang paling dasar. Untuk optimasi kecil di loop bagian dalam, Anda bisa menghitung terlebih dulu offset scanline sebelum masuk ke loop piksel:
      int s = y*screenRect.w;

      for (int x = 0; x < screenRect.w; x++) {
      pixels[s + x] = argb(255, frame>>3, y+frame, x+frame);
      }

    • Terima kasih sudah berbagi. Sudah ada beberapa fork Quake yang populer, tetapi Planimeter mendistribusikan fork Quake-VS2026 yang tidak memasukkan perubahan
      Timnya sedang mengerjakan build x64, dan untuk itu mereka harus mengganti SciTech Multi-platform Graphics Library lama (khusus x86) dengan SDL3. Alternatifnya adalah mem-porting scitech-mgl ke x64, tetapi itu tampaknya kecil kemungkinannya, dan terakhir yang saya tahu software renderer bahkan bisa saja dihapus
      Namun mungkin masih bisa dipertahankan dengan software renderer dan SDL_Texture

  • Artikel ini banyak terinspirasi oleh Doom, tetapi raycasting engine yang sebenarnya lebih dekat ke pendahulu Doom, yang paling terkenal adalah Wolfenstein 3D
    Pendekatannya memakai dinding vertikal serta tinggi lantai dan langit-langit yang tetap. Wolf3D tidak punya lantai dan langit-langit bertekstur karena alasan performa, tetapi ada game lain yang mirip yang memilikinya
    Jika saya ingat dengan benar, Doom dan juga Duke Nukem memakai BSP engine yang jauh lebih fleksibel, sehingga dinding bisa berpotongan pada sudut sembarang atau tinggi lantai/langit-langit bisa berubah. Namun levelnya tetap “datar”, jadi tidak bisa membuat beberapa lantai dalam satu level; misalnya, Anda tidak bisa merancang jembatan yang bisa dilalui baik di atas maupun di bawahnya

    • Engine Build tidak memakai BSP. Ia memperlakukan koneksi antar-sektor sebagai portal, melakukan clipping terhadap portal itu, lalu merasterisasi dinding seperti trapesium yang diputar 90 derajat
      Karena itu, geometri dinding dinamis seperti kereta yang bergerak atau pencahayaan yang berputar bisa dibuat, dan konfigurasi “room over room” juga dimungkinkan selama dua ruangan itu tidak terlihat bersamaan
      Di Blood dan Shadow Warrior, ruang yang lebih mirip “3D” dibuat dengan trik memakai sektor berbentuk sama, lalu menggunakan lantai satu sektor sebagai portal yang terhubung ke langit-langit sektor lain. Itu bukan fitur yang didukung langsung oleh engine, tetapi engine-nya cukup fleksibel sampai studio yang bahkan tidak punya akses ke source code pun bisa mewujudkannya sendiri
      Level pertama Duke Nukem 3D juga memakai beberapa trik Build. Misalnya, sprite bisa dibuat tidak berputar mengikuti kamera dan bisa sejajar sumbu serta memiliki collision, jadi jika tiap sprite diperlakukan sebagai persegi panjang sejajar sumbu, Anda bisa membuat geometri 3D dasar. Di level pertama, ini dipakai untuk membuat jembatan di antara dua bangunan tepat sebelum tombol keluar

    • Blake Stone dan Rise of the Triad memakai versi akhir dari engine Wolf3D, dan memiliki lantai serta langit-langit bertekstur
      Engine Build milik Duke Nukem tidak memakai BSP

      https://www.jonof.id.au/forum/topic-137.html#msg1548

    • Sepertinya di Shadow Warrior hal seperti itu kemudian memang bisa dilakukan. Saya ingat itu diimplementasikan dengan portal, dan pengaturannya di editor cukup menyakitkan

    • Soal lantai, setahu saya bahkan DOOM pun tidak menanganinya secara akurat. Untuk dinding vertikal, pada potongan dinding tertentu Anda hanya perlu melakukan pembagian perspektif sekali per kolom piksel
      Sayangnya untuk lantai tidak ada kemewahan seperti itu, dan jika saya ingat benar, DOOM membagi lantai menjadi beberapa patch lalu menghitung perspektif yang benar hanya di sudut-sudutnya, sementara bagian tengahnya diinterpolasi

    • Awalnya saya kira ini cuma Wolfenstein 3D dengan skin yang diganti. Itu penilaian yang sangat tidak adil, dan ternyata ada sangat banyak pekerjaan yang masuk ke sini

  • Tulisan yang sangat bagus. Pendekatan untuk membuat animasi gib khususnya terasa menarik.
    Walau ini demo teknis, sekitar pertengahan 90-an saya juga pernah membuat sesuatu yang mirip. Satu hal yang tidak terlihat di tulisan ini, saya menggunakan lightmap 8x8 atau 16x16 pada tekstur sehingga efek seperti obor yang berkedip atau roket yang melintas di koridor sambil memancarkan cahaya bisa dibuat dengan mudah. Kalau mau, lightmap juga bisa dipakai untuk “membakar” pencahayaan ke dalam tekstur
    Karena lightmap itu “hanya” 8x8, perhitungannya masih sanggup ditangani: untuk tiap luxel, yaitu tiap unit pada lightmap, dihitung jarak ke sumber cahaya dan garis pandangnya untuk mendapatkan nilai kecerahan. Saat merender tekstur, luxel dipakai bersama lookup table untuk menentukan warna piksel yang benar-benar digambar
    Demi performa, kalau saya ingat benar lightmap diperbarui 15 kali per detik. Berkat DJGPP, saya memakai assembly inline untuk rendering, dan karena operasi floating-point saat itu lambat, saya menggunakan operasi fixed-point yang bisa dioptimalkan dengan baik. Untuk ukuran komputer masa itu, performa rendernya luar biasa

    • Gagasan fixed-point rasanya terlalu jarang dipakai dan kurang dihargai. Ada banyak sekali bidang di mana itu benar-benar pilihan yang lebih baik, dan kadang performanya juga lebih bagus
  • Pemrograman grafis pada awal hingga pertengahan 1990-an cukup menyenangkan. Kita tinggal menulis data piksel ke video RAM yang dipetakan ke memori, lalu langsung muncul di layar
    Satu pointer ke 0xA0000 saja sudah cukup, dan tidak perlu API apa pun. Alasan mode VGA 320×200 dengan piksel tidak persegi yang disebutkan itu adalah karena buffer videonya berukuran 64000 byte, jadi muat dalam segmen 16-bit dan memudahkan pengalamatan bagi kode 16-bit dan CPU

    • Saya selalu merasa lucu bahwa dibanding konsol saat itu, PC punya CPU yang seperti monster, tetapi karena struktur grafisnya justru kesulitan mewujudkan scrolling halus seperti Mario di NES 1985
      Namun karena kelemahan itu, PC bisa melakukan jauh lebih banyak pekerjaan per piksel layar, dan karena itulah sistem ray casting atau pohon BSP seperti ini memungkinkan
      Tidak ada prosesor khusus untuk sprite dan layer latar belakang, tetapi sebagai gantinya kemampuan PC tidak terkurung dalam arsitektur fixed-function yang kaku
      Ketika prosesor 3D khusus muncul pada pertengahan hingga akhir 90-an, ini bukan masalah lagi, tetapi untuk sesaat pada awal 90-an ada taman bermain untuk rendering visual yang unik
    • Satu pointer ke 0xA0000 memang cukup, tetapi extender yang dipakai kadang bisa membuat bagian itu sedikit lebih merepotkan :-P
      DJGPP dan Free Pascal memakai extender go32 yang sama dari DJ Delorie, dan karena itu tidak melakukan pemetaan linear penuh, perlu sedikit utak-atik tambahan untuk menampilkan sesuatu di layar
    • Sebelum VGA muncul, ceritanya jauh lebih rumit
  • Yang paling menarik adalah alat-alat internalnya. Hal-hal seperti skrip Python untuk membuat animasi gib, atau skrip Python lain untuk menghasilkan spritesheet 2D dari Blender
    Penulis aslinya jelas tampak seperti engineer 10x yang juga bisa membuat gambar yang bagus, dan menurut saya kasus seperti ini benar-benar langka. Fakta bahwa ada art direction yang konsisten juga cukup mengagumkan

    • Dari sudut pandang penggemar genre ini di tahun 90-an, rasanya engineer tipe renaisans seperti ini selalu ada di balik karya-karya hit utama. Saya masih ingat beberapa nama, dan mereka benar-benar seniman
      Selama 15 tahun terakhir di industri game, selain CEO atau lead director, saya hampir tidak tahu nama siapa pun
  • Saya baru sadar bahwa game ini mungkin termasuk salah satu shooter langka dengan protagonis perempuan. Kucingnya berpola belang tiga, dan kucing seperti itu hampir selalu betina (https://en.wikipedia.org/wiki/Calico_cat)

    • Apakah shooter dengan protagonis perempuan memang sedemikian langka? Bahkan dari karya yang cukup arus utama yang langsung terlintas, Perfect Dark, Mirror's Edge, Dishonored 1 atau 2, Metroid, semuanya semacam shooter dan protagonisnya perempuan
      Tentu saja, kalau mau benar-benar akurat, Mirror's Edge lebih dekat ke “sudut pandang orang pertama” daripada “shooter”
      Selain itu, di antara game “RPG + FPS” juga banyak yang memungkinkan bermain sebagai laki-laki atau perempuan
      Penulisnya juga tampaknya tahu soal pola bulu dan kemungkinan jenis kelamin kucing:

      After all, I do need to give the protagonist his fair share. [image] (Yes, I know it's a female, but call it convention rooted in dialect.)

    • Ini bukan game Perfect Dark

    • Belakangan ini cukup banyak boomer shooter dengan protagonis perempuan. Misalnya Selaco[0], Supplice[1], The Citadel[2] dan sekuelnya[3], Zortch[4] dan sekuel yang akan datang[5], Nightmare Reaper[6], COVEN[7], Viscerafest[8], Hedon[9], dan lain-lain
      Malah sekarang rasanya boomer shooter dengan protagonis perempuan lebih banyak daripada yang bukan :-P Jika menggabungkan tag “boomer shooter” dan “female protagonist” di pencarian Steam, ada 143 hasil, meskipun itu termasuk game yang memungkinkan memilih gender karakter, atau yang sebagian besar dimainkan sebagai laki-laki tetapi pada beberapa bagian dimainkan sebagai perempuan

      [0] https://store.steampowered.com/app/1592280/Selaco/

      [1] https://store.steampowered.com/app/1693280/Supplice/

      [2] https://store.steampowered.com/app/1378290/The_Citadel/

      [3] https://store.steampowered.com/app/3371240/Beyond_Citadel/

      [4] https://store.steampowered.com/app/2443360/Zortch/

      [5] https://store.steampowered.com/app/3807500/Zortch_2/

[6] https://store.steampowered.com/app/1051690/Nightmare_Reaper/

[7] [https://store.steampowered.com/app/1785940/COVEN/](<https://store.steampowered.com/app/1785940/COVEN/>;)

[8] [https://store.steampowered.com/app/1406780/Viscerafest/](<https://store.steampowered.com/app/1406780/Viscerafest/>;)

[9] [https://store.steampowered.com/app/1072150/Hedon_Bloodrite/](<https://store.steampowered.com/app/1072150/Hedon_Bloodrite/>;)
  • Mungkin ini memang tidak disengaja, tetapi secara umum saya tidak terlalu terkesan dengan hal seperti itu dan juga tidak melihat nilainya. Hal yang sama berlaku untuk penggambaran di Hollywood ketika perempuan menjatuhkan pria yang ukurannya dua kali lebih besar dari dirinya
    Menurut saya itu tidak realistis, konyol, dan berbahaya

  • Keren sekali. Trik menarik lain yang dulu dipakai pada era 90-an adalah animasi palet. Hanya dengan mengubah palet, kita bisa membuat efek yang sangat keren dengan biaya eksekusi yang rendah

    • Betul. Untuk melihat contoh bagus dari teknik ini, saya sangat merekomendasikan situs web ini

      http://www.effectgames.com/demos/canvascycle/

    • Mengganti palet di tengah frame juga menarik. PC tidak punya sesuatu seperti copper di Amiga, jadi kita harus jauh lebih memperhatikan timing, tetapi tetap memungkinkan

    • Kalau tidak salah, banyak musuh di Diablo 1 dan 2 pada dasarnya adalah sprite yang sama dengan palet berbeda yang diterapkan. Apakah itu trik yang sama?

    • Biru adalah air, ungu adalah plasma, merah/jingga adalah darah atau lava

  • Saya benar-benar terkejut karena sprite yang dikuantisasi setelah dirender ternyata terlihat cukup bagus. Berkat konversi cepat itu, hasilnya tampak sangat tajam

  • Sebagai sesama pengembang yang membuat mesin 3D dengan batasan yang sangat tidak masuk akal, saya sangat senang melihat detail dan proses yang dijelaskan di sini

  • Saya sedang mengutak-atik tech demo rendering ruang voxel untuk homebrew PlayStation. Setelah satu atau dua hari kerja di akhir pekan, hasilnya sudah lumayan, sekitar 10~15 FPS, dan saya bahkan belum memakai DMA atau GTE, apalagi primitive polyline
    Menyegarkan rasanya kembali membuka trigonometri dan trik optimisasi low-level gaya lama. Saat scratch buffer hanya 1KiB dan stack pun hanya boleh memakai sebagian darinya, kita jadi sadar betapa mewahnya mikrokontroler yang saya pakai di tempat kerja. Di sana, setiap thread mendapat stack 8KiB, dan backtrace dengan lebih dari 50 fungsi templat C++ yang menumpuk pun masih bisa muncul