GMCheck — анонс
Немножко предыстории. Я ооочень давно познакомилась с замечательным игроконструктором Game Maker. Каждый апдейт, с 4.0 в 2001 году и до 6.1 в 2005, я встречала с нетерпением — чего же нового привнёс нам Марк Овермарс. Пусть за всё это время из-под моих лапок ни одной мало-мальски законченной игры не вышло, GM надолго стал одним из моих основных компьютерных развлечений, а скриптовый Game Maker Language — пожалуй, первым языком программирования.
Впоследствии по ряду причин — учёба, работа, другие увлечения — новые версии, созданные новыми разработчиками, прошли мимо. И когда меня на старости лет снова потянуло в геймдев, оказалось, за это время среда разработки очень сильно развилась в профессиональную сторону, похорошела, обросла множеством удобных фишечек. А вот язык остался практически на том же уровне, что и в начале нулевых. По сути, единственное крупное обновление произошло совсем недавно, в версии GMS 2.3. И даже оно, привнося несколько новых и действительно крутых возможностей, не исправляет имманентных проблем, лежащих в корне дизайна языка и его стандартной библиотеки.
Вообще говоря, даже немножко шаря в дизайне языков программирования, к Game Maker Language уже можно предъявить много объективных претензий, но это тема отдельной длинной статьи; а эта целенаправленно посвящена одному из самых больных мест — и чем проект крупнее, тем оно больнее. GML предоставляет множество способов наделать ошибок, но неохотно помогает их находить:
- Типизация в языке динамическая, что подразумевает проверки только в ходе выполнения, а выполнение за неимением юнит-тестов — это много-много пробных запусков игры, что долго и утомительно. И не факт, что эти запуски дойдут до ошибки, которая затесалась в ветке кода, срабатывающей только при очень особых условиях.
- При этом типичная реакция на ошибку — грохнуться с концами, сказав игроку «сорян» механизм исключений появился только в 2.3, а в остальном для отладки предлагается пошагово выполнять и останавливаться на брейкпойнтах, как в старых добрых 80-х.
- Разных типов, а соответственно, разных проверок — кот наплакал; даже такие вроде бы разные сущности, как булевые и целые значения, цвета, идентификаторы объектов, дескрипторы ресурсов и структур данных — это всё прикрытые фиговым листиком числа с плавающей точкой.
- Неявное объявление переменной по месту её использования массово приводит к ошибкам доступа к неинициализированной переменной, а флажок «treat as 0» — лишь уход от проблемы, лечение пульпита парацетамолом.
Я люблю игры, но не умею их делать. Зато люблю языки, и умею программировать, и хочу своими навыками помочь тем, кто тоже считает, что геймдев — это в том числе программирование. А также считаю, что самый быстрый и лучший способ исправлять ошибки — это заранее их не допускать. Поэтому с июня веду неспешную разработку GMCheck — статического анализатора кода в проектах на Game Maker Studio 2 (как более актуальной версии, но поддержку первой добавить несложно). Те, кто знаком с миром промышленного программирования, наверняка слышали о таких продуктах, как Сppcheck для C++, PVS Studio для C++ и Java, ReSharper для C#. А также о том, что старые динамические языки (PHP, Python, JavaScript) движутся в сторону опциональной типизации или ответвляются в статические диалекты (Dart, TypeScript). А если вы от всего этого далеки, то статический анализатор, вкратце — инструмент, позволяющий до запуска программы вылавливать в ней ряд потенциальных семантических (в т. ч. некоторых логических) ошибок, которые не заметил компилятор:
- Для динамического языка, коим является GML, это такой внешний тайпчекер, отслеживающий типы переменных и их возможные изменения, чтобы заранее не дать сложить строку с числом, использовать неинициализированную переменную, обратиться не тем аксессором к структуре данных или перепутать местами аргументы в развесистых функциях наподобие
draw_sprite_general
. - Причём динамические возможности — например, в рантайме поменять тип переменной, или передавать аргументом функции значения разных типов, в зависимости от чего она может вести себя по-разному — в языке-то и не используются. Все функции стандартной библиотеки имеют однозначные сигнатуры, без перегрузок. Свой скрипт можно написать каким угодно, нашпиговав внутри проверками типа
if is_real (argument0)
, но юз-кейсы такого рода сомнительны. Поэтому если одна переменная может иметь разные типы в разных участках кода или вдруг поменять его в ходе выполнения — это, возможно, и не ошибка, но как минимум предупреждение. - Поскольку типы переменных явно не указываются, их нужно выводить по контексту использования, и я не уверена, насколько полно это будет получаться. Однако несложно добавить опциональную типизацию, как в вышеупомянутых динамических языках — скажем, комментариями специального вида, которые сам GM просто игнорирует, а чекеру это будет помогать.
label /*: string*/ = <…>
- Для некоторых переменных имеет смысл отслеживать вхождение в возможный диапазон — например,
alpha
должен быть от 0 до 1, даже после всех возможных математических преобразований. - Скрипты в Game Maker — эдакие глобальные методы, которые можно вызвать из любого объекта, невзирая на его внутренности. Чекер может проверять, всё ли окружение, нужное скрипту, доступно в объекте на момент вызова, и не перетирает ли он чего-то важного.
- Не все, особенно новички, умеют грамотно пользоваться локальными переменными (
var
), из-за чего они могут висеть в объекте до скончания времён, или конфликтовать с другими (особенно при вызове скриптов). - Множество вещей, при которых программа вроде бы успешно работает, но что-то явно не так — неиспользование забытых переменных, вызов рисовательных функций вне события Draw, вызов или наследование пустых событий, обращение к
other
там, где его нет… - Структуры данных требуют ручного вызова
_create
и_destroy
, иначе можно словить утечку памяти. - Ошибки, порождаемые опечатками или копипастой — например, когда логическое выражение всегда получается истинным или ложным, в разных ветках условного выражения одинаковые конструкции, или параметрами передали
x
,y
,y
вместоx
,y
,z
. - …и много других.
Понятное дело, задача вот это всё обнаружить в общем случае неразрешима, что доказано ещё стариной Тьюрингом. Тем не менее, разнообразными эвристическими алгоритмами можно достичь очень неплохих результатов, пусть и с некоторым количеством ложноположительных срабатываний. Использование предполагается максимально простым — натравливаете программку на папочку с вашим проектом, и получаете HTML-отчёт обо всяких подозрительных местах. Интегрироваться в саму среду GM, увы, нельзя, но можно завести помощника-демона, который будет висеть в фоне и обновлять отчёт каждый раз, когда что-то добавляется в проект.
Разработка ведётся на Haskell — наилучшем языке для такого рода задач (компиляторов, трансляторов и прочих анализаторов сложноструктурированных данных). Репозиторий — здесь. На данный момент готов парсер практически всей грамматики GML в синтаксическое дерево, и растут зайчатки вывода и проверки типов. Stand-alone запускалки пока нет, разрабатываю, экспериментирую и проверяю юнит-тестами и в REPL.
Честно говоря, зная своё хроническое неумение доводить дела до конца, я совершенно не могу гарантировать, что проект дорастёт до хоть какого-то юзабельного состояния. И уж тем более не смогу своими скромными силами реализовать весь спектр возможностей, перечисленный выше. Но мне очень поможет, если буду знать, что он правда может кому-то пригодиться — любителей (и профессионалов!) Game Maker тут немало, я знаю. И кроме того, вы можете поддержать и другими способами:
- Триалка GMS2 у меня закончилась, а на лицензию раскошеливаться пока не хочу, поэтому очень полезными будут исходники маленьких проектов — например, с джемов, или просто синтетических примеров. Особенно здорово, если там действительно будут какие-нибудь загадочные ошибки, которые вы так и не смогли отловить.
- Рассказывать про самые-самые типичные и надоевшие баги, возникавшие у вас при разработке на GM.
- Проаннотировать сигнатуры всех этих бесчисленных функций стандартной библиотеки GML. Они лежат в отдельном текстовом файле с готовыми примерами, и знания хаскеля для этого не нужно.
- Просто предлагать всякие идеи и хотелки.
Stay tuned!
- 29 сентября 2020, 22:44
- 018
Вроде не троллинг, ну удачи!
Динамические языки движутся в сторону статизации, а статические - в сторону динамизации (например, заново изобретают композицию вместо наследования) :)
:D
Спасибо! Для троллинга всё-таки слишком много работы проделано, достаточно заглянуть в репозиторий =)
Композиция — это всё-таки не про динамику. Динамизация в статических языках — это, например, Component Object Model в C++, invoke через рефлексию в Java, dynamic в C#, Data.Dynamic в Haskell.
(извините, что я опять о языках общего назначения)
Я и говорю - и так плохо, и этак не очень. В динамических языках рефлексия и редактирование структуры типа в рантайме сами собой разумеются. А композиция (компоненты в Юнити и т.п.) - это такое же редактирование типа, но вид сбоку. :)
Самые надёжные и проверенные, но не под все задачи удобные, иначе бы их не было так много. :)
Хорошее начинание. Я бы может и писал игры на GML, если бы туда типизацию завезли.
А тесты это какой-то BDD?
Наверное стоит закинуть про это в какие-то основные гамакские сообщества помимо гамина, звучит как очень полезная вещь. Я удивлён что до сих пор не было сделано никакого статического анализатора для гэйммэйкера.
Просто юнит-тесты – вот для парсера. Полноценный TDD с «ни шагу вперёд без теста» я недолюбливаю, слишком нудно, да и избыточно для хаскеля и вообще языков с хорошими статическими гарантиями.
Ну и ручками тестирую – загружаю репл, дёргаю всякие функции,
parse "какой-нибудь код"
илиloadProject "D:/где/там/мой/тестовый/проект"
, смотрю, что загрузилось и что с этим можно сделать.В других сообществах (кстати, а какие есть, помимо официального?) пиариться начну, если проект таки доживёт до какого-то цельного костяка-черновика, который можно будет собрать в бинарник и показывать людям. Чтобы он мог пережёвывать хотя бы малюсенькие проекты и выдавать какой-то отчёт, пусть даже очень сырой и неполный.
Да в общем неудивительно. Статические анализаторы – штука сложная, в первую очередь предназначенная для больших проектов, где много кода и цена ошибки велика. А в GM и проекты обычно маленькие, и хардкорные программисты – которые вообще заморачиваются о качестве кодобазы – не идут, а начинающим разработчикам лишь бы хоть что-то написать, чтобы заработало. И если уж ЙоЙоАвторы даже язык почти не хотят улучшать (все усилия идут в среду разработки и кроссплатформенность), что уж говорить о сопутствующем инструментарии. А целевая аудитория хочет игры делать, а не инфраструктуру развивать (за редкими исключениями типа пресловутого GMLive).
Это и мои слова, но они означают совсем другое. Заранее не допущенные ошибки не требуют анализа кода.
Грустно это говорить, но я должен.
В 2013 году я сделал GMXD - вполне валидный инструмент для вполне понятных геймдевелоперских целей. Никто его всерьёз не воспринял, потому что ГМ8.1 уже сменился на Студию, а там не было execute_string() и все ГМщики с серьёзным лицом гнались за всем новым и молодёжным более похожим на серьёзное программирование.
Потом Жёлтый понял что он менее геймдевелопер и более программист, и создал GMLive, которым не пользуется никто из коммерчески вполне успешных ГМ-игр.
И теперь это. Я мысленно представляю себе своих знакомых ГМщиков, и не могу зачислить никого из них в ЦА этого продукта - они не программисты, и им чужда идея не то что статического анализа, но даже и просто версионирования через всякие git'ы.
Может быть это будет полезно, когда ГМ возьмут в оборот индустриальные дельцы со своим code monkey подходом, хотя бы по 10-20 кодеров-джуниоров на проекте, но когда наступит этот день - загадка.
«treat as 0» уже в ГМС1 был выпилен.
Просто не надо ошибаться, тогда и не нужны будут ни тесты, ни типы. В принципе, можно даже не запускать программу, если писать сразу без ошибок - сразу в релиз не глядя ее.
Мир был бы намного лучше, если бы люди были способны на такой уровень осознания.
Кситилон – сверхигродел, который не станет рассказывать про баги в GML, потому что за 14 лет никогда их не допускал.
Я бы рассказал, но, кроме шуток, я просто не помню какие были баги. Их возникновение и отлов воспринимается как неминуемая и привычная часть работы, по времени и силам теряющаяся на фоне настоящих проблем разработки игры - геймдизайна, левелдизайна, ощущения потока, сочности эффектов, и коопа с командой (там где она есть). Узкое место разработки игр - не программирование, а организация игры как цельного опыта/высказывания.
Или...
Имеются в виду баги в языке как таковом? Это какой-то слишком высокий уровень критики инструмента, который уже столько раз и столькими людьми проверен на практике, что в ней не особо нуждается.
Кому как, конечно.
Да нет, конечно. «самые-самые типичные и надоевшие баги, возникавшие у вас при разработке на GM». У меня это, кажется, были как раз неинициализированные переменные, и складывания строки с числом (забывала конвертировать их
real
ом). Перепутанный порядок аргументов вdraw_чегонибудь
. Ещё углы в градусах вместо радианов (тогда не былоdsin
), и вылезания за диапазон RGB или HSV от арифметических ошибок. Но всего уж не упомню, давно было очень, да и прототипы все мелкими остались.Не помнишь – ладно. Вообще, хотелось бы послушать Dreik , Herzenrg , DarkDes , lovixsama , alexsilent ...
Самое смешное, что у моих проектов могут повалиться столько багов, что уже не обращаешь на них внимание.
Буквально недавно словил некоторую логическую ошибку того, что обращался\менял view_* переменные, но забыл активировать (кодом или в комнате) собственно сам вид. Не понимал почему не работает, но и решить не пытался (не было приоритета, но потом решилось).
Чаще всего, после самых глупых ошибок, мои игры вылетают или не-дружат-с-логикой, когда дела доходят до дата структур.
Могу скинуть пару проектов с джемов(их ещё нужно найти конечно), правда, не знаю насколько это поможет.
Спасибо! Про
view_
интересный кейс, запишу в todo. За проекты тоже буду благодарна.ХЗ, у меня баги в основном с логикой самой игры, а не синтаксисом. Напутать индексы в сложносочинённых дата-структурах, например, но тут уж никакой чекер не поможет, увы.
Самое частое из того что возникает - переменная не найдена. Просто потому что забыл указать префиксом с точкой название объекта, например. Тут стоит отметить что под "частое" - это раз в хрен знает сколько времени. Я вообще не так часто ловлю баги рантаймом. Ну и с опытом вообще не так уж часто. Не скажу что прям чисто без багов пишу. Но это такой малый процент от всей работы, что я даже внимания на это не обращаю. То есть это не является для меня болью из-за которой я бы ходил и ныл что не могу ничего делать, ппц как неудобно. В этом плане у меня гораздо больше вопросов к другим языкам.
Может быть я просто сильно привык к ГМ.
Оговорюсь сразу, Кситилонская позиция мне гораздо ближе.
С одной стороны, лично я считаю что ГМС в целом и ГМЛ в частности имеют некоторое количество затыков. Багов, неочевидностей, недодумок - как хотите назовите. И, да, исправить многие из них сильно помогло бы, наверное, любому разработчику на ГМ.
С другой стороны, я не особо вижу (но это с учётом того, что лично я тупой), какие близкие мне проблемы может решить предлагаемое... решение. Либо это наследственные вшитые намертво гамакопроблемы, которые поправятся или апдейтами или никогда. Либо это, разумеется, мои собственные проблемы с кодом и реализацией, которые поправятся мной лично, лол. В обоих случаях предложенный солюшен лично мне полезным не выглядит.
Я могу даже подробнее написать, с чем мне не может помочь предлагаемый чекер! Хотя может и может, я не уверен, я не очень умный.
Ворнинг: ниже лично мой опыт который подвязан под тематику еле как, но вдруг будет полезен!
Например. Вы вот знали, что GMS1.4 (а может и другие!) исполняет код объектов в той последовательности, в которой объекты заданы в IDE? Лично я с самого начала думал, что последовательность исполнения кода зависит от порядка создаваемых в руме инстансов, НО НЕТ. Важно то, как объекты раскинуты в IDE. Серьезно, так и есть.
При отзеркаливании спрайта по иксу (я уверен что многие этим часто пользуются, потому что древняя практика и кому вообще нужно два набора спрайтов чтоб в обе стороны) смещаются его bbox_left и bbox_right. Ну, через image_xscale когда. У меня такое "смещение" приводило к застреванию персонажа в стенах (если его спрайт отзеркалить рядом со стеной, то он как раз застрянет в стене ибо в ее пределах оказался bbox_left или bbox_right)
Я решаю эту проблему идеально "ровной" маской коллизии - когда расстояние от ориджина до bbox_left равно расстоянию от ориджина до bbox_right. Тогда смещения не происходит.
Если персонаж имеет много стейтов (у вас крутой DMC-подобный экшен например) и соответственно - много спрайтов для этих стейтов - это тоже может привести к подобным проблемам с коллизией. Если маски этих спрайтов разного размера, лол. Поэтому маски коллизий я стараюсь делать одинаковыми для всех спрайтов.
А в последнем проекте, над которым работаю, пришлось вообще ввести отдельную сущность-хитбокс для получения дамага. Которая не совпадает с маской спрайта персонажа. Маска - для коллизий, хитбокс для дамага, шампунь для сухих и жирных волос
ГМС2, кстати, портирует объекты с ГМС1.4 довольно терпимо. Вьюпорты правда превращает в эти ваши "камеры", но при этом дает пачку сгенерированных методов через которые, покумекав, можно работать "как с вьюпортами". Правда, он попытался мне похерить скорость комнат и анимаций спрайтов, но я везде проставил 1 frame per game frame и продолжил регулировать индексы и скорости спрайтов из кода, как привык.
Очень сильно раздражает, что ошибка, которую тебе любезно предоставил билдер, никуда не записывается. На этапе компиляции ты можешь заглянуть в compile errors и посмотреть че как. Но если у тебя во время выполнения кода условный трындец, то ты можешь разве что скопипастить еггог инжалид дежище из появившегося попап-окна. Потому что стоит оное окно закрыть - и ты теряешь инфу насовсем, запускай еще раз, инциируй ошибку еще раз.
Ну и конечно ГМС2 потерял некоторую "гибкость" присущую ГМС1. Был случай когда я сделал массив из 7 элементов и выводил значения из него в цикле из 9 итераций. Осознанно: мне нужно было 7 полей заполненных значениями массива и 2 пустых. Плюс еще другая инфа, но это не суть важно. ГМС1, не обнаружив последних элементов, просто их не вывел. ГМС2 выдал мне маловразумительную ошибку на понимание которое мне потребовался час или два (напоминаю, я крайне не очень умный). Дописал последние два элемента как noone и проблема улетучилась.
Если вкратце, то я еще считаю что гамак предоставляет ненормально много фигни для упрощения жизни новичкам (типа драгндропов и прочей фигни). Больше, чем требуется. Не имею в виду сами драгндропы, конечно. Но при этом почти совершенно не расширяет "верхнюю границу" возможностей для тех, кто не хочет работать через те же драгндропы (слава богу что 2.3 наконец-то да).
Порог вхождения становится всё ниже, порог развития почти не меняется, вот.
"Порог развития" звучит очень иронично. Не совсем правда понятно, что ты имеешь в виду. Интуитивно догадываюсь, но сформулировать трудно.
А что за матан в ошибках при выходе за границы?
"Матан для роботов".
___________________________________________
############################################################################################
FATAL FATAL ERROR in Room Creation Code for room room0
Push :: Execution Error - Variable Index [0,1] out of range [1,1] - -1.arr(100029,1)
at gml_Room_room0_Create (line 2) - arr[1]+=1
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Room_room0_Create (line 2)
Читаю:
ФАТАЛЬНО-ФАТАЛЬНАЯ ОШИБКА ну тут понятно
Пихай :: Ошибка Выполнения - Индекс Переменной [0,1] вне пределов [1,1] - -1.arr(100029,1)
и тут дальше понятно.
Вызвано вот таким кодом в старте комнаты:
arr[0]=1
arr[1]+=1
Почему в квадратных скобах аж два индекса, это же не двухмерный массив? Что такое -1? Откуда 100029, если это даже не инстанс? И после этого ещё ",1" какое-то. Типа, Room Creation Code на самом деле помещается в контекст выполнения инстанса который под капотом движка создаётся позже всех, но выполняется раньше всех и тут же удаляется? Мне-то какое дело, что происходит в вашем машинном отделении? Я должен слышать нормальный отчёт:
"Ошибка: обращение на чтение к не инициализированному индексу 1 массива arr."
Это что, дофига сложные полёты в космос?
Причём Юджен жалуется на ошибку в ГМС2, которая в ГМС1 описывалась нормально. Но в ГМС1 тоже есть ошибки где отчёты примерно такого же качества, а именно хорошие отчёты были аж в ГМ8.1, очень давно.
I lol'd!
А что если... в машинном отделении GMS2 одномерные массивы – обёртка над двумерными, у которых первый индекс всегда 0, в целях лени разработчика упрощения реализации? А ошибки для всех одинаковые, поэтому
[0,1]
.Это до версии 2.3? (в которой массивы произвольной размерности уже, если правильно помню)
Да, это до 2.3. У нас продакшен на пре-2.3, и меня бесит что я не могу реализовывать новые вещи потому что тяну старые проекты. До конца года так и будет.
Ты хочешь новые вещи реализовывать уже на 2.3? Вроде бы ты говорил, что тебя тамошние нововведения не особо интересуют.
На 2.3 будут те новые вещи, которые действительно нуждаются в 2.3 - все трёхмерные игры, и некоторое количество игр в которых много структур данных, типа серии Castle of no Escape. А так-то прототипы до сих пор удобнее делать на 8.1, и даже релизить на консоли потом через 8.1->1->2->2.3.
Трёхмерные игры всё же нуждаются не в 2.3, а в другом движке <_<
Бедные игры, они нуждаются, а я их так огорчаю... Да ладно? XD
Другие движки мне не подходят - на них нельзя положиться в долгосрочной перспективе. Вот все орут - Юнити! Годот! Запишите меня в скучных консерваторов от геймдева, но я просто не верю в адекватность этих новомодных мегасистем, после того как мне Хейзер скинул проект, и я его не смог даже просто скомпилировать, ни на одной версии Юнити которые я ставил, включая ту самую 2013 года, на которой он этот проект делал. Тем временем ГМу уже почти 21 год и его проекты обратно-совместимы как минимум на 15 лет назад, проходя через эпохи Windows 98, XP, 7, 8 и 10.
И потом, неспроста же все эти смищные картиночки существуют:
Я ведь могу просто взять двухмерный движок и достроить его до того что мне нужно, а не начинать выскабливать всю неправильно реализованную ерунду из третьего измерения уже якобы готового движка, чтобы попасть на тот же этап, на котором нахожусь уже на старте с ГМС2.3 - этап достраивания до того что нужно.
Но зачем изобретать квадратные велосипеды, если для трёхмерной игры можно просто взять трёхмерный движок? И выскабливать ничего не потребуется.
Выскабливать - это я имел в виду именно Юнити. Большая часть того что там есть мне вообще не нужна (ragdoll, освещение, партиклы), а остальное мне не нравится как сделано (
float translation = Input.GetAxis("Vertical") * speed * Time.deltaTime;
).Алсо, ГМ - трёхмерный движок, его двухмерный режим это просто такой вид проекции, в которой depth не влияет на расстояние графических примитивов до камеры. Нет встроенных трёхмерных коллайдеров? См. аргумент про
if abs(z-other.z)<d
- их написать быстрее чем разобраться как использовать готовые. Мипмаппинг есть. Шейдеры есть.Проще перечислить, что там встроенное трёхмерное есть, чем то, чего нет.
А мог бы просто сказать «ортографическая проекция», и было бы короче, корректнее и понятнее.
Короче было бы. Понятнее - только тем кто знает что это такое.
Отличный аргумент, если бы игры делались перечислением что есть в используемом движке.
Срачами на форумах они делаются гораздо эффективнее, конечно же.
Ну что ты. Срачи на форумах - это заслуженный отдых от геймдева. XD
Столько игр наделал, что пора и отдохнуть? ;)
Просто отдыхаю прямо в процессе - делать ещё предстоит много.
Наконец Старый Старик Кситилон признал мои слова!
Я... Ты... не должен был тут быть, глупец... :kot:
2D > 3D!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Да, не нуждаются в 2.3. Нет, не в другом движке. На ГМС1.4 нормально 3д делалось и на 2+. Даже на ГМ8.1 видел трёхмерные игры.
3d-модельки с текстурами и анимацией туда уже можно загружать? Объекты в пространстве расставлять? Редактировать объёмную сцену в плоском редакторе комнат – как-то нифига не нормально!
Ну блин, Wolfenstein-style я и на 5.х видела (в котором поддержки 3d вообще ещё никакой не было), где-то даже в свалкархиве лежит.
Я видел некоторых безумцев, которые сделали редактор моделей\анимаций на ГМ.
А я тот безумец, который делает (опять (снова (переписываю))) редактор простых уровней в стиле Дума\Дюка. Можно вообще использовать внешний редактор - главное написать чтение этого формата и саму обработку в 3д. Поэтому я выбрал пока более простой "плоский" дум.
Модели, анимации и текстуры тоже нужно будет писать руками (загрузку). Хотя по поводу текстур вопрос странный - это же спрайты.
Всё, что вы хотели знать о «в 3D GM нормально делается»
Не, ну нормально же! Можно даже приспособить стандартный рум-эдитор (прописывать Z координату объектам, а то и автоматически это делать). Мне вообще особо не нравится редактор комнат в ГМС. В ГМС2 сделали чуть лучше.
Хорошо, сойдёмся, что у нас чересчур разные представления о нормальности...
>Так было в какой-то конкретном подмножестве версий ГМС1, но уже нет.
Уверен? А если проверю? Потому что я уже в 2.3 сталкивался с чем-то подобным и, как мне кажется, оно всё еще да. При этом оно еще и игнорирует сортировку ресурсов по алфавиту (будь она неладна)
>При ориджине ровно в центре спрайта ничего смещаться тоже не будет. Маску или ещё какие-то более сложные штуки при этом трогать не требуется.
Это если твой спрайт - квадарт икс на икс, то это вообще решит большинство проблем! Но будет ли это красиво и удобно?
>Не "пришлось", а ты решил (после того как послушал меня на тему что так можно не делать :yak:).
Я решил, потому что пришлось! Ну а если серьезно, мне было проще сделать так, чем заморачиваться с обработкой коллизий при изменяющейся маске персонажа.
>Silent fail может сыграть с тобой злую шутку однажды, я бы не называл это гибкостью.
Более чем согласен и наверное это даже хорошо. Но в ситуации когда гамак даёт ошибку в духе "не можу отрисовать спрайт которого нет", я иногда думаю "лучше б ты его просто не рисовал вовсе, чем вышибать ошибку"
А по поводу ошибки с массивом - прошу прошения, кажется я вам напиздел. Я неосознанно.
Там была несколько иная ситуация, как показывают архивы - я запилил зачем-то разные типы данных в в одном массиве. Типа:
key[8]=ord("U")
key[9]=" "
А потом выводил chr(key[variable]). Там где key[8] выводилось U (потому что chr(ord("U"))), а там где key[9] не выводилось ничего, потому что я так и планировал. В ГМС1.4.
Тот же код в ГМС2 начал спотыкаться и писать ошибку
chr argument 1 incorrect type (string) expecting a Number (YYGI32)
at gml_Object_o_hud_Create_0 (line 1) - df=chr(" ")
Что в общем-то правильно и хорошо, нефиг разные типы данных в массив запиливать. И если включить голову, то можно даже понять, что это за ошибка.
"Красиво" - это вкусовщина. А "удобно" - это сложно ли поддерживать при расширении системы в разные стороны. Я вот говорю - пропиши collision_line, и тебе будет наплевать какой там вообще назначен спрайт.
Разных спрайтов персонажа больше, чем разных масок. По-моему их там всего три - стояние, прыжок и висение. И то висение как-то смахивает на стояние по размеру, так что why even?
А вот это хрень, да.
ЧИВО? То есть теперь в ГМС2.3 есть проверка типизации, но только для массивов?! Это прикол года.
KOSTYLEE-KOSTYLIQUEE
Не, это при попытке конвертировать
chr
ом элемент массива, в котором лежала строка, а не число.Вообще-то костыли это как раз маски спрайтов, подаваемые как часть того самого набора фич "теперь вы можете делать игры без программирования". Всякие там "хотспоты" проверялись без масок на NES годами, и работало безотказно.
какая связь между троном и ганженом?
Второе - развитие первого.
то есть у них есть еще какая-то связь кроме того, что это единственные внятные шмапы на гм? ведь даже по времени наследование не получается. Меньше 4 месяцев на весь ганжн это нереально
Upd. о ганжн еще и юнити. тогда тем более
GM настолько крут, что может позволить иметь в своём шоукейсе даже игру на Юнити.
А так связь действительно только в том, что второй вдохновлялся первым: «Crooks stated that The Binding of Isaac was one of the game's biggest influences, they also were influenced by Nuclear Throne, Spelunky, Dark Souls and Metal Gear Solid».
Ой всё. Убрал Ганжен. Они слишком похожи, и это типичный пример того, как ГМ справился бы не хуже Юнити ровно с теми же задачами в том же жанре. И так-то наверняка бы и лучше, со всеми этими 4-мерными кватернионами там где нужны 2-мерные векторы.
...вот только в ГМ нет 2-мерных векторов :-P
Ну да, давай в табличку записывать заодно все игры, которые могли бы быть сделаны на ГМ.
Минус оверхед от упаковки в структуры, от этого только быстрее работает, а писать всё равно так же само два числа через запятую. Хотя направление можно указывать вообще одним числом - градусами.
Медленнее, потому что без упаковки аллоцировать нужно две переменные, а не одну (в которой два числа могут вообще рядышком лежать unboxed-ными). И передавать туда-сюда неудобно, и из функции разом не вернуть.
А как это ты так ловко без спецификации среды выполнения всё знаешь? Которых кстати две - VM и YYC.
Например, оттуда, что в YYC можно посмотреть промежуточный выхлоп в C++, и там видно, как значения устроены.
Алсо, YYC — это не среда выполнения, это компилятор. C++-бэкенд создаёт нативный код, рантайма там нет как такового (с некоторой натяжкой к нему можно причислить системные библиотеки); Android — код под JVM, Web — код на JS, где рантайм зависит от движка браузера.
Можно кстати много всякого найти в этих YYC\Си. например вот такое:
Можно делать "8"++ и получить 9!
Офигеть. При этом
"8"+1
нельзя, насколько помню.А разве не ++"8"? Тут же RVALUE.
Дело не в RValue (и R вообще может "Runtime" означать, например).
operator++()
– префиксный инкремент,operator++(int)
– постфиксный (int
-овый аргумент не используется, нужен исключительно чтоб различить сигнатуры). Обычно второй всё равно реализуют через первый (делают временную копию, инкрементируют себя, возвращают копию), как и в фрагменте выше, так что для целевой строки результат одинаковый будет.Пора применять мой любимый аргумент - "это* почти никто не использует". Пруфов не будет, я говорю за своё окружение из ~30 разработчиков, 10 из которых авторы и 5 из которых соавторы проектов мной издаваемых.
* YYC
VM - дефолтный, более медленный (потому что managed), но и более стабильный способ компиляции. Что по нему?
Вне зависимости от рантайма динамические переменные объектов неизбежно будут аллоцироваться в куче, и для примитивного типа «вектор длины N» (если бы он был) можно делать одну аллокацию вместо N.
Конечно, это всё экономия на спичках и неважно, но раз уж ты сам начал про мнимые оверхеды и «быстрее работает», надо разъяснить. Так-то в геометрических алгоритмах векторы – они больше даже для эргономики, а не скорости (конечно, если дело касается высокоуровневой логики, а не тяжёлых недр движка).
А мы не про количество аллокаций должны говорить, а про фактическое время их выполнения. Там точно нет каких-то конвейеров, которые быстрее выполняют аллокацию двух переменных меньшего размера, чем одной большего?
И потом:
В первую очередь меня беспокоит оверхед со стороны кодера, который вынужден будет писать position.x=100; position.y=200; вместо просто x=100; y=200; и так везде по объектам с координатами.
Увы, чудес не бывает. В развитии вычислительной техники постоянно шло стремление обрабатывать за раз большую пачку данных, чем много мелких, потому что так хронически быстрее. Увеличение разрядности процессоров, SIMD-расширения, векторизация, batch processing – всё про это.
Даже в самом простейшем варианте аллокатора, где выделение переменной – это сдвиг указателя в преаллоцированном куске памяти, две переменных – это два сдвига, а одна – один. А потом, если там GC, при поиске мусора для очистки или переноса в следующее поколение, он опять-таки должен проверить две переменные, а не одну.
Меня тоже беспокоит, потому что он мог написать
position = [100, 200]
. Иpoint_distance(position, other.position)
. И в других функциях, принимающих координаты, количество аргументов сократилось бы ~вдвое.Но блин, я же не хотела посвящать эту статью разбором всех языковых недостатков, а сосредоточиться на обработке ошибок. Но ладно, технический оффтоп так оффтоп. Может, мимокрокодилы что-то для себя подчерпнут :3
Хорошая фраза.
1) position длиннее чем x и y;
2) Приходится писать скобки, вот бы без них как-то;
3) В такой нотации мы, выходит, негласно договорились, что слева x, а справа y.
В коде
x=100; y=200;
всё ясно, а тут у тебя есть "левая координата" и "правая координата". Или "первая координата" и "вторая координата". Что если это позиция не в прямоугольной системе координат, а задаём мы радиус и угол? Не писать же position_rectangle?Неплохо бы писать
x, y = 100, 200
, но такого синтаксического сахара ещё не завезли, да и это визуально дольше соотносить между собой, чем квадратно-гнездовое:1) Ужас-то какой, буков много. Ну назови
pos
,hspeed
вместоhorizontal_speed
илиspeed_x
тебя не смущает, наверное. И главное, одна переменная, а не две.2) Ужас-то какой, скобки. Зато одно
= ;
, а не два.3) В функциях, принимающих координаты, мы же как-то договариваемся, что сперва x, а потом y. А при работе с прямоугольниками – что сперва
x1
иy1
, а неx1
иx2
(а ведь где-то наоборот). А могли бы просто одну переменную передать, а не две.3.1) Лучше, конечно,
pos = {x: 100, y: 100}
. Да, при инициации чуть длиннее, зато потом при использованиях короче.4) Если нужен массив точек, имеешь один массив точек, а не два массива с иксами и игреками.
5) Помимо хранения передачи туда-сюда, векторы непревзойденно заруливают в преобразованиях, когда можно разом сказать
pos.translate(offset).rotate(angle).scale(zoom_factor)
, что в случае отдельных переменных потребовало бы портянки на десяток строк.Вообще, упихивать несколько логически связанных значений в одно (массивы, структуры), чтобы не возиться с пачкой раздельных переменных, придумали ещё в 1960-х. Зачем противиться этому в 2020 – непонятно.
Короче. Чтоб всем угодить.
XDDDDDDDDDD
Это ж в какой игре нам нужно одновременно перемещать, поворачивать и масштабировать вектор? Не могу пример использования придумать. За последние 14 лет я перемещал почти исключительно точки (поворачивал и масштабировал куда более редко).
Опять начинается «я за 14 лет не смог придумать, значит нинужно».
Опять начинается «я знаю что это где-то нужно, значит оно и тут нужно».
Не везде в геймдеве нужна геометрия. Там, где она нужна, не обязательно нужно именно это. Поэтому мне интересно - а где же нужно именно такое?
Какой-то очень крутой движок, если в игре есть системные библиотеки и геймплейный код, но нет собственно кода движка. :)
Да, я на самом деле вру. В YYC-C++ есть такие штуки, как спецификация представления значений в памяти, их аллокатор и какой-нибудь GC, диспетчеризация скриптов, менеджер ресурсов. С точки зрения исходного GML-кода – это вполне себе рантайм.
мне кажеца лучше вернуть. на этом примере с первого взгляда заметно тотальное доминирование Юньки над ГМ
Undertale непревзойдён!
Хотя по продажам даже ему далеко до Terraria и Stardew Valley, которые оба на Microsoft XNA. Вот кто настоящий доминатор.
Ого, а я думал, что Terraria на кастомном движке.
Ну технически XNA не очень движок, а достаточно низкоуровневый набор библиотек. Наверное, каждый над ними удобную кастомную прослойку уже наворачивает.
и Axiom Verge, Bastion, Salt and Sanctuary, Skulls of the Shogun
Доминатор по клонированию Майнкрафта в 2D. Который написан на Джаве. Занавес.
Ну так 2D всегда лучше!
M-masaka...
Юнька доминирует в трёх измерениях, виаре, и визуализации медицинских данных, но не в лёгкости создания игр. Ну и ещё в запудривании школьникам мозгов ненужными абстракциями. Это доминирование? Это позор, оправдываемый общеизвестностью движка и "ну это полезный опыт на будущее которое заключается в получении полезного опыта на будущее".
Несите таблетки, старый старик снова за кватернионы зацепился! :yak:
Мало чего знаю о Юнити, но на мой взгляд, это правда странно, что для 2D не добавили каких-нибудь компактных двухкомпонентных врапперов над этими кватернионами для удобства.
Quaternion.Euler(float x, float y, float z);
Quaternion.AngleAxis(Vector3 axis, float angle);
непосредственно кватернионы там никто не трогает
Ну и вот зачем в плоской игре
float z
иVector3
?для слоев и фонов. Я не знаю как реализовано в других движках, но мне сложно представить игру идеально в 2D. всегда же есть бекграунды, ui, порядок отображения спрайтов.
Прост пугать кватернионами аще не честно, там только одну переменную дописывать
Хм, а ведь правда. Я как-то подзабыла, что
depth
в GM — это по сутиz
.Тем не менее, обычно координатные преобразования происходят в одной плоскости,
z
меняется редко.Шёл 20XX, в нормальных языках и "отсталом" GML давно придумали опциональные аргументы и "хвосты".
Так что пугать кватернионами ещё как честно.
Но для честности стоит сказать что в GML тоже есть свои приколы типа десятка вариаций функции (привет draw_sprite). Т.е. встроенные функции не умеют такой функционал. А кастомные скрипты - умеют.
Вдвойне странно, что на самом деле есть полторы стандартных функции с опциональными аргументами (
place_empty
, например). Что мешало использовать их поактивнее — загадка.У них нет скоростей в третьем измерении, это просто переменная глубины. Зачем им трёхмерные векторы?
чтобы иметь возможность в любой момент легко перемещать их в третьем измерении, ну.
![](https://i.ytimg.com/vi/yw8YkmOnUVQ/maxresdefault.jpg)
![](https://sun1-16.userapi.com/dVgOcDQipAzyraFzuDd9S6n_ZF3dO10tYnlryQ/ji-8EJkggek.jpg)
Чтобы в клоне Double Dragon не имитировать перемещение персонажа в глубину, возя его при этом по стене, а элементарным способом приближать и отдалять персонажа, автоматически и естественным образом обнаруживая доступные ему для взаимодействия коллайдеры. Чтобы в убийце фолаута брать модельку и вращать ее как угодно, не запариваясь с горой спрайтов с разных сторон. Чтобы освещение работало прямо из коробки, чтобы все эффекты резкости, тумана, размытия настраивались естественным элементарным способом. И еще гора частных ситуаций с падением кометы из глубины сцены, неактивным коллайдером притаившегося сбоку врага из робокопа, отдалившегося в глубину персонажа марк оф ниндзя или финтующего в принце.
Про вот этих покалеченых мутантов даже вспоминать не хочется
Мне просто в голову не приходит для чего кроме злога умысла возможно вообще лишать разраба простейшей геометрии с тем, чтобы потом накостылить ее же в слоях, взаимодействие между которыми крайне затруднено
Бритва Хэнлона же!
тут Бритва Хитченса поставит меня в неудобное положение
По бритве Хитченса скорее половина кситовых утверждений зудит.
Да, 2.5D - это боль...
Вопрос был, напомню:
Безусловно, хорошие случаи и примеры, но ничего из этого не плоское.
Плоские игры это, например, Марио оригинальный, МегаМены оригинальные, Иксы, Зеро и БаттлНетворки, куча всех этих новомодных соулс-лайк метроидваний типа Hollow Knight, Blasphemous, Bloodstained, и в таком духе. И абсолютно вся Контра кроме той одной механики тира на базе, которую ты привёл на картинке.
Когда я буду делать свой битэмап, коллизии будут решены тривиальным
if abs(z-other.z)<d
, тогда как большинство проблем Юнити в ГМе никогда не существовали и так. Вот и весь разговор.Если это, скажем, 2.5D-beat'em'up, скорость «глубины» вполне может быть.
EDIT: спасибо forever8pus, выше уже расписал всё основательно.
Ну всё-таки в мире гораздо больше ГМщиков, помимо тебе знакомых. Авось, и ЦА среди них обнаружится.
BTW, в Телеграме несколько чатов, посвящённых GMS, и почти все почему-то на арабском o_O
Наверное, Рами наинфлюенсил. Хорошо, что не на кситилонском :yak:
Убери эту хрень под спойлер, плиз, пол-экрана загораживает.
ВиллиВонка-Жульёнка.jpg
Вот да, тот же Дрейк положительно отзывался о гите.
Чувак. Ты осваивал OpenGL на C++ и реально сделал на нём какой-то кривой, но прототип какого-то космического медведя. Окей, для тебя лично надо прописать
if id!=DD
!Ну вообще я скорее про то, что гит используем как минимум мы с Дрейком (как отдельно друг от друга, так и для совместного проекта), за других говорить не буду.
Вы его используете для бэкапов и, раз в сто лет, мерджа. Сравните весь функционал системы типа pull request'ов с тем что по факту из него пригождается в разработке на ГМе. Да, вы используете систему больше чем на 0%, если тебя интересует именно такая формулировка.
Зато есть обратная корреляция - кто использует системы версионирования много, тот делает игр мало и плохо. Либо в больших игровых компаниях, то есть вообще не делает игры (целиком), а только их компоненты.
Скажем, кто на Гамине самый популярный игродел на ГМе? Йео. Что он использует? Ничего. Подключил Яндекс.Диск когда мы заспорили о системах версионирования, и то уже это было после релиза Ринго (а может и Будды).
Всё ещё не вижу, в чём проблема использовать систему хоть на 1%, если это несложно и удобно.
Проблемы нет, просто зачем засчитывать эти 1% в класс профессионального постоянного использования.
Эээ, что?
Кажется, ты неправильно понимаешь мои мотивы. Я не за шашечки, а за ехать. Я не за «профессиональное» использование, а за удобство и эргономику, чтобы облегчать себе жизнь. Комфортные IDE, статические верификаторы, системы контроля версий и прочее – из числа таких штук. Многим они действительно облегчают жизнь. Некоторым – нет, консерваторы, луддиты и любители бритья топором никогда не переведутся; проще оставить в покое, пусть работают как привыкли. Но большинство просто не в курсе, и добрым делом будет им показать. Пусть сами попробуют – зачем отговаривать, проецируя на массы исключительно свой опыт?
Что мы обсуждаем? Я просто забыл что ДаркДес и Дрейк используют git, потому что это абсолютно никак не сказывается на качестве или времени создания игр оными авторами. Спустя всего 7 комментариев, это моё вполне обоснованное упущение превращается в "проецирование на массы исключительно своего опыта"? Я потому и сказал об опыте других знакомых ГМщиков, чтоб не говорить только про себя.
А отговаривать - я не отговариваю. Просто и добрым делом это однозначно считать тоже нельзя - люди любят подменять свои желаемые достижения (разработать игру) чем-то просто повышающим quality of life (остальное перечисленное тобой). Проблема людей, скажешь? Понимаешь ли, энтузиазм заканчивается, и ответственность знающих - правильно давать или НЕ давать знания, чтобы случайно не дать то, что нужно на куда более позднем этапе, а то и совсем не нужно.
Если человек хочет делать игры, то он должен геймдизайнить, а не расставлять вокруг себя подушечки и думать что всё само как-то сделается. На код наплевать даже если он пропадёт - раз на предыдущем этапе уже создан хороший геймдизайн, код всегда можно написать заново. А вот хороший геймдизайн из кода не экстрагировать - это нужно только играть в игру и её воспринимать, плюс вести статистику ощущений других игроков.
Инди-разработчик игр это, в порядке приоритетности:
Может я туплю, давайте проверим... Гамин - сайт по инди-играм. ГМ - движок используемый инди-разработчиками. Говорим о том, где кто юзает git в ГМе - почти никто, почти нигде. Не, вроде с моей головой всё в порядке.
Если ты хочешь знакомить с git'ом некую общую массу кодеров - дак с этим никто и не спорит, он в айти везде востребован и всегда однозначный плюс.
ГМ используется не только на Гамине. git используется не только с ГМ.
А может, ты всё-таки не будешь за других говорить?
Ну да. Просто я тогда не понял как мы перешли в общее айти, если речь шла о целевом комментировании твоего проекта который ГМ-only.
А я не от их имени говорю. Это моё наблюдение, совершенно стороннее, и потому более объективное - я могу увидеть только результаты действий, а не комплекс их формирования. И даже если никто моего мнения не спрашивал, оно релевантно к обсуждаемому вопросу, так что я не понимаю почему надо его выкидывать.
Я тоже использовал - что Яд, что Гугловский Диск. Когда он стал создавать странные копии файлов объектов\скриптов\итд, то отказался от этого. Или подожди, ты про запаковку всего проекта в zip и отправку его в облака?
Кстати, не помню как в ГМС1, но в ГМС2 появилась возможность прям внутри IDE настроить git. И это очень удобно - удобнее даже самописных bat-ников на 3 строчки.
Для GMS1 был Feather в составе (теперь уже мертвого) Parakeet, что выполнял различный статичный анализ.
Я заказчикам пару раз писал кросс-компиляторы из GML в типизированные языки программирования (Haxe, C#) для миграции проектов, что включало автоматическую типизацию в пределах разумного. Писал под это дело файлики с описанием типов встроенных функций/переменных вроде данного — возможно, сэкономит чуть времени https://pastebin.com/2DCbBwaG
В целом, синтаксический анализ — дело веселое, но затратное. Особые странности выходят в определением типов полей объектов, так как они могут неочевидно объявляться из скрипта, что вызывается различными объектами без общего родителя.
К проблеме "слишком мало типизации / слишком много типизации" подходил несколько иначе — изолируемые под-системы пишу на типизированном Haxe и компилируются в GML (GitHub), а нехитрая игровая логика как была, так и остается на динамическом GML.
Ого, самый полезный коммент, спасибо за релевантный рассказ от опытного разраба! И за ссылки, постараюсь подчерпнуть чего-нибудь.
Семантический, всё-таки. С синтаксисом как раз никаких проблем ;)
Да, это меня тоже беспокоит. Но как минимум часть случаев надеюсь отловить, обходя код объектов в правильном порядке (скажем, если какой-то скрипт вызывается в
create
и устанавливает некоторые переменные, информация о них в обработке других событий уже будет доступна).Браво! Стоит потратить кучу времени и сил на изучение, чтобы потом из-за лицензии заиметь трудности.
А в чём проблема? Большую часть работы можно проделать, пользуясь исключительно референсной справкой. И небольших проектов для экспериментов прошу прислать, поначалу этого вполне достаточно. А там видно будет.
Прикольно, прикольно.
Только вот реально юзабельность такого инструмента под вопросом конкретно в гамаке.
Как говорил Кситилон - отлов багов в GMS-e не является какой-то прям супер-задачей, а скорее рутинный процесс. В ентерпрайз-ппректах где нужно серьёхное тестирование - ОК. Но ГМ больше для небольших проектов, где все аспекты разработки подвластны даже одному человеку.
Далее - на моей памяти(около 20 лет практики гм-а) багов в ГМ которые заставляли меня потеть несколько дней можно пересчитать по пальцам одной руки. И конкретно в этих ошибках никакой чекер меня не спас бы, увы. В остальном - сэкономил бы он мне время и силы? Может быть немного и сэкономил бы, но очень маленький процент от всего того времени что я вообще потратил на проект.
То что там переменные не инициализированы, типы не так сложили - это всё чисто культура кода и умение его правильно организовывать, пару раз на грабли наступил и стараешься больше так не делать. Если всё равно проскакивает - значит либо нужна практика, либо пересмотреть свой образ жизни. И тут как раз кроется интересная штука. Все эти код-чекеры понижают качество мирового кода фонда.
К чему это я. Вот кодер прогнал проект через эту тулзу и она тебе показала что вот тут-тут и тут у тебя ошибочки. Ты их пофиксил, но реального опыта для себя ты не вынес и будешь продолжать писать как и писал никак не улучшая свою организацию кода. Да, это удобно, но это не учит новичков понимать где их ошибки и почему они их допустили и развращает опытных кодеров, позволяя им допускать типовые ошибки.
ИМХО нужно уяснить такую вещь - раздолбаям не место в программировании. Это довольно ответственная область требующая интеллектуальной работы, внимательности и усидчивости. Попытки понизить порог вхождения в область - это много дураков на дорогах. Водить машину научился - а правила кто будет учить и ГЛАВНОЕ - соблюдать?
Новичков можно предохранять от деления на ноль, возгорания видекарты и вообще падения со стула. Но зачем это делать вместо того чтобы воспитывать культуру написания кода?
Вместо того чтобы общаться и делиться реальными знаниями и реальными практиками сейчас программисты делятся тем как как успешно заработал на своём продукте и как успешно автоматизировал то-то и то-то =) Именно по этой причине я не интересуюсь конференциями и интервью в ИТ сфере.
tl;dr: про юзабельность спросим в больших коммьюнити. Нет — так нет, для меня это в любом случае будет полезная практика и интересный пет-проект, который не стыдно и в резюме показать.
Мне казалось, Game Maker всегда стремился быть инструментом с низким порогом вхождения. А ты будто хочешь его повысить, требуя от разработчика сперва окультуриться и дисциплинироваться. Новичок неизбежно будет делать ошибки. Почему ты думаешь, что он поймёт что к чему, только если найдёт её лично; а если на неё покажет кто-то другой, он исправит и тут же забудет? И будет делать её снова и снова, ему на неё будут снова и снова указывать, а он всё ещё ничего не запомнит? К тому же, без внешней помощи он может вообще источник ошибки не найти, а взамен налепить костыль, и в итоге научится плохому. Самообучение штука не универсальная, многим — если не большинству — гораздо полезнее и эффективнее учиться с учителем, который расскажет, что такое хорошо, а что такое плохо. И если знающего человека рядом нет, таким учителем может стать программа-чекер.
Культуру кода можно воспитывать сколько угодно, но errare humanum est. И зачем приписывать переменным префиксы и заниматься всякими нудными ручными проверками, если их можно поручить инструменту, а высвободившиеся когнитивные ресурсы посвятить чему-то более полезному. Например, архитектуре или геймдизайну :3
Эээ, наоборот. Они находят ошибки, а значит, качество кода улучшается. На практике, чем строже язык (по сути, чем более мощный чекер в него встроен изначально) — Haskell, Rust, OCaml, F# как крайние примеры — тем более качественная и культурная на них кодобаза. И наоборот, чем язык свободнее и вольготнее — PHP, JavaScript, Python — тем больше из них выходит говнищ, разброда и шатания. ИЧСХ, выходцы из первого лагеря, если их по долгу службы заносит во второй, по привычке ходят строем и пишут код по линеечке. А попаданцы из второго в первый — жалуются, что всё сложно и не дают по-быстрому наговнякать.
У тебя какие-то очень странные и однобокие представления о программистах, не знаю, где ты на такое насмотрелся. На том же Хабре технических статей на порядки больше, чем «пиарных».
Если твоя программа чекер откусит новичку голову или хотя бы скажет "ай-яй-яй. В следующий раз следи за областью видимости" - то ОК, полезная штука. Но вряд ли твоя программа будет так делать. Скорее всего это будет классическое: Line 12, col 23, uninitialized variable "a". Я достаточно много кодил на всяких паскалях и сях чтобы хотеть развидеть эти ошибки на этапе компиляции. Скриптовые языки воспитали во мне внимательность и дали возможность организовывать свой код (причём в разных языках программирования). Я получил ружьё, пострелял себе в ногу, научился этим пользоваться и пошёл на охоту, в то время как остальной народ остался играть в песочнице с водяными пистолетами =)
Я получил универсальное знание о том как ошибок избегать вместо того чтобы тратить время на то чтобы пройтись по списку и пофиксить ряд ошибок не понимая причины их возникновения. У каждого свой путь ессно, но ИМХО все эти чекеры - путь довольно медленный, не добавляющий программисту квалификации.
Пока что не создан вменяемый движок создания игр без кода. DnD в GMS и Cinstruct - говнище в этом плане.
Если переменные будут с префиксами то ручные проверки не нужны. Правильно названная переменная - это можно сказать залог успеха и сокращение довольно большого количества человекочасов на отладку =) Как раз чтобы не ловить половину тех ошибок которые часто ловят новички. Это не призыв впадать в крайностиЮ составляя названия пременных и методов в 20+ символов. Но дать переменной имя чтобы в любом контексте знать что она строка или что она - список, а так же понимать её область видимости - это вроде бы ничем не плохо и так же позитивно влияет на архитектуру и геймдизайн =)
С точки зрения тестирования продукта и его качества - да(но не всегда). С точки зрения организации самого кода - нет. Хорошая организация кода позволяет писать этот код без ошибок. Так что само существование этих чекеров уже говорит о том что так себе дела с качеством написания кода. =)
В то время когда более новые программы должны быть быстрее, оптимизированнее и потреблять меньше ресурсов в современном мире новые программы тормознее, тяжелее, менее оптимизированные и жрут как не в себя. Та же хвалёная Java с горе-программистами из-за чего теперь наши браузеры хавают опертивку как лангольеры а приложения на телефоне с каждым годом занимают в два раза больше места. Охуенное качество кода когда то же приложение без фактических изменений жрёт в два раза больше места и ресурсов - ничего не скажешь, лол =) А потом программисты оправдываются что у них там архитектура поменялась чтобы реализовать в будущем потанцевал, но как показывает практика - потанцевал не приходит увы, а архитектура остаётся.
Вся печаль в том, что сильным мира сего нужна рабочая сила, которая проходит курсы "как долбить по клавишами чтобы что-то.." и потом ебашила на их продукт, причём на качество продукта насрать - главное чтоб денег приносил. Причём это видно невооружённым глазом. Качество всех программных продуктов за последние 20 лет тупо деградировало. Реально хорошие продукты можно пересчитать по пальцам куриной лапки. Так что на данный момент "многоуважемые" пользователи купаются в очень удобной ванне с говном - юзабилити, ёпта! К сожалению, реалии устроены именно так =(
А толку от этих статей? На том же StackOverflow больше полезной инфы, хотя он помогает в 3 случаях из 10. Информации кругом много, а толку от неё не очень много.
А какие "все эти"? Я лично не видел прог такого класса вообще никогда в жизни, т. к. работал сисадмином. Если бы этот чекер срабатывал прям в реалтайме, как автозаполнение, могло бы быть и полезно. Набираю я такой name+=1, а мне - "name" was initialized as a string at Create Event, Line 12. Хороший вопрос конечно, с какого перепугу я должен писать name+=1...
Не, ну тут ты неправ. Префиксы это прям совсем костыльный способ, а чтоб понимать какие переменные какого типа, я использую постфиксы, причём не типовые, а относящиеся к игре.
Что вообще в игре может быть string'ом?
Любая переменна, которая заканчивается на _name, _text, _guid и тому подобное. То есть, называя переменные понятным образом, ты одновременно и неявно обозначаешь их тип.
А что может быть real'ом?
Например, если мы заводим вещественную переменную, о которой мы уже изначально знаем, что будем на неё домножать, то имеет смысл дописать ей суффикс _multiplier. Если же это обозначение частоты чего-то в секунду, переменной нужен суффикс _rate, по которому сразу понятно (англо-читающему человеку) что строкой это быть не может. Хотя для большей точности надо писать не _rate, а конкретно единицу измерения - _per_step, _per_second, _per_okkusenman.
И так далее. Это должно браться из эдакого имплементационного подтипа/раздела дизайн-документа, который никто в мире до сих пор не стандартизировал.
У вещественных величин часто есть размерность, либо вычислительный функциональный смысл. Строки же, как правило, просто инициализируются и отрисовываются. Максимум - реинициализируются для того чтобы включить другую локаль (поменять язык в игре, проще говоря).
Так что есть много критериев разделения типов переменных ещё на этапе планирования, а не так что бросаешься головой вперёд вникуда. Ну то есть, как вообще человек пишет код игры? Пришёл такой, раз-раз i++ и само всё завелось? Нет же.
Сначала надо написать, допустим, так:
В игре должны быть юниты. У каждого юнита должны быть такие переменные:
И такое поведение:
Если юнит атакован, то он теряет hp по формуле:
Вне зависимости от атаки, юнит автоматически лечится по формуле с учётом яда:
Если юниту есть куда идти (цель назначается вышестоящим контроллером), то:
и так далее.
Подводя итог: ошибки типизации должны не допускаться на уровне проектирования, а не на уровне кодинга. Если они существуют на уровне проектирования, то автор такового диздока должен сначала вправить себе свои логические суставы на место.
Причём я не придумывал эту систему откуда-то из головы - это взято из договорённости используемой в самом ГМе в его встроенных переменных и функциях, смотрите:
В хороших современных IDE эти чекеры интегрированы в среду, и ошибки действительно показываются прямо по мере набора кода.
И правда отличная, кроме шуток. Класс.
Но ведь так чекеры обычно и работают.
Line 12, col 23, uninitialized variable "a"
- это про компиляторы, там сложно на все вариации ошибок написать человеческое сообщение (но есть весьма приятные вроде clang для c++ - на его основе даже делают чекеры в IDE).Есть промежуточные варианты. Например, визуальное программирование в анриле. Там даже художник/музыкант разберётся. Целые классы команд в зависимости от контекста могут просто отсутствовать в списке - тогда ошибка исправляется, ещё не успев допуститься - в этом сила GUI по сравнению с текстами.
Хотя для большого объёма кода, разумеется, картиночный код - та ещё радость. :D И да, там статическая типизация (если кто-то по ней сильно фанатеет).
В случае с лапшой из анрила, организация часто возникает сама по себе. Но дело не столько в языке, сколько в отполированности редактора кода.
А какие браузеры сейчас на Java? (или ты перепутал с Javascript?)
У
rustc
очень приятные сообщения об ошибках. Даже в консольке «подчёркивает» проблемное место, по-человечески объясняет, что с ним не так, и даже иногда предлагает, что где дописать, чтобы исправить.Он перепутал. И как раз то, что сайты, большинство которых написано на слаботипизированных динамических JS (на фронте) и PHP (на бэке), жрут как не в себя, тормозят и валятся, только лишний раз подтверждает, что без статических проверок и статических оптимизаций грустно.
Но ведь Java тоже жрёт и валится от нехватки памяти в VM! Статическая типизация сама по себе не решает и половины проблем с программами. Это скорее QoL для самих программистов. :)
А что ты такого используешь на Java, что оно жрёт и валится не хуже сайтов на каком-нибудь Node.js?
Ну половина или не половина, но какую-то долю решает. А проблем не привносит (в грамотно спроектированных языках). А кроме того, при прочих равных статический (тут я подразумеваю как языковую типизацию, так и дополнительную верификацию) код по целой куче причин будет быстрее и менее прожорливым, чем динамический. Я могла бы их тут расписать, но это выйдет очередная техническая телега, интересная только полутора тут присутствующим, наверное.
я, конечно, там ничо не пойму, мало что запомню и вряд ли применю где-нибудь кроме срачей, но оказалось, что рассуждения об аллокациях, ML-семействах и SIMD-расширениях, расположенные после суффикса -ла у глаголов прошедшего времени - это мой фетиш. Так что я категорически за
> А что ты такого используешь на Java, что оно жрёт и валится не хуже сайтов на каком-нибудь Node.js?
любая ide (netbeans\idea\eclispe)? atom\vscode не просто так появился и завоевал популярность, а то ощущение что космический корабль запускаешь, полминуты стартует, требует от 8гб и тормозит при наборе текста. А eclipse еще и Null pointer exception выдает при любой ошибке.
В IDEA очень много фич по сравнению с голыми Atom/VSCode. Если последние обвешать плагинами, дающими сравнимую функциональность – будет тупить и жрать не меньше.
Вообще, Atom даже ванильный мне показался очень дубовым и неотзывчивым, VSCode куда шустрее по ощущениям.
Ну да, но если наоборот урезать java ide до уровня vscode (в котором и автоподсказки и переходы по клику есть), то они по-прежнему будут кушать гигабайты для своего суперпуперGC и в остальном останутся монстрами. Так что java на десктопе скорее из области антипримеров к статическим языкам.
Я почти ничего не использую на Java, потому что как что-нибудь не запустишь, так сразу тормозит. Сейчас, в основном, LibreOffice, вроде особо не вылетает (у меня относительно много оперативки нынче), но тормозит знатно.
Я знаю, зачем нужна статическая типизация, и как можно этим ускорить программу (и как можно без этого). А ещё знаю, как можно через бюрократию ООП замедлить программу (в т.ч. на языках с zero-cost abstractions), не говоря про скорость её (изначальной) разработки.
Ассемблеру отсутствие богатого набора типов данных не мешает быть самым быстрым (если, конечно, не сравнивать со всякими ПЛИСами). Тут скорее "известные быстрые языки обычно статические", а не "статичность необходима для скорости". Для скорости надо в первую очередь дружить с железом, а не с математическими моделями.
LibreOffice на C++ в основном.
В теории – да, а на практике для любого мало-мальски нетривиального алгоритма ни один разработчик не сможет в разумное время выдать ассемблерный код, который был бы быстрее, чем собранный качественным оптимизирующим компилятором более высокоуровневого языка.
Скажем так – скорость сильно коррелирует со статикой, а тормознутость – с динамикой. Конечно, можно найти отдельные динамические языки, более производительные, чем отдельные статические, но это частные случаи, а тенденция см. выше. Я чуть позже соберусь и подробно распишу в ответе forever8pus. В т. ч. и про то, почему статика лучше дружит с железом, а не только математикой.
Ну это-то понятно, иначе бы операционки писали на лиспах и не заморачивались.
Но вот naughty dog скриптует игры на лиспах, и для них это работает. И ещё lua популярен для скриптования. Потому что достаточно быстро, просто для непрограммистов, и можно перезапускать скрипт, не перезапуская всей родительской программы.
Я имел в виду, что программисту надо дружить с железом. :)
Но он может заменить медленные части на ассемблер, так же как и заменить часть динамики на статику, если это решает проблему. Если нет - оставить, как есть.
Всё так, подходящая ниша динамических языков – небольшие скрипты, с которыми надо часто экспериментировать или подправлять. Или вообще одноразовые – запустить, обработать пачку данных, выкинуть. Там все их достоинства (гибкость, лаконичность, выразительность) расцветают в полной мере, а недостатки (больший простор для багов, проблемы с производительностью, масштабированием и рефакторингом) проявиться просто не успевают.
Но в какой-то момент история свернула не туда, и поскольку писать маленькие программки на этих симпатичных языках – особенно по сравнению с громоздкими индустриальными – всем понравилось, и по инерции на них стали писать вообще всё; благо, мощности компьютеров заодно подтянулись. Ну и теперь имеем то что имеем. Вот ситуацию и пытаются как-то выправить, в том числе, навороченными оптимизаторами и типизацией постфактум.
И да, поэтому выбор GML, где кода в проектах вроде как немного, в качестве цели для статического анализа – затея вправду странноватая. Но... почему нет? Другим языкам и так выделяют гораздо больше внимания и ресурсов, пусть и этому перепадёт. Тем более, повторюсь, для меня это прикольный опыт.
В частности, этим по возможности пытаются заниматься современные JS-движки. asm.js вообще весь про это, наверное.
Visual Studio, я так понимаю, написали на C++ (хз, были ли в какой-то версии добавлены части на C#, но он всё равно статический). Да что-то статика не спасла от тормознутости (которой не было, кстати, в старых версиях), может, проблема кроется где-то ещё, а не в том, что надо подвалить ещё более тяжёлой статики? :) Причём тормозит не от мегабайтов исходного кода, а просто всегда. А компиляторы для сборки этой IDE пишутся в той же конторе!
Наоборот, если хорошо разбираешься в проблемах именно GML, то это и логично.
Кстати, интересно, есть ли какие-нибудь технологии, которые не только меняют код при выполнении (jit), но и переносят/преобразуют вместе с этим сами данные в зависимости от доступа к ним (soa <-> aos)? Если всякие Rust научились ловить указатели, то, может, научить и перезаписывать их при перемещении данных? Хотя тут больше по идее подходят функциональные языки.
Автоматический soa <-> aos предполагается в Jai от небезызвестного Джонатана Блоу, но тот его ещё неизвестно когда в народ выпустит.
Прости, не совсем понимаю. Ты имеешь в виду, чтобы старые указатели на объект не инвалидировались? В C++ в некоторых библиотеках применяют идиому stable iterator, которая достигает этого ценой некоторого оверхеда. Перемещающие сборщики мусора (которые при чистке выполняют дефрагментацию памяти или переносят в следующее поколение) также поддерживают валидность ссылок. Но как сделать подобное более-менее zero-cost – непонятно.
Нет, не при удалении объектов и не для ручного рефакторинга.
А отследить, где можно оптимизировать доступ к данных, автоматически данные перетасовать и обновить все указатели.
zero-cost и статические типы - это принятие фич как данное и попытка их натянуть на все задачи. В предложенной мной задаче нужно как раз в рантайме и с разрезанием статических типов, которые накуралесил программист.
Суть статика как раз в том, чтобы избавиться от поиска таких ошибок. Разработчики не тратят время (хоть его и затрачивается чуть-чуть за раз) и силы на смену контекста, а могут заниматься более важными ошибками, от которых уже защититься сложней.
В целом согласен, но у простых инструментов как раз ниже порог вхождения, чем у компиляторов, выдающих по 100 ошибок на helloworld. Я даже если пишу на C++, не правлю код сразу по предупреждениям (для параноиков там есть флаг, чтобы они стали ошибками), а сначала пишу, чтобы работало, а правлю потом.
При этом предупреждения действительно полезные, из разряда неочевидных вещей, что накуралесил, а через 10 лет это только обнаружится кем-то (и не факт, что исправится). Как ты собираешь научиться на ошибке, не зная, что она была тобой допущена? :)
Товарищи гаминцы, я тут недавно, объясните одну вещь. Почему в любой теме, где речь заходит о движках и коде, обязательно образуется Кситилон и начинается поток комментов про следующее:
– я сделал GMXD, но потом подлецы выпилили execute_string;
– 14 лет жопыта;
– мне, моим знакомым и моей собачке не пригодилось – значит, никому нинужно;
– гит особенно нинужно;
– если кому-то нужно, то они тратят силы на шашечки, а могли бы игры делать;
– неча лезть в геймдев со своим программированием, он – не оно;
– инди-геймдев – особенно не оно;
– GM рулез, Unity/Godot/всёостальное сакс;
– Unity особенно сакс, потому что кватернионы;
– GM рулез, потому что на нём могут работать даже композиторы, не умеющие кодить;
– делаешь ошибки – GM не при чём, это ты дисциплинируйся и научись кодить;
– ...
Это местная традиция такая? Как вы с этим живёте?
Кажется, уже можно на его комментах обучить нейросетку и она будет его успешно заменять, пока он спит.
О, единственный человек на всём сайте, который меня заигнорил, потому что самый сноб. Чтоб не возникало вопросов с чего я взял - все остальные завсегдатаи мне отвечают на то что я написал, со знанием того что я написал.
Ну да ладно. С этого дня я пишу на Гамин только посты. Всё равно у каждого свои розовые очки и толковать с вами не о чем.
EDIT: А, так Антонка всё таки второй человек на всём сайте. Что ж. Не все способны согласиться с идеей, что их любимый движок (и другой просто популярный движок) не везде подходит, когда он якобы и 3D, и 2D, и 2.5D, и сколькохочешьD.
а_я_Д'артаньян.txt
Как самоиронично.
Если не подходит любимый движок, то есть гитхаб, чтобы скачать с него остальные движки, достойные внимания :yak:
Кватернионы вообще не трогаю, а юзаю только LocalEulerAnlges, я не особо в этом шарю, я художник,
а не программист, но пришлось учить юнити из-за доступности, по цене.
Но согласен с тем, что в юнити много гемороя.
Например, делал кастомизацию персонажа в юнити, вначале создал систему кастомизации, потом оказалось, что надо создать систему генерации кнопок списка меню, чтобы этой самой кастомизацией управлять, потом пришлось повозиться с месяц пытаясь понять как обойти все грабли
(ибо UI я не особо знаю, не люблю его использовать, потому-что вроде как внутри UI юнити нельзя или сложно использовать GameObject, мне например нужно было отображать объекты инвентаря прямо на кнопках, потому сделал систему меню просто обычными объектами), и вообще не силён в тонкостях C#)
потом пришлось прикручивать систему глобальной библиотеки, чтобы все объекты кастомизации легко находились через Dictionary по простому имени (string), гемора много было.
Добавил в черный список и вообще не парюсь. Профит.
патамушто весело
это не просто традиция, а одна из двигообразующих традиций. скрепа и основа
обучать нейросетку на комментах нейросетки такое себе
Вот ты этим и займись.
Мне пока хватает одного пет-проекта, спасибо :3
Наверное, потому что это сайт про игры, причём авторские и независимые. Статьи на тему верификации, валидации и трансляции здесь мало кому интересны. При всей их полезности, увы.
Те кто занимается здесь хоть каким-то программированием - реально игры делают. И обычно понимают что программирование как сферический конь в вакууме (сугубо скил) на игру не сильно влияет. Поэтому полезнее пообсуждать геймдизайн. Программирование можно обсудить на том же гдру в весёлой компании ненасытных троллей =)
Отчасти я не согласен с этими тезисами Кситилона, но с существенной частью могу согласиться:
Я не считаю, что правильно сводить vcs только к бэкапам. Это очень помогает следить за тем, что делаешь, и что когда сделал, то есть, экономит время в локализации проблем.
Типа, ты коммитнулся, пилишь что-то, потом вдруг смотришь - всё сломалось. В диффе unstaged commits можно увидеть, что добавлялось с последнего коммита, и быстро понять, куда смотреть.
Или работал на своей ветке, и вдруг находишь какую-то лажу, можно прыгнуть на мастер и увидеть, что её ещё не было, и этим сразу сильно локализовать проблему. В особо тяжких случаях спасает git bisect.
Если настроен CI со статиком (а может быть и тестами), то это помогает заметить разную лажу при пулл реквесте. Но даже если CI нет, тупо свежим взглядом просмотреть всё, что наделал в пулле при диффе, это уже помогает почистить.
По идее, качество кода, всякие статики и прочее как раз должны помогать меньше времени тратить на программирование и связанные с ним боли, и больше уделять созданию непосредственно игры.
Это потому что ты не понимаешь сути. Изменения никуда не проёбываются, все остаются в истории, и прошлые, и будущие. И если что-то и откатывается, то только содержимое конкретного патча, а не все патчи начиная с него и до сего дня (при этом откатанный патч тоже не проёбывается, а остаётся в системе, и потом эту часть работы можно перечитать и переделать).
Игру делает продюсер. Геймдизайнер - это перевод идей продюсера в более весёлую форму.
А программист делает движок, геймплейный код, утилиты для художника, для геймдизайнера, для продюсера и вот этот вот сайт.
Небольшой, но радостный для меня статус-апдейт. Проект всё-таки дополз до состояния, чтобы суметь прожёвывать маленькие проектики, находить простые ошибки и выдавать их пусть и в очень сыром виде:
На более крупных примерах (спасибо DarkDes и Xitilon.HD408 , а больше никто не откликнулся, к сожалению) иногда отказывается парсить код, выдавая загадочные синтаксические ошибки, но мы работаем над этим. А вообще, добавить человекочитаемый формат отчёта и отладить самые типичные проверки — и можно, наверное, анонсироваться в целевых GM-сообществах, параллельно прикручивая новые диагностики.
А проекты для GameMaker 8.1 и GameMaker Studio 1.4.9999 покатят?
Еще надо бы выводить название скрипта (объекта, события) и номер строки где обнаружена ошибка.
Поддержка GMS1 не в приоритете, но возможно, когда-нибудь добавлю – это вроде бы несложно, лишь структура проектных папочек немного отличается. 8.1 – очень навряд ли, там проекты в закрытом бинарном формате, который непонятно как расковыривать.
Само собой! Это входит в понятие человекочитаемости :3 Будет.
Я тут подумал - в принципе все это гораздо проще реализовать разработчику конструктора.
У него и так там и семантическое дерево строится и все такое, проще встроить все эти проверки в сам Game Maker. Или нет?
Или сделать что-то типа "разобрать код, но не запускать его" и там все проверки делать.
Какого конструктора? GM это IDE, GML это язык. Конструктор тут что?
Game Maker - конструктор игр. В википедии так написано.
У тебя какая-то другая Википедия.
А ты ссылочку открой.
Читаем справа "Игровой движок / Интегрированная среда разработки / Конструктор".
На странице Game Maker (не-студия) прямым текстом написано "это конструктор". И именно не-студию я имел ввиду.
GMCheck, в комментариях которого мы находимся, не поддерживает не-студию.
Конструктором называют Drag'n'Drop часть ГМа, которую используют очень редко, как правило при обучении и первые годы разработки.
Конструктор — это не только «нафигачить в IDE код из Drag'n'Drop блоков», это ещё и «нафигачить в IDE игру из спрайтов, объектов и комнат».
Под разработчиком конструктора, о котором говорилось, можно понимать разработчика чего угодно в нём, не обязательно связанного с кодом. Так что исходное высказывание не консистентно.
О божечки, опять терминосрачи.
GM(:S) — конструктор для создания игр+движок для их выполнения. Он включает в себя среду разработки, язык блоков, язык GML, компилятор+рантайм и всё такое. Так сойдёт?
Я знаю что такое ГМ, не обязательно мне это говорить. Адресовалось Масту. Я подумал, может он имел в виду какую-то конкретную часть IDE, мало ли чего там эти погромисты придумали.
Не знаю как там вне ГМ, но в рамках Мейкера думаю можно сойтись на том, что "конструктор" это более бытовое\широкое обозначение смысла IDE. То есть что делать в ДелателеИгр? Конструировать их! Рисовать спрайт, писать ИИ врагов, логику подбора монетки, уровни создавать и т.д. То есть это комбайн, для которого в теории не нужны никакие внешние средства (для спрайтов, уровней, звуков(?хм?) и текста - раньше даже можно было встроенный help файл сделать, кажется)
Ну это громко сказано. Просто RTF-документ (считай, уровня WordPad'а, без таблиц, хотя в 2020 проще сказать "как в Телеграме или Дискорде"), который можно скроллить только мышью и клавиатурой. Если б там можно было хотя бы разделы делать, было бы круче, но мало каким играм встроенный мануал прям вот нужен.
Делать. Гейм Мейкер это именно что Делатель, а не Конструктор.
Ну это да. как минимум можно было менять цвет фона и шрифта! Он вам не notepad.exe!
Делать это делать, а конструировать по смыслу "собирать из частей в единое целое" - спрайт по себе есть просто спрайт, но с кодом в объекте и размешёный в комнате начинается вотэтовсё.
С одной стороны, да; и если конструктор не предоставляет механизма расширений, только так можно добавить диагностики об ошибках прямо в редактор. С другой, для этого у разработчика должны быть желание и ресурсы; а учитывая, что трансляторы с долгой историей изнутри могут представлять собой невообразимое легаси, к которому сложно подступиться, может быть проще наваять стороннюю утилиту с нуля. Даже PVS, кажется, не стали брать за основу какой-нибудь GCC, а разработали свой парсер, а ведь парсить C++ — тот ещё ад, в отличие от GML.
(так-то я бы поковыряла исходники GMS, только кто ж мне их даст)
Ну хотя бы код интерпретатора, который какую-то структуру создает перед выполнением - можно у автора попросить? А потом уже писать свой код, который эту структуру будет анализировать. Если получится, может даже в следующие версии встроят.
Хаха, вот это лицемерие - как делать игры, так вы хотите чтоб ГМ делал всё, на уровне движка; а как о программерских штуках, так это ж конструктор. XDDDDD
Не поняла, о чём ты.
Дык не нравится ему что GM все еще называют конструктором, он же такой продвинутый.
Будто конструктор — это что-то плохое. Лично я никакого уничижительного смысла в этот термин не вкладываю, наоборот, – это что-то, что упрощает разработку, предоставляя готовые комбинируемые блоки.
Ну и я о том же.
Если прога все еще позволяет делать игру, не занимаясь программированием - это все еще конструктор.
Невозможно сделать игру без программирования. Визуальное программирование, сцепление готовых блоков - тоже программирование, просто более высокоуровневое - такое, которое в маркетинговых целях называют не программированием.