![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
![]()
Сообщение
#1
|
|
![]() Открытая реализация Heroes III на JavaScript Сообщений: 8 Спасибо сказали: 50 раз ![]() |
Хочу представить проект, над которым я работал три года.
Реализация «Героев меча и магии III: Дыхание смерти» для браузера Сайт: herowo.game (запустить Tutorial) Код: https://github.com/HeroWO-js Число строк в проекте - порядка 100 тысяч. JavaScript: клиент и сервер. PHP: конвертер карт, подготовка данных. По клику на картинки можно посмотреть короткие ролики, если лень открывать сайт: ![]() ![]()
Модификации Актуальная версия «Введения в модификации»: https://forum.herowo.net/t/topic/47 Самая сильная часть движка - расширяемость. JavaScript был выбран как альтернатива C++/Java, на которых написаны другие проекты (VCMI, fheroes2). Используемый фреймворк (Sqimitive.js) позволяет модифицировать абсолютно все - к примеру, в нем не существует методов (любой метод - это потенциальное событие, на которое можно подписаться) и закрытых полей классов. Но очень многие вещи не требуют программирования вообще. Вот некоторые примеры. Система эффектов В движке определено более 150 типов значений, влияющих на игровые механики, как то (в скобках - использование в SoD):
Например, в поле ввода можно вставить такой эффект и нажать Create: Код {"priority": 344, "target": 47, "ifWorldBonus": 3, "modifier": [11, 10.0]}
Можно добавить еще какой-нибудь селектор, например, "не применять к AI": Код {"priority": 344, "target": 47, "ifWorldBonus": 3, "modifier": [11, 10.0], "ifPlayerController": "human"} А таким эффектом можно увеличить шанс возникновения чумы и ее силу: Код {"target": 154, "modifier": [16, {"3,PLAGUE,0.1": 100}], "priority": 500} Правда, в HeroWO мировые бонусы определяются раз в день, а не раз в неделю, поэтому если мы не хотим, чтобы 6 дней в неделю из 7 был чума, нужно добавить селектор (день 1 = понедельник, неделя 1 = первая неделя месяца): Код {"target": 154, "modifier": [16, {"3,PLAGUE,0.5": 100}], "priority": 500, "ifDateDay": 1, "ifDateWeek": 1} ![]() Вот пример поинтереснее, назовем его артефактом Hand of Midas: Код {"target": 146, "modifier": [17, "exp500", "exp1000", "exp1500"], "ifBonusObjectClass": 944, "priority": 10000}
Код array_fill_keys($c_treasureChest, [ ['quest_chances', $chances('ge500/32 ge1000/32 ge1500/31 chArtT/5')], ]), 'ge500' => [['quest_choices', [$append, 'gold1000', 'exp500']]], 'ge1000' => [['quest_choices', [$append, 'gold1500', 'exp1000']]], 'ge1500' => [['quest_choices', [$append, 'gold2000', 'exp1500']]], Читается это так: при встрече с объектом класса treasureChest, бросить кубик с шансами: по 32% на исходы ge500 и ge1000, 31% на ge1500 и 5% на chArtT. В свою очередь, первые три дают игроку выбор между типами gold1000/1500/2000 и exp500/1000/1500. Описания этих типов, как и chArtT, для простоты я здесь приводить не буду, они есть по ссылке выше. Так вот, наш эффект применяется после стандартных quest_choices, так что в результате вычисленное значение никогда не будет содержать exp500/1000/1500. Игрок будет всегда получать либо золото (без возможности выбрать опыт), либо артефакт. Как вариант, можно было бы перекрыть не quest_choices, а quest_chances, получая из всех сундуков всегда только артефакты (или что-то другое, например, существ - как это сделано для Pandora's Box). Банк данных Банк данных HeroWO, по-заморски "databank" - хранилище независимых от карты данных. В основном получаются из TXT-файлов SoD (или модифицированных). Однако карта может менять их произвольно (в отличие от SoD, где допускается изменение только некоторых вещей - например, параметров героя, но не здания). Например, можно добавить новое здание City Lights к Castle, которое, будучи построенным, будет раскрывать по 1 дополнительной клетке вокруг шахт и других объектов. Для начала добьемся нужного эффекта добавив, гм, эффект: Код {"target": 137, "modifier": 1} 137 = ownable_shroud, а 1 - это короткая форма записи modifier: [5, +1], где 5 = delta, то есть сложение результата с числом. В такой форме эффект работает для всех игроков, т.к. у него только один селектор - target. Но это мы исправим позже. Добавим здание в банк данных. Для этого в папке с картой в формате HeroWO (это набор JSON-файлов, в том числе map.json) создадим папку databank, а в ней файл buildings.json с таким содержимым: Код [ [ { "-1": { "name": "City Lights", "description": "Increases scouting radius around mines and dwellings that you own.", "cost_gold": 1000, "cost_wood": 5, "cost_ore": 5, "require": [2], "town": [0], "image": [ ["HALLTOWR", 0, 26], "TBTWHOLY", "TOTHOLYA", [], [], 0, 0, 50, "BOTGRAIL", false, false, false, false, false, false, false ], "effects": [false,false,false,true,false,false,false,false,false,false,false,false,false ,false,false,false,false,false,false,false,false,137,false,false,false,false,fal s e,false,false,false,2,false,false,false,false,false,false,false,false,false,fals e ,false,false,false,false,false,false,false,false,false,false,false,false,false,f a lse,false,false,false,false,false,false,false,false,false,false,false,false,fals e ,false,false,false,false,false,false,false,false,false,false,false,false,false,f a lse,false,false,false,false,false,false,false,false,false,false,false,false,fals e ,false,false,false,false,false,false,false,false,false,false,false,false,false,f a lse,false,false,false,false,false,false,false,false,false,false,false,false,fals e ,false,false,false,false,false,false] } } ] ]
![]() ![]() Тонкость в том, что запакованный эффект на самом деле задан так: Код {"target": 137, "modifier": 1, "ifPlayer": true} Селектор ifPlayer имеет особое значение true; движок заменяет его на номер игрока, у которого есть постройка. Такой трюк работает со многими селекторами (например, ifObject = конкретный объект на карте, ifX = точка на карте), так что, например, наш Hand of Midas можно было бы прописать в эффектах артефакта, задав селектору ifObject значение true, что читается как "для героя-владельца артефакта". Такой эффект будет давать 1 клетку на каждый город с City Lights. Если это нежелательно, можно использовать особое поле stack, запрещающее применять более одного эффекта данного типа к значению (например, оно используется для однократного применения бонуса морали к отряду). Программирование модулей Эффектами и изменениями в банке данных можно добиться очень многого. Практически вся механика объектов на карте (сундук, ресурс, артефакт, монстр, жилище, страж врат, колодец, мельница, фонтан и т.д. и т.п.) задана именно эффектами, а не кодом, так как это намного проще - движок сам следит за тем, когда применить эффект и как его сбросить. Тем не менее, в HeroWO есть и система модулей (плагинов) на JavaScript. На herowo.io, кроме панели эффектов, есть панель подключаемых скриптов (кнопка Add script). Предлагаю нажать на нее и указать такой URL: Код https://herowo.game/pub/mod-ex-1.js По этому URL находится такой скрипт: Код define([], function () { var coords = '' return { start: function (cx) { $('<button id=mybtn>') .text('Go') .insertBefore('#controls .map-size') .click(function () { coords = prompt('Enter X-Y coordinates to center on:', coords) || '' var pos = coords.match(/(\d+)\D+(\d+)/) if (pos) { cx.screens().forEach(function (sc) { sc.set('mapPosition', [pos[1], pos[2]]) }) } }) $('<style id=mystyle>') .text( ` #mybtn { display: block; background: red; } ` ) .appendTo('body') }, stop: function () { $('#mybtn,#mystyle').remove() }, } })
Код https://herowo.game/pub/mod-ex-2.js ![]() Код define(['DOM.Common'], function (Common) { var Mod = Common.Sqimitive.extend({ mixIns: [Common.ScreenModule], _map: null, events: { render: function () { this._map = this.sc.modules.nested('HeroWO.DOM.Map') var dwelling = this.map.constants.object.type.dwelling this.autoOff(this.map.objects, [ 'ochange_p_' + this.map.objects.propertyIndex('available'), function (n) { var id = this.map.objects.fromContiguous(n).x if (this.map.objects.atCoords(id, 0, 0, 'type', 0) == dwelling) { this._updateObject(id) } }, ]) this.map.byType.findAtCoords( dwelling, 0, 0, 0, this._updateObject, this ) }, }, _updateObject: function (id) { this._map.objectEl(id).classList.toggle('mymod-available', this.map.objects.readSubAtCoords(id, 0, 0, 'available', 0) .find(0, count => count > 0 || null) != null) } }) var style = $('<style>') .text( ` .mymod-available { outline: .1em dashed lime; } ` ) return { start: function (cx) { style.appendTo('body') cx.autoAddModule('mymod', Mod) }, stop: function (cx) { $('.mymod-available').removeClass('mymod-available') cx.screens().forEach(sc => sc.unlist('mymod')) style.remove() }, } })
-------------------- Открытая реализация Heroes III на JavaScript | herowo.game
Спасибо сказали: XEL, Ashka, hippocamus, XEPOMAHT, feanor, DRONыч, Berserker, SerAlexandr, Day7, Эроласт, Airat, Арысь-Поле, QuestLion, Zabuza-san, AGG, dr0n, KypaToP_HM, Elmore, Lokos, DOC'a, Grossmaster, Хоботов, void_17, Gong Zigoton |
|
|
![]()
Сообщение
#2
|
|
![]() Advanced Member Сообщений: 125 Спасибо сказали: 155 раз ![]() |
Идея интересная. Хоть и не совсем понятно для кого это сделано.
Протестировать не удалось, та как не играбельно вообще. Не получается даже героем походить. А оно связано с лобби СОД? |
|
|
![]()
Сообщение
#3
|
|
Member Сообщений: 72 Спасибо сказали: 100 раз ![]() |
Идея интересная. Хоть и не совсем понятно для кого это сделано. Протестировать не удалось, та как не играбельно вообще. Не получается даже героем походить. А оно связано с лобби СОД? Не знаю что у вас не получилось протестировать, лично у меня заработало даже с телефона. Потыкал, в бой зашёл, потыкал. Играбельно. Для кого это сделано? Как минимум для себя отвлечься например от основной работы. Как вариант в портфолио. Просто выражение любви к одной из любимых игр. По поводу лобби полагаю что нет. Хд функционал тут не накручен пока что. тот проект сырой что бы пускать в онлайн к ориджен соду. Респект автору, работы ещё конечно туева туча, если ли какие нибудь сообщества что бы отслеживать прогресс. Гит не очень для этого подходит для юзеров все же. ![]() -------------------- N/A
|
|
|
![]()
Сообщение
#4
|
|
![]() Сейчас чем-то занят. Как и всегда. Сообщений: 687 Спасибо сказали: 479 раз ![]() |
Протестировать не удалось, та как не играбельно вообще. Не получается даже героем походить. Ну, в целом, я соглашусь, что достаточно неиграбельно. Как бы герой ходит, но это "10 fps experience", конечно же. Протестировать-побегать я могу, особенно, пока видно, что с самого начала есть жуткие проблемы со всем, но начинание же хорошее. Так что да, лет 20 работы в одиночку и, быть может, каждый сможет бегать в герои 3: СоД версию на телефоне и в браузере. Ну, если Убейсофты не запретят. А так да, норм. -------------------- I'm a furry dragoness, 'cause I can.
|
|
|
![]()
Сообщение
#5
|
|
![]() Открытая реализация Heroes III на JavaScript Сообщений: 8 Спасибо сказали: 50 раз ![]() |
Идея интересная. Хоть и не совсем понятно для кого это сделано. А для кого VCMI сделано? И другие? Потенциально может развиться в полноценный проект, не связанный рамками оригинальной игры. Моды существуют, значит интерес есть. А оно связано с лобби СОД? Никак. Протестировать не удалось, та как не играбельно вообще. Не получается даже героем походить. Ну, в целом, я соглашусь, что достаточно неиграбельно. Как бы герой ходит, но это "10 fps experience", конечно же. Это преувеличение или действительно так? У меня обычный ноутбук 5-летней давности. Открыл два окна в Chrome, запустил мультиплеер. Работает не без проблем, конечно, но отзывчивость нормальная и вполне играбельно, даже когда записываешь видео. Замок работает, битва работает, шахту взял. Ну, и ролики в шапке я ведь как-то записал. ![]() Только на телефоне не нужно пытаться открывать - там точно не играбельно, плюс интерфейс SoD не подходит для таких экранов. Так что да, лет 20 работы в одиночку и, быть может, каждый сможет бегать в герои 3: СоД версию на телефоне и в браузере. Почему обязательно в одиночку? Респект автору, работы ещё конечно туева туча, если ли какие нибудь сообщества что бы отслеживать прогресс. Гит не очень для этого подходит для юзеров все же. df2 есть, а так пока больше ничего. -------------------- Открытая реализация Heroes III на JavaScript | herowo.game
|
|
|
![]()
Сообщение
#6
|
|
![]() Сейчас чем-то занят. Как и всегда. Сообщений: 687 Спасибо сказали: 479 раз ![]() |
Протестировать не удалось, та как не играбельно вообще. Не получается даже героем походить. Ну, в целом, я соглашусь, что достаточно неиграбельно. Как бы герой ходит, но это "10 fps experience", конечно же. Это преувеличение или действительно так? У меня обычный ноутбук 5-летней давности. Открыл два окна в Chrome, запустил мультиплеер. Работает не без проблем, конечно, но отзывчивость нормальная и вполне играбельно, даже когда записываешь видео. Замок работает, битва работает, шахту взял. Ну, и ролики в шапке я ведь как-то записал. ![]() Только на телефоне не нужно пытаться открывать - там точно не играбельно, плюс интерфейс SoD не подходит для таких экранов. У меня телефон хоть и андроид, QR-коды не читает, спасибо, не надо. И фиг знает, то ли видеокарты отсутствие мешает, то ли код у вас как-то лучше работает, но у меня менюшка тупит дольше, чем на вашем видео. Примерно на 1-2 секунды задержка на всё. Зато карта быстрее загрузилась. Бой же точно также работает. И это тоже можно отнести в "относительно неиграбельную" категорию. И да, то, что работает - не значит, что оно работает. Фактически - может быть. Но играть в 10 фпс или в 800 на 600, когда игра поддерживает 1920 на 1080 (привет Path of Exile, оптимизация неиронично становится лучше с каждой лигой. А вот баланс ровно на столько же пунктов падает, пробивая дно за дном) - это не очень клёво. Так что да, лет 20 работы в одиночку и, быть может, каждый сможет бегать в герои 3: СоД версию на телефоне и в браузере. Почему обязательно в одиночку? Потому что вы пока что работаете один. А я привык прикидывать худшие, но минимальные варианты. Очевидно, что самый фиговый - если никто работать не будет. Но если никто не будет, то, полагаю, очевидно, что никто и не сделает. Поэтому и минимальный вариант - один человек из пока что заявленных 1. -------------------- I'm a furry dragoness, 'cause I can.
|
|
|
![]()
Сообщение
#7
|
|
![]() допустим, мяў Сообщений: 24 113 Спасибо сказали: 13422 раза ![]() |
У меня на ноуте (винда 11) открылась хорошо. Быстрые действия пропускают кадры.
Например, на коне по карте прокатиться - сначала пауза, потом со средины начинает двигаться со шлейфом предыдущих кадров. То есть графика страдает (что и неудивительно - javascript вообще не об этом) - но так всё работает норм. -------------------- Вокруг столько фильмов, книг, музыки - а природа какая невероятная!
Если тебе скучно жить - ты совсем дурак. (Татьяна Черниговская) |
|
|
![]()
Сообщение
#8
|
|
![]() laughed as one fey Сообщений: 12 167 Спасибо сказали: 20603 раза ![]() |
И чому я так ору с названия?
Очень хорошо, больше ремейков, хороших и разных |
|
|
![]()
Сообщение
#9
|
|
![]() HotA Crew Сообщений: 119 Спасибо сказали: 235 раз ![]() |
В...вау... Такой объем работы в одиночку....
Очень неожиданно. Даже не знаю что написать. Эпических масштабов работа! ![]() upd.: Можно было бы кстати сразу на С++ писать, благо с недавних пор есть компилятор LLVM в webassembly. Так все работало бы в разы быстрее -------------------- |
|
|
![]()
Сообщение
#10
|
|
![]() Открытая реализация Heroes III на JavaScript Сообщений: 8 Спасибо сказали: 50 раз ![]() |
Так что да, лет 20 работы в одиночку и, быть может, каждый сможет бегать в герои 3: СоД версию на телефоне и в браузере. Почему обязательно в одиночку? Потому что вы пока что работаете один. А я привык прикидывать худшие, но минимальные варианты. Очевидно, что самый фиговый - если никто работать не будет. Но если никто не будет, то, полагаю, очевидно, что никто и не сделает. Поэтому и минимальный вариант - один человек из пока что заявленных 1. Ну, я затем и начал эту тему, чтобы найти заинтересованных участников. Основу я заложил, все видимые проблемы не носят принципиального характера. У меня нет цели в одиночку довести движок до полностью завершенного состояния. Задачи по проекту есть разные, на любой вкус:
Еще можно просмотреть и поправить текстовое описание формата h3m, которое я собрал из разных источников. Это будет полезно всем подобным проектам, потому что единого цельного описания до сих пор нет (или оно мне неизвестно). У меня на ноуте (винда 11) открылась хорошо. Быстрые действия пропускают кадры. Например, на коне по карте прокатиться - сначала пауза, потом со средины начинает двигаться со шлейфом предыдущих кадров. То есть графика страдает (что и неудивительно - javascript вообще не об этом) - но так всё работает норм. JS сам по себе ни при чем. Дело в методе рисования карты (плюс, я подозреваю, у вас еще рисунки не сразу загрузились - следующее движение может быть уже плавным). Переделать на canvas, т.е. на ручное рисование 2D-графики, реально, просто для меня было важно закрыть весь функционал, пусть и не оптимальным образом, и я экономил время на всем, чем мог. Нужно помнить, что в текущем виде проект никак не претендует на звание завершенного. Между скоростью разработки и скоростью работы всегда выбиралось первое. Это нормально. И чому я так ору с названия? Штирлиц еще никогда не был так близок к провалу... ![]() В...вау... Такой объем работы в одиночку.... Очень неожиданно. Даже не знаю что написать. Эпических масштабов работа! ![]() Спасибо, очень приятно это слышать! Работы, действительно, было много. Но, надеюсь, на этом проект не закончится. upd.: Можно было бы кстати сразу на С++ писать, благо с недавних пор есть компилятор LLVM в webassembly. Так все работало бы в разы быстрее Смысла нет - VCMI именно так и делает. Если и стоило начинать новый проект, то на иных принципах. И, опять же, не в JS дело - по крайней мере, можно точечно переписать тормозящий функционал на wasm, его там будут единицы процентов от общего объема кода, зато сохранится расширяемость модами и простота разработки. -------------------- Открытая реализация Heroes III на JavaScript | herowo.game
|
|
|
![]()
Сообщение
#11
|
|
![]() Крайне средняя кошка Сообщений: 2 928 Спасибо сказали: 5184 раза ![]() |
*OwO intensifies*
-------------------- |
|
|
![]()
Сообщение
#12
|
|
![]() Nevada-kun Сообщений: 1 986 Спасибо сказали: 854 раза ![]() |
Прекрасная работа. Респект.
Но хотелось бы обратить внимание на баги. Тыкаешь на шахту - герой до нее еще не дошел, а флажки уже перекрасились. -------------------- ![]() |
|
|
![]()
Сообщение
#13
|
|
![]() Открытая реализация Heroes III на JavaScript Сообщений: 8 Спасибо сказали: 50 раз ![]() |
Прекрасная работа. Респект. Благодарю! Но хотелось бы обратить внимание на баги. Тыкаешь на шахту - герой до нее еще не дошел, а флажки уже перекрасились. Да, это есть во многих местах. При совершении действия его эффекты вступают в силу моментально, тогда как визуальный отклик вроде движения героя по карте происходит в отложенном режиме, с лагом по времени относительно состояния игрового мира. В битве это реализовано как положено, но в основной карте есть только рудементарная поддержка (как то поэтапное перемещение героя, но не смена флагов или раскрытие тумана войны). Это следует считать не багом (т.к. поддержка в ядре есть), но недоделанным функционалом. Хотя для игрока все одно, согласен. -------------------- Открытая реализация Heroes III на JavaScript | herowo.game
|
|
|
![]()
Сообщение
#14
|
|
![]() HotA Crew Сообщений: 119 Спасибо сказали: 235 раз ![]() |
-------------------- |
|
|
![]()
Сообщение
#15
|
|
![]() Открытая реализация Heroes III на JavaScript Сообщений: 8 Спасибо сказали: 50 раз ![]() |
У проекта появился Discord-сервер: https://discord.gg/UcGCNhJEUx
...форум: https://forum.herowo.net ...и несколько роликов с демонстраций возможностей на YouTube-канале: https://www.youtube.com/@PlayHeroWO
-------------------- Открытая реализация Heroes III на JavaScript | herowo.game
|
|
|
![]()
Сообщение
#16
|
|
![]() Открытая реализация Heroes III на JavaScript Сообщений: 8 Спасибо сказали: 50 раз ![]() |
Приглашаю всех, кому интересна разработка игр, оценить мою статью на Хабрахабре о суровых буднях работы над движком HeroWO:
-------------------- Открытая реализация Heroes III на JavaScript | herowo.game
|
|
|
![]()
Сообщение
#17
|
|
![]() допустим, мяў Сообщений: 24 113 Спасибо сказали: 13422 раза ![]() |
Цитата Z-координата (глубина/дальность от глаз пользователя) вычисляется неясным образом. Вначале я думал, что она зависит от порядка следования объектов внутри .h3m и их координат, но после многочасовых экспериментов с редактором карт я оставил попытки разобраться, как же именно она определяется, так что текущая формула выглядит не очень. Кто знает, расскажите! В общем, обычно, чем ниже основание объекта (больше Y) - тем позже он отрисовывается (то есть, он ближе к игроку). Но есть объекты, имеющие флаг "элемент ландшафта" - шахты, блоки цветов, холмиков. Они отрисовываются первыми (то есть любой объект без этого флага их загородит, отрисовавшись поверх). -------------------- Вокруг столько фильмов, книг, музыки - а природа какая невероятная!
Если тебе скучно жить - ты совсем дурак. (Татьяна Черниговская) |
|
|
![]()
Сообщение
#18
|
|
![]() Открытая реализация Heroes III на JavaScript Сообщений: 8 Спасибо сказали: 50 раз ![]() |
В общем, обычно, чем ниже основание объекта (больше Y) - тем позже он отрисовывается (то есть, он ближе к игроку). Но есть объекты, имеющие флаг "элемент ландшафта" - шахты, блоки цветов, холмиков. Они отрисовываются первыми (то есть любой объект без этого флага их загородит, отрисовавшись поверх). Да, про это я знал, но оказалось, что алгоритм еще учитывает наложение объектов друг на друга, как мы выяснили из исходников VCMI: https://github.com/vcmi/vcmi/blob/develop/c...Handler.cpp#L73 * * * На Хабрахабре вышла вторая статья по истории разработки и внутренностях движка HeroWO: -------------------- Открытая реализация Heroes III на JavaScript | herowo.game
Спасибо сказали: |
|
|
![]()
Сообщение
#19
|
|
![]() Immortal Сообщений: 614 Спасибо сказали: 749 раз ![]() |
Шикарный сделано, очень большой объем работы.
Честно говоря, всегда считал и считаю динамические языки, вроде js, очень обтекаемыми. В том смысле, что им не хватает строгости. Тиринг и лаги прорисовки связаны с рисованием через DOM? Какой браузер рекомендуется для игры в эту игру? |
|
|
![]() ![]() |
Текстовая версия | Сейчас: 22 October 2025 - 07:46 |
Copyright by Алексей Крючков
![]() Programming by Degtyarev Dmitry |
|