Telegram Web
Как делать сайты в 2024

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

Короткий ответ: сайт надо хостить на Github Pages, генерить статику с помощью Jekyll.

Теперь напишу более развёрнуто, как я дошёл до таких мыслей. Личных сайтов у меня, как и у многих, была целая куча. Штук 6 или 7 разных итераций. Начиная от кринжовой странички AlprogCompany на народе с фоткой в разделе «обо мне»; и заканчивая блогом на PHP с самописной админкой контента. Проблемы у этих сайтов всегда одни и те же, и к ним я ещё вернусь. Но изначально я решал вообще другую проблему.

Как вы возможно знаете, я иногда пишу рассказы на всякие литературные конкурсы, и закономерно встаёт вопрос: куда их выкладывать? Требования очень простые: хотелось залить куда-то один раз в одно место и забыть на миллион лет, но чтобы оно всегда было доступно по прямой ссылке в читабельном виде. С одной стороны есть специализированные коммерческие ресурсы, типа Литрес или Автор.тудей, но они пихают рекламу и часто меняются. С другой стороны вырвиглазный Самиздат и зашкварная Проза.ру, на которых в принципе не очень приятно находиться в окружении web 1.0 и иконок одноклассников. Пилить и поддерживать своё решение ради этого тем более казалось оверкиллом.

Решение нашлось гениальное: github.com. Просто кидаем файлы в репо и всё: ваши рассказы доступны по прямой ссылке, они читабельно свёрстаны, в окружении нормального дизайна, есть список всех рассказов, да и ссылка на них явно в большей сохранности, чем большая часть интернета. А может быть ещё и во льдах арктики забекапят на случай постапокалипсиса.

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

Потому что у личных мелких сайтов проблемы всегда одни и те же:
- Дизайн устаревает быстрее, чем они выбираются из под плашки «Under Construction»;
- Обновления случаются так редко, что ты порой уже и не помнишь, как там правильно добавлять контент. И какой пароль от FTP;
- Неудобно обновлять контент и управлять версиями. Либо для того, чтобы стало удобно, надо сделать ряд дополнительных приседаний. Особенно на новой машине;
- Надо думать о хостинге. Регулярно платить ему какие-то деньги, да ещё и сталкиваться с его закидонами: то он работы на серверах будет проводить, то PHP обновит до неудобной версии, то тарифы и ограничения поменяет;
- Домены имеют свойство протухать, угоняться киберсквоттерами и прочие неприятности. Из-за чего у вас потом по всей сети протухшие ссылки в старых постах. Нет ничего более жалкого, чем протухшие ссылки на личную страницу.

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

Кроме того, Github Pages это уже что-то вроде стандарта индустрии для лэндинга и документации по всяким опен-сорсным библиотечкам. Почему бы не расширить это на личные сайты в принципе?

Я так запилил свой личный сайт (там можно почитать мои рассказы) и сайт нашего подкаста (там уже можно послушать новый выпуск про эмиграцию).
Сейчас я занимаюсь написанием большой интерактивной статьи по матрицам. Почему-то все статьи по матрицам, что я видел, объясняют их по сложному пути. Я хочу сделать значительно проще и нагляднее. Для этого я сейчас на голом JS и html-канвасе пишу мини-движок визуализации интерактивных диаграмм. Она тоже будет на гитхабе.
Ёж восстаёт из могилы.

Ребят, я не сдох. Честно. Я даже генерил какой-то контент последнее время, но почему-то только не сюда. Давайте отчитаюсь, что и как.

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

Во-вторых, подкасты. Мы записали 4 выпуска, в том числе с Хомаком, Ториком и Апанасиком. Это была моя вторая, и, похоже, последняя попытка попробовать себя в этом жанре. Ходить гостем и отвечать на конкретные вопросы мне норм (помните, я ходил в КДИ пояснять за С++?), но вот быть ведущим — это вот прям совсем не моё. Мне нравится производить относительно сложный контент, в котором ты, по крайней мере, контролируешь каждую букву. А говорить что-то нон-стопом без подготовки — это не то, что я могу потом с чистой совестью посоветовать другим людям послушать.

