На чем написана dwarf fortress

711 тысяч строк кода, 20 лет, один разработчик: как создавалась Dwarf Fortress

На чем написана dwarf fortress. Смотреть фото На чем написана dwarf fortress. Смотреть картинку На чем написана dwarf fortress. Картинка про На чем написана dwarf fortress. Фото На чем написана dwarf fortress

Dwarf Fortress — один из тех странных проектов, ставших любимыми в Интернете. Это бесплатная игра, в которой можно быть или авантюристом, или управлять крепостью дворфов в случайно сгенерированном фэнтези-мире. Симуляция очень подробна, каждая новая игра создает множество цивилизаций со своей историей, мифологиями и артефактами.

Она стала знаменитой, и вполне справедливо. Каждый дворф уникален, он имеет эмоциональное состояние, предпочтения в драгоценных камнях и причины для недовольства. И всё это происходит в ASCII-интерфейсе, кажущемся новичкам каким-то обманом, но опытные игроки способны ориентироваться в нём как в бегущем тексте из фильма «Матрица»: они видят в этих символах дворфов, реки, легендарных огромных чудовищ.

Вся игра стала творением одного разработчика — Тарна Адамса с ником Toady One, который работал над Dwarf Fortress с 2002 года. Первые четыре года это был хобби-проект, но с 2006 года он стал его основной работой. Адамс пишет весь код сам, а его брат помогает с дизайном и создаёт истории на основе игры. До недавнего времени он собирал пожертвования, чтобы продолжать работу, но сейчас создаёт версию с пиксельной графикой и переработанным UI, которую можно будет купить в Steam.

Я связался с Тарном Адамсом, чтобы узнать у него о том, как ему удавалось в течение пятнадцати с лишним лет справляться с единой увеличивающейся кодовой базой, сложностями поиска путей и отладкой мёртвых кошек.

Вопрос: Какие языки программирования и технологии вы используете? Каков ваш стек? Менялся ли он за 15-20 лет вашей работы?

Ответ: DF — это некая комбинация из C и C++, но не в каком-то подчиняющемся стандартам формате, а скорее, накопившийся со временем хаос. Я пользовался Microsoft Visual Studio, начиная с MSVC 6, а сейчас работаю в версии Visual Studio Community.

Для решения задач движка я использую OpenGL и SDL. Мы выбрали их, потому что их проще портировать на OSX и Linux, хотя я даже сейчас не смог бы сделать всё это самостоятельно. Не знаю, будь у меня выбор, использовал ли бы я сегодня что-то вроде Unity или Unreal, потому что не знаком ни с тем, ни с другим. Однако поддержка собственного движка — это настоящая боль, особенно теперь, когда я работаю с пиксельной графикой. Для создания звуков я использую FMOD.

Всё это оставалось неизменным на протяжении многих лет развития проекта, за исключением SDL, который был добавлен спустя несколько лет после начала, чтобы можно было создавать порты. Что касается механик игры, то я не пользуюсь большим количеством внешних библиотек, но иногда подбираю библиотеки для генерации случайных чисел — очень давно я добавил Mersenne Twister, а последним дополнением стал SplitMix64, о котором рассказывали в докладе на последнем Roguelike Celebration.

В: Какие сложности возникают при такой длительной разработке одного проекта? Считаете ли вы, что проще делать его самому? Ведь если каждую строку написал ты, его проще поддерживать и изменять?

О: Всё очень быстро забывается! Если посчитать количество символов «;», чтобы приблизительно оценить объём, то получится, что в коде примерно 711 тысяч строк, поэтому я уже просто не могу держать всё в голове. Я пытаюсь давать своим переменным и объектам стандартизированные и легко запоминающиеся имена, и оставляю достаточно много комментариев, чтобы напоминать себе, что происходит, когда мы доходим до конкретного участка кода. Иногда требуется несколько операций поиска, чтобы найти именно тот поток, над которым мне нужно поработать, когда я возвращаюсь к какому-то фрагменту кода, десяток лет остававшемуся неизменным, что бывает достаточно часто. Можно сказать, что большинство изменений происходит в отдельных частях игры, поэтому есть некое активное расплавленное ядро, которое знакомо мне больше всего. Но есть и сильно закостеневшие части кода, которые я не трогал с момента первого релиза игры в 2006 году.

Что касается простоты работы в одиночку, то это идеальный вариант, особенно для меня, не имевшего опыта работы над крупным коллективным проектом! Очевидно, что другие люди выполняют задачи иначе, например, в контексте AAA-игр, и чтобы справиться вовремя, в этой сфере нужно много инженеров. Не могу с уверенностью сказать, что способен вносить изменения быстрее, чем они, потому что раньше не работал в этом контексте, и если нужно внести изменения, передо мной не встаёт никаких бюрократических преград. Я могу просто браться и делать. Но делать приходится в одиночку.

В: Самый крупный рефакторинг/изменение, которое вам приходилось вносить?

О: Было несколько рефакторингов, которые длились месяцами, я переделывал некоторые структуры данных и тому подобное, однако я не считаю, что это можно назвать строго рефакторингом, потому что всегда есть возможности параллельно совершенствовать механики, и это логично делать, пока твои знания кода ещё свежи.

Добавление координаты Z, чтобы механически игра вышла в 3D (оставаясь при этом текстовой), было одним из таких изменений, оказавшимся почти самой сложной задачей за всю мою жизнь. Мне потребовались долгие недели на изучение логики и вызовов функций, в которых использовались X и Y, и на анализ того, как в них встроится ось Z.

Внедрение полиморфизма в систему предметов в конечном итоге оказалось ошибкой, и очень крупной.

На чем написана dwarf fortress. Смотреть фото На чем написана dwarf fortress. Смотреть картинку На чем написана dwarf fortress. Картинка про На чем написана dwarf fortress. Фото На чем написана dwarf fortress

В: Почему это было ошибкой?

О: Когда объявляешь класс, являющийся типом предмета, то ты оказываешься привязанным к этой структуре сильнее, чем если бы это были элементы. Возможность использования виртуальных функций и тому подобного удобна, но плата за это слишком высока. Я стал использовать в иерархии предмет «tool», который начал получать различные функции, и теперь может поддерживать всё, от приставной лестницы до улья или ступы (и отдельно песта для неё, ха-ха), и такая система кажется более гибкой, поэтому я хочу, чтобы каждый создаваемый в игре предмет относился к этой иерархии.

У нас много процедурной генерации, и если бы мы хотели, допустим, сгенерировать предмет, который частично действует как один предмет, и частично как другой, то это было бы намного сложнее сделать, если бы мы были ограничены иерархией классов. Добавление таких вещей, как ромбовидных зависимостей и тому подобного в результате запутывает тебя в узлах. При этом существует более чистый способ реализации такой схемы. Если различные компоненты можно просто включать и отключать, то это проще и даёт больше возможностей.

Кажется, некоторые разработчики называют это entity component system, однако те, кто делает сильный упор на оптимизацию, воспринимают её как нечто иное — как систему, в которой ты разбиваешь элементы на отдельные поля. Использование единого объекта с различными распределёнными подобъектами почти всегда хуже сказывается на промахах кэша, однако преимущества для упорядочивания, гибкости и расширяемости такой системы нельзя игнорировать, а различные подполя в предмете «tool» используются не настолько часто, чтобы это превратилось в проблему оптимизации.

В: Столкнулись ли вы с какими-нибудь проблемами при переходе с 32 на 64 бита? Кажется, это один из тех аспектов, которые в своё время были очень важны, но со временем стали достаточно привычны.

О: Вообще никаких проблем! Я с трудом могу припомнить какие-то сложности. К счастью для нас, мы уже и раньше хорошо контролировали байтовые размеры, потому что это важно для сохранения и загрузки миров; с форматом нужно было определиться ещё в начале работы, особенно потому что нам приходится иметь дело с различиями в endian между разными операционками и тому подобным. Поэтому мы избегаем любых хитрых операций с указателями и других вещей, которые могли бы вызвать проблемы. В конечном итоге наш код оказался очень подходящим для перехода на 64 бита только благодаря другим нашим практикам, это было полной случайностью. Основная проблема заключалась в том, чтобы выделить время на внесение изменений, но в конце концов это заняло значительно меньше времени, чем я рассчитывал.

На чем написана dwarf fortress. Смотреть фото На чем написана dwarf fortress. Смотреть картинку На чем написана dwarf fortress. Картинка про На чем написана dwarf fortress. Фото На чем написана dwarf fortress

В: Я видел другие игры, похожие на DF, которые тормозили из-за алгоритмов поиска пути. Какой алгоритм вы используете и как обеспечиваете его эффективность?

О: Да, базовый алгоритм — это только часть дела. Мы используем A*, который, разумеется, быстр, но сам по себе недостаточно хорош. Мы не можем воспользоваться некоторыми его инновациями (например, поиском точки перехода), потому что наша карта сильно меняется. Обычно разработчики для упрощения используют решения, добавляющие поверх карты различные крупные структуры, а из-за меняющейся карты их поддержка занимает слишком много времени или слишком трудоёмка. Поэтому мы решили просто следить за соединёнными компонентами, которых можно достичь пешком. Такую систему довольно легко обновлять даже при быстром изменении карты. однако в ней используется заливка. Например, если вода разделяет крепость пополам, то она должна вытечь с одной стороны и присвоить всей половине крепости новый индекс, но после всего этого проблем обычно не бывает. Это позволяет нам вырезать из игры почти все неудачные вызовы A* — нашим агентам достаточно опрашивать числа компонентов, и если они одинаковы, агенты будут знать, что вызов окажется успешным.

Эта система быстра в поддержке, но её недостаток заключается в том, что индексы компонентов хранятся только для ходьбы. Это значит, что летающие существа, например, не имеют знания о глобальном поиске путей, кроме пешеходных. Однако чтобы дать им некоторое преимущество, в боях и некоторых других ситуациях мы используем заливки на короткие расстояния, применяя их обычную логику. Но такое решение для них неидеально.

Не уверен, будем ли мы пробовать другие структуры, чтобы улучшить работу системы. При наших размерах карт все попытки заканчивались провалом, даже когда за них брались сторонние разработчики. Разумеется, если сконцентрировать усилия, решить проблему можно, и я видел, что в некоторых других играх использовались, например, прямоугольные оверлеи и другие решения, которые выглядят многообещающе, но я не знаю, насколько неизменны и крупны их карты.

Самой простой идеей было бы добавление для летающих существ нового индекса, но это сильно повлияет на память и скорость, и поэтому мы не хотим хранить одновременно два индекса; даже один — это уже серьёзная нагрузка. Более специфические оверлеи способны отслеживать свойства прокладывания пути (после чего они прокладывают путь через оверлеи, а не тайлы), но при изменении карты их поддержка сложна и медленна. У нас есть и множество других идей, например, отслеживание лестниц или выполнение ограниченного кэширования путей, и возможно, они могут дать определённые преимущества. Мы определённо находимся на пределе того, что можем на данный момент поддерживать с точки зрения агентов и сложности карты, поэтому чтобы выжать больше, нам необходимо что-то придумать.

В: Кстати, об этом: вы одновременно симулируете множество элементов — как вам удаётся управляться с таким количеством асинхронно (и действительно ли вы используете асинхронность)?

О: Если под асинхронностью понимать многопоточность, то нет, её мы не реализуем, если не считать самого графического отображения. Это многообещающая тема, даже при микропоточности, с которой мне сильно помогло сообщество, но у меня не было времени на глубокое изучение. У меня нет никакого опыта в этом, и такая система сильно подвержена багам.

В: Пробовали ли вы наряду с DF работать над другими проектами/технологиями?

О: Разумеется! Папка побочных проектов, которая мигрировала между компьютерами на протяжении примерно десятка лет, содержит в себе примерно 90 проектов. Некоторые из них длились несколько дней, другие — несколько лет. В основном это другие игры, почти всегда в других жанрах, но есть и несколько вспомогательных проектов для DF, например, прототип генератора мифов. Ничто из этого не близко к релизу, но экспериментировать с ними интересно.

В: Имея около 90 побочных проектов, исследовали ли вы другие языки программирования? Если да, есть ли у вас любимчики?

О: Ха-ха, нет! Мне больше нравится разбираться с архитектурой, чем с технологиями. Однако я уверен, что некоторые вещи сильно бы ускорили реализацию моих архитектур, поэтому мне, вероятно, стоит изучить скриптинг и глубже разбираться с потоками. Другие разработчики любезно предоставили мне в помощь библиотеки и другие вещи, но сложно уделить время работы над побочными проектами для изучения технологий, если моё время для побочных проектов предназначено для расслабления.

В: У вас очень интересные описания изменений в версиях игры. Какой ваш любимый баг и что его вызывало?

О: Наверно, это покажется скучным, но для меня на первом месте баг с пьяными кошками. О нём уже сняли несколько видео. Кошки валяются на полу таверны и кажутся мёртвыми, но оказывается, что они налакались пролитого алкоголя, пока облизывали свои лапы. В коде проглатывания при чистке одно число было не на том месте, и это вызывало у них все симптомы алкогольного отравления (которое мы добавили, когда совершенствовали ядовитых существ.)

Источник

Автор Dwarf Fortress Тарн Адамс рассказывает о разработке игры

На чем написана dwarf fortress. Смотреть фото На чем написана dwarf fortress. Смотреть картинку На чем написана dwarf fortress. Картинка про На чем написана dwarf fortress. Фото На чем написана dwarf fortress

Одним из лучших способов применения мощных процессоров для развлечений долгое время была Dwarf Fortress — игра, в которой весь мир состоит из символов ASCII, и которая с радостью съест гигабайт памяти и большую долю процессорного времени.

Но в отличие от некоторых других игр, в случае DF игрок чувствует, что ей действительно нужно всё то, что она требует. Её подробные вычисления создают целый мир со зданиями, городами, торговцами, реками, вулканами, монстрами и, разумеется, гномами. Если бы один человек создал всё это, то это было бы потрясающим достижением; Dwarf Fortress — программа, создающая все эти объекты самостоятельно.

Автор игры Тарн Адамс согласился ответить на наши вопросы о своём творении, которое, несмотря на существование множества имитаций, до сих пор остаётся совершенно уникальной игрой.

Gamasutra: мы слышали, что Dwarf Fortress выходит в Steam и itch.io в платной версии с упрощённым интерфейсом. Говорят, что это вызвано вашими грядущими тратами на лечение. Сложно ли оставаться на плаву инди-разработчику?

Адамс: Да, много усилий приходится прикладывать, чтобы не уходить из бизнеса, и почти все разработчики вынуждены выдумывать творческие способы, чтобы иметь возможность оплачивать аренду жилья и прочие первостепенные нужды. И иногда ты сталкиваешься с проблемами, с которыми не можешь справиться. Нам пока везло, но со временем приходится меняться: увольняться и устраиваться на другое место работы, переходить на Patreon, а теперь и в Steam с itch, или рисовать карандашные рисунки, что очень далеко от создания видеоигр.

Как выглядит ваша повседневная работа по созданию кода для Dwarf Fortress? Какие языки вы используете? Какие библиотеки? Какие IDE, если пользуетесь ими? На каком компьютере вы разрабатываете игру?

Я работаю на обычном, ничем не примечательном ноутбуке Toshiba с Windows 10. Пишу код на ужасной смеси C/C++ в MSVC Community. Для legacy-версии я пользуюсь OpenGL, для основной — SDL, а для звука использую FMod. Больше ничем другим в Windows я не пользуюсь, за исключением части заголовков из MSVC (и до него), которые я использую уже десятки лет. Я не совсем в курсе, что происходит в версиях для Linux/Mac, потому что не разрабатываю их на регулярной основе.

На чем написана dwarf fortress. Смотреть фото На чем написана dwarf fortress. Смотреть картинку На чем написана dwarf fortress. Картинка про На чем написана dwarf fortress. Фото На чем написана dwarf fortress

Dwarf Fortress разрабатывается уже почти 17 лет, и её кодовая база должно быть достигла гигантских размеров. На моей машине для создания мира при стандартных настройках требуется больше 1,2 гигабайта ОЗУ. Проблема таких мегапроектов заключается в том, что они становятся слишком большими и не помещаются целиком в мозгу. Какими стратегиями вы пользуетесь, чтобы проект оставался доходчивым и понимаемым для работы?

У меня есть строгая система наименований, и я не экономлю на длинных названиях переменных и функций, чтобы всё было читаемым даже спустя несколько лет. В целом я стараюсь заботиться о будущем себе. Все мои комментарии в коде нацелены на это. Я активно пользуюсь функцией «найти в файлах». Но бывают ситуации, когда мне заново приходится разбираться в том, что происходит, например, при расширении старой системы или устранении бага; в таком случае просто на исследование может уйти час или больше. Это позволяет мне оставлять дополнительные полезные комментарии, о которых я изначально не подумал.

Я помню, что Threetoe (партнёр Тарна в разработке игры) пишет истории, а вы потом пытаетесь создать игровой движок, в котором они могут произойти. Мне до сих пор кажется, что это вдохновляющий способ работы. Были ли истории, которые вы отклонили, как слишком сложные в реализации? Бывало ли так, что сюжет одной из них полностью повторялся в игре?

Ха, я думаю, что в каком-то смысле все они слишком сложны. Мотивации персонажей, задание целей и т.д. продолжают надолго отставать от того, как они происходят в историях. Тем не менее, это всё равно полезный процесс, потому что всегда есть более лёгкие элементы генерирования истории; кроме того, мы можем приближаться к базовой механике персонажей, пусть даже никогда её и не достигнем.

Я завершаю релиз со злодеями, который выйдет в ближайшие несколько месяцев. Он должен быть довольно любопытным. Затем мы реализуем графику и повысим удобство игры для версий в Steam/itch. Потом мы улучшим процесс осад и выполним ещё кое-какую работу, и после этого перейдём к Big Wait. Это крупнейшая реструктуризация и расширение за всю историю DF. Она позволит нам генерировать мифы о творении и создавать полностью процедурные системы магии, а также открывать несколько окон обзора разных частей мира, и т.д. Это будет отличное дополнение. Потом будет релиз с собственностью/законами/таможней. После этого порядок пока не определён, но мы будем работать над экономикой, кораблями и другими важными компонентами, которых пока нет. Нам ещё многое предстоит сделать! Мы даже не прошли ещё полпути до версии 1.0. А ведь версией 1.0 разработка игры на самом деле не закончится… возможно, к моменту её выпуска у нас просто останется не так много времени.

На чем написана dwarf fortress. Смотреть фото На чем написана dwarf fortress. Смотреть картинку На чем написана dwarf fortress. Картинка про На чем написана dwarf fortress. Фото На чем написана dwarf fortress

В играх существует баланс между сюжетом и симуляцией, между заранее написанной историей, которая есть в большинстве игр, и созданием глубокого мира с набором правил, позволяющим возникать множеству различных историй. Я бы сказал, что Dwarf Fortress — один из самых серьёзных аргументов в пользу симуляции. Делают ли персонажи на этапе генерации мира или во время игры нечто такое, что удивляет даже вас? Можете привести какие-нибудь интересные/запоминающиеся примеры?

Да такое происходит постоянно! Частично это вызвано тем, что когда играешь, сложно держать все правила в голове. Однако все мои запоминающиеся истории — это баги, потому что я редко имею возможность достаточно долго играть в игру, поэтому с точки зрения самостоятельно возникающего геймплея они мало интересны (даже если удивляют меня). Хорошие истории можно найти на форумах, у стримеров, и так далее.

Граница между «микро» и «макро»: почему вы сделали её именно такой, между тем, что гномы могут делать сами, и что игрок приказывает крепости?

Это сложный баланс, и его не всегда легко соблюсти, но в данный момент концепция заключается в том, что игрок является «официальным выразителем воли крепости», а гномы проявляют автономность, которая должна присутствовать за пределами их официальных обязанностей. Это позволяет им быть актёрами в собственных историях, которые и являются основным источником возникающего (эмерджентного) повествования. В то же время игрок должен иметь возможность управлять основным потоком своей части игры (на самом деле это не критично, но часто более интересно, чем наблюдать за симуляцией).

Эти две цели могут конфликтовать, и часто это связано с тем, чтобы игрок продолжал получать от игры удовольствие — например, если аварийный рычаг действительно нужно опустить, то система приоритетов задач может практически заставить гнома сделать это, автономно или нет, в зависимости от того, должен ли он «знать» об этом, или нет. В прошлом у нас были проблемы с добавлением слишком сильной бюрократии, когда у нас, например, был гном-квартирмейстер, занимающийся выдачей оборудования. Но эта система была слишком медленной, подверженной багам и сбивала игроков с толку. Очень важно думать о том, как каждая отдельная игровая механика может добавлять потенциальные истории, а квартирмейстер почти не играл в этом никакой роли.

Какие шаги выполняет программа при построении мира?

Она выделяет память для карты. Затем она выбирает, какой полюс у неё будет (например, север, юг) (или учитывает параметры, переданные игроком). Seed генератора случайных чисел задаёт базовые значения полей карты (высота, осадки, температура, водоотвод, вулканическая активность, дикая природа) для сетки переменного размера с учётом различных параметров (океанов, размеров островов, другой вариативности), а затем программа фрактально заполняет их. От полюсов зависит изменение температуры, и программа выбирает точки для высочайших пиков. Здесь она делает первый проход, чтобы посмотреть, как выполняется процесс, и пытается изменить высоты, чтобы карта укладывалась в желательные параметры. На этом этапе, если мир нельзя исправить, он отбрасывается, и всё начинается заново.

Затем задаётся первое производное поле — растительность — зависящее от высоты, количества осадков, температуры и т.д. Программа проверяет, соответствуют ли биомы заданным в параметрах интервалам. На этом этапе сглаживаются высоты середины уровня, чтобы создать больше равнинных областей, а также размещаются вулканы в соответствии с полем вулканической активности.

Затем мы переходим к этапу эрозии и рек. Мелкие океаны осушаются, программа находит края склонов гор, с которых она может пустить тестовые реки. Кроме того, она располагает камеру на одной из них, чтобы игрок мог следить за процессом. Множество фальшивых рек течёт вниз из этих точек, прорывая каналы, если они не могут найти путь к морю. Слишком большие высоты иногда сглаживаются, чтобы вся карта не превратилась в каньоны. В идеале нужно бы использовать для этого виды минеральных веществ, но пока мы их не применяем. В нескольких точках рек выращиваются озёра.

На чем написана dwarf fortress. Смотреть фото На чем написана dwarf fortress. Смотреть картинку На чем написана dwarf fortress. Картинка про На чем написана dwarf fortress. Фото На чем написана dwarf fortress

Высоты снова сглаживаются от гор вниз к морю, а для пиков и вулканов выполняются локальные корректировки. После завершения создания высот программа вносит корректировки в величину осадков на основании дождевых теней и атмосферных осадков в горных областях. На основании высоты и осадков, а также сдерживающего эффекта лесов заново устанавливаются температуры, после чего программа использует новые значения для окончательного задания уровня растительности. Для океана и соседних с ним тайлов задаются значения солёности.

Определившись со всем этим, мы теперь можем найти границы окончательных областей биомов, чтобы дать им названия и индивидуальность. Здесь мы также добавляем геологические и подземные слои, хоть, как и сказано выше, геологическую информацию следовало бы добавлять раньше. Далее проводится финальный процесс верификации на соответствие параметрам, чтобы убедиться, что мы не слишком отклонились от того, что хочет игрок. Закончив с этим, программа генерирует для каждого региона изначальные популяции животного мира и задаёт переменные погоды.

Сама история начинается с этого момента. Затем располагаются цивилизации и пещеры. Довольно сложно объяснить, что происходит дальше, но основная идея заключается в том, что симулируется огромная стратегическая игра с нулём игроков с довольно произвольными правилами ходов и плохим ИИ (но с тысячами агентов), на основании чего записывается история. Процедурная генерация историй при помощи ведения журнала симуляции — это вполне рабочий подход, но он имеет и свои недостатки. Это большой объём работы, необходимо выполнять постобработку и изучение, чтобы найти хорошие моменты, которые вы хотите подчеркнуть, и если динамики и механизмов будет недостаточно, то результат может оказаться скучным.

В DF мне больше всего нравится то, что игра не содержит никакой явной системы хитпоинтов, всё связанное с силой и уроном персонажа является частью сложной модели частей тела. Какие преимущества даёт подобная система? Если кто-то решит создать нечто подобное, то какие препятствия его могут ожидать?

Эта модель создаёт более подробные сюжетные моменты, долговременные последствия и обеспечивает бОльшую связь систем. Здесь легко перегнуть палку, и мы действительно кое-где её перегнули, по крайней мере, на текущем этапе — некоторые свойства материалов больше нигде не используются. Кроме того, существуют способы смягчения системы, примеры которых можно увидеть в играх, где, например, есть общий пул выдержки/энергии/хитпоинтов, но конкретные раны возникают или вследствие критических ударов, или как последствия достижения нулевых или близких к нулевым значений в пуле. Правильный выбор системы зависит от игры. Мы стремимся как можно меньше использовать числа, потому что числа обычно плохо вяжутся с историями.

Как выглядит основной цикл игры?

Возьмём для примера режим гномов. Он начинается с проверки объявлений и считывания автосохранений, и т.п. БОльшая часть остального цикла происходит не в каждом такте. Например, через каждую сотню тактов программа проверяет назначенные задачи и «странные настроения». Армии перемещаются по карте мира. Через каждую сотню тактов программа обрабатывает выдаваемые гномам задачи. Это своего рода невидимый аукцион, который используется для управления разными конфликтующими приоритетами. Каждые десять тактов меняются времена года, что влияет на погоду и карту (и локально, и во всём мире), а также выполняется проверка развития элементов сюжета (дипломаты, осады и т.д.) и проверка того, что форт всё ещё жив.

Затем программа берётся за то, что делается в каждом такте. Движутся жидкости и меняется другая информация тайлов карты (однако есть различные оптимизации, чтобы в каждом ходе не обязательно проверялся каждый тайл; кроме того, существуют флаги, которые позволяют пропускать целые области карты, если в них ничего не произошло.) Обновляется перемещение хищников и обрабатываются другие «события» карты, например, активные пожары.

Если флаг задан, то раненые/испытывающие жажду/голодные гномы, которые не могут позаботиться о себе, получают обновление. Мёртвые гномы «думают» о своих ритуалах погребения, чтобы можно было назначить другим эти задачи. Заключённые в клетки и цепи существа периодически обновляют свои мысли и ситуацию.

Затем, если существа пересекли края карты, они с неё убираются.

На чем написана dwarf fortress. Смотреть фото На чем написана dwarf fortress. Смотреть картинку На чем написана dwarf fortress. Картинка про На чем написана dwarf fortress. Фото На чем написана dwarf fortress

Каждые пятьдесят тактов обновляется информация всех таверн, храмов, библиотек и т.д, зависящих от других тактов. Припасы, тоже зависящие от других тактов, работают аналогично. Аналогично выполняется создание заданий на хранение. Несмотря на то, что этот процесс дополнен различными оптимизациями, он всё равно достаточно медленный и на определённом моменте 50 с лишним тысяч камней может вызвать проблемы.

Каждую тысячу тактов объекты, помеченные на удаление из игры, на самом деле удаляются, и освобождается выделенная под них память. С предметами это происходит чаще, раз в пятьдесят тактов, как и проверка использования зданий (в основном это обновления для колодцев и некоторые другие флаги, которые нужно проверять часто.)

Каждую сотню тактов портятся предметы. Каждый такт выполняется рост растительности (хоть здесь есть много зависимостей и флагов.) При необходимости в каждом такте обновляются состояния зданий и перемещаются вагонетки. Выполняется продвижение по маршрутам перевозки. Обновляется температура (здесь есть множество флагов оптимизации, но пока это по-прежнему довольно медленный процесс.)

Наконец, обновляется камера, следующая за существом, за которым наблюдает игрок.

В Dwarf Fortress для отображения мира используется тайловая карта на основе сетки — простой и эффективный способ представления. Я заметил, что существует множество способов отрисовки тайлов, и это зависит от того, что делает или как себя чувствует существо, сколько элементов на тайле, есть ли что-нибудь над ним, является ли тайл текущей водой или он погребён под камнем. Когда DF принимает решение о том, как нужно отображать тайл, то что она делает? Как вы оптимизировали этот процесс?

Это просто символ (байт) с ещё несколькими байтами цвета, поэтому система совсем не затратна и мы можем просто заменить выбранное решение перед выводом на экран, а не пытаться решить всё одновременно, а большинству тайлов всё равно достаточно одного символа земли/стены. Программа идёт снизу вверх, в каком-то смысле используя «высоту» (существа находятся выше предметов, предметы — выше земли), время от времени меняя решение. Тем не менее, несмотря на наличие различных флагов и вспомогательных массивов, можно сделать ещё многое. Существует маленький массив возможных юнитов, которые можно вывести в каждый тайл, поэтому программа может реализовать покадровую анимацию, позволяющую увидеть каждый элемент на тайле, даже когда игра поставлена на паузу.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *