Bab 4: Sejarah Lengkap Pembangunan Aset (CP1–CP49)

Bab ini berisi catatan sejarah lengkap pembangunan aset 3D untuk game mancing sudut pandang orang pertama. Catatan ini disebut "checkpoint" (disingkat CP), diberi nomor urut dari CP1 sampai CP49, dan disusun secara kronologis — checkpoint paling lama di atas, paling baru di bawah. Setiap checkpoint mencatat apa yang dikerjakan, kenapa dikerjakan, apa yang berubah, dan hasilnya. Beberapa checkpoint ternyata salah atau belum benar-benar selesai, dan baru dikoreksi di checkpoint berikutnya — hal ini akan ditulis dengan jelas supaya tidak membingungkan pembaca. Proyek ini mencakup pembuatan 10 spesies ikan dan seluruh aset lingkungan (dermaga, air, tanah, joran, langit, batu, pohon, dll) untuk game yang dibangun dengan RealityKit di iPad/macOS.

CP1 — Riset ilmiah Ikan Badut (Clownfish) (tag: Sourcing/Riset)

Tim mengumpulkan data biologi asli tentang Ikan Badut dari FishBase, IUCN, ADW, dan USGS Wikipedia. Ini perlu dilakukan karena tahap pertama dari alur kerja proyek mengharuskan data spesies yang akurat sebelum mulai membuat model 3D. Hasilnya: ukuran rata-rata 80mm, maksimal 110mm. Termasuk ordo Perciformes, famili Pomacentridae. Cara berenangnya disebut "labriform" (mendayung pakai sirip dada). Punya 11 duri punggung dan 3 garis putih di badan oranye. Umur hidup 6–10 tahun. Hasil: berhasil, data ini jadi dasar dan tidak pernah diubah.

CP2 — Pencarian aset Ikan Badut (tag: Sourcing)

Tim menilai 9 kandidat model 3D dari Sketchfab, CGTrader, Meshy.ai, Fab, dan GitHub untuk dijadikan dasar model. Pemenangnya: model "fabip Clownfish" di Sketchfab (kode UID eb4e28ae), lisensi CC-BY, 20.700 segitiga (triangle). Hasil: berhasil.

CP3 — Unduh dan verifikasi Ikan Badut (tag: Sourcing/Verifikasi-Ekspor)

File sumber diunduh lewat API Sketchfab: file ZIP (9,9MB) dan file GLB (0,8MB), lalu diverifikasi. Hasil verifikasi: 20.654 segitiga, 4 material, dan 1 peta UV dengan cakupan 99,9%. Hasil: berhasil.

CP4 — Retopologi/UV Ikan Badut dilewati (tag: Modeling)

Tahap merapikan topologi mesh dan peta UV dilewati karena keduanya sudah cukup bagus apa adanya — topologi berbasis segitiga sudah oke, dan peta UV sudah tervalidasi. Hasil: berhasil, tidak perlu dikerjakan ulang.

CP5 — Texturing Ikan Badut (tag: Material/Shader)

4 material dibangun ulang jadi shader PBR (Principled BSDF). Base Color dan Roughness dipasang, Normal map dipasang, Clearcoat diset 0,3, dan Subsurface Scattering diset 0,1. Hasil: berhasil.

CP6 — Rig kerangka Ikan Badut (tag: Rigging)

Kerangka (armature) 10 tulang dibangun: Root, Spine, Spine.001, Tail, Head, Dorsal_Fin, Anal_Fin, Caudal_Fin, Pectoral_Fin_L/R. Ini perlu sebelum animasi bisa dibuat. Weight painting (pembobotan mesh ke tulang) dilakukan per zona anatomi. Hasil: berhasil — struktur 10-tulang ini jadi template standar proyek yang dipakai lagi di ikan-ikan berikutnya.

CP7 — Animasi Cruise (berenang santai) Ikan Badut (tag: Animasi)

Dibuat animasi loop berenang 48 frame (2 detik) pada 24fps. Ini animasi pertama dari 4 state animasi yang dibutuhkan. Detailnya: gerakan gelombang badan, sirip dada mendayung dengan frekuensi dua kali lipat, gelombang sirip punggung/anal, dan ekor yang serasi. Total 432 keyframe di 9 tulang. Hasil: sebagian selesai — hanya state Cruise yang jadi; Bite (menyambar umpan), Caught (tertangkap), Preview (pratinjau) masih perlu dibuat.

CP8 — Polishing Ikan Badut (tag: Modeling/Rigging)

Mesh dipusatkan ulang ke titik origin dunia, kerangka dibangun ulang di posisi yang benar, mode rotasi diperbaiki jadi Euler XYZ, lalu diekspor ulang jadi GLB (3,74MB) tanpa ada peringatan (warning). Hasil: berhasil.

CP9 — Ekspor pertama Ikan Badut (tag: Ekspor/Verifikasi)

File GLB (3,74MB) diekspor dan file .blend (3,8MB) disimpan ke folder yang benar. Hasil: sebagian — baru state Cruise saja yang diekspor pada titik ini.

CP10 — Penutupan tahap dokumentasi Ikan Badut (tag: Serah Terima/Dokumentasi)

File Asset_Candidates.md dan Source_Log.md diperbarui dengan catatan perbaikan; CHECKPOINT.md juga diperbarui. Status Fish01 (Ikan Badut): SEBAGIAN (baru Cruise). Yang masih tertunda: 3 state animasi lagi, lalu uji import ke RealityKit.

CP11 — Riset ilmiah Blue Tang (tag: Sourcing/Riset)

Data spesies dikumpulkan: nama ilmiah Paracanthurus hepatus, famili Acanthuridae, ukuran maksimal 31cm, perenang labriform, badan biru dengan pola bentuk-palet hitam dan ekor kuning. Hasil: berhasil.

CP12 — Pencarian aset Blue Tang (tag: Sourcing)

7 kandidat dinilai dari Sketchfab, CGTrader, Free3D, BlendSwap, Poly Haven, TurboSquid, dan A23D. Pemenangnya: "bronze82 BlueTang" (Sketchfab, UID d06263fc, lisensi CC-BY, 51.100 segitiga). Hasil: berhasil.

CP13 — Alur penuh Blue Tang (tag: Rigging/Animasi/Ekspor)

Model diunduh, di-rig pakai kerangka standar 10-tulang yang sama, dianimasikan berenang 48 frame, diekspor jadi GLB (3,29MB). Masalah yang diperbaiki: sumbu Y/Z tertukar pada mesh dan tulang — model tampil miring di RealityKit sampai dikoreksi. Hasil: berhasil (berhasil memperbaiki bug orientasi yang nyata).

CP14 — Push git dan penulisan aturan (tag: Dokumentasi/Serah Terima)

Repo di-push ke git@github.com:K-ere-Horee/blender-assets.git. File AGENTS.md dibuat berisi aturan lengkap alur kerja, ditambah aturan wajib memperbarui dokumentasi. Status Fish02 (Blue Tang): SEBAGIAN (baru Cruise, 3 state lain masih tertunda).

CP15 — Alur penuh Giant Trevally, pembuatan pertama (belakangan diketahui rusak) (tag: Sourcing/Rigging/Animasi/Ekspor)

Model pindaian CC0 dari ffishAsia diunduh (966.000 segitiga). Di-decimate (dikurangi jumlah poligon) jadi 20.000 segitiga. Kerangka 10-tulang dibangun dengan weight painting manual per zona (fitur otomatis "Bone Heat" gagal dipakai). 4 animasi dibuat (Cruise 48 frame, Bite 24 frame, Caught 72 frame, Preview 48 frame). GLB diekspor, masing-masing 17,7MB (kebesaran karena tekstur 4K). Hasil: waktu itu ditandai selesai, tapi belakangan diketahui rusak (lihat CP27) — mesh-nya pecah jadi segitiga-segitiga lepas bahkan saat diam. Penyebabnya: tidak ada langkah "weld" (menyatukan vertex) sebelum decimate. Baru dibangun ulang total di CP30.

CP16 — Alur penuh Bluefin Tuna, tahap pertama (tag: Sourcing/Rigging/Animasi/Ekspor)

Model diunduh dari Sketchfab buatan "dhjwdwd" (6.920 poligon, rig 98-tulang, tekstur PBR 4K, sudah ada klip animasi berenang profesional bernama "FishSwim.012"). Diskalakan ke ukuran nyata 3,0 meter. GLB diekspor, 54MB (kebesaran). Masalah: nama tulang tidak standar tapi klip animasinya tetap dipakai; GLB awalnya menggabungkan semua action di scene, lalu dibersihkan supaya cuma berisi klip berenang saja. Hasil: sebagian — belakangan dikerjakan ulang besar-besaran di CP17–CP19 dan CP23–CP25.

CP17 — Pembersihan scene Bluefin Tuna (tag: Modeling/Rigging)

20 node kosong sisa import Sketchfab yang berantakan dihapus (Sketchfab_model, RootNode, ExportRIG, dll), satu set model duplikat dihapus, rantai parent dibersihkan, armature dipindah ke origin dunia, semua transform di-apply, dan modifier armature dibangun ulang (98 vertex group cocok dengan 98 tulang). File BluefinTuna.blend disimpan terpisah. Ini perlu dikerjakan karena hasil import punya kesalahan skala/rotasi bawaan dari hierarki 5-level node kosong plus ketidakcocokan skala antara mesh badan dan armature. Verifikasi pembobotan: tulang Hips_01 menggerakkan 61% vertex, Spine_02 59%, Head_05 21%. Hasil: berhasil.

CP18 — Downscale tekstur Bluefin Tuna (tag: Ekspor/Verifikasi)

Tekstur PBR 4K (baseColor, metallicRoughness, normal) diperkecil jadi 2K (2048×2048). Transform diterapkan ulang, mesh diselaraskan ulang ke armature. GLB diekspor ulang. Hasil: berhasil — ukuran GLB turun dari 54MB jadi 17,9MB (turun 67%). File .blend disimpan di ukuran 53,3MB.

CP19 — 3 state animasi tambahan Bluefin Tuna (tag: Animasi/Ekspor)

Dibuat state Bite (24 frame: melengkung→menyambar→tenang, gerak rahang+sirip), Caught (72 frame: meronta 1–30 → tenang 31–50 → showcase 51–72), Preview (48 frame: idle bernapas pelan). Hasil ekspor: Cruise 18,1MB/60 frame, Bite 18,2MB/24 frame, Caught 18,2MB/72 frame, Preview 18,2MB/48 frame. Status Fish04 (Bluefin Tuna) ditandai LENGKAP di titik ini — tapi bug animasi/ekspor baru muncul belakangan (lihat CP23–CP25).

CP20 — 4 state Blue Tang (tag: Animasi/Ekspor)

Dibuat Cruise (60f), Bite (24f), Caught (72f), Preview (48f) di rig standar 10-tulang dengan pembobotan otomatis baru. Semua 4 file GLB berukuran 3,33MB. Hasil: ditandai LENGKAP — belakangan diketahui SALAH (lihat catatan tabel Progres Keseluruhan): Blue Tang sebenarnya cuma punya SATU animasi asli; 3 "state" lainnya ternyata cuma salinan identik byte-per-byte dari Cruise. Klaim CP20 soal "4 state lengkap" ini ditandai keliru setelah dicek ulang. Dibiarkan apa adanya karena Blue Tang di luar daftar utama ikan Indonesia.

CP21 — 4 state Giant Trevally (di atas mesh yang rusak) (tag: Animasi/Ekspor)

Dibuat Cruise/Bite/Caught/Preview (60/24/72/48 frame). Modifier Decimate diterapkan (rasio 0,21, dari 21K jadi 12K vertex). GLB diekspor pada ukuran 16,94MB. Hasil: ditandai LENGKAP, ukuran GLB kebesaran — tapi seluruh pembuatan ini dilakukan di atas mesh yang sudah pecah/hancur; digantikan total oleh pembangunan ulang di CP30.

CP22 — 4 state Ikan Badut (tag: Animasi/Ekspor)

Dibuat Cruise/Bite/Caught/Preview (60/24/72/48 frame) di rig standar 10-tulang. Semua 4 file GLB berukuran 3,79MB. Hasil: ditandai LENGKAP — catatan sama seperti Blue Tang (CP20): belakangan dipastikan (dicek ulang) bahwa Bite/Caught/Preview cuma salinan identik byte-per-byte dari Cruise, bukan animasi terpisah yang asli. Tidak pernah ada file USDZ untuk Ikan Badut. Dibiarkan apa adanya, di luar daftar utama.

CP23 — 3 bug ekspor USDZ kritis Bluefin Tuna diperbaiki (tag: Ekspor/Verifikasi)

Tiga bug ekspor nyata diperbaiki:

  1. Kanal metallic tidak punya tekstur kulit — sebuah node Math (Multiply ×0,5) pada input metallic secara diam-diam dibuang oleh exporter USD; diperbaiki dengan menghapus node math tersebut dan menyambungkan langsung kanal Blue ke Metallic.
  2. Bagian mesh yang hilang — pengaturan relative_paths=False menaruh tekstur di folder 0/ di dalam USDZ alih-alih di folder textures/, sehingga referensinya rusak; diperbaiki dengan relative_paths=True.
  3. Animasi tidak muncul di Reality Composer — pengaturan export_animation defaultnya False; diperbaiki dengan menyetel export_animation=True. Juga diset convert_orientation=True dan export_global_up_selection='Y' supaya kompatibel dengan sumbu Y-up.

Semua 4 state diekspor ulang sebagai GLB+USDZ. Ukurannya sekitar 1,95MB (GLB) / 2,1MB (USDZ) masing-masing. Hasil: ditandai LENGKAP — tapi masih ada bug lain yang ditemukan di periode yang sama (lihat CP24/CP25).

CP24 — Bangun ulang animasi penuh Bluefin Tuna (tag: Bug Animasi/Material-Shader)

Pengguna melaporkan kulit ikan hilang/kosong dan animasi terlihat tidak wajar. Ditemukan TIGA bug yang saling terpisah:

  1. File .blend kerja kehilangan 3 dari 4 action animasi (hanya Preview yang selamat) — pembersihan data yatim (orphan data) lama menghapus action yang tidak punya use_fake_user.
  2. Animasi yang tersisa hanya menggerakkan 22 dari 98 tulang (sekitar 50 tulang jari-jari sirip punggung dan sebagian besar segmen sirip lain diam saja), dengan amplitudo sangat kecil sekitar 0,2° — ini penyebab sebenarnya dari kesan "tidak wajar".
  3. Ekspor USDZ membakar (bake) latar belakang World scene yang hampir hitam menjadi prim DomeLight yang ikut tertanam, membuat model yang teksturnya sudah benar jadi tampak hampir hitam di Reality Composer — ini penyebab sebenarnya dari kesan "kulit kosong" (material sebenarnya tidak pernah benar-benar rusak).

Perbaikan: semua 4 state dibangun ulang (Cruise 90f, Bite 30f, Caught 90f, Preview 60f) mencakup setiap rantai tulang dengan amplitudo yang meruncing secara biomekanis. Ekspor USDZ diperbaiki (convert_world_material=False) dan ekspor GLB diperbaiki (export_animation_mode='ACTIVE_ACTIONS', sebelumnya setiap file state malah menggabungkan semua 4 action). Sekitar 18 file ekspor debug sisa dihapus. Keterbatasan yang diketahui: tekstur dikirim di resolusi 512×512, turun dari dokumentasi 2K (sumber resolusi lebih tinggi sudah tidak tersedia lagi secara lokal). Hasil: bug animasi/ekspor diperbaiki — tapi CP25 menemukan regresi BARU di hari yang sama (mesh sobek), jadi ini belum jadi perbaikan final.

CP25 — Perbaikan sesungguhnya untuk regresi mesh sobek Bluefin Tuna (tag: Bug Rigging/Animasi)

Pengguna menguji hasil ekspor CP24 di Reality Composer dan menemukan mesh sobek — jari-jari sirip punggung terlepas, segmen sirip patah, celah terlihat di sambungan — padahal render uji terpisah di CP24 terlihat baik-baik saja.

Penyebab utama: banyak vertex di dekat pangkal sirip dibobotkan secara halus ke beberapa rantai tulang independen sekaligus (contoh: satu vertex membawa bobot pada 3 jari sirip punggung berbeda sekaligus: UpperFin.001_032 bobot 1,0, UpperFin.005_036 bobot 0,3, UpperFin.013_039 bobot 0,12; pangkal sirip dada dan sirip anal bertumpang tindih bobot sampai 84%). Animasi di CP24 memberi setiap jari sirip fase/frekuensi independen, sehingga tulang yang berbagi bobot vertex bergerak berbeda arah dan menyobek mesh.

