Pull to refresh
349
58
Send message

Система объектов из Quake: шелл-скриптинг для игр

Reading time11 min
Views1.6K

Игровой движок Quake невероятно сильно повлиял на технологию разработки игр. Он активно лицензировался, в том числе, для использования в таких топовых играх как «Half-Life», «Call of Duty» и «Star Wars: Jedi Knights». Вероятно, наиболее серьёзное влияние оказали те многочисленные разработчики, которые научились писать игры, занимаясь его моддингом, а затем принесли с собой его принципы в другие студии, обогатив ими развитие других движков.

Большая часть того, что уже написано о движке Quake — это информация с акцентом на технологию 3D-рендеринга или многопользовательские сетевые игры. Но почти без внимания остаётся инновационная система объектов — парадигма, с опорой на которую дизайнеры уровней создают динамические взаимодействия, не прибегая к написанию кода.

В этой статье будет сделан краткий обзор системы объектов, сложившейся в Quake, и рассказано, на основе каких принципов она была спроектирована. С моей точки зрения особенно интересно, насколько сильно эта философия схожа с принципами, заложенными в основу UNIX. Оба решения можно резюмировать как системы, в каждой из которых есть одна базовая субстанция (в UNIX это файл) и язык, на котором можно описывать сочетание простых поведений, комбинирующихся в эмерджентном порядке (оболочка).

Читать далее

Странности в исключениях JVM с точки зрения декомпилятора

Reading time11 min
Views1.4K

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

На тот момент я полагала, что этот метод не составит труда расширить и на декомпиляцию потока управления, возникающего при обработке исключений — то есть, что ему будут поддаваться блоки try…catch. В ретроспективе признаю: следовало ожидать, что это будет не так просто. Оказывается, здесь возникает множество пограничных случаев, варьирующихся от странного поведения javac до последствий, отражающихся на самой структуре JVM и формате файлов классов. Всё это – серьёзные осложнения. В данном посте я разберу все эти детали, расскажу, почему простые решения не работают, и на каком подходе я в итоге остановилась.

Читать далее

В процессе обучения нейронных сетей получаются красивые фракталы

Reading time12 min
Views9.5K

Как-то раз моя пятилетняя дочка, вернувшись домой из детского садика, сообщила мне и моей жене, что математика — тупая штука (!). С тех пор мы не покладая рук работаем (пока что успешно), стараясь увлечь её всевозможными математическими интересностями, а теперь ещё и гордимся её успехами в математике. Одна из наших наиболее удачных находок привела к тому, что теперь дочь очень интересуется фракталами вообще. Особенно ей нравится смотреть видеоролики, где с увеличением показаны множества и оболочки Мандельброта, а вдобавок есть капусту романеско. Благодаря этому увлечению дочери, я стал больше задумываться о фракталах, а также о том, как они соотносятся с особенно волнующей меня темой — искусственными нейронными сетями.

Читать далее

Rust без паник: дельная техника для системного программирования

Reading time13 min
Views6.9K

Может ли Rust заменить C? Этот вопрос беспокоил меня много лет. Тем временем я успел написать upb — библиотеку C для работы с Protocol Buffers, и сейчас являюсь её техническим руководителем. Вполне понятно стремление обеспечить безопасность памяти в пределах всего программного стека — поэтому и возникла идея портировать upb на Rust.

Притом, что мне приятны базовые принципы Rust, я долгое время относился к этой идее скептически и сомневался, что, портировав upb на Rust, удастся сберечь её производительность и компактность кода, которые мы с коллегами так старались оптимизировать. На самом деле, исходно я собирался написать статью о том, почему именно применительно к upb языку Rust никогда не сравниться с C по производительности.

Но недавно я открыл для себя одну технику, которая заставила меня немного переосмыслить этот вопрос. Я назову её «Rust без паник». Притом, что этот метод определённо не нов, мне нигде не удалось найти подробного разбора, в котором бы рассказывалось, как именно этот метод используется и какие проблемы решает. Правда, интересная дискуссия по этому поводу велась в теме Enforcing no-std and no-panic during build, где есть ссылки на некоторые релевантные треды из почтовой рассылки, посвящённой разработке ядра Linux. Вот другой интересный тред: Negative view on Rust: panicking

Надеюсь, эта статья позволит заполнить данный пробел.

Читать далее

BERT — это всего лишь одноэтапная диффузия текста

Reading time9 min
Views2K

Некоторое время назад компания Google DeepMind представила Gemini Diffusion — экспериментальную языковую модель, генерирующую текст методом диффузии. В отличие от традиционных моделей, написанных в стиле GPT и генерирующих слово за словом,  Gemini создаёт текст целыми блоками, пошагово уточняя случайный шум.

Я прочитал статью «Large Language Diffusion Models» — и с удивлением узнал, что дискретная диффузия языка представляет собой просто обобщение метода генерации пропущенного токена (MLM), практикуемого уже с 2018 года. Я сразу подумал: «А можно ли тонко настроить BERT-подобную модель так, чтобы приспособить её к генерации текста?» Из чистого любопытства решил наскоро набросать проверку концепции.

Примечание: уже после того, как написал эту статью, я наткнулся на исследование DiffusionBERT, где сделано практически то же самое, что и у меня, но проект гораздо тщательнее протестирован. Посмотрите этот пост, если тема вас заинтересовала.

Читать далее

Что именно ИИ-чатботы делают «под капотом»

Reading time10 min
Views3.8K

Среди друзей я пользуюсь репутацией «ты ж программист», поэтому у меня нередко интересуются, как именно работают «под капотом» такие известные инструменты как ChatGPT, Claude, Grok или DeepSeek. Со временем я отточил ответ на этот вопрос — и потому, что нашёл способы лучше на него отвечать, и потому, что научился сам создавать большую языковую модель с нуля. Поэтому и сам понимать большие языковые модели я стал гораздо лучше.

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

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

Читать далее

Подробно о неопределённом поведении в С и C++

Reading time24 min
Views11K

При работе с C или C++ необходимо в какой-то степени разбираться в неопределённом поведении (UB): что это такое, каковы его эффекты, и как о него не споткнуться. Для простоты картины я буду в этой статье рассказывать только о C, но всё изложенное здесь также применимо и к C++, если явно не указано иное.

Читать далее

Собираем собственный ЦОД. 30 петабайт дискового пространства для предобучения моделей

Reading time15 min
Views4K

Как потратить почти полмиллиона долларов, чтобы собрать в центре Сан-Франциско хранилище данных объёмом 30 петабайт

Мы собрали в центре Сан-Франциско центр для хранения данных с общим дисковым пространством, где хранятся видеоданные общей длительностью 90 миллионов часов. Зачем? Мы предобучаем модели, чтобы разобраться с использованием компьютеров. Дело в том, что видео гораздо крупнее, чем текстовые данные. Например, на обучение такой текстовой БЯМ как LLaMa-405B требуется ~60 ТБ текстовых данных, а на хранение видео нужно в 500 раз больше текстового пространства. За хранение всей этой информации на серверах AWS пришлось бы выложить 12 миллионов долларов в год, поэтому мы пошли другим путём и арендовали пространство в колокационном центре в Сан-Франциско. Так нам удалось снизить эти расходы примерно в 40 раз (до $354 тысяч в год, считая издержки на устаревание).

Читать далее

Компенсация сетевой задержки: как зародилась технология rollback netcode

Reading time5 min
Views1.5K

Как сообщил мне GPT5, технология компенсации сетевой задержки в играх, также известная как «откат сетевого кода» (rollback netcode) впервые была применена в игре «Super Street Fighter II Turbo HD Remix» (2008). Но это не так: именно такой механизм я реализовал в «Pathway to Glory» (Nokia N-Gage, 2004) и «Warhammer 20K: Squad Command (PSP, NDS, 2007)». В этой статье кратко рассказано, как данная технология работает...

Читать далее

Хватит валидировать CLI — сначала лучше распарсите код как следует

Reading time7 min
Views2.5K

Есть за мной такой грешок: если какая-то проблема мне долго досаждает, я в конце концов пишу библиотеку, которая её решает. На сей раз такая история возникла с кодом для валидации CLI.

Смотрите, я немало времени уделяю чтению кода, который написали другие люди. Это код опенсорсных проектов, всякий материал по работе, а также код из случайных репозиториев с GitHub, на которые, бывает, наткнёшься в два часа ночи. Причём, я то и дело замечаю одну и ту же проблему: в любом инструменте CLI найдётся одинаковый уродливый валидационный код, запрятанный поглубже. Знаете, в таком роде:

Читать далее

DOOMQL: DOOM-подобный многопользовательский шутер на чистом SQL

Reading time10 min
Views21K

Недавно я набрёл на шедевр Патрика — клон DOOM, основанный на DuckDB-WASM и работающий в браузере. Прочитав о нём, я решил  довести  эту великолепную идею до логического завершения: написать многопользовательский DOOM-подобный шутер целиком на SQL. При этом всю тяжёлую работу хотел сделать через базу данных CedarDB. Отлучившись с работы в месячный отпуск по уходу за ребёнком (бессонных ночей хватало), я попытался сделать именно это.

Вот вам тизер DOOMQL:

Читать далее

Кубистая планета — делаем шарообразный мир в стиле Minecraft

Reading time18 min
Views14K

Вооружившись игровым движком Unity, я написал техническое демо, в котором пытаюсь наложить кубические воксели Minecraft на шарообразное тело (планету). Планета генерируется процедурно, и её можно полностью разрушить. Игроки могут расставлять или убирать разные блоки, которых насчитывается более 20 типов.

Да, во многом эта реализация базируется на обычных приёмах, которые могут быть знакомы вам из типичного кустарного клона Minecraft, но благодаря сферической структуре игрового мира возникает ряд уникальных аспектов, которые учитываются в строительстве. Основное внимание в этом посте будет уделено именно таким нетривиальным задачам.

Читать далее

Если ваш запрос на слияние сгенерирован ИИ, я его отклоню. Объясню, почему

Reading time5 min
Views21K

Иногда запрос на слияние (merge request) даже не стоит отправлять на код‑ревью, так как при его составлении кто‑то злоупотреблял искусственным интеллектом, и это повредило как проекту, так и команде. Например:

1. Удалив часть кода, можно значительно улучшить запрос на слияние.
2. Вы не знаете основ языка, на котором подавали запрос.
3. Спам в документации.
4. Вопиющая несогласованность материала.
5. Чрезмерно подробно рассмотрены пограничные случаи.
6. Вы добавили бессмысленные или нежелательные зависимости и сами не понимаете, зачем.

Если я прислал вам обратно ваш запрос на слияние с невычищенным ИИ и без всяких прочих комментариев — значит, какие‑то из этих пунктов вы выполнили.

Несмотря на свежие исследования и дискуссии на эту тему, мне известно, что ИИ действительно помогает писать код. Но злоупотребление ИИ — это новый феномен, и нам нужно чем‑то руководствоваться, чтобы выявлять такие случаи. Оригинал этой статьи написан в 2025 году, надеюсь, со временем улучшится ситуация как с инструментами, так и с регламентацией.

Читать далее

От математики к машине: преобразуем функцию в машинный код

Reading time15 min
Views3.7K

В этом посте будет исследовано, как математическую концепцию можно постепенно переформулировать во всё более «вычислительных» понятиях, от высокоуровневого языка, далее до машинного кода и, наконец, до прямого исполнения компьютером. Для этого определю одну и ту же логику в нескольких разных, но перекликающихся друг с другом форматах:

1. Математика — чистая математика
2. Haskell — язык для функционального программирования
3. C — язык для императивного программирования
4. Ассемблер — сравнительно удобочитаемое представление машинного кода
5. Машинный код для архитектуры x86-64 — вот это уже интересно

Если вам интересно, какие отличия бывают между языковыми стилями или любопытно, как ваш код может выглядеть после компиляции — добро пожаловать под кат!

Читать далее

Безопасная загрузка, TPM и античитерские движки

Reading time44 min
Views4.3K

В настоящее время от игроков, желающих участвовать в онлайновых многопользовательских сеансах, в античитерских движках обязательно требуется включить безопасную загрузку (Secure Boot) и встроенный доверенный платформенный модуль (fTPM). Удастся ли таким образом обуздать читеров, или же это бесплодная попытка купировать разрастающуюся проблему?

Читать далее

Визуализатор сборок в режиме реального времени

Reading time5 min
Views5.2K

Под катом – анимация, демонстрирующая сборку приложения для macOS в режиме реального времени:

Я расскажу, как она получилась, но для начала обрисую контекст этого проекта.

Компиляция конкретного софта может быть очень длительной просто потому, что в этой программе очень много кода — как, например, в проекте LLVM. Но бывает и так, что сборка идёт медленно по глупым и вполне устранимым причинам. Подозреваю, что большинство сборок просто тормозят из-за ерунды, но проверить это мне пока не удавалось. Поэтому я разработал кроссплатформенный инструмент для визуализации сборок (пока он существует в приватной бета-версии, ссылка в конце статьи). Он работает с любой системой сборки и с любым языком программирования (а не только C/C++/Rust).

Читать далее

Как правильно вызывать CUDA

Reading time16 min
Views6.9K

Вероятно, вам уже попадались подобные руководства по CUDA: хрестоматийный пример «Hello World», в котором перемешан код для ЦП и графического процессора. Всё это сложено в один гетерогенный файл с исходниками на CUDA C++, а для запуска ядра применяется синтаксис NVCC с тройными угловыми скобками <<<>>>, который уже стал культовым:

Читать далее

Протокол HTTP совсем не прост

Reading time7 min
Views14K

Часто доводится слышать, будто протокол HTTP прост. Естественно, чаще всего — от тех, кто не слишком поднаторел в обращении с ним и слабо представляет, как именно этот протокол реализован. Думаю, сам я тоже мыслил в таком ключе, когда ещё только начинал работать с HTTP.

К настоящему времени я уже без малого три десятка лет усердно пишу клиентский код, взаимодействующий с HTTP. Я участвую в работе IETF и приложил руку ко всем спецификациям HTTP, составленным примерно с 2008 года. Поэтому полагаю, что вполне имею право развёрнуто высказаться об этом протоколе. Протокол HTTP не прост. Далеко не прост. Даже если предположить, что те, кто отмечает его простоту, имеют в виду лишь HTTP/1.

Читать далее

Думай как компилятор: позиции и значения в Rust

Reading time10 min
Views3K

Некоторое время назад мне попался в Интернете вопрос о таком синтаксисе в Rust:

*pointer_of_some_kind = blah;

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

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

Читать далее

Программа «Hello World» на машинном коде под DOS

Reading time14 min
Views11K

Как-то раз я послушал следующее интересное выступление (по-немецки): ссылка

В нём разобрано, как написать программу «hello world» для 64-разрядного дистрибутива Linux в шестнадцатеричном редакторе. Ассемблер здесь не используется, программа пишется непосредственно на машинном коде. Правда, в ней есть издержки на использование ELF.

Мне понравилась такая идея, и я решил повторить такой опыт, но немного в иной форме — а именно под 16-разрядной DOS в реальном режиме. У меня должен был получиться файл в формате COM, а не EXE, так как (на данном этапе) меня интересовал не столько формат файла, сколько кодировка инструкций. В вышеупомянутой лекции, если честно, не сообщается почти никаких подробностей о том, как именно перейти от ассемблерного кода к машинному — поскольку в случае разбора этих тем лекция, пожалуй, растянулась бы на несколько часов. Но здесь я всё разберу подробно, и при этом собираюсь пользоваться только документацией lntel, а также дизассемблировать код в целях верификации.

Также мы коротко поговорим о сегментации.

В качестве шестнадцатеричного редактора на этот раз воспользуемся hexedit.

Читать далее
1
23 ...

Information

Rating
Does not participate
Registered
Activity