Я стал крестным отцом подкаста, познакомив Никиту и Марка, а сам изначально не планировал туда влазить, но зачем-то влез под общие уговоры. Но теперь закономерно ухожу в тень, а вот ребята фигачат дальше. У них уже были Кортез и Альфина, ребята развиваются. Их можно слушать на всех платформах.

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

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

Где-то в самом начале блоге упоминалось, что тут будет что-то и про путешествия, поэтому поведаю, что в отпуск мы собрались в Средиземноморский Круиз. У меня на счету пока 23 страны. Должны добавиться 3 новые: Италия, Франция и Ватикан.

Ну а после отпуска я всё ещё планирую, наконец-то, вернуться к скриптовому языку ку-ку и симулятору геймдева Crunch House. Очень надеюсь, что в скором времени этот блог превратится в дневники разработки Crunch House и будет таким оставаться на долгие годы. Stay tuned.
Я пишу новый движок

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

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

Да, сука. Опять.

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

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

— Во-вторых, несмотря на то, что Godot намного приятнее Unity, с ним всё-таки приходится немного бороться. У меня почти получилось сделать там хорошую мультиоконность, но ценой проклятой структуры проекта и одного скрытого окна. Также каскадные шадоумапы почувствовали себя не очень хорошо при рендере в несколько вьюпортов. Ну и конечно необходимость перепиливать систему инпут евентов под себя. В общем, моментиков хватает.

— В-третьих — и это, наверное, на самом деле самый главный аргумент — Crunch House будет игра про трушную разработку на собственных движках. Как будто бы делать такую игру не на своём движке — зашквар.

— В-четвёртых, это мой пет — чё хочу, то и делаю. Я в другом городе, как говорится.

В общем, снова пишу движок. Но в этот раз совсем другая концепция.

Моя прошлая попытка движка (Judy) концентрировалась вокруг совсем низкоуровневых вещей (и дальше не продвинулась): собственный кроссплатформенный оконный менеджер и инпут, кроссплатформенный рендер и компиляция шейдеров, IDE на Qt, встроенный текстовый редактор и дебагер скриптов.

В этот раз я прям так шизеть не буду. Формула такая: SDL2 + DX12 + ImGui + KuKu.

Всю кроссплатформенную возню с ОС я заменяю индустриальным стандартом в виде SDL2 (писать самому было интересно, но бессмысленно).

А рендер я пока вообще не буду делать кроссплатформенным. Это можно будет сделать когда-нибудь в будущем, но постфактум, а не заранее. Так что пока для простоты буду на голом DX12. Хотя слово «простота» плохо подходит для DX12. Там, на минуточку, даже мипмапы и MSAA надо руками резолвить. Благо мне не так-то много всего надо написать. Каскадные тени, блум. Особо больше ничего использовать не собираюсь. Вряд ли даже TAA буду лепить.

Возня с Гуи на Qt тоже идёт нафиг: берём индустриальный стандарт ImGui. Отлично подойдёт как для девелоперских тулзов, так и для внутриигрового Gui (под жанр симулятора оно идеально).

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

Но самая мутная часть движка — это, конечно, Ku-ku. Я там давно застрял на куче архитектурных дилемм, когда хочется всего и сразу, но хотелки конфликтуют друг с другом. Надо будет в какой-то момент сесть, подумать, что мне больше всего нужно именно для Crunch House, и устроить нещадный фичекат.

Вот как-то так. А движок на этот раз называется Finik. В честь кота. Он мелкий (это же кот), но бойкий. Шугает тут шведских котов. Имя короткое, легко произносимое и, вроде бы, уникальное.
Извините, но снова про Сакутина.

Щас зашла опять речь про его курсы, зашёл глянуть его «самый полный курс по юнити». Раздел математика. Они позвали Земскова рассказать про вектора. Оси в юнити он показал правильно, левой рукой. Видимо, ЯЮниоровцы додумались сказать, что там LHS. Но дальше он объясняет кросс-продукт. И несколько раз подчёркивает, что для кросс-продукта (в отличие от осей) нужно пользоваться именно правой рукой. И векторное произведение a⃗ x b⃗ у него получается вниз.

