«Прошло семь лет, но я вспоминаю о провале Elemental: War of Magic каждый день»

Основатель студии Stardock Брэд Уорделл об ошибке, которая погубила амбициозную стратегию.

В закладки
Брэд Уорделл (слева)

Когда в 2007 году создание Elemental: War of Magic только начиналось, у разработчиков были поистине грандиозные планы. Stardock планировали создать огромный живой мир, в котором невозможно было бы встретить двух одинаково выглядящих юнитов.

Игровые персонажи могли жениться и заводить детей, которые со временем вырастали бы и тоже приобретали уникальную внешность. Также разработчиками была придумана система создания городов, в которой можно было строить абсолютно уникальные поселения — «прямо как в Sim City».

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

В конце 2000-х годов 3D-графика уже массово использовалась в стратегиях. По словам Бреда Уорделла, это была «интересная эпоха»: игроки ждали от внешнего вида юнитов очень многого, но разработчикам приходилось создавать игры, ориентируясь на 32-битные операционные системы. Проблема заключалась в том, что компьютеры под управлением 32-битной версии Windows позволяли использовать только 2 ГБ оперативной памяти.

Примерно через год после начала разработки Elemental игра вдруг стала вылетать без всякой видимой причины.

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

Брэд Уорделл
основатель Stardock

Спустя два года разработки необъяснимые вылеты не прекратились. Плюс к этому, по словам Уорделла, с игрой стали происходить «странные вещи», которых разработчики не ожидали.

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

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

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

Брэд Уорделл

В запущенном состоянии игра даже не приближалась к лимиту памяти — она использовала всего около 800 мегабайт. Несмотря на это, приложение постоянно вылетало.

Отказ от того или иного элемента снижал количество вылетов, но не предотвращал их полностью.

Для меня, как для инженера, это было техническим вопросом. Игра вылетает, значит, можно сделать только одно: потратить достаточно времени и отыскать этот баг в коде. Вот только это не было багом в коде.

Брэд Уорделл

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

После нескольких часов постоянного перераспределения память оказывалась настолько фрагментированной, что свободное место заканчивалось.

Это невозможно было пофиксить. И это наводило ужас, — ты осознаёшь, что корень проблемы лежит в самом основании движка, над которым ты работал долгие годы.

Брэд Уорделл

При этом оригинальный дизайн игры за долгие месяцы удаления контента изменился до неузнаваемости. По мнению Уорделла, при взгляде на финальный вариант Elemental у игрока мог бы возникнуть вопрос: «А где, собственно, игра?»

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

После релиза игра вызвала жуткую отрицательную реакцию. Мы раньше никогда не выпускали плохих игр. Это был огромный удар по боевому духу в коллективе, а продажи оказались просто ужасными.

Один поклонник Master of Magic, который делал фанатскую одежду, прислал нам в знак протеста грязную футболку. Мы были просто раздавлены. Прошло семь лет, но я вспоминаю о провале игры каждый день.

Кто-то скажет: «Как они могли не знать про фрагментацию памяти?» Но если вы будете честны с собой, то признаете, что это не такое уж распространённое знание.

Даже сейчас довольно трудно найти достойные программы для фрагментации памяти. С этим не так уж часто сталкиваются.

Брэд Уорделл

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

Сиквел к Elemental под названием Fallen Enchantress разработчики отдали бесплатно каждому, кто купил первую часть. Движок был радикально переработан и в результате лишился проблемы, погубившей War of Magic.

Но это, по словам Уорделла, привело к фундаментальным изменениям в геймдизайне: оригинальная задумка Stardock так и не была реализована.

#gamedev

{ "author_name": "Никита Евдокимов", "author_type": "editor", "tags": ["\u0438\u0433\u0440\u044b","gamedev"], "comments": 11, "likes": 20, "favorites": 1, "is_advertisement": false, "subsite_label": "flood", "id": 34467, "is_wide": false }
00
дни
00
часы
00
мин
00
сек
(function(){ var banner = document.querySelector('.teaserSberbank'); var isAdsDisabled = document.querySelector('noad'); if (!isAdsDisabled){ var countdownTimer = null; var timerItem = document.querySelectorAll('[data-sber-timer]'); var seconds = parseInt('15395' + '50799') - now(); function now(){ return Math.round(new Date().getTime()/1000.0); } function timer() { var days = Math.floor(seconds / 24 / 60 / 60); var hoursLeft = Math.floor((seconds) - (days * 86400)); var hours = Math.floor(hoursLeft / 3600); var minutesLeft = Math.floor((hoursLeft) - (hours * 3600)); var minutes = Math.floor(minutesLeft / 60); var remainingSeconds = seconds % 60; if (days < 10) days = '0' + days; if (hours < 10) hours = '0' + hours; if (minutes < 10) minutes = '0' + minutes; if (remainingSeconds < 10) remainingSeconds = '0' + remainingSeconds; if (seconds <= 0) { clearInterval(countdownTimer); } else { timerItem[0].textContent = days; timerItem[1].textContent = hours; timerItem[2].textContent = minutes; timerItem[3].textContent = remainingSeconds; seconds -= 1; } } timer(); countdownTimer = setInterval(timer, 1000); } else { banner.style.display = 'none'; } })();
{ "id": 34467, "author_id": 61917, "diff_limit": 1000, "urls": {"diff":"\/comments\/34467\/get","add":"\/comments\/34467\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/34467"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 199791 }

11 комментариев 11 комм.

Популярные

По порядку

Написать комментарий...

Комментарий удален

–3

Точно так же как вы, видимо, не дочитали статью. Тут явно сказано было, что проблема была не самая тривиальная требующая не самых тривиальных инструментов. Поэтому шутки про "C++ за неделю" тут неуместны.
Кто-то скажет: «Как они могли не знать про фрагментацию памяти?» Но если вы будете честны с собой, то признаете, что это не такое уж распространённое знание.

Даже сейчас довольно трудно найти достойные программы для фрагментации памяти. С этим не так уж часто сталкиваются.

Ответить
19

Они написали свой менеджер памяти, но не подумали про фрагментацию? Серьезно? Шутка про с++ за неделю более чем уместна.

Ответить

Комментарий удален

9

Брэд второй раз внимательно просмотрел код и понял, что программа написана индусами-аутсорсерами на PHP3. Кто-то скажет: «Как они могли не знать про такое?» Но если вы будете честны с собой, то признаете, что это не такое уж распространённое знание.

Ответить
1

Серьезно?

Ответить
0

Косяк, согласен. Поправил

Ответить

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

1

«странные вещи», которых разработчики не ожидали.

Да блин, какие? Прямо вот мистика и непознанное.
Страшно подумать, неужели у юнитов, которые расплачивались последней ОДНОЙ монетой за товар стоимостью в 2 монеты, - вдруг оказывалось 65 535 монет?

Ответить
1

На DTF в комментах пишут, что "не знать" они явно не могли, т.к. проблема известная, и в принципе решаемая. А еще оригинальное видео интервью удалено с youtube, т.к. канал нарушал копирайт многократно.
Сама статья в vc версии, к сожалению, получилась совсем невнятной :(

Ответить
0

Судя по стиму, вторую часть очень тепло встретили.
Среди системных требований - RAM 2 GB )

Ответить
0

можно было увидеть горожан, прогуливающихся по улицам,

причём каждый обладал бы уникальным оружием и одеждой.

Ну допустим, уникальность оружия видимо состояла в сочетании скинов (как и одежды), но каков милитаристский замах - никогда в истории горожане не прогуливались по улицам, _поголовно_ вооруженные (видимо, включая мужчин и женщин, стариков и детей).

Ответить
0

Скажем, в сенате Древнего Рима пробовали предложить одевать рабов как-то по особому - чтобы отличать от свободных людей - но сами же и передумали, потому что "тогда они будут знать как их много". И уж никто и никогда не собирался всех поголовно вооружать ... даже в осажденных городах на одного вооруженного защитника приходились десятки безоружных граждан.

Ответить
0

Этот облом лишниий раз напоминание всем-не изобретайте колесо, тем более если сами не умеете

Ответить

Комментарий удален

0

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "bugf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fjog" } } }, { "id": 10, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "bscsh", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "bugf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-223676-0", "render_to": "inpage_VI-223676-0-1104503429", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=bugf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudx", "p2": "ftjf" } } }, { "id": 16, "label": "Кнопка в шапке мобайл", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byzqf", "p2": "ftwx" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "bugf", "p2": "fzvc" } } }, { "id": 19, "label": "Тизер на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "p1": "cbltd", "p2": "gazs" } } } ]
Компания отказалась от email
в пользу общения при помощи мемов
Подписаться на push-уведомления