У нас такое не слишком часто, чтобы фича прям совсем не пошла в релиз. Обычно, если мы что-то запланировали, то оно идёт до прода пока не дойдёт, или пока не станет ясно, что там совсем муть, и надо переделать задачу.
Я просто в текущую задачу отдельным коммитом в той же ветке делаю фиксы вроде плавающих тестов или малого рефакторинга. У нас за такое по рукам не бьют =)
Вы наверное называете очевидным необходимость написания атомарных коммитов. Спешу вас заверить, это совершенно неочевидно для всех вокруг. Пока что ни на одном месте работы, где я работал, это не ценилось в достаточной мере. Это может быть связано как с недостаточным уровнем разработчика, когда фокус идёт на просто работающий и логичный код, а не на организацию этого кода по коммитам; и когда используется "squash merge", то есть все коммиты в ветке сжимают в один перед вливом в основную ветку. Это сложные ситуации, где атомарные коммиты не приживутся, потому что их выгода совершенно неочевидна для людей, работающих с такими условиями.
Я не требую исчерпывающего описания, потому что ставлю главной идеей именно произведение декомпозиции. Если человек производит декомпозицию - я уже буду в выигрыше, с таким человеком будет приятно работать. Ставить дополнительные условия, как например, вы сказали, более подробное описание коммитов, - это уже следующий уровень для тех, кто освоил саму идею и практику атомарных коммитов. Мне, несомненно, было бы гораздо приятнее работать в такой кодовой базе.
Ко второму пункту дополнительно добавлю моё субъективное мнение: обычно развёрнутые коммиты получаются там, где логика идёт больше технического толку, чем бизнес-логика. Бизнес-логика слишком часто меняется, под неё даже нанимают специальных людей вроде аналитиков или технических писателей. Её трудно написать в описании к коммиту в том числе, потому что разработчик сам может не полностью понимать суть своего задания (это типично для больших проектов). Когда речь идёт о более технических проектах, как например библиотеки, операционные системы, сетевые сервисы - тут у разработчика гораздо больше компетенции написать коммит развёрнуто, потому что это полностью его зона экспертизы.
Интересно почитать, спасибо за точку зрения. Где вы проводите грань между дизайн системой и библиотекой визуальных компонентов? Аля сторибук, но даже не обязательно формализовывать.
Наверное для стартапа всё-таки хочется иметь набор классов CSS, которые описывают первичные и вторичные кнопки. А иногда даже выбор фреймворка, как tailwindcss, просто заставляет разносить всё по компонентам.
Интересно будет услышать про степень свободы, которую вы себе позволяете, когда ещё нет дизайн системы.
Большое спасибо за комментарий! Понимаю, что барьер для прочтения здесь имеется, и я рад, что вы всё-таки смогли его преодолеть. Вы сказали, что вам статья была интересна, а что больше всего понравилось?
Отвечая на вопрос, как глубока эта система, я думаю, что речь будет идти о возможности воплотить перечисленные вами механики, используя концепты из этой статьи. И отдельный вопрос, насколько будет легко адаптировать текущую имплементацию для этих механик. Я попробую ответить по порядку сначала про концепты, а затем про имплементацию.
Смешать яд и воду, чтобы получить отравленную воду. Это работает в текущей концепции так: к поверхности "вода" применяется элемент "яд", и вода из обычной воды WaterSurface становится отравленной водой, или просто ядом PoisonSurface. В текущей имплементации это уже есть, правда сделано с особенностью Divinity, что там высчитывается вероятность, будет ли замещение воды ядом.
Испарить огнем для получения отравленного облака. Работает аналогично, к поверхности PoisonSurface применяется элемент FireElement и мы испаряем эту поверхность, превращая в ядовитое облако PoisonCloud. В текущей имплементации, следуя канону Divinity, когда огонь соединяется с ядом, то образуется взрыв. Но это можно легко поменять, сейчас эта логика находится в этом мульти методе:
class PoisonSurface is Surface does Solution is export {
# ...
multi method apply (FireElement) { [StateChange.empty, ExplosionEnvironmentEffect.new] }
}
В мульти-методе выше при столкновении ядовитой лужи с огнем происходят две вещи: убираем все поверхности и облака с клетки, и мы вызываем эффект взрыва.
Сдуть облако на клетку с противником. Это интересная механика, она не ограничивается просто клеткой, на которую оказывают воздействие, поэтому в текущем концепте это будет еще один эффект окружающей среды. Выглядеть это будет примерно следующим образом:
class PoisonCloud is Cloud is export {
multi method apply (AirElement $e) {
[StateChange.empty,
MoveEnvironmentEffect.new(
source => $e.source-cell,
cell => StateChange.cloud(PoisonCloud.new))]
}
# ...
}
Мы очищаем текущую клетку и вызываем эффект окружающей среды, чтобы произвелась механика "сдвига" облака. Мы передаем туда source, клетку-источник нашего элемента, чтобы рассчитать траекторию, куда должно сместиться облако. На данный момент в имплементации не хватает клетки-источника у элемнтов — элементы не знают, кто и откуда их применил. Скорее всего эту информацию все равно можно будет использовать, поэтому ее нужно будет добавить. Как мне кажется, это будет правка достаточно большого количества кода, но не потребует редизайна имеющейся системы, просто добавить данные.
***
Мне на ум еще приходит игра, в которую я играл в детстве и сейчас не могу найти. Это был дарк фентези сеттинг, там была книга заклинаний, где тоже можно было комбинировать разные школы. Почему-то на ум приходит название "Blood Magick", но увы, я не могу ничего найти. Помню, что там была темная церква, в которой проводили месу, и рядом с ней было какое-то существо, похожее на голума из Властелина колец.
Такие элементы, может быть, и связаны с обманом, но, по сути, это win-win для всех
Когда твоей профессией становится вызывать у игрока чувства, которые заставят его продолжить играть, то это уже как азартные игры. Здесь положительные эмоции являются не целью, а средством заставить игрока посидеть за игрой подольше. Такая мотивация не может служить экологичному взаимодействию. Важно находить более экологичные способы удержания. Например, приводится пример:
в Gears of War обнаружили, что игрок, не набравший ни одного фрага в своем первом мультиплеерном матче, с 90% вероятностью не будет играть второй раз
Наверное, в первую очередь важно сделать матч со схожим по уровню игроками. И сделать первый опыт относительно легким, чтобы повторение не казалось чем-то сложным (например, тяготные получасовые передвижения без экшена будут скучными без рагов). Если и давать преимущество, то сделать это можно прозрачно, например, отобразив в интерфейсе баф на урон "первопроходец: до конца раунда весь ваш урон удвоен".
И в случаях со статистикой было бы полезно узнать, сколько из этой первой воронки все равно остаются, вдруг там под 90% все равно уходят после 5-го матча.
Еще Джонатан Блоу в своем интервью плевался от того, как на презентации Сид Мейерс дизайнер рассказывал, как они подкручивали проценты, потому что "игрок чувствует процент иначе", отбирая возможность переосмыслить проценты и научиться лучше воспринимать свои шансы.
Мне кажется, что мотивация в большинстве примеров сильно отдает запахом денег, а потому не сотрудничает с игроком, а пытается его подчинить.
Спасибо большое за ваш комментарий и за упоминание в вашей статье. Я рад, что Raku не стал слишком высоким барьером для понимания, я немного боялся, что он будет слишком отталкивать.
По хардкодингу: что думаете о проблеме "невозможных состояний"? То есть, если какая-то комбинация из субстанция/агрегатное не будет существовать в игре. Похоже, что нужно будет при создании или изменении везде ставить проверки на то, что набор свойств позволителен. Например для electrify у вас такое условие:
self.base_surface == BaseSurface.NEUTRAL and self.aggregate_state != AggStates.VAPOR) or self.aggregate_state == AggStates.SOLID
Наверное нужно будет что-то придумать, если система будет расширяться. Какое-нибудь пост-условие, что конечный объект всегда валидный.
Спасибо большое за ваш комментарий и за упоминание в вашей статье. Я рад, что Raku не стал слишком высоким барьером для понимания, я немного боялся, что он будет слишком отталкивать.
По хардкодингу: что думаете о проблеме "невозможных состояний"? То есть, если какая-то комбинация из субстанция/агрегатное не будет существовать в игре. Похоже, что нужно будет при создании или изменении везде ставить проверки на то, что набор свойств позволителен. Например для electrify у вас такое условие:
self.base_surface == BaseSurface.NEUTRAL and self.aggregate_state != AggStates.VAPOR) or self.aggregate_state == AggStates.SOLID
Наверное нужно будет что-то придумать, если система будет расширяться. Какое-нибудь пост-условие, что конечный объект всегда валидный.
Это правда, что в Питоне более идиоматично будет написать в две строки, а не в одну. Это не является объективным добром, но в Питоне так принято. Что интересно, мне кажется, что на скорость чтения это может не влиять, если привыкнуть к моржовому оператору. Если привычно, то не будет ступора от непонятной конструкции.
Это очень интересно. Для меня открытие, что перестановка математических выражений местами может повысить производительность на 10%. Обычно инструкции хотя бы связаны, это же перестановка независимых выражений. Мне все еще непонятно, почему здесь играет роль разрядность системы, 32 или 64 бита, я так полагаю, что просто так оно работает без общего правила. Я посмотрю, что такое llvm-mca, спасибо за наводку.
Очень интересная статья. Я загорелся идеей сделать подобную систему на Raku, попробую написать ответную статью со сравнением, как бы выглядело то же самое, но в контексте другого языка. Мне кажется, что многие повторяющиеся части вроде веток if-else, конструкций с and можно упростить. Например, отдельные ветки можно разбить на мультиметоды, а повторяющиеся условия сократить с помощью Junctions https://docs.raku.org/type/Junction
Из интересного, Perl часто является установленным на системах Линукс, и утилита git имеет прямую зависимость от Perl. Поэтому писать скрипты на этом языке кажется очень заманчивой идеей, как лучшая альтернатива Bash, sed, awk и подобным.
В отличие от Raku, Perl имеет довольно быстрый запуск виртуальной машины, и на моем компьютере это примерно 500 и 50 миллисекунд соответственно. Поэтому пока что Raku не удается встать на тот же уровень, например, для написания скриптов для текстового редактора, потому что задержка в 500 мс сильно бьет по производительности.
У нас такое не слишком часто, чтобы фича прям совсем не пошла в релиз. Обычно, если мы что-то запланировали, то оно идёт до прода пока не дойдёт, или пока не станет ясно, что там совсем муть, и надо переделать задачу.
Я просто в текущую задачу отдельным коммитом в той же ветке делаю фиксы вроде плавающих тестов или малого рефакторинга. У нас за такое по рукам не бьют =)
Спасибо за вопросы, отвечаю.
Вы наверное называете очевидным необходимость написания атомарных коммитов. Спешу вас заверить, это совершенно неочевидно для всех вокруг. Пока что ни на одном месте работы, где я работал, это не ценилось в достаточной мере. Это может быть связано как с недостаточным уровнем разработчика, когда фокус идёт на просто работающий и логичный код, а не на организацию этого кода по коммитам; и когда используется "squash merge", то есть все коммиты в ветке сжимают в один перед вливом в основную ветку. Это сложные ситуации, где атомарные коммиты не приживутся, потому что их выгода совершенно неочевидна для людей, работающих с такими условиями.
Я не требую исчерпывающего описания, потому что ставлю главной идеей именно произведение декомпозиции. Если человек производит декомпозицию - я уже буду в выигрыше, с таким человеком будет приятно работать. Ставить дополнительные условия, как например, вы сказали, более подробное описание коммитов, - это уже следующий уровень для тех, кто освоил саму идею и практику атомарных коммитов. Мне, несомненно, было бы гораздо приятнее работать в такой кодовой базе.
Ко второму пункту дополнительно добавлю моё субъективное мнение: обычно развёрнутые коммиты получаются там, где логика идёт больше технического толку, чем бизнес-логика. Бизнес-логика слишком часто меняется, под неё даже нанимают специальных людей вроде аналитиков или технических писателей. Её трудно написать в описании к коммиту в том числе, потому что разработчик сам может не полностью понимать суть своего задания (это типично для больших проектов). Когда речь идёт о более технических проектах, как например библиотеки, операционные системы, сетевые сервисы - тут у разработчика гораздо больше компетенции написать коммит развёрнуто, потому что это полностью его зона экспертизы.
Интересно почитать, спасибо за точку зрения. Где вы проводите грань между дизайн системой и библиотекой визуальных компонентов? Аля сторибук, но даже не обязательно формализовывать.
Наверное для стартапа всё-таки хочется иметь набор классов CSS, которые описывают первичные и вторичные кнопки. А иногда даже выбор фреймворка, как tailwindcss, просто заставляет разносить всё по компонентам.
Интересно будет услышать про степень свободы, которую вы себе позволяете, когда ещё нет дизайн системы.
Большое спасибо за комментарий! Понимаю, что барьер для прочтения здесь имеется, и я рад, что вы всё-таки смогли его преодолеть. Вы сказали, что вам статья была интересна, а что больше всего понравилось?
Отвечая на вопрос, как глубока эта система, я думаю, что речь будет идти о возможности воплотить перечисленные вами механики, используя концепты из этой статьи. И отдельный вопрос, насколько будет легко адаптировать текущую имплементацию для этих механик. Я попробую ответить по порядку сначала про концепты, а затем про имплементацию.
Смешать яд и воду, чтобы получить отравленную воду. Это работает в текущей концепции так: к поверхности "вода" применяется элемент "яд", и вода из обычной воды
WaterSurfaceстановится отравленной водой, или просто ядомPoisonSurface. В текущей имплементации это уже есть, правда сделано с особенностью Divinity, что там высчитывается вероятность, будет ли замещение воды ядом.Испарить огнем для получения отравленного облака. Работает аналогично, к поверхности
PoisonSurfaceприменяется элементFireElementи мы испаряем эту поверхность, превращая в ядовитое облакоPoisonCloud. В текущей имплементации, следуя канону Divinity, когда огонь соединяется с ядом, то образуется взрыв. Но это можно легко поменять, сейчас эта логика находится в этом мульти методе:В мульти-методе выше при столкновении ядовитой лужи с огнем происходят две вещи: убираем все поверхности и облака с клетки, и мы вызываем эффект взрыва.
Сдуть облако на клетку с противником. Это интересная механика, она не ограничивается просто клеткой, на которую оказывают воздействие, поэтому в текущем концепте это будет еще один эффект окружающей среды. Выглядеть это будет примерно следующим образом:
Мы очищаем текущую клетку и вызываем эффект окружающей среды, чтобы произвелась механика "сдвига" облака. Мы передаем туда
source, клетку-источник нашего элемента, чтобы рассчитать траекторию, куда должно сместиться облако. На данный момент в имплементации не хватает клетки-источника у элемнтов — элементы не знают, кто и откуда их применил. Скорее всего эту информацию все равно можно будет использовать, поэтому ее нужно будет добавить. Как мне кажется, это будет правка достаточно большого количества кода, но не потребует редизайна имеющейся системы, просто добавить данные.***
Мне на ум еще приходит игра, в которую я играл в детстве и сейчас не могу найти. Это был дарк фентези сеттинг, там была книга заклинаний, где тоже можно было комбинировать разные школы. Почему-то на ум приходит название "Blood Magick", но увы, я не могу ничего найти. Помню, что там была темная церква, в которой проводили месу, и рядом с ней было какое-то существо, похожее на голума из Властелина колец.
Когда твоей профессией становится вызывать у игрока чувства, которые заставят его продолжить играть, то это уже как азартные игры. Здесь положительные эмоции являются не целью, а средством заставить игрока посидеть за игрой подольше. Такая мотивация не может служить экологичному взаимодействию. Важно находить более экологичные способы удержания. Например, приводится пример:
Наверное, в первую очередь важно сделать матч со схожим по уровню игроками. И сделать первый опыт относительно легким, чтобы повторение не казалось чем-то сложным (например, тяготные получасовые передвижения без экшена будут скучными без рагов). Если и давать преимущество, то сделать это можно прозрачно, например, отобразив в интерфейсе баф на урон "первопроходец: до конца раунда весь ваш урон удвоен".
И в случаях со статистикой было бы полезно узнать, сколько из этой первой воронки все равно остаются, вдруг там под 90% все равно уходят после 5-го матча.
Еще Джонатан Блоу в своем интервью плевался от того, как на презентации Сид Мейерс дизайнер рассказывал, как они подкручивали проценты, потому что "игрок чувствует процент иначе", отбирая возможность переосмыслить проценты и научиться лучше воспринимать свои шансы.
Мне кажется, что мотивация в большинстве примеров сильно отдает запахом денег, а потому не сотрудничает с игроком, а пытается его подчинить.
Если вы гордый пользователь Emacs, то можете попробовать denote
Спасибо большое за ваш комментарий и за упоминание в вашей статье. Я рад, что Raku не стал слишком высоким барьером для понимания, я немного боялся, что он будет слишком отталкивать.
По хардкодингу: что думаете о проблеме "невозможных состояний"? То есть, если какая-то комбинация из субстанция/агрегатное не будет существовать в игре. Похоже, что нужно будет при создании или изменении везде ставить проверки на то, что набор свойств позволителен. Например для
electrifyу вас такое условие:Наверное нужно будет что-то придумать, если система будет расширяться. Какое-нибудь пост-условие, что конечный объект всегда валидный.
Спасибо большое за ваш комментарий и за упоминание в вашей статье. Я рад, что Raku не стал слишком высоким барьером для понимания, я немного боялся, что он будет слишком отталкивать.
По хардкодингу: что думаете о проблеме "невозможных состояний"? То есть, если какая-то комбинация из субстанция/агрегатное не будет существовать в игре. Похоже, что нужно будет при создании или изменении везде ставить проверки на то, что набор свойств позволителен. Например для
electrifyу вас такое условие:Наверное нужно будет что-то придумать, если система будет расширяться. Какое-нибудь пост-условие, что конечный объект всегда валидный.
Я написал статью, но она пока в песочнице, не знаю, увидит ли свет. В любом случае вот для вас ссылочка, будет интересно услышать мысли и комментарии.
https://habr.com/ru/sandbox/222460/
Это правда, что в Питоне более идиоматично будет написать в две строки, а не в одну. Это не является объективным добром, но в Питоне так принято. Что интересно, мне кажется, что на скорость чтения это может не влиять, если привыкнуть к моржовому оператору. Если привычно, то не будет ступора от непонятной конструкции.
Для меня это не очевидно. Если вы говорите про усложнение, то здесь два противодействующих фактора:
Усложнение кода одной строки
Выражение мысли в двух строках
Для меня совершенно не очевидно, что прочитать две "простые" строки будет быстрее, чем одну "сложную".
Вот оно что, спасибо большое за пояснение!
Почему у вас наступает эффект замедления чтения кода при виде моржового оператора?
Когда твоя главная проблема в том, чтобы вовремя вылезать из пузыря богатой жизни и высокого самомнения, то жизнь удалась.
Это очень интересно. Для меня открытие, что перестановка математических выражений местами может повысить производительность на 10%. Обычно инструкции хотя бы связаны, это же перестановка независимых выражений. Мне все еще непонятно, почему здесь играет роль разрядность системы, 32 или 64 бита, я так полагаю, что просто так оно работает без общего правила. Я посмотрю, что такое llvm-mca, спасибо за наводку.
Это что-то специфичное для Паскаля?
Очень интересная статья. Я загорелся идеей сделать подобную систему на Raku, попробую написать ответную статью со сравнением, как бы выглядело то же самое, но в контексте другого языка. Мне кажется, что многие повторяющиеся части вроде веток if-else, конструкций с and можно упростить. Например, отдельные ветки можно разбить на мультиметоды, а повторяющиеся условия сократить с помощью Junctions https://docs.raku.org/type/Junction
Из интересного, Perl часто является установленным на системах Линукс, и утилита git имеет прямую зависимость от Perl. Поэтому писать скрипты на этом языке кажется очень заманчивой идеей, как лучшая альтернатива Bash, sed, awk и подобным.
В отличие от Raku, Perl имеет довольно быстрый запуск виртуальной машины, и на моем компьютере это примерно 500 и 50 миллисекунд соответственно. Поэтому пока что Raku не удается встать на тот же уровень, например, для написания скриптов для текстового редактора, потому что задержка в 500 мс сильно бьет по производительности.