Perbaikan yang dilakukan:

  • Fase acak per-rantai diganti dengan satu fase global yang diturunkan dari posisi rest-pose asli setiap tulang, supaya tulang-tulang yang berdekatan secara spasial tetap sinkron tanpa peduli nama rantainya.
  • Frekuensi osilasi disatukan dalam tiap state (sirip dada dan sirip anal tidak lagi berjalan dengan kecepatan berbeda).
  • Amplitudo yang meruncing dari pangkal ditambahkan untuk setiap embel-embel tubuh (amplitudo mendekati nol di ~45% awal rantai tempat pembobotan bertumpang tindih, baru naik di segmen luar yang bobotnya bersih).
  • Diverifikasi dengan render lebar dan dekat pada frame puncak amplitudo di semua 4 state sebelum menyentuh file asli.
  • Semua 4 state + main showcase diekspor ulang; kelima file USDZ lolos usdchecker.
  • Pelajaran umum (bobot kulit yang dibagi antar rantai tulang "independen" menyebabkan sobek jika dianimasikan tidak sinkron) didokumentasikan di AGENTS.md §13 untuk spesies mendatang.

Hasil: Fish04 (Bluefin Tuna) LENGKAP — animasi, ekspor, dan masalah sobek semuanya benar-benar terselesaikan dan tervalidasi.

CP26 — Perencanaan pivot roster spesies + debug koneksi MCP (tag: Serah Terima/Sourcing)

Sesi diakhiri untuk beralih ke koneksi Blender MCP langsung (yang bisa dilihat) alih-alih headless. Belum ada pekerjaan aset baru dimulai. Pengguna ingin "ikan besar yang umum ditangkap di Indonesia" sebagai spesies berikutnya. Kandidat yang dibahas: Yellowfin Tuna, Skipjack Tuna, Giant Trevally (sudah jadi Fish05), Grouper, Marlin (diketahui terhalang — belum ada aset gratis ditemukan), Bluefin Tuna (sudah jadi Fish04).

Keputusan: lanjut dengan Yellowfin Tuna (Thunnus albacares / Madidihang) lebih dulu, urutan cadangan Skipjack Tuna → Grouper kalau tidak tersedia. Folder baru: Fish07_YellowfinTuna.

Debug MCP: penyebab gagalnya koneksi live ditemukan — sesi chat berjalan sebagai job latar belakang, proses OS terpisah dari terminal pengguna tempat dialog kepercayaan MCP disetujui, jadi tidak pernah tersambung. Perbaikan: .claude/settings.local.json diset enableAllProjectMcpServers: true dan enabledMcpjsonServers: ["blender"], supaya sesi baru bisa otomatis tersambung tanpa dialog. Hasil: hanya catatan serah terima, tidak ada perubahan aset.

CP27 — Pivot gaya seni dicoba lalu dibatalkan; Giant Trevally dipastikan rusak (tag: Sourcing/Art-direction)

Pengguna meminta uji coba gaya seni "cozy casual-game" (gradasi datar, lalu gaya lukisan ala AFK-Journey) pada Bluefin Tuna sebagai perbandingan. Setelah melihat hasil render, pengguna memutuskan mempertahankan gaya realistis asli dan membatalkan pivot ini. Pembatalan: semua folder output bergaya (Stylized/ di bawah Fish01/02/04) dihapus — file realistis asli tidak pernah tertimpa.

Temuan nyata yang terbawa ke depan: Giant Trevally (Fish05) terbukti rusak dalam status "lengkap" yang sudah dikirim sebelumnya — baik GLB Cruise yang sudah dikirim maupun file .blend kerja menampilkan mesh yang pecah jadi ribuan segitiga lepas bahkan saat diam, cacat bawaan dari modifier DECIMATE (rasio 0,21) di CP21 yang diterapkan pada pindaian mentah tanpa "weld" (penyatuan vertex). CHECKPOINT.md sebelumnya menandai Fish05 "LENGKAP" (CP15/CP21) tapi sebenarnya tidak — dipastikan dengan me-render ulang GLB asli tanpa gaya baru. Perlu di-weld ulang dan di-rig ulang dari sumber (kemudian dilakukan di CP30).

Catatan lain: sumber model CC0 untuk Fish07 Yellowfin diunduh sesi ini (disimpan), tapi pembuatannya belum dimulai. Hasil: gaya seni berhasil dikembalikan; cacat asli yang sebelumnya tidak diketahui (Giant Trevally) terungkap dan terdokumentasi.

CP28 — Roster "tangkapan besar" Indonesia dipastikan (tag: Sourcing/Dokumentasi)

Pengguna memastikan roster ikan kerja adalah set tangkapan besar Indonesia (Bluefin Tuna, Yellowfin Tuna, Giant Trevally, Skipjack Tuna, Grouper, Marlin/slot ikan todak) — menggantikan daftar lama AGENTS.md berisi Ikan Badut/Blue Tang/Arwana/Barracuda/Bluefin.

Ringkasan status di titik ini: Bluefin Tuna selesai; Yellowfin Tuna selesai (CP29, hari yang sama); Giant Trevally dibangun ulang (CP30, hari berikutnya); Skipjack Tuna selesai (CP31); Grouper selesai (CP32); slot Marlin/ikan todak diisi oleh Sailfish (CP33, pengganti CC-BY, karena belum ada Marlin asli gratis).

Catatan: Ikan Badut dan Blue Tang tetap lengkap tapi di luar target set ini; Fish06 Mekong Giant Catfish juga di luar set ini. Hasil: checkpoint dokumentasi/penetapan cakupan.

CP29 — Yellowfin Tuna (Fish07), pembuatan penuh selesai (tag: Sourcing/Rigging/Animasi/Ekspor)

Dibangun dari awal sampai akhir dari pindaian CC0 ffishAsia.

  • Pembersihan/decimate: 20 ubin (tile) pindaian foto digabung, satu properti bagan warna yang melayang dihapus, di-weld (gabung vertex berdasarkan jarak) dari 1,17 juta jadi 0,69 juta vertex, menurunkan rasio boundary dari 0,34 jadi 0,0 (tersambung penuh). Lalu di-decimate dari 1,39 juta jadi 28.000 segitiga sambil tetap tersambung (boundary 0,007). Langkah "weld dulu" ini persis yang tidak ada di pembuatan awal Giant Trevally (CP15/CP21).
  • Orientasi: pindaian mentah rotasinya kusut; diperbaiki lewat penyelarasan sumbu PCA (panjang di +Y, kepala di origin) plus rotasi 180° supaya punggung gelap menghadap atas, diterapkan ke mesh+tulang bersamaan supaya pembobotan tetap terjaga. Diskalakan ke 2,0m.
  • Rig: armature standar 10-tulang + tulang Jaw (rahang), ditempatkan dari deteksi anatomi. Auto-weight Bone-heat gagal (grup kosong) → dipakai pembobotan zona (blend rantai tulang belakang + sirip meruncing dari pangkal untuk mencegah sobek).
  • Animasi: 4 state lewat gelombang berjalan kepala-ke-ekor (gaya berenang tuna "thunniform"): Cruise 90f loop, Bite 30f (melengkung→menyambar+gerak rahang), Caught 90f (meronta→tenang→showcase), Preview 60f (idle). Dipastikan tidak sobek lewat render ortho di amplitudo puncak.
  • Ekspor: tekstur 4K→2K. 4 GLB (~4,2MB masing-masing) + 4 USDZ (~1,9MB masing-masing). Re-import memvalidasi mesh, 3 material bertekstur, animasi 33-kanal, skin 11-joint.

Hasil: Fish07 LENGKAP, file YellowfinTuna.blend disimpan. Metode "weld dulu" ini jadi template untuk semua spesies berikutnya.

CP30 — Giant Trevally (Fish05) DIBANGUN ULANG dari sumber, memperbaiki keretakan (tag: Rigging/Sourcing)

Fish05 lama rusak (mesh dasar pecah, sesuai CP27). Sumber CC0 ffishAsia yang sama diunduh ulang (UID e6446df50ba746ed8ce8a3dd66b3b8e8) dan dibangun ulang pakai metode weld-dulu yang sudah terbukti di Yellowfin.

  • Pindaian mentah berupa "sup segitiga" (rasio boundary 36,6%). Di-weld dari 428 ribu jadi 241 ribu vertex → boundary jadi 0,0. Ubin bagan warna dihapus. Di-decimate dari 483 ribu jadi 28.000 segitiga, tetap tersambung (boundary 0,003).
  • Diorientasikan pakai PCA (panjang +Y, punggung gelap +Z, tegak, tidak perlu dibalik kali ini), diskalakan ke 1,2m.
  • Rig: 10-tulang + Jaw, pembobotan zona, semua vertex tercakup.
  • Animasi: 4 state (90/30/90/60 frame), gelombang berjalan, dipastikan tidak sobek termasuk di frame puncak meronta Caught yang paling ekstrem.
  • Ekspor: tekstur→2K; 4 GLB (~3,3MB, turun dari yang rusak sebesar 16,94MB) + 4 USDZ (~2,0MB). File GiantTrevally.blend baru menggantikan yang rusak.

Hasil: Fish05 LENGKAP (dibangun ulang) — benar-benar bekerja, tidak pecah. (Catatan: mesh Preview-nya belakangan ditemukan masih ada sisa topologi bermasalah — lihat CP43/CP46, dan tindak lanjut CP46 menemukan mesh-nya tampak berduri/sobek lagi dengan cara berbeda — jadi kata "diperbaiki" di sini khusus merujuk ke cacat pecah dari CP27, bukan semua cacat di masa depan.)

CP31 — Skipjack Tuna (Fish08), pembuatan penuh selesai (tag: Sourcing/Rigging/Animasi/Ekspor)

Spesies baru pakai alur weld-dulu yang sekarang jadi standar.

  • Pencarian: hanya satu model yang bisa diunduh sesuai anatomi spesies — pindaian CC0 ffishAsia (UID 9431157b2fce…), ideal (CC0, anatomi tepat).
  • Weld/decimate: boundary 0,318→0,0 (setelah weld), 1,26 juta→28.000 segitiga, tersambung.
  • Orientasi/skala: PCA (panjang +Y, punggung gelap +Z, tegak, tidak dibalik), 0,9m.
  • Rig: 10-tulang + Jaw, bobot zona, semua vertex tercakup.
  • Animasi: 4 state gaya thunniform, tidak sobek (dipastikan di puncak meronta Caught).
  • Ekspor: tekstur 2K; 4 GLB (~4,1MB) + 4 USDZ (~1,9MB). File SkipjackTuna.blend disimpan. Garis-garis diagnostik di perut tetap dipertahankan di tekstur.

Hasil: Fish08 LENGKAP.

CP32 — Grouper/Kerapu (Fish09), pembuatan penuh selesai (tag: Sourcing/Rigging/Animasi/Ekspor)

Spesies non-tuna pertama; pakai animasi yang disesuaikan untuk ikan karang (bukan thunniform).

  • Pencarian: dipilih kerapu CC0 ffishAsia dengan segitiga paling sedikit — Kerapu Kuning E. awoara (UID 17f6e5eb3efa…, 934 ribu segitiga) dari beberapa kandidat CC0.
  • Weld/decimate: boundary 0,381→0,0, 934 ribu→28.000 segitiga, tersambung.
  • Orientasi/skala: PCA (tegak, tidak dibalik), 0,6m.
  • Rig: 10-tulang + Jaw (rahang dibobotkan untuk animasi menghisap-mangsa).
  • Animasi: amplitudo lebih rendah + tempo lebih lambat dari tuna, gerakan Bite berupa hisapan rahang besar. 4 state, tidak sobek, semua 4 file GLB punya checksum berbeda (memastikan bukan duplikat tidak sengaja).
  • Ekspor: tekstur 2K; 4 GLB (~3,8MB) + 4 USDZ (~2,0MB). File Grouper.blend disimpan.

Hasil: Fish09 LENGKAP. Roster Indonesia sekarang 5/6 selesai (hanya Marlin yang tersisa, masih ditandai terhalang di titik ini).

CP33 — Sailfish (Fish10), slot ikan todak terisi, selesai (tag: Sourcing/Animasi/Ekspor)

Belum ada model Marlin asli (Makaira) yang gratis/CC di titik ini (hanya pindaian fosil) — pengguna menyetujui pengganti berupa Sailfish (Ikan Layaran), kerabat dekat ikan todak, spesies khas Indonesia.

Detail: berbeda dari ikan-ikan hasil pindaian foto sebelumnya, ini adalah model game bersih yang sudah di-rig dan dianimasikan sejak awal: "Sailfish" oleh Mateus Schwaab, lisensi CC-BY (UID 5c7b14e21fba…), 4.700 segitiga, rig 17-tulang, 3 animasi asli (Swim/SwimFast/Bite), PBR penuh.

  • Pembersihan: diskalakan ulang dari 967 unit jadi 2,72m; diorientasikan ulang sesuai konvensi proyek (panjang +Y, layar/sirip punggung besar +Z, tegak) lewat transform armature, di-bake saat ekspor.
  • State-state memakai ulang klip dari rig yang sudah ada: Cruise←Swim, Bite←Bite, Caught←SwimFast, Preview←Swim dengan kecepatan waktu ×2 (sekitar 0,5× kecepatan sesuai spesifikasi). Semua 4 berbeda satu sama lain.
  • Ekspor: 4 GLB (~1,0MB) + 4 USDZ (~1,1MB), masing-masing dengan animasi (51 kanal) + skin + baseColor. File Sailfish.blend disimpan.

Hasil: Fish10 LENGKAP. Atribusi wajib (CC-BY). Roster Indonesia efektif 6/6 (slot ikan todak = Sailfish); Marlin asli (Fish03) masih ditandai "tidak ada aset gratis" di titik ini.

CP34 — Blue Marlin (Fish03), terhalang teratasi, pembuatan penuh selesai (tag: Sourcing/Rigging/Animasi/Ekspor)

Fish03 sebelumnya ditandai "tidak ada aset gratis / perlu generasi AI" — tapi kesimpulan itu terlalu dini: pencarian awal menyaring lisensi Sketchfab berdasarkan kolom slug yang sebenarnya tidak ada, dan hanya mencari kata "marlin" (yang didominasi hasil senapan merek Marlin). Pencarian ulang yang diperbaiki (lisensi dicocokkan lewat kolom label, hasil senapan/pesawat luar angkasa/fosil disaring, hanya yang bisa diunduh, sinonim ikan todak dicoba) menemukan model marlin CC-BY yang layak. Tidak perlu generasi AI.

  • Sumber: "Blue Marlin" oleh Gotta_go_evil_Fast, lisensi CC-BY 4.0 (UID 7d5e0636…), 8.280 segitiga, tekstur diffuse 2K (alur kerja spec-gloss), belum di-rig. Atribusi wajib.
  • Pembersihan/orientasi: hierarki node kosong Sketchfab dibersihkan, transform diterapkan; dibalik supaya kepala di −Y / ekor di +Y / punggung di +Z lewat perhitungan vertex langsung (fungsi transform_apply Blender ternyata tidak berfungsi sama sekali lewat konteks eksekusi MCP — kendala nyata yang ditemukan); diskalakan ke 3,0m; dipusatkan.
  • Tekstur: alur kerja spec-gloss dikonversi ke Principled BSDF (Base Color, roughness 0,4, coat 0,3).
  • Rig: armature baru 11-tulang (Root +Y, Spine×3, Head/moncong, Tail, Caudal, Dorsal, Anal, Pect L/R); pembobotan zona berbasis jarak-terbalik; 0 vertex tanpa bobot; tidak sobek.
  • Animasi: 4 state gaya thunniform, semua loop mulus (celah 0,0): Cruise 48f/2,0d, Bite 24f/1,0d, Caught 72f/3,0d, Preview 48f/2,0d. Semua berbeda amplitudo/durasi.
  • Ekspor: 4 GLB (~0,91MB) + 4 USDZ (~1,07MB); usdchecker "Sukses!"; semua di bawah 10MB. File Marlin.blend disimpan.

Hasil: Fish03 LENGKAP — CC-BY, atribusi wajib. Slot ikan todak sekarang punya baik Sailfish (Fish10) maupun Marlin asli (Fish03).

CP35 — Mekong Giant Catfish (Fish06), terhalang teratasi, pembuatan penuh selesai (tag: Sourcing/Rigging/Animasi/Ekspor)

Aset terhalang terakhir. Tidak ada model gratis untuk spesies langka asli Pangasianodon gigas — tapi karena spesies ini masuk famili Pangasiidae, model CC-BY gratis Pangasius ("ikan patin") dari famili/bentuk tubuh yang sama tersedia. Diganti dengan kerabat sefamili; tidak perlu generasi.

  • Sumber: "Ikan Patin" (Sketchfab, dibuat pakai Meshy AI), lisensi CC-BY 4.0 (UID d9e7f483…), 118.096 segitiga, PBR 2K penuh. Atribusi wajib.
  • Weld/decimate: 2 bagian digabung, di-weld (tepi boundary 25.705→8), di-decimate dari 118 ribu jadi 17.950 segitiga. Diverifikasi boundary 0,0003, 1 pulau (island), tidak ada yang terpecah.
  • Orientasi/skala: kepala −Y / punggung +Z sudah benar (tidak perlu dibalik), diskalakan ke 2,0m, dipusatkan.
  • Tekstur: PBR metallic-roughness dipertahankan (metallic 0, kulit dielektrik).
  • Rig: armature 11-tulang, bobot zona, 0 tanpa bobot.
  • Animasi: 4 state gaya subcarangiform (gelombang badan penuh, tempo lebih lambat dari tuna/ikan todak, karena lele lebih lentur saat berenang). Semua loop mulus (selisih titik akhir 0,0), berbeda-beda.
  • Ekspor: 4 GLB (~4,75MB) + 4 USDZ (~5,0MB); usdchecker "Sukses!"; di bawah 10MB. File MekongCatfish.blend disimpan.
  • Masalah di tengah pembuatan yang berhasil dipulihkan: 3 action animasi terhapus sebagai data yatim saat penyimpanan pertama (diperbaiki dengan menambahkan fake user); loop verifikasi berat membuat add-on Blender macet (diganti dengan pengecekan titik-akhir fcurve yang ringan).

Hasil: Fish06 LENGKAP — CC-BY, atribusi wajib. Checkpoint ini menandai semua aset yang sebelumnya terhalang sudah teratasi: Marlin (Fish03) dan Catfish (Fish06) sama-sama dibangun di sesi ini. Tidak ada ikan yang tersisa terhalang di titik ini.

CP36 — Rekonsiliasi konsep lingkungan + 6 aset esensial dimulai (dermaga, air, tanah, joran, tali pancing — tahap pertama) (tag: Lingkungan)

Koreksi premis besar: brief awal mendeskripsikan "game mancing AR", tapi pengguna memastikan ini BUKAN AR — kamera perangkat tidak pernah dipakai; RealityKit merender dunia 3D sepenuhnya virtual sudut pandang orang pertama. Latar: danau pancing trofi yang sudah distok ikan (dalam, buatan manusia/eksotik, skala waduk) yang membenarkan spesies laut dalam dan air tawar berbagi satu badan air. Pemain berdiri di dermaga kayu pada tinggi mata sekitar 1,6m.

Dokumentasi yang diperbarui: AGENTS.md §1.1 ditulis ulang (konsep "kolam" dan "deteksi permukaan datar" digantikan — tidak perlu deteksi bidang lagi), §1.2 diperluas (tulang joran, rig tali, reel), §4.1b baru (anggaran segitiga lingkungan, terpisah dari anggaran ikan), §4.2b baru (tingkatan tekstur 2K hero / 1K latar belakang / 512 kecil), §4.6 baru (konvensi pencahayaan golden-hour bersama), §8.0 baru (aturan penamaan snake_case), §14 dikoreksi (bukan AR, USDZ, tinggi mata 1,6m). File baru BUILD_PLAN_ENV.md dibuat berisi alur lingkungan (E01–E12).

Keputusan pengguna: satu scene lingkungan yang imersif, penamaan snake_case di mana-mana, USDZ saja untuk aset lingkungan, sumber Sketchfab diutamakan (generasi AI hanya jalan terakhir), pencahayaan dibakar (skybox + lampu directional statis, tidak ada siklus siang-malam).

Pengecekan realita alat MCP: nama alat "TANS"/"WinU1" di brief awal ternyata tidak ada. Yang tersedia: Sketchfab, Poly Haven (CC0), Hunyuan3D (pernah ada error billing), Hyper3D Rodin (tidak ada API key). Kedua generator ini akhirnya tidak pernah dipakai.

Aset yang dibangun di checkpoint ini:

  • dock_main.usdz — DIAMBIL DARI SUMBER, LENGKAP. "Old pier (Game ready)" oleh PT34, CC-BY (atribusi wajib), UID 3c21842960a7…, dipilih dari 97 kandidat. 9.084 segitiga; diskalakan ke 4,09×9,0×2,86m; dek berada tepat di +0,80m. Tekstur di-encode ulang dari 13,3MB jadi 3,66MB (turun 72%); usdchecker Sukses.
  • water_surface.usdz — DIBUAT TANGAN, LENGKAP. Sengaja tidak diambil dari sumber luar (grid datar mudah dibuat sendiri, mengambil dari sumber luar cuma menambah risiko topologi/lisensi yang tidak jelas tanpa manfaat). 80×60m, 60×44 kotak = 5.280 segitiga, semua vertex tepat di z=0, UV 0..1. 0,18MB, usdchecker Sukses. Ditandai: shader air real-time (riak/refraksi/normal) adalah tugas lanjutan terpisah yang belum dibuat — ini baru berupa geometri statis siap-shader saja.
  • Penyelarasan diverifikasi: rentang z dunia dermaga [−0,67, +2,19] vs bidang air z=0 — dek berjarak 0,80m di atas air, tiang pancang masuk ke air.

Dua bug ditemukan dan diperbaiki di tahap ini:

  1. USDZ tidak bertekstur (0,45MB, cuma geometri) — import glTF membungkus gambar ke dalam .blend, dan exporter USD lalu menghilangkannya; juga parameter export_textures ternyata bukan parameter Blender 5.1 yang asli (nama yang benar: export_textures_mode dengan pilihan KEEP, PRESERVE, NEW).
  2. Dek berada 0,2m di bawah air — deteksi bidang dek berdasarkan jumlah wajah menghadap atas malah terkunci ke wajah-wajah kecil di ujung tiang, bukan dek sungguhan; diperbaiki dengan mendeteksi berdasarkan luas wajah (dek 21,69 m² vs ujung tiang <0,4 m²). Pelajaran: cari bidang lantai/dek berdasarkan luas, jangan berdasarkan jumlah wajah.
  • terrain_underwater.usdz — GEOMETRI DIBUAT TANGAN + TEKSTUR CC0, LENGKAP. Dibuat tangan karena dasar danau hasil unduhan generik tidak bisa cocok dengan kedalaman rak yang tepat dibutuhkan tiang dermaga. Tekstur: damp_sand dari Poly Haven, CC0, tidak perlu atribusi (dipilih dibanding coast_sand_03/04 dan brown_mud_rocks_01 yang ditolak karena tampilan salah; juga menolak pasir udara-foto yang teksturnya terlalu kasar). 80×60m, 80×56 kotak = 8.960 segitiga; 26 gundukan batu diukir langsung ke geometri + riak pasir; noise disamarkan di bawah area dermaga supaya tiang bisa duduk rata. 7 peta tekstur Poly Haven dipangkas jadi 3 (Diffuse/nor_gl/Rough — Displacement tidak bisa bertahan lewat ekspor USD). 2,78MB, usdchecker Sukses.
    • Profil kedalaman: tepi pantai +1,34m → garis pantai 0,0 → rak −0,65m di bawah dermaga → −3,19m di y=12 → −9,46m di y=25 → minimum −11,04m.
    • Tiang dipastikan tertancap (rak −0,649…−0,601 vs dasar tiang −0,67 ⇒ menembus 0,02–0,07m) — air dangkal di dermaga memang disengaja; air dalam ada di cekungan tempat ikan berpatroli.
    • Bug diperbaiki: error "StructRNA has been removed" karena membaca properti .type sebuah node setelah node itu dihapus — diperbaiki dengan menghitung dulu set node yang akan dihapus, baru menghapusnya; file sebelum operasi dimuat ulang alih-alih melanjutkan dari kondisi setengah berubah.
  • rod_main.usdz — GEOMETRI DIAMBIL DARI SUMBER + RIG DIBUAT TANGAN, LENGKAP. "Fishing Rod, Rigged and Animated" oleh ergin3d.com, CC-BY (atribusi wajib), UID 78991bf4…, dipilih dari 47 kandidat. Rig 10-tulang bawaan sumber ini dibuang meski kualitasnya bagus (spesifikasi butuh rantai tulang tertentu), pendekatan yang sama dipakai di semua 10 ikan.
    • 6 bagian mesh digabung (satu bola ikosahedron nyasar tanpa bobot dibuang), diorientasikan ulang jadi panjang +Y/gagang di origin/ujung di +Y, diskalakan ke 2,2m.
    • Di-decimate secara selektif per material: badan joran/reel (lebih bulat, mudah di-decimate) rasio 0,49; lilitan tali (tipis, susah di-decimate) rasio lebih lembut 0,78 → dari 23.276 jadi 12.531 segitiga (masuk anggaran hero 8–15 ribu).
    • Tekstur 4K→2K/2K/1K (baseColor/normal/metallicRoughness).
    • Rig 6-tulang baru dibangun: Root → Handle (gagang+reel, kaku) → Rod_01 → Rod_02 → Rod_03 → Tip; bobot zona (2 terdekat, pangkat 4); 0 dari 13.100 vertex tanpa bobot.
    • Uji lengkung: pose bertahap 6°/14°/24°/34° menghasilkan kurva parabola mulus, tidak sobek/terjepit, gagang+reel tetap kaku.
    • 2,33MB, usdchecker Sukses.
    • Tiga bug nyata ditemukan dan diperbaiki:
      1. Pencocokan gambar check_existing=True yang "keracunan" mengembalikan gambar 4K lama yang sudah di-pack setelah percobaan repoint sebelumnya diam-diam gagal — diperbaiki dengan check_existing=False plus nama unik.
      2. usdchecker menangkap bug ketepatan yang nyata: gambar normal map dan metallicRoughness defaultnya pakai colorspace sRGB alih-alih Non-Color, yang kalau dibiarkan akan mengoreksi gamma dua kali pada peta data dan menghasilkan pencahayaan yang salah — diperbaiki dengan mengeset colorspace ke Non-Color sebelum ekspor.
      3. Pengguna menemukan bug rig nyata dari sebuah screenshot: rantai tulang berjalan sejajar di SAMPING tabung joran, bukan di tengahnya. Penyebab: rotasi reorientasi hanya menetralkan sumbu panjang (Y); tidak pernah mengoreksi offset Z sekitar 0,055 warisan dari FBX sumber yang tidak dipusatkan. Diperbaiki dengan mengukur garis tengah tabung yang sebenarnya (tidak menghitung tonjolan reel) dan menggeser seluruh mesh −0,0556 di sumbu Z; uji lengkung diulang untuk memastikan bobot yang ada masih valid (memang masih valid, karena pergeseran kaku yang seragam tidak mengubah penetapan tulang terdekat).
  • rod_line.usdz — DIBUAT TANGAN, LENGKAP. Sketchfab dicari dulu (56 hasil CC, tidak ada satu pun tali pancing berdiri sendiri) memastikan pembuatan tangan memang tepat, alasan sama seperti water_surface. Tabung bersegi 6 × 18 segmen + tutup ujung, radius 2,5mm, panjang istirahat 2,4m, 224 segitiga (spesifikasi <500), PBR datar, tanpa tekstur (disengaja — tidak menambah apa-apa di ketebalan ini). Punya rig 6-tulang sendiri yang independen (Root→Anchor→Line_01..04), sepenuhnya terpisah dari rig rod_main supaya tegangan tali bisa dianimasikan terpisah dari lengkungan joran, sesuai spesifikasi. Bobot zona (0 dari 114 vertex tanpa bobot). 12,3KB, usdchecker Sukses.
    • Kontrak titik sambung didokumentasikan untuk pihak app: titik origin tali harus berada di EKOR (tail) tulang Tip milik rod_main (Y=2,2 dunia), bukan di kepalanya (Y=1,95) — kekeliruan kepala/ekor ini persis terjadi saat render verifikasi pembuat sendiri dan ketahuan setelah dicek ulang terhadap panjang joran yang sudah diketahui; ditandai secara eksplisit untuk pihak integrator app.
  • sky_dome.usdz — HDRI CC0 + KUBAH DIBUAT TANGAN, LENGKAP. Semua 6 aset esensial selesai di titik ini. Dipilih HDRI bell_park_dawn dari Poly Haven (CC0) dibanding bell_park_pier (danau yang sama, memperlihatkan dermaga sungguhan — sangat mirip tapi pencahayaannya mendung/datar, melanggar spesifikasi cahaya hangat).
    • HDRI (equirect EXR 2048×1024) di-tonemap lewat view transform AgX milik proyek sendiri → JPEG 2048×1024, 408KB.
    • Kubah dibuat tangan: hemisfer radius 300m, 12° di bawah horizon, 368 segitiga (spesifikasi <500), material Emission unlit (tampil benar tanpa peduli pencahayaan scene) — sengaja tanpa prim Light/DomeLight yang dibakar (export_lights=False) supaya tidak mengulang bug "DomeLight membuat model hampir hitam" persis dari CP24. "Lampu directional statis" adalah lampu terpisah yang harus ditambahkan sendiri oleh aplikasi RealityKit (lihat AGENTS §4.6).
    • 14,9KB, usdchecker Sukses.
    • Tiga bug nyata ditemukan dan diperbaiki: (a) percobaan pertama punya 744 segitiga (16×24 cincin/segmen), dikurangi jadi 368 (12×16) karena konten langit tahan dengan jauh lebih sedikit facet. (b) Wajah berluas nol di kutub (disampel tepat di φ=0, menduplikasi vertex puncak) — diperbaiki dengan menyampel cincin hanya dari φ>0. (c) Sambungan jahitan UV equirect — 12 dari 192 wajah melintasi diskontinuitas atan2 (UV.x melompat dari ~0 ke ~1), yang akan membuat tekstur belepotan di satu kolom wajah — diperbaiki dengan unwrap UV per-wajah plus perbaikan khusus untuk wajah kutub sisa (UV-nya diturunkan dari rata-rata dua tetangga cincinnya).

Hasil: 6/6 aset esensial lingkungan lengkap di checkpoint ini. Aset sekunder (batu/vegetasi/pohon/properti) menunggu persetujuan pengguna sebelum dimulai.

CP37 — Semua 11 aset sekunder lingkungan dibangun (tag: Lingkungan)

Pengguna menyetujui "lanjut bangun aset sekunder." Semua 11 dari BUILD_PLAN_ENV §1b dibangun, sumber utama Sketchfab.

  • Batu (3) + tumbuhan bawah (2): rock_shoreline_01 (Gray Lake Rock, 594 segitiga), _02 (Mossy Rock, 876), _03 (Low Poly Rock Formation, 1.484) — dipilih dari 107 kandidat untuk variasi bentuk. foliage_grass_01 (728 segitiga, helai rumput kartu-alpha sungguhan), foliage_reed_01 (1.314 segitiga, digabung dari 2 bagian). Semua origin dipusatkan ulang ke dasar (pivot properti tanah).
  • Pohon (3): Cemara tree_01 (3.744 segitiga, digabung dari 93 objek mesh terpisah), pohon berdaun lebar tree_02 (3.018 segitiga — sumber ini sebenarnya berisi 2 pohon, hanya yang lebih besar yang dipertahankan berdasarkan perbandingan kotak-pembatas, membuang pohon yang lebih kecil + sebuah decal bayangan — aset tree_02 ini belakangan diketahui punya geometri yang tercemar, lihat CP41), pohon palem tree_03 (1.812 segitiga, dipilih untuk kesan "eksotik" danau yang distok ikan). Dua kandidat ditolak karena arahan gaya seni meski nama cocok persis: dua hasil "Oak Tree" ternyata pohon kartun dengan kanopi bulat ikosahedron; "Wil The Weeping Willow" ternyata maskot kartun berkacamata hitam dengan pot warna pink.
  • Properti dermaga (3): prop_bucket_01 (Rusty Metal Bucket, 1.054 segitiga), prop_tacklebox_01 (di-decimate dari 4.174 jadi 2.003 segitiga), keduanya diambil dari sumber luar. prop_rope_01 dibuat tangan (tabung spiral 496 segitiga) setelah pencarian Sketchfab 36 hasil yang sungguhan tidak menemukan yang bisa dipakai (hanya lilitan gaya voxel/piksel-art atau scene tali-temali kapal yang kebesaran).
  • Koreksi tingkatan tekstur diterapkan retroaktif: brief hanya menyebut dermaga/joran sebagai tingkat "hero" 2K — disadari di tengah pembuatan (setelah ekspor batu 2K pertama mencapai 6,4MB) dan sejak itu setiap aset sekunder diturunkan ke tingkat "background" 1K.
  • Dua bug nyata ditemukan dan diperbaiki: (a) usdchecker melaporkan UnresolvableDependency pada tekstur specGloss rumput/cemara — menghapus gambar hanya saat users==0 tidak cukup kalau ada node yang tidak esensial masih mereferensikannya; diperbaiki dengan menghapus node yang mereferensikan itu dulu. (b) Pembacaan dimensions yang basi pada kotak perkakas memberi hasil 26×36×20m padahal seharusnya sekitar 0,4m — diperbaiki dengan mengukur koordinat vertex mentah alih-alih percaya .dimensions tepat setelah edit script yang sama. Ditandai sebagai kendala API Blender yang berulang (bug sejenis pernah kena juga di pohon palem sebelumnya).
  • Cek perakitan scene penuh: semua 6 aset esensial + 10 aset sekunder (16 objek) = 53.346 segitiga total, jauh di bawah anggaran scene ~150 ribu. Tampilan orang-pertama dan udara di-render.

Hasil: Semua 11 aset sekunder lengkap. Masukan pengguna setelah melihat render: "keseluruhan lingkungan terlihat seperti kardus tempel." Ini memicu tahap perbaikan CP38.

Tabel Progres Keseluruhan (dicatat di tengah log, antara CP37 dan CP38)

Merangkum status ikan di titik itu, dengan catatan penting berikut:

  • Ikan Badut dan Blue Tang: masing-masing hanya punya SATU animasi asli; 3 state lainnya adalah file duplikat identik byte-per-byte, tidak ada USDZ sama sekali. Dipastikan setelah dicek ulang. Klaim "4 state lengkap" di CP20/CP22 SALAH.
  • Fish05 (Giant Trevally): ditandai RUSAK — pecah saat diam — perlu dibangun ulang total (ini sudah diselesaikan di CP30, di antara waktu-waktu tersebut).
  • Fish03 (Marlin)/Fish06 (Catfish): ditandai sudah teratasi sesuai CP34/CP35 — vonis "terhalang" sebelumnya berasal dari pencarian yang belum tuntas.
  • Fish07 (Yellowfin): lengkap sesuai CP29.

Juga dicatat bahwa tabel Pond (kolam) lingkungan lama sudah DIGANTIKAN oleh desain non-AR dari CP36.

CP38 — Tahap perbaikan lingkungan — perbaikan "kardus tempel" (tag: Lingkungan/Bug Material-Shader)

Pengguna meminta tiga perbaikan: (a) panorama langit resolusi lebih tinggi, (b) cincin bukit/deretan pohon 3D nyata sebagai transisi ke pantai, (c) pencahayaan/gradasi warna yang selaras antara latar depan dan skybox.

  • (a) HDRI bell_park_dawn diunduh ulang di resolusi 8K (maksimal yang tersedia, naik dari 2K), dibakar jadi 4096×2048 lewat pipeline AgX yang sama. sky_dome.usdz diekspor ulang.
  • (b) Aset baru terrain_horizon_ring.usdz (dibuat tangan): cincin bukit radial dari radius 55–140m, profil bukit bergelombang lewat noise sinus berlapis, sekitar 18 "pohon impostor" 3D sederhana (3 segitiga masing-masing) tersebar di puncak. 971 segitiga, 39,3KB.
  • (c) Lampu Sun ditambahkan sesuai spesifikasi AGENTS §4.6 (elevasi 15°, azimuth 135°, sekitar 3400K), World scene diset memakai HDRI yang sama untuk pencahayaan berbasis gambar (kekuatan 0,6), tampilan viewport diganti ke mode Rendered untuk render verifikasi. Ini perbaikan proses khusus untuk render pratinjau repo ini saja — pencahayaan nyata yang setara adalah tanggung jawab pihak app RealityKit sendiri.

Dua bug ekspor material signifikan ditemukan (berdampak ke seluruh proyek):

  1. sky_dome.usdz ternyata dikirim dengan NOL data shader/tekstur (14,9KB) dalam dua kali percobaan ekspor ulang, keduanya lolos usdchecker. Penyebab utama, dua masalah bertumpuk: (i) exporter USD Blender punya tabel terjemahan shader yang sempit — hanya benar-benar menangani nilai datar dan pengkabelan langsung Image Texture→Base Color/Normal Map→Normal. Material asli langit (Image Texture→Emission→Output, tanpa Principled BSDF) tidak punya jalur terjemahan, sehingga exporter diam-diam menulis prim Material kosong tanpa anak Shader. Diperbaiki dengan mengkabel ulang lewat input Emission Color/Strength milik Principled BSDF. (ii) Mesh/material objek ternyata bergeser ke datablock duplikat hasil auto-rename (sky_dome_mesh.002/sky_dome_mat.002) setelah beberapa siklus buka/append berulang — setiap edit mendarat di datablock yatim. Diperbaiki dengan mengecek data yang benar-benar terikat ke objek, bukan menebak namanya, serta membersihkan material sisa yang tercemar silang. Hasil akhir: 424KB, tekstur dipastikan tertanam lewat usdcat.
  2. Gradasi warna yang dimaksudkan untuk terrain_horizon_ring ternyata terekspor jadi abu-abu datar (0,8, 0,8, 0,8) — penyebab sama: materialnya memakai grafik node prosedural (Geometry Position→Separate XYZ→Math→Color Ramp→Base Color) yang tidak bisa dievaluasi jadi nilai statis oleh exporter. Diperbaiki dengan membakar gradasi jadi gambar JPEG 8×256 sungguhan yang cocok dengan UV radial mesh, dikabel sebagai Image Texture→Base Color biasa.

Tidak satu pun dari kedua bug ini menghasilkan error ekspor atau kegagalan usdchecker. Keduanya baru ketahuan karena ukuran file yang mencurigakan lalu diperiksa manual isi hasil ekspornya pakai usdcat. Aturan tetap seluruh proyek ditambahkan: material harus disederhanakan jadi nilai datar atau pengkabelan langsung Image-Texture sebelum diekspor; apa pun yang lebih rumit dari itu tidak dijamin selamat dan wajib diperiksa dengan usdcat, bukan sekadar usdchecker. (Ini insiden yang dirujuk di CLAUDE.md §7 dan CP42 belakangan.)

Material bernilai datar yang lebih sederhana ikut diperiksa (prop_rope_01, water_surface, rod_line) — ketiganya terekspor benar; hanya dua grafik node yang rumit di atas yang bermasalah.

Render ulang tampilan orang-pertama dan udara: mengonfirmasi pencahayaan hangat directional dan cincin yang menjembatani air dan langit — memecahkan keluhan "kardus tempel" (sebagian — lihat CP39 untuk masalah lanjutan).

Hasil: 18/18 aset lingkungan lengkap (6 esensial + 11 sekunder + 1 aset perbaikan baru berupa cincin horizon). CLAUDE.md diperbarui.

CP39 — Perbaikan cincin horizon — mengambang tidak menyatu dengan pantai (tag: Bug Lingkungan)

Pengguna melaporkan cincin "terlihat tidak benar" — tampak sebagai pita gelap datar mengambang di udara, dengan foto air/bukit bawaan langit terlihat lewat celah di bawahnya, alih-alih naik menyatu dari pantai.

Penyebab utama: radius dalam cincin (55m) mulai jauh melewati jangkauan air/tanah (setengah-lebar 40×30m) — celah 15–25m tanpa geometri sama sekali — dan fungsi ketinggian cincin punya batas dasar keras 6m di tepi dalamnya tanpa peruncingan ke garis air, jadi bahkan di tempat mulainya pun tetap mengambang.

Perbaikan: R_INNER dikurangi jadi 27m (di dalam setengah-lebar air 30m, menjamin tumpang tindih tanpa celah di semua sisi), fungsi ketinggian diubah jadi tepat 0,0 di tepi dalam dengan kenaikan halus pangkat 1,3 dan amplop peredam noise, pohon-pohon deretan digeser lebih ke tanah yang lebih tinggi. Mesh bertambah dari 971 jadi 1.233 segitiga, 39,3 jadi 48,2KB. Diekspor ulang, usdchecker lolos, usdcat memastikan tekstur tetap ada.

Insiden tak disengaja: sesi Blender live macet di tengah perbaikan karena satu script gabungan yang terlalu besar (15 objek + material/world/kamera dalam satu panggilan, plus perubahan mode shading). Dipulihkan dengan memecah jadi beberapa panggilan script yang lebih kecil — pelajarannya: pecah operasi Blender yang berat, terutama apa pun yang menyentuh mode shading viewport, jadi langkah-langkah berukuran kecil.

Hasil: cincin sekarang naik menyatu terus-menerus dari tepi air; celah dan kesan mengambang keduanya hilang.

CP40 (entri pertama) — Tekstur tanah + pratinjau yang ramai (tag: Lingkungan)

Permintaan pengguna: "kasih tekstur, banyak pohon dan aset sekunder lain supaya terlihat hidup."

  • Perubahan aset nyata pada terrain_horizon_ring.usdz: tekstur tanah sungguhan diterapkan (sebelumnya cuma gradasi warna datar yang dibakar), dan pohon-pohon spike dipisah ke material sendiri.
    • Percobaan pertama: aerial_grass_rock dari Poly Haven (CC0) — cocok secara visual tapi tiling-nya menghasilkan pola bergaris (banding) yang kuat. Didiagnosis dengan teliti (menyingkirkan resolusi mesh, kepadatan ubin, pencahayaan/bayangan satu per satu) — penyebabnya ditemukan pada tekstur itu sendiri: kategorinya "aerial" (foto drone tunggal yang dimaksudkan untuk dipakai sekali saja, bukan diulang-ulang) yang punya gradasi pencahayaan dunia-nyata halus yang jadi periodik begitu di-tile.
    • Diperbaiki dengan beralih ke brown_mud_leaves_01 (Poly Haven CC0, tekstur studio yang memang dirancang untuk tiling) — banding hilang.
    • Peningkatan resolusi mesh dari 9 jadi 26 cincin tetap dipertahankan (peningkatan kehalusan yang sah, meski bukan perbaikan banding sesungguhnya). Pohon-pohon spike diberi material hijau tua datar tersendiri. 3.409 segitiga, 618,5KB, usdchecker Sukses.
  • Pratinjau yang diramaikan (bukan aset yang dikirim): instans duplikat-tertaut dari aset pohon/batu/tumbuhan yang sudah ada disebar hanya di dalam Blender — 26 pohon (45% cemara/40% berdaun lebar/15% palem), 14 batu, 30 rumpun rumput, 16 alang-alang — untuk melihat pratinjau bagaimana scene terlihat dengan instancing waktu-nyata. Tidak ada USDZ baru dihasilkan; rentang penempatan dicatat di Source_Log untuk logika instancing pihak app sendiri.

Hasil: dipastikan tekstur tanah bersih tanpa banding dan variasi pohon 3D di render; perbaikan cincin-mengambang dari CP39 masih bertahan.

CP40 (entri kedua, diberi label "CP40 — Ganti HDRI → Lakeside Sunrise") (tag: Lingkungan)

HDRI bell_park_dawn diganti dengan "Lakeside Sunrise" dari Poly Haven (CC0, HDR 4K). Alasannya: HDRI sebelumnya terlalu polos/membosankan; Lakeside Sunrise memberi kehangatan golden-hour yang lebih kaya.

Detail: file lakeside_sunrise_4k.hdr diunduh (24,8MB, 4096×2048). Color space Linear Rec.709, kekuatan latar belakang 0,8. Lampu Sun disesuaikan ke energi 4,0, warna (1,0, 0,7, 0,4).

Hasil: DIGANTIKAN oleh CP41. HDRI ini sebenarnya tidak pernah benar-benar dikabel ke tekstur sky_dome.usdz sendiri (hanya dikabel ke pencahayaan World) — dan setelah benar-benar diterapkan, foto sumbernya ternyata punya ranting pohon mati yang terlihat seperti "cabang melayang di langit" begitu cincin tanah tidak lagi menutupinya. Diganti dengan evening_road_01_puresky di CP41.

CP41 — Penyebab pohon putih, pemindahan kamera/joran, kepadatan ditingkatkan, perbaikan langit sungguhan (tag: Lingkungan/Bug Material-Shader)

Masukan pengguna disertai screenshot: "masih terlihat terlalu kosong dan tidak wajar, terus kenapa pohonnya putih? dan perlu majukan sudut pandang pemain... dan pisahkan joran karena joran nanti dianimasikan di RealityKit." Lalu, di tengah perbaikan: "kok jadi tidak benar... ada cabang besar di langit" dan "perlu ganti HDR supaya sudut pandang pemain bisa melihat matahari jadi tidak terlalu suram."

1. Pohon putih — TIGA bug nyata yang berbeda, semuanya diperbaiki di level aset yang dikirim

  • Bug A — IOR=1000 di enam material. Pemindaian properti menemukan IOR = 1000,0 (padahal defaultnya normal 1,5) pada tree_01_foliage_mat, material batang tree_01, foliage_grass_01_mat, m_plant_cattail, m_plant_cattail_top, dan rock_shoreline_01_mat. IOR sebesar 1000 mendorong pantulan Fresnel dielektrik jadi sekitar 99,6% di semua sudut, membuat material jadi hampir seperti cermin sempurna — di bawah cahaya golden-hour terang ini terbaca sebagai putih pekat/pudar, persis cocok dengan laporan "pohon putih". Penyebab pasti nilai ini belum dipastikan (kemungkinan besar keanehan importer glTF). Diperbaiki dengan mengembalikan IOR ke 1,5 di semua enam material, dipastikan lewat usdcat, lalu tree_01.usdz, foliage_grass_01.usdz, foliage_reed_01.usdz, rock_shoreline_01.usdz diekspor ulang (semua lolos usdchecker). Semua aset lingkungan lain diperiksa — semuanya bersih, masalah ini hanya di enam material tersebut.
  • Bug B — batang tree_02 sama sekali tidak bertekstur. Base Color tidak tersambung, jadi abu-abu default datar (0,588, 0,588, 0,588). Di bawah pencahayaan AgX+terang ini terbaca pucat/pudar, dan siluet percabangan tipisnya salah dikira pengguna sebagai sosok kecil mirip manusia pucat. Diperbaiki dengan warna kulit kayu yang masuk akal (0,22, 0,14, 0,08), roughness 0,85, metallic 0 (tidak ada tekstur kulit kayu di sumber untuk dipakai sebagai gantinya).
  • Bug C (ditemukan saat menyelidiki Bug B) — geometri batang tree_02 tercemar dan menyatu:
    • Sekitar 28 pulau kecil terputus (253 vertex) bertekstur foto tanah rumput, mengambang terputus 4–7m di atas batang — inilah yang belakangan pengguna sendiri identifikasi salah sebagai "cabangnya dari hdri" untuk masalah langit, padahal sebenarnya cacat geometri 3D yang terpisah pada tree_02. Dihapus.
    • Sosok mirip manusia yang menyatu langsung ke dalam mesh batang itu sendiri — dipastikan lewat raycast dan flood-fill bahwa komponen tersambung yang berisi posisi layar sosok itu MEMANG bagian dari pulau batang itu sendiri, bukan objek terpisah. Diisolasi berdasarkan jarak-radial-dari-sumbu per pita-Z: radius batang normalnya sekitar 0,02–0,26m, tapi melonjak sampai sekitar 0,5m untuk sekitar 550 vertex di z≈0,65–1,6m (torso/bahu/lengan). Semua vertex bermaterial batang di pita itu dengan radius >0,22m dihapus. Ini menghapus lengan/torso (bagian yang jelas-jelas mirip manusia), tapi sisa kaki/kepala yang lebih tipis masih tersisa. Penghapusan penuh perlu sesi pemilihan vertex interaktif langsung di UI Blender, karena tidak ada aturan geometris murni yang bisa memisahkan "sisa sosok" dari "batang yang meruncing secara wajar". Dicatat sebagai tindak lanjut yang belum selesai. Diterapkan sama persis baik ke tree_02.blend yang berdiri sendiri (diekspor ulang jadi tree_02.usdz, 1.040 segitiga, usdchecker lolos) maupun ke template sebar-tanam scene pratinjau live.

2. Kamera dimajukan + joran dijadikan anak dari kamera (hanya visualisasi scene pratinjau, bukan perubahan aset yang dikirim)

  • player_pov dipindah dari y=−1,5 jadi y=3,2 (ujung dermaga di y=4,5) — menempatkan pemain dekat ujung dermaga menghadap air terbuka.
  • rod_main dijadikan anak langsung dari player_pov dengan offset yang disetel (0,6m maju, 0,22m kanan, 0,45m di bawah mata, kemiringan ~65°) supaya terbaca sebagai properti yang dipegang sudut pandang orang pertama. Ini hanya untuk pratinjau Blenderrod_main.usdz dikirim tanpa perubahan; penempatan relatif-kamera yang sesungguhnya adalah keputusan pihak app yang tidak ditentukan pratinjau ini.
  • Di tengah proses, objek armature rig ternyata hilang dari file setelah simpan/muat-ulang (ada di data yatim tapi tidak ada objek yang mereferensikannya) — diatasi dengan menjadikan mesh anak langsung dari kamera, melewati armature.

3. Kepadatan sebar kira-kira dilipatgandakan

tree_01 10→26, tree_02 14→36, tree_03 2→10, batu 14→32, rumput 30→70, alang-alang 16→36 (total 210 instans, naik dari 86), condong ke arah pandang kamera.

4. HDRI langit — perbaikan sungguhan + pelajaran baru "double tonemapping" (tag: Bug Material-Shader)

Bug sebenarnya: tekstur emisif sky_dome.usdz sendiri tidak pernah diperbarui melampaui bakuan bell_park_dawn yang asli — pergantian HDRI di CP40 hanya mengkabel penggantinya ke pencahayaan World, bukan ke tekstur kubah itu sendiri.

Perburuan HDRI (empat ditolak, satu dipilih): lakeside_sunrise_4k (pilihan CP40) ditolak — ranting pohon mati terbaca sebagai cabang melayang begitu cincin tanah tidak lagi menutupinya. belfast_sunset_puresky ditolak — terlalu berkabut, tidak ada matahari yang jelas. kloppenheim_02_puresky ditolak — ternyata langit MALAM (ada bulan+bintang) meski namanya begitu. industrial_sunset_02_puresky ditolak — punya matahari yang terlihat di panorama penuh, tapi tampilan orang-pertama level hanya menyampel lingkaran silau desaturasi lebar, terbaca datar abu-abu. evening_road_01_puresky dipilih — langit biru meluas lebih dekat ke horizon, jadi tampilan level menunjukkan warna dan awan sungguhan. Keempat sumber dari Poly Haven CC0, masing-masing diputar supaya matahari berada di u=0,75 (arah yang dilihat player_pov) sebelum dinilai.

Pelajaran double-tonemapping (baru, berbeda dari aturan ekspor-material CP38): membakar HDRI lewat AgX untuk membuat tekstur Emission kubah memang benar untuk USDZ yang dikirim (RealityKit tidak punya pipeline warna yang sebanding). Tapi memakai JPEG yang sudah di-tonemap itu sebagai sumber Emission di dalam scene pratinjau Blender, yang sendirinya merender dengan AgX, menerapkan AgX dua kali — melipatgandakan desaturasi highlight dan membuat langit yang tadinya hidup jadi abu-abu datar. Dipastikan lewat perbandingan langsung (pantulan air, satu kali lewatan AgX, menunjukkan detail kaya; kubah, dua kali lewatan AgX, menunjukkan abu-abu datar dari konten sumber yang identik). Perbaikan: material kubah di pratinjau Blender memakai file .hdr linear mentah langsung (sesuai jalur satu-lewatan World sendiri); sky_dome.usdz yang dikirim tetap memakai JPEG hasil bake AgX satu-lewatan yang benar.

Juga ditemukan: node Environment Texture World yatim yang nyasar (sisa dari pilihan HDRI pertama) menyebabkan export_textures_mode='NEW' ikut membungkus file EXR sementara 5,5MB yang tidak terkait ke dalam .usdz meski tidak ada material di mesh yang diekspor yang mereferensikannya — exporter membungkus berdasarkan referensi seluruh-file, bukan referensi yang relevan-ekspor. Diperbaiki dengan menghapus node nyasar tersebut sebelum ekspor. sky_dome.usdz: dari 14,9KB jadi 452,8KB, usdchecker lolos, usdcat memastikan sambungan emisif mengarah ke tekstur baru.

Hasil: Bug A/B/C diperbaiki dan diekspor ulang (sisa sosok manusia tree_02 hanya sebagian teratasi — sisa kaki/kepala masih ada, dicatat terbuka). HDRI langit benar-benar diperbaiki kali ini (evening_road_01_puresky). Kepadatan sebar dilipatgandakan. Shader air dan penggantian nama snake_case ikan tetap jadi tindak lanjut terpisah yang sudah ada sebelumnya.

CP42 — Hotfix bug DomeLight sky_dome.usdz (laporan bug lintas-repo) (tag: Serah Terima/Bug Lingkungan)

Agen di pihak app (bekerja di repo RealityKit saudara, ~/repos/c4/CtSPoC) melaporkan scene yang dirakit tampil datar/suram/abu-abu alih-alih golden-hour. Dipastikan bahwa sky_dome.usdz yang persis sama (identik byte-per-byte, dicek pakai shasum) menunjukkan langit abu-abu datar yang sama di viewport Blender proyek ini sendiri — ini bug aset yang dikirim sungguhan, bukan masalah integrasi pihak app.

Penyebab utama: sky_dome.usdz yang dikirim (dari ekspor evening_road_01_puresky di CP41) ternyata mengandung prim nyasar def DomeLight "env_light" (abu-abu tengah datar, intensitas 1) — kejadian ulang persis bug yang sudah diperingatkan di CLAUDE.md §1 dan CP24 (lampu lingkungan yang terbakar di dalam USDZ yang dikirim, diterapkan sebagai IBL global, memucatkan pencahayaan yang dimaksudkan). Verifikasi CP41 sendiri hanya memeriksa sambungan emisif material mesh, bukan prim DomeLight nyasar di level root — kemungkinan besar disebabkan opsi ekspor USD convert_world_material milik Blender (independen dari export_lights, yang memang sudah dimatikan) yang defaultnya menyala saat ekspor itu.

Perbaikan: dihotfix di level arsip yang sudah dikirim — USD diekstrak jadi teks ASCII lewat usdcat, prim DomeLight dihapus manual, dikemas ulang. Dipastikan tidak ada prim DomeLight, material mesh utuh, usdchecker Sukses. 462,9KB (sebelumnya 463,7KB). Dikirim identik byte-per-byte ke repo ini dan ke ~/repos/c4/CtSPoC/World/World/Assets/Environment/sky_dome.usdz (dipastikan lewat shasum).

Belum dikerjakan: Blender live tidak responsif di sesi ini, jadi panggilan ekspor sky_dome.blend kerja tidak bisa diperbaiki di sumbernya — ditandai bahwa ekspor ulang di masa depan kemungkinan besar akan memunculkan lagi bug ini kecuali convert_world_material=False ditambahkan secara eksplisit bersamaan dengan export_lights=False.

Catatan lintas-repo: repo app berada di ~/repos/c4/CtSPoC (workspace CtSPoC.xcworkspace, aplikasi World+Rod). File EnvironmentSceneBuilder.swift miliknya memuat aset dari salinan bundelnya sendiri di World/World/Assets/Environment/ — aset apa pun yang diekspor ulang di sini harus disalin ulang ke sana juga.

CP42 pembaruan hari yang sama — perbaikan DomeLight saja belum berhasil; bug sebenarnya adalah backface culling

Repo app melaporkan file hasil hapus-DomeLight tidak memberikan perbedaan yang terlihat. Diselidiki dengan loader Swift/RealityKit mandiri dan build uji hot-swap. Ditemukan: normal wajah depan mesh kubah menghadap keluar (baik-baik saja untuk dilihat dari luar di Blender, yang cukup longgar soal urutan winding), tapi kamera orang-pertama berada DI DALAM kubah ~300m, jadi setiap wajah menghadapkan sisi belakangnya ke kamera — RealityKit tidak menghormati atribut doubleSided=1 yang diotorisasi pada mesh, jadi kubah sepenuhnya ter-backface-cull baik di file asli maupun "perbaikan DomeLight saja". Yang terlihat seperti "cucian IBL abu-abu datar" sebenarnya cuma warna latar polos RealityKit yang terlihat tembus — kubahnya tidak pernah digambar sama sekali.

Perbaikan: urutan winding setiap wajah dibalik (membalik arah menghadap efektif, tanpa mengubah posisi vertex) dan primvar normal lama yang basi dibuang. Dipastikan lewat pengambilan sampel piksel langsung di instans app live — langit sekarang menunjukkan tekstur yang benar-benar bervariasi. File final menggabungkan ini dengan penghapusan DomeLight: 453,9KB, usdchecker Sukses, dikirim ke kedua repo dan di-hot-patch ke build DerivedData app (langsung tanpa perlu build ulang Xcode).

Sisa, kosmetik, belum diperbaiki: jahitan vertikal samar antara 16 segmen bujur kubah — kemungkinan besar konsekuensi bawaan dari anggaran rendah 368 segitiga, bukan cacat baru.

CP42 tindak lanjut #2 — bug winding yang sama mengenai terrain_horizon_ring dan terrain_underwater juga

Setelah perbaikan langit, tanah/pantai masih hilang total di app — pohon/batu/rumput mengambang di garis air tanpa apa pun di bawahnya. Penyebab sama: terrain_horizon_ring.usdz punya winding menghadap-keluar/salah yang identik. Diperbaiki dengan cara yang sama, dipastikan langsung di app. Proaktif juga diterapkan dan dipastikan perbaikan yang sama pada terrain_underwater.usdz (meski efek visualnya saat ini tertutup oleh pendekatan shader air real-time app — tetap diperbaiki demi konsistensi).

Catatan: dock_main (diambil dari sumber) dan water_surface (bidang datar buatan tangan sederhana, metode konstruksi berbeda) tidak terpengaruh. Ketiga aset yang diperbaiki dikirim ke kedua repo. Tampilan air yang datar tanpa pantulan adalah pendekatan shader real-time yang memang disengaja di pihak app — bukan yang dibenahi lewat perbaikan ini.

Tindak lanjut tetap: tidak satu pun file .blend sumber dikoreksi di akarnya (script pembuat bmesh) untuk ketiga aset yang terpengaruh — masih dicatat sebagai terbuka.

CP42 tindak lanjut #3 — kubah langit dibangkitkan ulang di resolusi 2×, banding diperbaiki

Pengguna: "sudah lebih baik, tapi masih perlu perbaiki langit yang kaku" — ada banding vertikal terlihat (jahitan antara 16 segmen bujur kubah beresolusi rendah). Karena MCP Blender masih tidak responsif, kubah dibangkitkan ulang secara prosedural lewat script Python mandiri yang langsung menghasilkan USD ASCII (tanpa Blender sama sekali): 24×32 cincin/segmen (2× di setiap dimensi), bentuk/material/tekstur sama, rumus UV direkayasa balik dari file asli, winding diturunkan benar dari prinsip dasar (memverifikasi sendiri, membalik jika perlu alih-alih coba-coba).

Bug yang ketahuan saat pembangkitan: material bersarang di tempat yang salah dalam hierarki prim relatif terhadap jalur material:binding-nya, menyebabkan RealityKit diam-diam jatuh kembali ke material generik — usdchecker tidak menangkap ini; hanya introspeksi material yang benar-benar diurai di RealityKit yang menemukannya.

Hasil: 465,4KB (naik dari 462,9KB), 768 wajah/setara ~1.536 segitiga (naik dari 368 — penyimpangan yang disengaja dan dibenarkan dari spesifikasi asli <500 segitiga). Dipastikan langsung: banding hilang, langit merender mulus.

Perubahan proses signifikan: sky_dome.usdz sekarang dihasilkan lewat script mandiri, bukan diekspor dari Blender sama sekali — ditandai sebagai titik keputusan untuk sesi Blender berikutnya (pindahkan logika pembangkitan ke .blend, atau tetap pakai script sebagai versi resmi).

CP42 tindak lanjut #4 — Perbaikan scene keseluruhan ("terlihat kosong dan tidak wajar") (tag: Lingkungan)

Pengguna mengizinkan pendelegasian ke subagent di kedua repo. Dua subagent forked diluncurkan paralel tapi keduanya kena batas penggunaan API sesi dan berhenti sebelum selesai (masalah batasan, bukan kegagalan tugas). Sisa pekerjaan dilanjutkan langsung.

  • Wajah "pohon spike" hijau tua datar di terrain_horizon_ring.usdz dihapus. "Pohon" berbentuk kerucut placeholder ini (dibuat sejak CP39, sebelum ada pohon 3D sebar yang sungguhan) sekarang terasa berlebihan/kelihatan palsu. Setiap wajah di GeomSubset tree_mat dihapus (81 dari 1.745 wajah) dan blok GeomSubset serta definisi material yang sudah tidak dipakai lagi dihapus. Dari 1.745 jadi 1.664 wajah. usdchecker Sukses; uji muat RealityKit memastikan hanya ada satu material tanah, tidak ada sisa subset hijau. Dikirim ke kedua repo.
  • Sosok manusia di tree_02.usdz — dipensiunkan dari sebaran, bukan diperbaiki di level mesh. Analisis CP41 dicoba ulang dengan statistik per-pita-tinggi yang segar — memastikan kesimpulan CP41 masih berlaku: tidak ada ambang batas geometris murni yang bisa mengisolasi sisa sosok tanpa ikut memotong geometri batang yang sah; perlu sesi pemilihan vertex interaktif Blender yang tidak tersedia di sesi ini. Solusi sementara di pihak app: fungsi scatterInstances milik EnvironmentSceneBuilder.swift mengalihkan setiap slot tree_02 yang diotorisasi jadi bergantian tree_01/tree_03. File tree_02.usdz sendiri tidak berubah dan masih punya cacat itu — cuma sudah tidak dipakai di sebaran saat ini.

Tindak lanjut tetap (diperbarui): file .blend sumber untuk sky_dome/terrain_horizon_ring/terrain_underwater masih perlu perbaikan winding/DomeLight dipindahkan kembali begitu akses Blender tersedia lagi; terrain_horizon_ring.blend perlu geometri pohon-spike benar-benar dirombak di sumbernya; kontaminasi sosok manusia di tree_02.usdz masih belum terselesaikan di level geometri.

CP42 tindak lanjut #5 — Langit lebih berawan, tekstur tanah lebih rapat, dua aset tumbuhan baru (tag: Lingkungan)

Melanjutkan polesan level file, tanpa akses Blender.

  • sky_dome.usdz dibakar ulang dengan HDRI yang lebih berawan dan lebih keemasan. Dibandingkan kloppenheim_05 (ditolak — padang rumput siang bertona dingin dan datar, meski label tagnya "awan tebal, matahari hangat") vs qwantani_sunset (dipilih — gradasi matahari-terbenam jingga hangat sungguhan, awan terlihat, ada danau dalam bingkai yang cocok dengan latar game). Dibangkitkan ulang lewat generator prosedural yang sama dari tindak lanjut #3 (24×32 cincin/segmen, winding memverifikasi sendiri, UsdPreviewSurface). Tekstur diperkecil dari 8192×4096 jadi 4096×2048. usdchecker Sukses; uji muat RealityKit memastikan tekstur emisif ada. 465KB→2,11MB. File sky_ibl.jpg mandiri (dipakai app untuk pencahayaan berbasis gambar) juga diperbarui agar cocok, dan salinan asal-usul ditambahkan untuk pertama kalinya di Model/sky/.
  • terrain_horizon_ring.usdz — tekstur rumput + normal map, tiling lebih rapat. Satu tekstur diffuse-saja 1024×1024 terbaca belepotan di mesh berdiameter ~280m tanpa normal map yang memecah kesan datar. Diganti dengan set 2K leafy_grass dari Poly Haven (diffuse+normal+roughness), tetap mempertahankan pola aman Image-Texture langsung (bukan grafik prosedural). Koordinat UV dikalikan ×5 (sekadar edit data biasa, bukan node shader transform-UV) untuk tiling yang lebih rapat. usdchecker Sukses; RealityKit memastikan tekstur baseColor/roughness/normal semuanya ada, bukan material fallback. 550KB→12,5MB (tiga JPEG 2K tanpa kompresi sekarang ikut terbungkus).
  • Dua aset tumbuhan baru: foliage_fern_01.usdz dan foliage_shrub_01.usdz. Diambil dari ekspor USD asli Poly Haven (fern_02, shrub_01, keduanya 2K) alih-alih dari Blender.

    Temuan penting: ekspor USD asli Poly Haven sendiri mengotorisasi dua konteks material paralel — UsdPreviewSurface biasa (pola aman yang diandalkan proyek ini) dan grafik node MaterialX terpisah. Konteks universal fern_02 terkabel dengan benar, tapi usdchecker tetap gagal pada file unduhan mentahnya karena subgrafik MaterialX Poly Haven sendiri punya bug otorisasi sungguhan (ND_normalmap_float tidak ada di registry shader, plus ketidakcocokan tipe color3f/float3) yang tidak terkait dengan apa yang sebenarnya dibaca RealityKit. shrub_01 lebih parah: sama sekali tidak ada outputs:surface universal, hanya konteks MaterialX — akan membuat RealityKit diam-diam jatuh ke material default generik, persis pola kegagalan yang sudah pernah dialami proyek ini.

    Perbaikan: subgrafik MaterialX yang tidak dipakai dibuang dari keduanya (konsisten dengan aturan proyek "tidak ada grafik prosedural"). Untuk fern_02, material universal yang sudah ada dipertahankan. Untuk shrub_01, material universal baru dibuat dari nol mengikuti pola standar proyek. Peta normal/roughness kedua model dikirim sebagai EXR dari Poly Haven; dikonversi jadi PNG 8-bit (pakai opencv-python, karena Pillow maupun sips macOS gagal membuka EXR) sebelum dikemas.

    usdchecker Sukses pada keduanya; uji muat RealityKit memastikan setiap sub-mesh punya material bertekstur sungguhan.

    • foliage_fern_01.usdz: 4 daun pakis, 3.116 wajah/setara ~6.232 segitiga, satu material bersama, 4,84MB.
    • foliage_shrub_01.usdz: 9 rumpun cabang, 97.076 wajah/setara ~156.012 segitiga, satu material bersama, 16,86MB.

    Ditandai secara eksplisit, tidak diam-diam diterima: jumlah segitiga shrub_01 adalah pencilan sungguhan — sekitar 25× lipat pakis dan ~40× lipat tree_01 (3.744 segitiga) padahal cuma properti sebar latar belakang. Ini memang kepadatan mesh asli Poly Haven (bukan artefak resolusi tekstur); tidak ada alat decimate yang tersedia di level pengeditan teks USD mentah yang dipakai sesi ini (decimate sungguhan butuh Blender, tidak tersedia sepanjang sesi). Dikirim apa adanya, tapi ditandai bahwa siapa pun yang punya akses Blender berikutnya sebaiknya men-decimate shrub_01 sebelum dipakai di kepadatan sebar tinggi, atau mempertimbangkan ulang apakah perlu dipakai sama sekali.

CP42 tindak lanjut #8 — Langit diganti lagi: qwantani_sunset → cedar_bridge_sunset_1 → cloud_layers (tag: Lingkungan)

(Catatan: diberi nomor #8 di file sumber; tindak lanjut #6/#7 dirujuk tapi teksnya tidak ada sebagai header terpisah di log ini — hasil #7 dijelaskan di sini.)

Pilihan qwantani_sunset dari tindak lanjut #7 ternyata hampir tidak punya detail awan yang terlihat saat diperiksa langsung, jadi agen pihak app beralih ke cedar_bridge_sunset_1 — tutupan awan badai tebal dengan cahaya hangat menembus. Itu dibangun dan dikirim, tapi screenshot pengguna menghasilkan penolakan yang jelas: "ini keren sih, tapi aku butuh yang lebih tenang, menyenangkan, terang daripada gaya ultra-realistis dan gelap ini." — vonis menentang suasana badai-dramatis-fotorealistis itu sendiri, bukan permintaan untuk terus mengulik ke arah itu.

Daftar pendek ulang: disaring ke kategori siang/cerah/agak-berawan, secara eksplisit mengecualikan matahari-terbenam/senja/malam/badai/mendung. Lima unduhan pratinjau 1K diperiksa langsung alih-alih percaya tag: kloppenheim_05 (biru pucat kusam, awan jarang), quarry_02 (terang tapi langit sebagian besar kosong), clarens_midday (redup, perbukitan kering), drackenstein_quarry_puresky (gradasi senja lembut, terlalu dekat dengan suasana yang ditolak), dan cloud_layers — pemenang jelas: langit biru jenuh, awan putih besar dan tebal, matahari penuh, tanpa karakter badai/senja.

Dibangkitkan ulang sky_dome.usdz dari cloud_layers lewat pipeline prosedural yang sama (gen_dome.py, kubah cincin 24×32), tekstur diperkecil ke ukuran standar proyek 2048×1024. usdchecker lolos; usdcat memastikan referensi tekstur mengarah ke file baru, bukan material kosong diam-diam (persis pola kegagalan CP38). Dikirim identik byte-per-byte ke kedua repo (shasum cocok), repo app berhasil dibangun ulang.

Belum dipastikan secara visual di app yang berjalan — screen-capture terhalang di sesi ini (satu percobaan gagal dengan pesan "could not create image from display"; sesuai aturan tetap, ini tidak dijadikan loop percobaan ulang). Tekstur sumber disimpan untuk keperluan pencatatan asal: sky_dome_diffuse_cloud_layers.jpg (2048×1024, CC0, tidak perlu atribusi).

Hasil (menurut catatan memori pengguna, lebih baru dari teks log ini sendiri): riwayat HDRI terus berlanjut melewati titik ini — qwantani→cedar_bridge (ditolak, terlalu gelap)→cloud_layers (yang berlaku saat checkpoint ini dicatat; konfirmasi visual langsung di app masih tertunda per pembaruan terakhir yang tercatat di memori proyek).

CP43 — Perbaikan normal ekspor Preview (serah terima ke tim app), 2 dari 5 spesies teratasi (tag: Ekspor/Verifikasi)

Tindak lanjut dari FishAssets/APP_TEAM_HANDOFF.md, diajukan oleh sesi yang mengerjakan fitur pratinjau ikan AR di repo app, yang menemukan cacat orientasi/tekstur/normal pada ekspor Preview/ milik Bluefin Tuna, Skipjack Tuna, Grouper, Yellowfin Tuna, dan Giant Trevally, memakai Mekong Giant Catfish sebagai referensi yang diketahui baik.

Penyebab utama ditemukan: percobaan sebelumnya di sesi yang sama sudah mengubah kelima file spesies dan mengekspor ulang, tapi membandingkan persentase wajah terbalik sebelum/sesudah menunjukkan persentasenya tidak berubah untuk semua 5 (contoh: Yellowfin 12,02%→12,19%, Grouper 1,73%→1,73% persis sama) — percobaan sebelumnya itu tidak berguna sama sekali.

Penyebab sebenarnya: setiap mesh yang terpengaruh punya mesh.has_custom_normals == True — data custom split-normal yang dibakar sisa dari alur pindaian fotogrametri, yang menimpa urutan winding wajah untuk shading maupun ekspor. Menghitung ulang normal berbasis winding tanpa lebih dulu membersihkan data custom ini jadi tidak berpengaruh apa-apa pada file yang diekspor. Resep perbaikan yang dipastikan bekerja: bpy.ops.mesh.customdata_custom_splitnormals_clear() lalu bpy.ops.mesh.normals_make_consistent(inside=False), dalam Edit Mode, semua vertex terpilih.

Hasil per spesies (resepnya TIDAK bekerja seragam):

  • Bluefin Tuna: 16 pulau terputus, 1.196 tepi non-manifold, custom normals sudah False — 5,23%→0,26% — Berhasil diperbaiki
  • Yellowfin Tuna: satu pulau saja, custom normals basi — 12,19%→0,64% — Berhasil diperbaiki
  • Giant Trevally: 107 serpihan mikro-segitiga cacat + 149 tepi junction non-manifold (topologi sungguhan, berkumpul di area sirip dada/insang) — 0,78%→1,41% (LEBIH BURUK) — Dibatalkan (revert)
  • Skipjack Tuna: 348 pulau serpihan + 2.923 tepi non-manifold (kontaminasi jauh lebih berat) — 1,83%→10,30% (JAUH LEBIH BURUK) — Dibatalkan (revert)
  • Grouper: 249 pulau serpihan + 1.426 tepi terlalu-rapat — 1,73%→5,52% (LEBIH BURUK, baru diuji ke file percobaan saja) — Tidak disentuh di file sungguhan

Kenapa resep ini gagal di 3 dari 5 spesies: ditemukan pada Giant Trevally bahwa mengekspor TANPA menjalankan operator konsistensi sama sekali memberikan hasil identik 1,41% — algoritma flood-fill konsistensi Blender tidak punya cara pasti untuk menyelesaikan orientasi lewat tepi yang dibagi 3 wajah, jadi dibiarkan apa adanya. Cacat sebenarnya adalah sub-patch yang konsisten secara lokal tapi berorientasi terbalik relatif terhadap seluruh tubuh — ini butuh pembangunan ulang weld-sebelum-decimate yang sama seperti yang pernah dialami Giant Trevally (CP30), bukan tambalan normal. Skipjack/Grouper punya 10–20× lebih banyak tepi junction semacam ini, jadi masalahnya jauh lebih besar di sana.

Gejala "tekstur kosong" Bluefin — tidak bisa direproduksi: file Material_baseColor.png (512×512) diperiksa langsung — terlukis dengan benar, bukan abu-abu datar. Sampling UV menemukan 17,4% jatuh di latar belakang abu-abu, konsisten dengan fraksi latar-belakang-abu-abu tekstur itu sendiri sebesar 23,1% — tidak ada bukti UV kehilangan pulau yang terlukis. Ditandai sebagai kemungkinan sudah teratasi atau khusus untuk state build yang berbeda.

Orientasi — baru dicek kasar: kotak pembatas kelima spesies semuanya punya rentang terpanjang di sumbu Y, cocok dengan konvensi Mekong sendiri (ukuran: Bluefin 2,74m, Yellowfin 2,20m, Giant Trevally 1,22m, Skipjack 0,90m, Grouper 0,56m — semuanya konsisten dengan urutan ukuran nyata yang sudah diketahui). Ini menyingkirkan kemungkinan salah-orientasi kasar kelas 90°, tapi tidak bisa menyingkirkan kemungkinan flip yang lebih halus (cermin kiri-kanan, terbalik atas-bawah) karena xformOp:rotateXYZ bernilai (0,0,0) untuk setiap spesies — perbedaan flip akan terbenam dalam data vertex. Belum benar-benar dicek tuntas, masih terbuka.

Ketidakcocokan protokol Blender MCP ditemukan (catatan infrastruktur penting): alat MCP blender yang dikonfigurasi lewat .mcp.json proyek (paket resmi blmcp) tidak bisa tersambung sepanjang sesi. Penyebab utama: add-on Blender yang benar-benar berjalan adalah add-on pihak ketiga ahujasid BlenderMCP, yang protokol soket raw-JSON-nya (port 9876) tidak kompatibel dengan protokol null-terminated milik klien resmi blmcp — panggilan macet sampai timeout. Diatasi dengan berbicara langsung ke port 9876 pakai protokol ahujasid lewat raw Python socket. Ditandai untuk diperbaiki dengan benar di sesi mendatang (arahkan ulang .mcp.json ke paket ahujasid, atau jalankan add-on resmi).

Status: Bluefin Tuna dan Yellowfin Tuna: sudah diperbaiki, file .blend disimpan, ekspor Preview diekspor ulang. Giant Trevally, Skipjack Tuna, Grouper: belum diperbaiki, tidak berubah dari sebelumnya. Langkah berikutnya yang disarankan: sesi pembangunan ulang khusus dengan akses viewport live, dimulai dari langkah weld-by-distance, meniru perbaikan CP30 milik Giant Trevally sendiri.

CP44 — Persiapan animasi "Caught" (tertangkap) meronta baru — serah terima, pekerjaan belum dimulai (tag: Serah Terima)

Tindak lanjut dari APP_TEAM_HANDOFF_CAUGHT_STRUGGLE.md (ADR-045–051 di repo app). Ini serah terima, bukan penyelesaian — sesi kena masalah koneksi MCP sebelum ada perubahan Blender apa pun dan tidak bisa dimulai ulang sendiri.

Keputusan yang dipastikan dengan pengguna: menganimasikan ulang klip Caught milik Fish06_MekongGiantCatfish yang sudah ada di tempat yang sama (model/rig sama) dengan gerakan meronta "ngamuk" yang lebih ganas — sepertiga awal ganas, satu puncak sapuan besar di sepertiga tengah (masuk ke jeda slow-motion app sesuai ADR-051), sepertiga akhir opsional lebih tenang.

Masalah konektivitas MCP ditemukan dan diperbaiki (pengulangan temuan CP43, repo berbeda): penyebab utama yang sama — add-on Blender yang terpasang berbicara protokol soket raw-JSON ahujasid (port 9876, tanpa null terminator), bukan paket resmi blmcp dari PyPI. Diperbaiki dengan menjalankan, di repo saudara blender-mcp:

claude mcp remove blender -s local
claude mcp add blender -- uv --directory /Users/radityaaydin/repos/blender-mcp run blender-mcp

Dipastikan uv run blender-mcp berhasil tersambung ke localhost:9876. Perbaikan baru berlaku setelah sesi dimulai ulang — karena itu jadi serah terima alih-alih menyelesaikan pekerjaan sungguhan.

Kondisi live dipastikan lewat raw socket: Blender terbuka ulang langsung di MekongCatfish.blend; scene berisi Catfish (MESH) + CatfishArmature (ARMATURE), cocok dengan hierarki rig yang terdokumentasi (Root→Spine_00→{Head, Spine_01→{Dorsal_Fin, Spine_02→{Tail→Caudal_Fin, Anal_Fin}}, Pectoral_Fin_L, Pectoral_Fin_R}).

Daftar TODO eksplisit ditinggalkan untuk sesi berikutnya (7 butir): baca ulang AGENTS.md §5.3/§7/§10; periksa struktur keyframe klip Caught yang ada; buat animasi 3-fase baru langsung di viewport; ekspor GLB+USDZ dengan pengaturan terdokumentasi; verifikasi dengan unzip+usdcat+usdchecker dan pastikan sumbu rig tidak berubah; tambahkan checkpoint baru; laporkan waktu klip final ke pihak app.

Hasil: hanya persiapan/serah terima — pekerjaan animasi sungguhan dikerjakan berikutnya di CP45.

CP45 — Animasi "Caught" meronta baru dibuat, diekspor, diverifikasi — selesai (tag: Animasi/Ekspor)

Menyelesaikan persiapan CP44. Klip Caught milik Fish06_MekongGiantCatfish dianimasikan ulang di tempat sesuai spesifikasi serah terima. Konektivitas MCP: solusi sementara sama seperti sebelumnya (raw socket, protokol ahujasid).

Sumbu rig dipastikan ulang langsung (tidak sekadar percaya dokumen): hierarki cocok persis; panjang badan sepanjang Y lokal (Head Y≈−0,6 sampai −1,0, Tail/Caudal_Fin Y≈+0,5/+0,75), arah punggung-perut sepanjang Z lokal (Dorsal_Fin Z≈+0,1, Anal_Fin Z≈−0,1). Dipastikan ulang lagi setelah ekspor langsung dari bindTransforms/restTransforms file .usdz hasil ekspor.

Struktur klip lama yang sebenarnya (konteks, mengoreksi deskripsi Source_Log sebelumnya): memeriksa fcurve langsung (lewat API layered-action baru Blender 5.1, action.layers[0].strips[0].channelbags[0].fcurves karena Action.fcurves sudah tidak ada lagi) menunjukkan klip lama sebenarnya hanya gelombang sinus berjalan beramplitudo konstan selama 72 frame penuh — BUKAN kurva amplitudo meronta→tenang→showcase sungguhan seperti yang dideskripsikan sebelumnya. Dorsal_Fin/Anal_Fin tidak pernah dianimasikan di keempat state manapun (di-rig tapi diam) — tidak disentuh supaya tidak memunculkan gerakan di rantai tulang yang belum teruji di bawah tenggat (mencegah risiko mesh sobek).

Desain animasi baru: 90 frame (0–89) @ 24fps = 3,75 detik total (naik dari 72f/3,0 detik), tiga sepertiga literal 30-frame dengan crossfade blending halus ~6-frame di batasnya:

  • Meronta (0–29, ~0–1,21 detik): gelombang berjalan cepat berfase-lag, periode 7 frame (~3,4Hz vs ~1,3Hz klip lama), amplitudo 1,5–1,9× nilai klip lama (Spine_00 0,34→Caudal_Fin 1,05 rad), plus goyangan kepala independen yang lebih cepat (periode 6, amplitudo 0,50 rad). Sirip dada dipertahankan mendekati bentangan tetap (±0,55 rad) dengan getaran cepat, bukan mendayung halus seperti sebelumnya.
  • Puncak (30–59, ~1,21–2,46 detik): satu lengkungan seluruh-badan yang koheren tidak berjalan, semua tulang tulang belakang/ekor/caudal melengkung ke arah yang sama sekaligus, memuncak di frame 44 (~1,83 detik). Percobaan pertama memakai amplitudo skala-meronta (Caudal_Fin 1,20 rad) dan menghasilkan total lengkungan ~230° — hidung hampir menyentuh ekor, lingkaran tertutup yang tidak wajar. Disetel turun jadi sekitar setengahnya (Caudal_Fin 0,60 rad, total lengkungan ~115°) — terbaca sebagai bentuk "C"/kail yang kuat dan jelas. Kepala berputar berlawanan arah dengan tulang belakang (−0,32 rad). Sirip dada paling lebar bentangannya di sini (~0,75 rad), kaku.
  • Mereda (60–89, ~2,46–3,75 detik): ayunan lembut sefase yang meluruh, periode 20 frame, amplitudo meluruh sampai ~30% dari skala awal — mereda mendekati idle tenang.

Verifikasi: di-render lebar + dekat (sambungan ekor/caudal, sambungan kepala/insang) + tampak-atas di seluruh frame checkpoint yang mencakup semua fase dan jendela crossfade, memakai kamera/lampu sementara yang dihapus sebelum disimpan. Tidak ada sobek di sambungan mana pun, termasuk di puncak frame 44. Tampilan tampak-atas inilah yang menangkap percobaan puncak yang terlalu melengkung pertama — tampilan samping saja terlihat masuk akal (karena pemendekan perspektif) tapi menyembunyikan seberapa jauh badan sudah melilit. Pelajaran dicatat: satu kamera samping saja bisa menyembunyikan lengkungan berlebihan yang baru ketahuan dari tampak-atas/sudut alternatif.

Ekspor: kamera/lampu verifikasi dibersihkan sebelum disimpan (tidak ada objek yatim tersisa, sesuai aturan "tidak ada objek yatim" AGENTS §13). Kendala konteks headless untuk operator select_all/mode_set diatasi dengan memakai select_set() langsung. Diekspor ke Caught/MekongCatfish_Caught.{glb,usdz} (menimpa di tempat). GLB 4,86MB, USDZ 5,13MB (lebih besar dari yang lama 4,75/5,0MB karena setiap frame di-keyframe langsung, tidak jarang, supaya blending crossfade-nya presisi).

Pengecekan verifikasi, semua lolos: usdcat memastikan tepat ada satu SkelAnimation, sendi (joint) cocok dengan hierarki 11-tulang; usdchecker Sukses (dua baris "Coding Error" cuma noise pendaftaran-ganda yang tidak berbahaya, bukan kegagalan); material selamat utuh saat ekspor; upAxis="Z" dan bindTransforms/restTransforms cocok persis sebelum ekspor — sumbu rig tidak berubah.

Dilaporkan balik ke pihak app: durasi total berubah jadi 3,75 detik (dari 3,0 detik), tiga sepertiga literal sama besar, beat paling dramatis (puncak lengkungan penuh) di frame 44 ≈1,83 detik (≈49% dari total, terpusat di sepertiga tengah sesuai permintaan). Pihak app perlu menyetel ulang catchCutsceneRiseDuration/FreezeDuration/SettleDuration, catchCutsceneFishAnimationSpeed (saat ini 1,4, disetel untuk klip lama), dan konstanta amplop slow-motion.

Hasil: Selesai dan terverifikasi. File APP_TEAM_HANDOFF_CAUGHT_STRUGGLE.md dihapus sesuai instruksinya sendiri (tugas selesai).

CP46 — Pembersihan mesh Preview Giant Trevally: serpihan/wajah interior; satu teori awal terbukti alarm palsu; spesies akhirnya dipastikan masih rusak (tag: Ekspor/Verifikasi)

Melanjutkan APP_TEAM_HANDOFF.md (ditinggalkan di angka 2/5 teratasi oleh CP43). Giant Trevally dipilih berikutnya (tepi non-manifold paling sedikit dari 3 yang tersisa: 149 dibanding Skipjack 2.923 dan Grouper 1.426).

Apa yang sebenarnya salah (lebih presisi dari dugaan CP43): dari 165 tepi non-2-manifold: 39 adalah segitiga serpihan yang benar-benar terisolasi (kelas yang sama dengan "107 serpihan mikro-segitiga cacat" milik CP30, batch berbeda yang lolos), 16 adalah celah batas sungguhan berukuran sub-milimeter, dan 110 adalah junction non-manifold sungguhan — dipastikan lewat inspeksi bmesh bahwa sebagian punya wajah dari dua rentang indeks vertex berbeda dengan normal berlawanan arah berbagi satu tepi (geometri duplikat yang tumpang tindih, bukan sekadar winding yang bisa dibalik).

Perbaikan yang diterapkan — cuma pembersihan, bukan pembangunan ulang total (sengaja tidak menyentuh mesh badan bersama dengan cara yang bisa membuat bobot vertex-group Cruise/Bite/Caught jadi tidak sinkron, yang di luar cakupan tugas ini):

  1. 39 segitiga serpihan terisolasi dihapus (union-find lewat tepi boundary).
  2. 30 wajah yang ditemukan operator bawaan Blender select_interior_faces() dihapus, dijalankan sampai konvergen (lewatan kedua menemukan 0).
  3. Tepi wire yatim/vertex lepas dibersihkan.
  4. Hasil: tepi non-2-manifold dari 165 jadi 101; kategori boundary/3-wajah tuntas hilang; hanya tersisa junction 4-wajah, berkumpul di dua patch ~23-wajah yang dipastikan (lewat render dekat) berada di ujung sirip tipis (dorsal + satu sirip kecil lain), bukan di badan — kosmetik minor.
  5. 13 celah boundary sub-mm kecil sengaja dibiarkan tidak disentuh (risiko memperburuk lebih besar dari manfaatnya untuk sesuatu sekecil itu).

Temuan negatif penting: resep clear-splitnormals+recalc dari CP43 dicoba lagi pada mesh yang sudah dibersihkan dan dipastikan secara visual (render sebelum/sesudah identik piksel-per-piksel) bahwa tidak mengubah apa pun — memastikan cacat yang tersisa memang masalah geometri duplikat sungguhan, bukan sekadar winding yang bisa dibalik.

Terpisah, sebuah kekhawatiran "berlubang seperti dimakan ngengat" tersingkir: render backface-culling pertama menunjukkan yang tampak seperti ratusan lubang kecil di satu sisi badan, awalnya dibaca cocok dengan laporan bug "hanya bagian dalam model yang terekspor". Disingkirkan lewat uji langsung: render ulang dengan (a) material abu-abu datar (masih backface-culled) — benar-benar solid, nol lubang; (b) material sungguhan dengan latar magenta terang — juga solid. Kesan "berlubang seperti dimakan ngengat" ternyata artefak pencahayaan (lampu matahari keras + detail normal-mapped terhadap latar gelap membuat penurunan shading terlihat seperti transparansi). Pelajaran dicatat: pakai latar dunia yang cerah dan jenuh warna, bukan abu-abu netral, dan silang-cek dengan material flat unlit sebelum menyimpulkan "lubang" di render adalah kerusakan geometri sungguhan.

Kesalahan yang dibuat dan tertangkap sebelum dikirim: saat uji backface-culling, use_backface_culling=True diset di kedua material mesh, tapi pembersihan sesudahnya hanya mengembalikan material PERTAMA ke False — ekspor pertama terkirim dengan material kedua (tex1) masih backface-culled, ketahuan lewat pengecekan ulang nilai doubleSided file hasil ekspor. Diperbaiki dengan mengatur ulang semua material lewat loop yang benar dan mengekspor ulang. Pelajaran: percobaan debug yang mengubah "semua material" lewat loop harus dibatalkan dengan loop semua-material yang sama, bukan cuma yang pertama ditemukan.

Masalah lama di luar cakupan yang dipastikan masih ada: material USDZ hasil ekspor kosong (tidak ada jaringan shader) — bug kelas CP38 yang sama yang sudah diatasi di pihak app (membangun ulang material dari tekstur tertanam di GLB saudaranya). Bukan diperkenalkan oleh langkah ini.

Verifikasi/ekspor: usdchecker Sukses; doubleSided=1 dipastikan benar. Diekspor ke Preview/GiantTrevally_Preview.{glb,usdz} (GLB 2,71MB, USDZ 2,01MB), menimpa di tempat. File .blend disimpan.

Keterbatasan jujur yang dinyatakan di awal: tidak bisa memastikan ini memperbaiki laporan asli di perangkat "hanya bagian dalam model yang terekspor" — cacat dramatis spesifik itu tidak berhasil direproduksi di renderer Blender sendiri pada langkah ini.

Tindak lanjut hari yang sama — screenshot viewport pengguna sendiri menunjukkan MASIH rusak terlihat jelas

Segera setelah langkah ini, pengguna membagikan screenshot viewport Blender live dari GiantTrevally_Body dalam Edit Mode (area kepala/dorsal): siluet mesh benar-benar terlihat berduri dan sobek — tonjolan tajam mirip pecahan di sekitar kepala/insang/sirip punggung, terlihat jelas, cacat yang jauh lebih besar dari 101 tepi sisa ujung sirip yang dicirikan langkah ini sebagai "kosmetik". Ini jauh lebih mirip cacat "pecah/hancur" kelas CP30 yang asli daripada masalah geometri duplikat halus yang sungguhan ditemukan dan diperbaiki oleh langkah ini. Penjelasan yang paling mungkin: kerusakan topologi skala besar (kemungkinan collapse decimation yang buruk), tidak tertangkap oleh uji tepi/wajah lokal mana pun di langkah ini.

Keputusan pengguna: lewati Giant Trevally untuk sementara, lanjut ke Skipjack/Grouper. Butuh pembangunan ulang weld-sebelum-decimate penuh dari pindaian sumber mentah (Model/gltf/scene.gltf masih ada), bukan tambalan topologi lokal lagi.

Hasil: Giant Trevally BELUM teratasi — jangan sampai dilaporkan sebagai sudah diperbaiki di mana pun. Pembersihan CP46 ini nyata tapi tidak cukup.

CP47 — Mesh Preview Skipjack Tuna: pendekatan pembersihan sama di skala jauh lebih besar, dipastikan bersih secara visual (tag: Ekspor/Verifikasi)

Melanjutkan APP_TEAM_HANDOFF.md, beralih ke Skipjack setelah Trevally dilewati. Skipjack punya kontaminasi terberat dari tiga yang tersisa (2.923 tepi non-manifold).

Pengecekan awal lebih dulu (pelajaran dari kejutan Trevally di CP46): dicek vertex-vertex berduri (tidak ada — panjang tepi maksimum cuma ~4,8× median, jauh di bawah ambang "collapse yang salah") dan pemecahan pulau (cuma 2 pulau: satu badan sungguhan 27.998 wajah + satu serpihan segitiga 1-wajah nyasar — bukan pecah berantakan). Render lebar+atas dengan tekstur sungguhan lebih dulu — bersih, anatomi benar. Memastikan ini mode kegagalan yang secara material berbeda dari Trevally, meski CP43 mengelompokkan keduanya sebagai "kontaminasi non-manifold berat".

Pembersihan (metode sama seperti CP46, dijalankan sampai konvergen penuh):

  1. 1 segitiga serpihan terisolasi dihapus.
  2. 134 tepi wire yatim, 217 vertex lepas dibersihkan.
  3. select_interior_faces() dijalankan sampai konvergen: lewatan pertama saja menghapus 3.180 wajah interior (11,4% dari total 27.999 wajah mesh) — dua kali lipat orde besarnya dibanding 30 milik Trevally, konsisten dengan perbedaan jumlah tepi non-manifold.
  4. Pembersihan yatim terakhir.
  5. Hasil: tepi non-2-manifold dari 3.194 jadi 798, semua sekarang masuk kategori 4-wajah yang lebih ringan. Mesh final: 24.818 wajah (dari 27.999), 11.068 vertex (dari 12.153).

Verifikasi — dilakukan dengan benar kali ini mengingat kejutan alarm-palsu CP46: render 5 sudut (depan, belakang, kedua sisi, atas) dengan (a) material bertekstur sungguhan + backface culling, dan (b) material abu-abu datar + backface culling terhadap latar magenta terang. Keduanya lolos bersih di setiap sudut — tidak ada celah, tidak ada kesan dimakan-ngengat, tidak ada tonjolan bergerigi.

Kesalahan CP46 dihindari: use_backface_culling=False diatur ulang di SEMUA material lewat loop yang benar sebelum satu putaran ekspor, dipastikan benar lewat usdcat sebelum menganggap tugas selesai.

Ekspor: Preview/SkipjackTuna_Preview.{glb,usdz} (GLB 3,94MB, USDZ 1,76MB), usdchecker Sukses, doubleSided=1 dipastikan. File .blend disimpan.

Pengecekan sekilas pengguna di tengah sesi: pengguna menandai yang terlihat seperti tambalan tekstur putih/kosong di kepala/moncong; setelah diperiksa lebih dekat dipastikan tekstur sebenarnya baik-baik saja (alarm palsu, kemungkinan besar artefak shading/pencahayaan viewport) — tidak ada perubahan dibuat.

Hasil: Skipjack Tuna dibersihkan dan dipastikan solid secara visual — lebih meyakinkan dari Trevally, mengingat uji material-flat/latar-terang yang sengaja dilakukan tidak menemukan apa pun. Belum dipastikan di perangkat sungguhan. Grouper berikutnya.

CP48 — Mesh Preview Grouper: metode sama, hasil bersih sama (tag: Ekspor/Verifikasi)

Melanjutkan APP_TEAM_HANDOFF.md — spesies terakhir dari tiga yang masih rusak sejak CP43.

Pengecekan awal: tidak ada vertex berduri (tepi maksimum cuma 4,17× median), 321 pulau mesh tapi yang terbesar mencakup 98,7% dari total mesh (sisanya serpihan kecil, bukan pemecahan skala besar). Render tekstur sungguhan bersih — tidak ada siluet bergerigi ala Trevally. Kelas kegagalan yang bisa diatasi sama seperti Skipjack.

Pembersihan:

  1. Semua pulau terputus di bawah 20 wajah dihapus dalam satu lewatan (364 wajah di ~320 pulau serpihan kecil) — pendekatan yang sedikit lebih langsung dibanding union-find per-komponen milik CP46/CP47, karena pengecekan awal sudah menunjukkan pulau serpihan terbesar cuma 14 wajah (aman memakai ambang ukuran menyeluruh).
  2. 1.015 tepi wire yatim, 3 vertex lepas dibersihkan (jumlah tepi boundary turun dari 1.085 jadi 133 sebagai efek samping).
  3. select_interior_faces() sampai konvergen: 1.023 wajah interior dihapus lewatan pertama, 0 lewatan kedua.
  4. Pembersihan yatim terakhir.
  5. Hasil: tepi non-2-manifold dari 2.511 jadi 479, semua sisa masuk kategori 4-wajah yang lebih ringan. Mesh final: 26.296 wajah (dari 27.683), 12.340 vertex (dari 13.402) — sekitar 5% mesh terhapus (lebih kecil dari 11% Skipjack, lebih besar dari fraksi-sepersekian-persen Trevally — kira-kira sebanding dengan tingkat kontaminasi awal masing-masing spesies).

Verifikasi: uji material-flat + latar-magenta-terang + backface-culling yang sama di 5 sudut — sepenuhnya solid di mana-mana, hasil bersih yang sama seperti Skipjack. Kesalahan CP46 dihindari lagi (loop semua-material, dipastikan benar setelah ekspor).

Ekspor: Preview/Grouper_Preview.{glb,usdz} (GLB 3,70MB, USDZ 1,91MB), usdchecker Sukses, doubleSided=1 dipastikan. File .blend disimpan.

Status — menutup tugas serah terima CP43: dari 5 spesies yang awalnya rusak — Bluefin dan Yellowfin dipastikan diperbaiki (CP43); Skipjack dan Grouper dibersihkan dan dipastikan solid secara visual tapi belum diuji di perangkat sungguhan (CP47/CP48); Giant Trevally masih benar-benar rusak (CP46), butuh pembangunan ulang weld-sebelum-decimate penuh, bukan tambalan topologi lagi. Tidak satu pun dari perbaikan ini dipastikan di luar renderer Blender sendiri — tim app sebaiknya menguji ulang di perangkat sungguhan.

CP49 — Animasi Caught meronta "ngamuk" diterapkan ke 7 spesies lengkap yang tersisa (tag: Animasi)

Permintaan pengguna: terapkan perlakuan Caught meronta ganas yang sama, yang dibangun CP45 untuk Mekong Giant Catfish, ke setiap spesies lain yang sudah punya roster 4-state lengkap — Bluefin, Yellowfin, Skipjack, Giant Trevally, Grouper, Marlin, Sailfish. Ikan Badut/Blue Tang dikecualikan (di luar roster utama, tidak punya animasi Caught sungguhan sejak awal). Sailfish secara eksplisit disertakan meski ada catatan "jangan sentuh Sailfish" sebelumnya yang tidak berhubungan (catatan itu khusus untuk tugas orientasi ekspor Preview saja).

Kenapa metode CP45 tidak bisa diskalakan, dan penggantinya: rumus sinus per-tulang buatan tangan CP45 tidak bisa diskalakan ke 7 spesies dengan rig yang sangat berbeda (Bluefin sendiri punya 96 tulang di selusin rantai jari-sirip). Dibangun metode umum dan bisa dipakai ulang, dua bagian (ngamuk_lib2.py's build_ngamuk_action_v2hanya disimpan di scratchpad sesi, tidak pernah dikomit ke repo):

  1. Tulang rantai utama (tulang belakang/ekor/kepala, diklasifikasi otomatis berdasarkan kata kunci nama) mendapat lengkungan tiga-fase sintetis (meronta→puncak lengkung koheren→mereda tenang), jeda fase dan arah diturunkan otomatis dari posisi rest-pose setiap tulang relatif terhadap tulang yang secara literal bernama "Head" — bukan diasumsikan dari rentang koordinat, karena arah-kepala TIDAK konsisten antar rig (Head milik Bluefin berada di Y maksimum, sementara Head milik Yellowfin/Skipjack/Trevally/Grouper berada di Y minimum — bug nyata yang ketahuan lewat membandingkan langsung rig-rignya).
  2. Tulang sekunder sirip/rahang/mata/lain-lain mendapat gerakan yang sudah ada dari sebelumnya di-time-warp (dipercepat+diperbesar saat meronta, dibekukan+diperbesar saat puncak, diperlambat+meluruh saat mereda) alih-alih diganti total — secara otomatis mempertahankan hubungan fase bebas-sobek apa pun yang sudah divalidasi animator aslinya.

Klasifikasi tulang (berdasarkan substring nama, diperluas dua kali): primary jika namanya mengandung Hips/Spine/Head/Tail/Caudal/Body (Body ditambahkan untuk Body1_01..Body5_08 milik Sailfish); fin jika mengandung Fin/Sail (Sail ditambahkan untuk Sail1_010..Sail4_013 milik Sailfish); face jika mengandung Jaw/Eye atau diawali Side.; selain itu other. Urutan pengecekan penting (Caudal harus dicek sebelum Fin generik, atau Caudal_Fin salah terklasifikasi jadi sekunder).

Dua bug nyata ditemukan dan diperbaiki di tengah rollout:

  1. Bug rotasi majemuk (Marlin): untuk tulang rantai utama yang dianimasikan di ketiga sumbu Euler sekaligus (bukan hanya satu sumbu), versi pertama synthesizer menulis sudut yang sama ke X, Y, dan Z secara bersamaan — rotasi majemuk yang secara visual saling meniadakan jadi nyaris tidak ada gerakan. Setiap rig sebelumnya cuma pernah menganimasikan satu sumbu per tulang, jadi ini tersembunyi sampai action Marlin yang dipulihkan ternyata punya ketiga sumbu terisi. Diperbaiki dengan mendeteksi sumbu dominan tiap tulang (rentang keyframe terbesar) dan hanya menggerakkan sumbu itu.
  2. Bug action-slot tidak terikat (Marlin, Sailfish): sistem layered-action Blender 5.x mengharuskan AnimData.action_slot diikat secara eksplisit — memindahkan data sebuah action ke objek berbeda tidak otomatis membawa ikatannya. Gejalanya: nilai keyframe yang tersimpan sepenuhnya benar (dipastikan lewat membaca keyframe_points langsung), tapi pose yang dievaluasi diam-diam mengembalikan nilai yang jauh lebih kecil dan salah — artinya bug ini bisa membakar gerakan yang jelas-jelas rusak ke dalam hasil ekspor padahal setiap pengecekan data mentah terlihat baik-baik saja. Diperbaiki dengan secara eksplisit mengeset arm.animation_data.action_slot = act.slots[0] setelah setiap penugasan ulang; ditambahkan ke helper ekspor bersama supaya tidak terlewat lagi.

Marlin dan Sailfish: action Caught sama sekali tidak ada di file .blend-nya — kedua file cuma punya action Cruise (dipastikan lewat backup .blend1 milik Marlin sendiri, yang juga tidak punya action itu); data Bite/Caught/Preview yang dipakai untuk menghasilkan ekspor yang sudah dikirim ternyata tidak pernah disimpan di file kerja. Dipulihkan dengan mengimpor ulang Caught.glb yang sudah dikirim untuk masing-masing, mengonversi rotasi kuaternion glTF ke Euler (mathutils.Quaternion.to_euler('XYZ')), lalu diberi nama ulang/dibangun ulang di atasnya sebagai action sumber normal. Efek samping yang ditandai: ini memaksa rotation_mode='XYZ' di setiap pose bone di kedua armature (properti objek yang hidup, bukan per-action) — jika action Marlin_Cruise atau action gabungan Animation milik Sailfish mengharapkan mode kuaternion, ekspor ulang di masa depan untuk action-action lain yang tidak disentuh itu sebaiknya mengecek ulang mode rotasinya dulu.

Tabel hasil per spesies (semua diverifikasi dengan sapuan render lebar+tampak-atas, mengecek baik sobek maupun rotasi berlebihan):

  • Bluefin Tuna (rig custom 96-tulang): butuh pemisahan primary/fin sejak awal; gerakan sumber terlalu halus (Head nyaris tidak bergerak) sehingga harus diperbesar terus sampai terbaca sebagai lengkungan sungguhan.
  • Yellowfin Tuna (10-tulang standar): berhasil bersih di percobaan pertama; di sinilah bug arah-referensi-kepala ketahuan (Head di Y minimum di sini, berbeda dari Bluefin).
  • Skipjack Tuna (10-tulang standar, data Caught sumbernya identik dengan Yellowfin — jumlah t_peak/energy/fcurve persis sama, memastikan keduanya berbagi template animasi yang sama): bersih, gain yang sama langsung berhasil.
  • Giant Trevally (10-tulang standar, template sama): hasil animasi bersih; mewarisi cacat mesh CP46 yang belum teratasi (geometri berduri/sobek) karena langkah ini cuma menyentuh animasi, bukan topologi — jangan laporkan Trevally sebagai sudah diperbaiki.
  • Grouper (10-tulang standar, data Caught sumbernya sendiri berbeda, t_peak=16 vs 30, energi berbeda — bukan salinan template tuna): hasil paling dramatis dari ketujuh spesies (rahang terbuka lebar, bentangan tulang punggung penuh) — cocok untuk predator penyergap karang.
  • Marlin (10-tulang standar sesuai AGENTS.md, action Caught harus dipulihkan dari GLB yang sudah dikirim): kena kedua bug di atas; hasil akhir bersih setelah diperbaiki.
  • Sailfish (rig asli Sketchfab, Body1_01..Body5_08, CaudalFin_09, Sail1_010..Sail4_013, action Caught juga dipulihkan dari GLB yang sudah dikirim): pengklasifikasi tulang diperluas untuk penamaan ini; hasil paling bagus dari ketujuh spesies — bill (moncong), ekor, layar semuanya terbaca bersih, tidak ada sobek.

Ekspor/verifikasi (seragam di ketujuh spesies): masing-masing diekspor ke FishNN_Species/Caught/Species_Caught.{glb,usdz} menimpa di tempat, pengaturan standar. Setiap ekspor diverifikasi dengan unzip+usdcat (tepat satu SkelAnimation masing-masing) dan usdchecker (Sukses di ketujuhnya). File .blend disimpan untuk ketujuh spesies.

Keterbatasan jujur yang dinyatakan:

  • Belum dipastikan di perangkat sungguhan untuk ketujuh spesies — hanya diverifikasi di renderer EEVEE Blender sendiri.
  • Ekspor Caught Giant Trevally animasinya sudah benar tapi masih membawa mesh yang diketahui rusak (CP46) — butuh pembangunan ulang mesh, bukan pekerjaan animasi lagi.
  • Script ngamuk_lib2.py yang bisa dipakai ulang hanya hidup di scratchpad sesi itu, tidak dikomit ke repo — jika teknik ini dibutuhkan lagi, harus ditulis ulang dari deskripsi ini.

Status Terkini

Status ini berlaku per CP49 (2026-07-21) — bagian paling akhir dari log kronologis.

Ikan (10 spesies total, 8 lengkap penuh + 2 di luar roster utama)

Lengkap penuh (4 state terbakar: Cruise/Bite/Caught/Preview, format GLB+USDZ, animasi Caught "ngamuk" diterapkan CP49):

  • Fish03 Blue Marlin (Makaira nigricans) — CC-BY, atribusi wajib, sumber 8.280 segitiga, rig 11-tulang, 3,0m.
  • Fish04 Bluefin Tuna (Thunnus thynnus) — rig custom 98/96-tulang, 3,0m, rig paling kompleks di roster. Normal ekspor Preview sudah diperbaiki (CP43).
  • Fish05 Giant Trevally (Caranx ignobilis) — RUSAK. Mesh Preview punya cacat topologi berduri/sobek sungguhan (dipastikan lewat screenshot viewport pengguna sendiri, tindak lanjut CP46), terpisah dari keretakan yang sudah diperbaiki CP30. Butuh pembangunan ulang weld-sebelum-decimate penuh dari pindaian sumber mentah (Model/gltf/scene.gltf), bukan tambalan lagi. Animasi Caught (CP49) secara teknis sudah benar tapi mewarisi mesh yang rusak ini — jangan dilaporkan sebagai sudah diperbaiki.
  • Fish06 Mekong Giant Catfish (pengganti Pangasius/"ikan patin" — spesies asli tidak punya model gratis) — CC-BY, atribusi wajib. Spesies referensi "diketahui baik" untuk penyelidikan normal ekspor Preview. Punya animasi Caught paling baru/paling dirancang khusus (CP45, 3-fase, 90 frame).
  • Fish07 Yellowfin Tuna (Thunnus albacares) — CC0. Normal ekspor Preview sudah diperbaiki (CP43).
  • Fish08 Skipjack Tuna (Katsuwonus pelamis) — CC0. Mesh Preview sudah dibersihkan dan dipastikan solid secara visual (CP47), belum dipastikan di perangkat sungguhan.
  • Fish09 Grouper/Kerapu (Epinephelus awoara) — CC0. Mesh Preview sudah dibersihkan dan dipastikan solid secara visual (CP48), belum dipastikan di perangkat sungguhan.
  • Fish10 Sailfish (Istiophorus, pengganti slot ikan todak untuk Marlin) — CC-BY, atribusi wajib.

Di luar roster utama Indonesia (lengkap tapi terbatas):

  • Fish01 Ikan Badut (Clownfish) — hanya ada 1 animasi sungguhan; Bite/Caught/Preview adalah file duplikat identik byte-per-byte dari Cruise. Tidak ada USDZ.
  • Fish02 Blue Tang — keterbatasan sama seperti Ikan Badut.

Masalah terbuka yang diketahui pada ikan:

  1. Mesh Giant Trevally rusak — topologi berduri/sobek di dekat kepala/dorsal, butuh pembangunan ulang total. Ini cacat ikan tunggal terbesar yang masih terbuka.
  2. Perbaikan Preview Skipjack dan Grouper belum dipastikan di perangkat sungguhan (baru terverifikasi lewat render Blender).
  3. Semua animasi Caught "ngamuk" CP49 baru terverifikasi di Blender, belum dipastikan di perangkat.
  4. Semua spesies berpola atlas (Skipjack/Grouper/Yellowfin/Giant Trevally) punya bug ekspor shader yang sudah diketahui dan di luar cakupan: material USDZ-nya terekspor kosong (tidak ada jaringan shader) — pihak app sudah mengatasi ini dengan membangun ulang material dari tekstur tertanam di GLB saudaranya.
  5. Ketidakkonsistenan penamaan ikan: aset lingkungan pakai snake_case, ikan masih pakai PascalCase (dicatat sebagai item terbuka, belum diganti nama ulang secara retroaktif).

Lingkungan (18/18 aset lengkap, dengan polesan yang terus berlanjut)

Semua 6 aset esensial + 11 aset sekunder + 1 aset perbaikan (terrain_horizon_ring) sudah dibangun dan dikirim. Polesan berlanjut melewati penyelesaian awal:

  • HDRI langit sudah diganti berkali-kali mengejar suasana yang tepat: bell_park_dawn → lakeside_sunrise (ditolak, ranting pohon mati) → evening_road_01_puresky (memperbaiki bug nyata: prim DomeLight, backface culling, resolusi/banding) → qwantani_sunset → cedar_bridge_sunset_1 (ditolak pengguna: terlalu gelap/dramatis) → cloud_layers (pilihan terakhir per checkpoint terakhir yang tercatat; konfirmasi visual langsung di app yang berjalan masih tertunda — screen capture terhalang di sesi itu).
  • sky_dome.usdz sekarang dihasilkan lewat script Python mandiri yang langsung menulis USD, bukan diekspor dari Blender — perubahan proses yang disengaja (CP42 tindak lanjut #3), masih ditandai perlu keputusan (dipindahkan kembali ke .blend, atau tetap pakai script sebagai versi resmi).
  • Dua bug lintas-repo nyata ditemukan dan diperbaiki lewat pengujian pihak app (CP42): (1) prim DomeLight nyasar yang terbakar di sky_dome.usdz, memucatkan pencahayaan — kelas bug yang sama dengan bug ikan CP24; (2) RealityKit tidak menghormati atribut doubleSided yang diotorisasi, jadi winding mesh yang salah menyebabkan kubah langit, terrain_horizon_ring, dan terrain_underwater sepenuhnya ter-backface-cull (tidak terlihat) di app meski terlihat baik di Blender. Ketiganya diperbaiki dengan membalik winding wajah. Tindak lanjut tetap: file .blend sumber untuk ketiga aset ini masih punya winding yang salah di akarnya — hanya arsip .usdz yang dikirim yang dihotfix. Siapa pun yang mendapat akses Blender berikutnya sebaiknya memperbaiki script pembangkitnya, bukan cuma terus menambal hasil ekspor.
  • tree_02.usdz punya cacat geometri yang belum teratasi: mesh berbentuk sosok manusia yang tercemar menyatu ke batang (lengan/torso sudah dihapus lewat heuristik radius pita-Z, CP41, tapi sisa kaki/kepala masih ada — butuh sesi pemilihan vertex interaktif Blender, bukan aturan berbasis script). Saat ini diatasi sementara di pihak app dengan mengganti tree_02 dengan tree_01/tree_03 di mana pun tree_02 tersebar (CP42 tindak lanjut #4) — file asetnya sendiri belum diperbaiki.
  • foliage_shrub_01.usdz punya jumlah segitiga yang tidak wajar tinggi (setara ~156.012 segitiga, ~25× lipat aset pakis dan ~40× lipat tree_01) diwarisi langsung dari geometri sumber Poly Haven — ditandai perlu di-decimate sebelum dipakai di sebaran padat, belum dikerjakan (butuh akses Blender).
  • Shader air secara eksplisit BELUM dibangun — water_surface.usdz dikirim sebagai geometri statis siap-shader saja (tiling UV 1,33m sesuai CLAUDE.md). Normal beranimasi/riak/refraksi/depth-fade adalah tugas terpisah pihak RealityKit, belum dimulai.
  • Animasi joran dan tali berbasis tulang BELUM dibangun — keduanya dikirim sebagai kerangka rest-pose saja; pihak app harus memutar tulang secara live dari input kemiringan perangkat setiap frame. Tidak ada klip terbakar untuk keduanya.
  • Aturan ekspor tetap seluruh proyek (dari insiden CP38, juga ada di CLAUDE.md §7): exporter USD Blender diam-diam membuang shader non-standar (node Emission-saja, grafik node prosedural) tanpa error sama sekali dan lolos usdchecker. Setiap ekspor di masa depan wajib diperiksa sekilas dengan usdcat/usdchecker, bukan cuma usdchecker saja.

Lisensi (untuk layar kredit app)

CC-BY (atribusi wajib): dock_main, rod_main, rod_line (warna datar/tanpa tekstur tapi tetap cek Source_Log), semua batu/pohon/properti (sesuai CLAUDE.md §5), Fish03 Marlin, Fish06 Mekong Catfish (pengganti Pangasius), Fish10 Sailfish.

CC0 (tidak perlu atribusi): semua sumber HDRI sky_dome (semuanya — bell_park_dawn, evening_road_01_puresky, qwantani_sunset, cloud_layers, dll), tekstur damp_sand milik terrain_underwater, semua tekstur bersumber Poly Haven pada umumnya.

Pengecualian yang ditandai di tempat lain dalam memori proyek: tekstur riak-air waternormals.jpg dari three.js berlisensi MIT dan tetap perlu atribusi (disinggung sekilas di CP42 tindak lanjut #5, dicatat terpisah dari Source_Log repo ini sendiri).

Item lintas-repo/proses yang masih terbuka

  • Repo app berada di ~/repos/c4/CtSPoC (workspace CtSPoC.xcworkspace, aplikasi World + Rod). Aset apa pun yang berubah di repo ini harus disalin ulang secara identik byte-per-byte ke World/World/Assets/Environment/ dan sebaliknya — dipastikan lewat shasum setiap kali.
  • Konektivitas Blender MCP jadi masalah berulang di beberapa sesi (CP43/CP44/CP45): add-on yang terpasang berbicara protokol soket raw-JSON pihak ketiga "ahujasid" (port 9876, tanpa null terminator), bukan protokol paket resmi blmcp dari PyPI. Solusi sementara: berbicara langsung ke port 9876 lewat raw Python socket memakai {"type": "execute_code", "params": {...}}. Perbaikan permanen (mengarahkan ulang .mcp.json, atau menjalankan add-on resmi) sudah berkali-kali ditandai tapi belum benar-benar diselesaikan per entri terakhir.