К Земскову никаких претензий нет. Он математик. Но сука. Ни у кого из этих юнитологов ничего не щёлкнуло, когда они это в курс вставляли. Какой же стыд адский.
Да ёперный театр.

Опять мне попался ролик Сакутина. "Как ПРАВИЛЬНО сделать передвижение в Unity? Нормали поверхностей". Естественно не удержался и посмотрел, особенно на фоне моего прошлого поста.

На скрине вы видите его попытку вычислить проекцию вектора F на плоскость, описанную нормалью N. Типа, чтобы скользить вдоль этой поверхности.

Я не берусь комментировать, что за ахинея происходит у него в формуле; но даже на его численном примере невооружённым взглядом видно, что получается какая-то ерунда. Нормаль у него диагональная под 45° (0.5; 0.5). А вектор вдоль плоскости, который по определению должен быть перпендикулярен нормали, нифига не под 45° (-0.75; 0.25).

Вот это вот хрен победи что подаётся как ПРАВИЛЬНОЕ (капсом) передвижение в Unity.

Я уже просто не знаю. Может и правда пора огромный пост на DTF написать?
Upd: в комментах написали, что если бы нормаль была нормализованной, как ей и положено, то формула работает. Присмотрелся, вдумался в написанное: и да, получается мы из исходного вектора вычитаем компоненту движения вдоль нормали (проекцию на нормаль), так что наш вектор «ложится» на плоскость.

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

Но готов признать, что в данном случае я поторопился с выводами. Код там в порядке, ошибка только в объяснениях. Что всё равно не очень хорошо для тех, кто собрался учить, но всё-таки намного меньшее зло, чем я выставил изначально.
Ixxtension

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

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

Однако же, я в полной мере вкусил во-вторых: мешать модули и обычные хедеры нельзя. Если ты сделал import std в одном хедере, то будь добр делай так же во всех (в рамках одного транслейшн юнита). Заинклудил 3rd-party библиотечку, которая где-то там внедрах использует vector? Ну всё, каюк: нечитабельные ошибки тебе обеспечены.

В-третьих, почти нереально модулизировать что-то перекрытое макросами, типа directx 12 API. Оно ещё тянет всякие виндовые хедеры, ComPtr и прочие приколы, которые тоже могут с std законфликтовать. В общем, без хаков не обходится.

Я уж молчу про то, что подсветка IDE конкретно тупит и отваливается на модулях. И всяких банальных удобств нет, типа переключения между cpp и ixx файлами. Последнее меня настолько сильно бесило, что я написал VS extension для этой цели. Назвал его Ixxtension, забирайте, если вдруг таким же страдаете.

Тем не менее намерен дальше пилить модулями. Всё ещё хочется верить, что за ними будущее. Надеюсь, что когда-нибудь это перестанет быть редким инопланетным синтаксисом (как trail return type), а станет мейнстримом. Если это случится, то пусть у меня уже будет модульный проект к тому времени. Потому что портировать большую кодобазу это совсем анрил.
Умер король. Трое наследников поссорились и разделились на 3 страны. Они договорились, что через 3 поколения их правнуки проголосуют, объединяться ли назад в одно королевство или жить дальше отдельно.

В каждой из стран все 3 поколения была постоянная рождаемость (у каждого в стране одинаковое количество детей, бездетных нет). Все правнуки дожили до голосования. Жители двух стран были единогласно ЗА, а третьего — ПРОТИВ. И получилась НИЧЬЯ.

Злые языки шепчут, что обязательно был инцест. Докажите, что это не так.
Тяжёлые выборы #1: чёртовы оси

В разработке своего движка иногда нужно делать такие выборы, которые со стороны кажутся плёвыми и не особо важными, а на деле их не так-то легко и сделать.

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

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

1. Изначально я положил XYZ самым привычным для себя образом: Right-Up-Forward. Так было по умолчанию в классическом DirectX, так сделано в Unity и так сейчас у меня на работе (Clausewitz engine). Это также NDC в большинстве GAPI (кроме вулкана), так что это такой крепкий default для 3D.

Но мой движок в первую очередь предназначен для TopDown игр, а Y-up, как известно, не очень для этого подходит. Я уже делал TopDown игру в такой системе координат (Encased на Unity) и это влекло за собой некоторое количество неудобств:

Во-первых, чтобы не заниматься постоянной перестановкой y и z из Vector2 в Vector3 и обратно, боясь рано или поздно опечататься, мне пришлось завести довольно искусственный VectorXZ и использовать везде его. Он абсолютно такой же как Vector2, но с полями xz вместо xy.

Во-вторых, в такой системе координат по-честному вращение вокруг вертикальной оси должно идти по часовой стрелке. Но мы, естественно, пихали z вместо y во все тригонометрические функции и делали вид, что так и надо. У нас всё начинало вращаться против часовой стрелки, как в школьной тетрадке, но вообще это довольно грешноватенько так делать.

2. Первый логический шаг по улучшению ситуацию — это перейти на z-up, как в Blender. VectorXZ больше не нужен. Вращение по честному начинает идти против часовой стрелки. Красота!

Но я не захотел на этом останавливаться. В получившейся схеме меня бесит, что Y-координата моей тайловой карты смотрит на север, и это не совпадает с тем, как работают координаты в TextureSpace и ScreenSpace. Не знаю, как вас, а меня бесят эти бесконечные перевороты текстур по вертикали. Я хочу работать с тайловой картой по правилам GUI: прибавлять Size спрайта целиком в положительную сторону. Потому что когда нужно прибавлять Width, но отнимать Height — это чистой воды дичка.
3. Чтобы достичь этого, я расположил X на восток, а Y на юг. Получилась довольно упоротая комбинация Right-Back-Up. По крайней мере я никогда такую не встречал. Какое-то время я пытался привыкнуть к такому расположению, но здесь ровно та же проблема, почему я ненавижу систему координат Godot или XNA: Back это положительное направление.

По моему глубокому убеждению, положительными осями должен быть Right, а не Left; Up, а не Down; и особенно, мать твою, Forward, а не Backward. Сколько бы я не смотрел код чуваков, у которых Z+ это back, там всегда какое-то упоротое двоемыслие начинается. То они направление на камеру называют Forward вместо Back, то выворачивают гизмо наизнанку, чтобы синяя палка в негативную сторону смотрела. Словом ты уже не знаешь, чего ждать и кому верить. Да и в целом во всех формулах с участием Z уродский минус появляется, о котором надо постоянно помнить. Лучше его в кодобазу вообще не впускать. Только плюс, только вперёд.

4. И тут (после мучительных качелей туда-сюда), я в итоге пришёл к анриловской схеме Forward-Right-Up. Дефолтное положение камеры становится -90°, но зато исчезает проклятый минус. Бонусом, по умолчанию все объекты становятся ориентированы forward-ом на восток, а не север. Что, типа, более привычно, так как 0° в школьной тетрадке мы рисуем вправо.

Буквально единственный недостаток, который я в этом во всём вижу, это то, что углы будут считаться по часовой стрелке, а не как на уроке математики. Но всё GUI и многие 2D игры зачастую работают с такими углами, и ни у кого жопа не отваливается. Учитывая, сколько других проблем это решает, это довольно малая жертва.
Иронично, но изначально я считал схему Unreal одной из самых упоротых, но по итогу сам к ней пришел.

Но зато я остался верен более нативной для DX левосторонней системе координат. Как видите, microsoft-бой однажды — навсегда microsoft-бой.

Ну и, кстати, забыл упомянуть одну из самых главных киллер-фич левосторонней системы: я правша. А это значит, что когда у меня в руке мышь, левой рукой гнуть пальцы банально удобнее. Впрочем, надо бы обзавестись распечатанной на 3D-принтере гизмой осей.
2025/02/04 19:58:55
Back to Top
HTML Embed Code: