TGViewer
Сіпласпластик Сіпласпластик @cpplastic · 739 subscribers
Post #469 1.06K
Колись вже писав був статтю про локалізацію текстур у грі. На той момент треба було чік-чік і в продакшн, тому ми там чимось щось кудись експортували, моєю тулою обробили, потім назад якось запхали — доволі незручний процес.

Згодом зʼявився настрій то все покращити. А для цього треба розібратися, як у ресурсах гри що зберігається. На щастя основну роботу зворотної розробки вже проробили модери й навіть документували структуру файлів, тож мені лишалося цим скористатися.

Отже, в старих іграх на рушії Infinity Engine — Baldurʼs Gate, Planescape: Torment тощо — структура приблизно така: є key-файл (зазвичай називається chitin.key) і є тека data з низкою BIF-файлів (не дуже багато — штук 80, наприклад). Але фактично рушій працює з конкретними ресурсами: маю на увазі всілякі скрипти, зображення, описи анімацій, діалогів, звуки тощо. От їх якраз купа. Наприклад, у першій Baldurʼs Gate їх 37341 штука.

Але жорсткі диски в компах раніше були доволі повільні, а інколи й доволі малі, тому в певних випадках доводилося грати зі вставленим CD, який ще повільніший. Ну а файлові системи на вінді й зараз не фонтан у сенсі швидкодії. Тому читання такої кількості дрібних файлів напряму з жорсткого диска — це вирок. Натомість краще мати меншу кількість великих файлів. Саме так розробники й зробили (та й досі роблять).

Отож key-файл — це бінарний формат, який описує всі ресурси, а також де саме вони лежать. А лежать вони в BIF-файлах. Кожний BIF — теж бінарний: фактично архів, у який напаковані різні ресурси, тобто файли й тайлсети. Розробники їх згрупували якось для зручності.

Я вже мільйон разів писав, як мені подобається Kaitai Struct 🏗, тож не обійшлося без нього й цього разу. Писати бінарний парсер по готових спеках — якесь дивне задоволення, трохи медитативний процес навіть. Сидиш ото, пиришся в hex-редактор, щоб переконатися, що ніде не сплутав big-endian з little-endian — кайф! Хоча цього разу парсери конкретно для key та BIF сів писати мій дружбан.

А мені ж треба було вже працювати з конкретним типом ресурсів. В ідеалі я хотів би читати їх прямо з key+bif-файлів так само як це робить гра, але на той момент єдиним виходом було експортувати їх вручну іншим інструментом в локальну файлову систему. Постає питання: як написати код так, щоб потім не треба було його адаптувати?

Я пишу на 🦶 і спочатку думав абстрагувати якось процес читання в якийсь Reader абощо, а потім передавати його у свої обробники всюди. Але це якось кволо. До того ж якщо подумати, будь-який файл — це вже Reader, а точніше io.Reader. Тож гіпотетично можна написати свою імплементацію. Правда, виявилося, що для Kaitai одного io.Reader замало — треба ще io.Seeker, щоб можна було читати з будь-якого офсета.

Тут я натрапив на лібу spf13/afero, яка ніби трохи спрощувала все це. Тож я просто завʼязався на інтерфейс afero.Fs усюди у своєму коді, і на той момент працював з локальною файлухою. А згодом написав свою «віртуальну» файлову систему, яка дає змогу працювати з усіма запакованими ресурсами гри «прозоро» для користувача, хоча насправді я читаю їх прямо з BIF-файлів без проміжного видобування. І вуаля: підмінив одну фс на іншу, а воно досі працює 😎

Повільнувато трохи тільки 😅 Наприклад, видобування ~1200 файлів на 25 МБ загалом у мене на M1 Max ішло 2,5 хвилини 😂 Довелося зайнятися профілюванням, яке, маю зазначити, в Go дуже легко додати в програму! Посиділи трохи з тим же друганом, знайшли найболючіші місця, і тепер видобування всіх ресурсів на майже 2 ГБ загалом триває близько 12 секунд.

У підсумку скажу (знову) пару слів про Go 💻: я ще починаючи з торішнього Advent of Code писав, що мова мені не подобається. І в принципі це досі так. Вона якось деревʼяно відчувається, немає в ній наче фану зовсім. Але наскільки ж легко й зручно в ній доводити справу до кінця! От просто сідаєш і пишеш без виїбонів, а воно потім працює, так ще й компілюється в один бінарь для будь-якої системи. І тулінг зручний. Можливо, це наразі єдина розробка від ґуґла, яку я поважаю.
Telegram Cіпласпластик Два з половиною роки роботи, мільйон перекладених слів… І все ж ледь не перше, що бачить гравець — це головне меню іноземною мовою 🙁 Непорядок? І ми так подумали, тож взялися за локалізацію написів. Як ми здолали цю головоломку, читайте в статті від самих…
  • 👍 12
  • 🤣 1
More from @cpplastic
  1. Oct 7, 2026Post #543
  2. Oct 2, 2026Щось не злетіло з self-driving cars у автовиробників, еге ж? А стільки галасу було. Ну зат…
  3. Sep 24, 2026Ух, яку ж класну доповідь подивився: «Scott Jenson: Are we really going to use the same De…
  4. Sep 23, 2026Post #540
  5. Sep 21, 2026«Порекламую» вам український сайт, який мені дуже подобається. Взяв слово в лапки, бо як і…
  6. Sep 18, 2026Ви ж знаєте, що я полюбляю Tailscale 💠 попри те, що недоліків у них теж вистачає? Але сам…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →