<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Alex Chernyshev</title><generator>teletype.in</generator><description><![CDATA[Очень давно в этом вашем ойти. Видел сеть до интернета, помню интернет без фейсбука.
До сих пор пишу код.
Telegram/VK/LinkedIn/Rutube/Дзен: alex0x08]]></description><image><url>https://img4.teletype.in/files/f2/49/f24940ec-9b03-411b-9a3d-8000564face0.gif</url><title>Alex Chernyshev</title><link>https://blog.0x08.ru/</link></image><link>https://blog.0x08.ru/?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/alex0x08?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/alex0x08?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Tue, 18 Aug 2026 11:03:40 GMT</pubDate><lastBuildDate>Tue, 18 Aug 2026 11:03:40 GMT</lastBuildDate><item><guid isPermaLink="true">https://blog.0x08.ru/commercial-articles-2026-details</guid><link>https://blog.0x08.ru/commercial-articles-2026-details?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/commercial-articles-2026-details?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>&quot;Порно для инженеров&quot; или как мы пишем статьи на заказ</title><pubDate>Sun, 05 Jul 2026 12:44:35 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/89/ba/89ba8afe-2f23-4a06-bf5a-35179cff36d2.png"></media:content><category>people</category><description><![CDATA[<img src="https://img2.teletype.in/files/17/77/1777d3b7-b9c4-4453-a4ad-da4e75df5026.jpeg"></img>Мы создаем «серьезно-развлекательные» статьи для взрослых, заинтересованных в ИТ-тематике — то самое «порно для инженеров»:]]></description><content:encoded><![CDATA[
  <figure id="vBs3" class="m_column">
    <img src="https://img2.teletype.in/files/17/77/1777d3b7-b9c4-4453-a4ad-da4e75df5026.jpeg" width="1000" />
  </figure>
  <h2 id="DCAE">Формат и аудитория</h2>
  <p id="WrUM">Мы создаем «серьезно-развлекательные» статьи для взрослых, заинтересованных в ИТ-тематике — то самое «порно для инженеров»:</p>
  <figure id="xNEO" class="m_original">
    <img src="https://img2.teletype.in/files/12/b2/12b2a028-248a-406d-a033-53bfe1084c4a.png" width="679" />
    <figcaption>Тут все ради чего мы и работаем, не покладая рук.</figcaption>
  </figure>
  <p id="6hnS">Стилистически это близко к первым выпускам знаменитого (ныне скатившегося) журнала «Хакер» и работам «известного гуманиста» Дани Шеповалова, если бы тот не забросил программирование сразу после ВУЗа и провел следующие 20 лет за серьезной разработкой ПО вместо бесконечных тусовок и ядерно-алкогольных трипов.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="hwEJ"><strong>Целевая аудитория</strong> — наши дорогие читатели в основной своей массе <em><a href="https://blog.0x08.ru/shine-and-poor-of-it" target="_blank">не имеют отношения к ИТ-индустрии</a></em>, ничего не понимают в разработке и компьютерах, зато очень хотят <s>подрочить</s> представлять себя крутыми профи, легко побеждающими все проблемы и сложности.</p>
  </section>
  <p id="F16B">Таким образом <strong>контент</strong>, который мы выдаем это современная вариация концепции «комикса про супергероев», в данном случае — супергероев от ИТ и программирования. Создаваемый с такой же несбыточной мечтой о равенстве и справедливости:</p>
  <blockquote id="U5eI">как Бетмен в комиксах валит бандитов без суда и следствия, поскольку суды и следствие не работают, так и автор валит оборзевшие компьютеры, заставляя их делать всякое.</blockquote>
  <p id="Z0hV">В наш цифровой век с тотальным контролем, платными подписками и оборзевшей электроникой, простому человеку только и остается читать наши супергеройские статьи, чтобы не расколотить зависший ноутбук об стену.</p>
  <p id="lzSn">Последняя надежда человечества под возрастающим гнетом машин.</p>
  <figure id="bXfn" class="m_column">
    <img src="https://img3.teletype.in/files/29/e9/29e939cb-a609-42f8-9c4d-91c84e046555.jpeg" width="780" />
    <figcaption>Автор в воображении наших любимых читателей.</figcaption>
  </figure>
  <p id="LbbS">Именно для таких супергеройских целей в наших статьях используются <a href="https://blog.0x08.ru/netbsd-nvidia-optimus" target="_blank">редкие</a> и <a href="https://blog.0x08.ru/marktext-on-freebsd" target="_blank">нестандарные операционные системы</a>, <a href="https://blog.0x08.ru/digital-mars-cpp-on-dos" target="_blank">винтажное железо</a>, <a href="https://blog.0x08.ru/chrome-xfce-very-scary-movie" target="_blank">кастомное графическое окружение</a>, <a href="https://blog.0x08.ru/parse-json-xml-on-pure-asm" target="_blank">изощренные средства разработки</a> и прочие инженерные изыски — чтобы читатель словил кайф, сопоставимый с просмотром хорошего <s>порно</s> боевика.</p>
  <p id="e6Gk">В качестве героев статей — как главного, так и приглашенных выступают <strong>взрослые</strong>, опытные инженеры с большой практикой, которые не лажают, не теряются и не дрожат от страха при встрече с неведомым и электронным, а сразу кидаются «с шашкой в бой», решая сложную проблему бодрым кавалерийским наскоком. </p>
  <p id="M5b4">Хотя-бы в теории и в масштабах статьи.</p>
  <p id="n0Bb">Мы не пытаемся косить под подростков и говорить с молодежью «на ты», не пытаемся выдерживать алкогольно-хулиганский стиль почившего ныне Udaff.com и уж точно не пишем корпоративным канцеляритом — как в ТЗ по 44ФЗ на разработку ПО.</p>
  <p id="fK6w">Наш стиль это Боярский, Высоцкий и <s>Жириновский</s> Маяковский из параллельной вселенной, где вместо песен и прозы эти замечательные люди занимались бы пару десятков лет программированием.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Tq74">«Тысяча чертей и Segmentation Fault», «Как мы пустили по кругу мейнфрейм IBM», «Компилятор Watcom и 100 дней содома» — вот наш незабываемый стиль. </p>
  </section>
  <p id="wLIt">Но разумеется накал выдаваемой дичи регулируемый и у вас будет возможность «пощелкать тумблерами».</p>
  <figure id="4UxW" class="m_column">
    <img src="https://img4.teletype.in/files/38/43/384305b1-cee3-479d-b795-5e912e0e3b50.jpeg" width="1024" />
    <figcaption>Рабочая станция DEC и грубые мужские ласки, 1982 год.</figcaption>
  </figure>
  <h2 id="1ZMe">Рамки и ограничения</h2>
  <p id="TaRS">Мы вполне неплохо владеем родным языком и навыками письма, с чего получается выражать мысли без использования нецензурной лексики и откровенно желтушных заголовков.</p>
  <blockquote id="mhED">Но если ситуация позволяет, редактор одобряет, а душа требует — можем и главное <strong>умеем</strong> вставить в нужном месте нехорошее слово. </blockquote>
  <p id="dakV">Так чтоб #бнуло.</p>
  <p id="xBGh">Будучи достойными <a href="https://blog.0x08.ru/house-chernyshevs" target="_blank">последователями</a> гусарских традиций, мы <strong>не жалуемся</strong> в своих статьях и не опускаемся до прямых угроз, жалоб и оскорблений. Поскольку до прямого столкновения <a href="https://blog.0x08.ru/how-to-kick-ass" target="_blank">все равно не дойдет</a>.</p>
  <p id="9HZ9">Еще мы не пишем про <s>гео</s>политику, экономику, не даем прогнозов и вообще стараемся не выходить за рамки развлекательного <s>прона</s> чтива для инженеров.</p>
  <p id="a0Xt">Ну и разумеется, мы всячески любим прекрасный пол и не опускаемся до оскорбления женщин. Так что все истории про «инцелов», «куколдов» и прочих персонажей современного межполового фольклора — строго <s>нах#й</s> мимо.</p>
  <h3 id="eba2">Авторские права </h3>
  <p id="GetJ">Мы можем передать как все права на создаваемый контент, так и ограничиться правами на публикацию. Во втором случае будет <strong>необходимо</strong> сохранить ссылку на автора при публикации на любых ресурсах, зато в первом можно договориться о чем угодно, вплоть до «white label» — полном обезличивании материала.</p>
  <p id="rRno">Разумеется первый вариант будет существенно дороже.</p>
  <h3 id="Q4DO">Paywall и платный доступ</h3>
  <p id="VKsH">Наш контент создается в первую очередь для <strong>развлечения</strong> широкой аудитории и не преследует каких-то серьезных образовательных целей. </p>
  <blockquote id="NATF">Так что практический смысл сокрытия его под paywall ради платного доступа — под большим вопросом.</blockquote>
  <p id="Ofio">Нам самим интересно ровно обратное: чтобы контент лайкали, на него ссылались, пересылали друг другу и всячески копировали, увеличивая аудиторию.</p>
  <p id="0xln">Поэтому хотя мы и сможем договориться о создании контента, который в последствии будет закрыт «платной стеной» — подобное не одобряем и в такие порочные практики не верим.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="IL3i">Не приучен отечественный пользователь платить за контент.</p>
  </section>
  <p id="742L"></p>
  <h2 id="9yZB">Варианты статей</h2>
  <p id="99el">На данный момент существует два основных варианта заказной статьи:  </p>
  <ul id="c1fO">
    <li id="BOBF">классическое «инженерное порно», создаваемое и публикуемое со спонсорской поддержкой; </li>
    <li id="Hjbs">полностью рекламная статья, создаваемая в нашем незабываемом стиле для продвижения вашей компании или сервиса.</li>
  </ul>
  <p id="DrrT">Оба варианта неплохо дополняют друг друга и запросто превращаются в сериал — серию статей, с предсказуемой выдачей уникального контента за означенный период.</p>
  <h3 id="deOS">Вариант 1. Золотая классика</h3>
  <p id="PU3I">В этом варианте мы просто продаем вам готовую статью и помогаем с публикацией и анонсами в соцсетях (см. ниже), допускаются минимальные стилистические правки, но как тема так и формат <strong>выбирается нами.</strong></p>
  <p id="DLaa">Такие статьи создаются непрерывно согласно годовому плану, затем по мере готовности продаются заказчикам.</p>
  <p id="R1js">Классический пример такой статьи из недавних: <a href="https://habr.com/ru/companies/timeweb/articles/1035184/" target="_blank">Интересные развлечения со змеей</a>.</p>
  <h3 id="Hv06">Вариант 2. Чисто рекламная история</h3>
  <p id="PpLx">Это уже следующий уровень, который открывается не всем  — есть ограничения по темам, по формату, по продвигаемому бизнесу или сервису. Чтобы не тратить ни ваше ни наше время, заранее описываем что будет работать а что <strong>точно нет</strong> в нашем коммерческом исполнении.</p>
  <p id="BSq9"><strong>Что не работает</strong></p>
  <p id="bQSf">Любые темы, связанные с ИИ, криптой, обменниками, казино, онлайн-курсами про «успешный успех», психологией и политикой — все это с нашей помощью продвигать не получится.</p>
  <p id="Rtb5">Да, пробовали, нет не работает.</p>
  <p id="Jx9b"><strong>Что работает</strong></p>
  <p id="RQfW">Классическая серьезная наука, промышленность, история ИТ, официальные учебные заведения — с радостью расскажем читателям о, например, реальных научных разработках, обучении студентов программированию <strong>в реальном ВУЗе</strong>, не на онлайн-курсах.</p>
  <p id="TiUv">Отлично зайдет история с хостингом, с серверами и сетевым оборудованием, с интернет-магазином электроники, с какими-то собственными разработками в сфере электроники и ПО. </p>
  <p id="lhSH">К сожалению в 21 веке уже не прокатит простая рекламная статья, не прокатит и сложная — с нативной интеграцией, «темными паттернами» и прочей психологической магией.</p>
  <p id="I4y4">Поэтому мы делаем аккуратно, но «в лоб»:</p>
  <ul id="0ZNh">
    <li id="L5d9">не скрываем, что статья коммерческая и создана для продвижения конкретной компании, сервиса или услуги;</li>
    <li id="Aq05">обязательно даем конкретику — в статье будет конкретный кейс использования сервиса, возможно какая-то история, но четкая и конкретная.</li>
  </ul>
  <p id="OjKj">Хороший пример из недавних:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="lUwj">для компании, оказывающей услуги хостинга, мы создали серию статей, где рассказали и показали как развернуть типовые приложения и сервисы, используемые в современной разработке.</p>
  </section>
  <p id="lNdX">В итоге читатель смог увидеть в действии инструменты хостинга, оценил процесс настройки и использования оказываемой услуги для конкретной задачи. Ну и заодно <s>подрочил</s> насладился интересным контентом.</p>
  <p id="Lert">Такой подход дает серьезный положительный эффект, поскольку мы общаемся <strong>со взрослыми людьми на взрослом языке</strong> — в результате нет выраженного негатива от явно коммерческого материала.</p>
  <p id="X6ST"></p>
  <figure id="HoTI" class="m_original">
    <img src="https://img3.teletype.in/files/6b/74/6b74f707-f8d0-4667-8a56-8ccc6fb7bfb9.jpeg" width="540" />
    <figcaption>Как-то так выглядит процесс написания наших статей (нет).</figcaption>
  </figure>
  <h2 id="y2P0">Процесс</h2>
  <p id="0D3P">Опустим историю с процессом создания наших нетленок для <s>рукоблудия</s> инженеров — если узнаете <strong>каких</strong> сил и времени стоило создание чего-то <a href="https://habr.com/ru/articles/1008734/" target="_blank">такого</a>, вам станет грустно и печально. Что плохо скажется на вашем настроении и наших продажах.</p>
  <p id="tVG0">Поэтому расскажем лучше про более актуальный процесс создания коммерческой статьи. Сразу замечу, что любые работы начинаются только <strong>после</strong> подписания договора и получения гонорара (см. ниже).</p>
  <p id="RHw2">1. Мы создаем под вас уникальную историю на основе продвигаемого сервиса, товара или услуги, так чтобы не оттолкнуть читателей вульгарной «джинсой», но при этом раскрыть возможности продукта.</p>
  <p id="XYMr">2. Создаем план статьи, в котором будет видна примерная структура и общий сюжет. План разумеется согласовываем с вами.</p>
  <p id="qnqL">3. Собираем материал: фактуру, скриншоты, настройки и т.д. </p>
  <p id="nBiq">4. Пишем саму статью, по готовности выдаем черновик, доступный по ссылке для просмотра только вам. Если есть правки, ошибки в терминологии или что-то получилось слишком жестко — смягчаем и дорабатываем. Финальную версию разумеется согласовываем с вами.</p>
  <p id="GyLY">5. Передаем вам финальную версию в формате <a href="https://ru.wikipedia.org/wiki/Markdown" target="_blank">Markdown</a>, опционально помогаем с публикацией в соцсетях.</p>
  <p id="i6Ti">6. Переходим к пункту 1. (шутка)</p>
  <p id="a8TR">Первая статья для нового заказчика от момента обращения до публикации занимает ориентировочно <strong>1 месяц.</strong> Если запускается серия — каждая следующая статья готовится проще и быстрее чем предыдущая, поэтому мы вполне можем выдерживать двухнедельные дедлайны.</p>
  <p id="xVDk">Но повторюсь, что все это касается <strong>коммерческих статей</strong>, сколько времени уходит на подготовку наших «инженерно-порнографических» шедевров вам лучше не знать.</p>
  <figure id="mfRi" class="m_column">
    <img src="https://img1.teletype.in/files/45/69/4569b09a-fbea-4265-8287-954453d659bb.jpeg" width="1024" />
    <figcaption>На что именно идут ваши деньги. (нет)</figcaption>
  </figure>
  <h2 id="f5RZ">Договор и оплата</h2>
  <p id="71LL">Работа по созданию статей осуществляется согласно договору, чаще всего это будет договор ГПХ. </p>
  <blockquote id="fuuX">У нас есть готовые шаблоны договоров и большой опыт их применения, поэтому сможем ответить на все вопросы по НДС, НДФЛ и закрывающим документам — все покажем, расскажем <s>споем и спляшем</s>.</blockquote>
  <p id="qQoE">Ввиду сложной оперативной обстановки, наличия огромного количества проблем и непредсказуемых событий вокруг, мы работаем только и исключительно <strong>при 100% предоплате</strong>. </p>
  <p id="7n9G">Конкретная стоимость статьи будет озвучена в день обращения и будет зависеть от текущих реалий: </p>
  <blockquote id="8AbW">курса доллара, % инфляции, <s>продвижения наших войск</s>, твиттера Трампа и всех прочих событий в мире, влияющих на наши расходы и светлое будущее.</blockquote>
  <p id="qrTp">По-другому увы, никак.</p>
  <p id="eSk8">Работа над статьей начинается в момент получения гонорара, ровно в тот день и час когда на наш счет поступают ваши деньги. Не при подписании договора и не на этапе согласования, только в тот момент когда приходит оплата.</p>
  <p id="0RAB"><code>Нет оплаты — нет работы (ц) Сократ.</code></p>
  <p id="xz0x">Счета блокируют, переводы морозят, заказчики морозятся, представители заказчиков отмораживаются и все дружно ждут перемен и наступления светлого завтра. </p>
  <p id="n8G2">А у нас от этого <s>несварение</s> кассовые разрывы.</p>
  <p id="0ljc"></p>
  <figure id="ncf3" class="m_column">
    <img src="https://img3.teletype.in/files/67/c1/67c1a52a-94d9-4965-aca2-8d715f77cacf.png" width="1024" />
  </figure>
  <h2 id="AYQY">Публикация в соцсетях</h2>
  <p id="FCgj">По согласованию с вами, мы можем сделать публикацию в соцсетях от наших профилей, так и просто передать готовый материал вам, для последующей публикации собственными силами.</p>
  <p id="1iGf">Можно комбинировать оба варианта, можно публиковать у вас в корпоративном блоге, затем давать анонс со ссылками на наших площадках — вариантов масса и все интересные. </p>
  <h3 id="cwm5">Наши каналы</h3>
  <p id="1qhD">Полный список наших каналов:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="wIBG">Блог: <a href="https://blog.0x08.ru/" target="_blank">https://blog.0x08.ru/</a></p>
  </section>
  <p id="wNxT">Основной ресурс для публикации наших статей, отсюда они расползаются по интернету.  </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="EF7w">Хабр: <a href="https://habr.com/ru/users/alex0x08/articles/" target="_blank">https://habr.com/ru/users/alex0x08/articles/</a></p>
  </section>
  <p id="dI84">Ключевой ресурс для отечественных айтишников, практически все наши статьи публикуются тут. </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="SJF9">Телеграм: <a href="https://t.me/alex0x09" target="_blank">https://t.me/alex0x09</a></p>
  </section>
  <p id="YQPH">Используется для анонсов, бекстейджа и общения с аудиторией. Содержит дополнительные материалы.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="92O6">Яндекс.Дзен: <a href="https://dzen.ru/alex0x08" target="_blank">https://dzen.ru/alex0x08</a></p>
  </section>
  <p id="Dvt4">Дублируем тут наши статьи ввиду переодических блокировок платформы Teletype, на которой работает блог.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Z1cm">Пикабу: <a href="https://pikabu.ru/@alex0x08" target="_blank">https://pikabu.ru/@alex0x08</a></p>
  </section>
  <p id="zCdh">Дублируем наши статьи на этой площадке, ввиду большой аудитории. Ныне это вторая после Хабра площадка для публикаций.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="IEzB">LinkedIn: <a href="https://www.linkedin.com/in/alex0x08/" target="_blank">https://www.linkedin.com/in/alex0x08/</a></p>
  </section>
  <p id="79OJ">Публикуем только анонсы новых материалов. По согласованию с вами, поскольку ресурс под санкциями.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Co2V">Сетка: <a href="https://setka.ru/users/07dbf4f2-49e4-48d4-84a6-44f048e05137" target="_blank">https://setka.ru/users/07dbf4f2-49e4-48d4-84a6-44f048e05137</a></p>
  </section>
  <p id="GVfU">Только анонсы новых материалов.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="GkHQ">VC: <a href="https://vc.ru/id512727" target="_blank">https://vc.ru/id512727</a></p>
  </section>
  <p id="9i6T">Только анонсы новых материалов.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="suic">VK: <a href="https://vk.com/alex0x08" target="_blank">https://vk.com/alex0x08</a></p>
  </section>
  <p id="xqv3">Только анонсы новых материалов.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="ob7X">Instagram:  <a href="https://www.instagram.com/alex0x08/" target="_blank">https://www.instagram.com/alex0x08/</a></p>
  </section>
  <p id="cYEF">Публикуем только анонсы новых материалов. По согласованию с вами, поскольку ресурс под санкциями.</p>
  <p id="fRmZ">Во всех случаях необходимо <strong>соблюдать правила</strong> каждой конкретной платформы а также <strong>адаптировать материал</strong> под каждую из платформ.</p>
  <p id="kqao">В случае стандартного пути и публикации в наших профилях — вся эта сложная и нудная работа делается нашими силами и бесплатно, но если мы только передаем готовую статью вам — решение возникающих проблем с публикацией остается на вашей стороне.</p>
  <h3 id="WUub">Бекстейдж</h3>
  <p id="KvNe">В случае стандартного пути, во время работы над статьей мы делаем несколько постов в нашем Telegram-канале с бекстейджем — демонстрацией процесса работы над статьей, в качестве промо-материалов для нагнетания интереса к будущему шедевру:</p>
  <figure id="ll3E" class="m_original">
    <img src="https://img4.teletype.in/files/3d/40/3d406cea-aa12-4534-98fb-3b26bfe460e0.png" width="450" />
  </figure>
  <h3 id="GDR6">Публикация</h3>
  <p id="ODL6">У разных площадок разные пиковые часы и правила набора популярности, но чаще всего публикация наших статей происходит в выходные дни, либо утром понедельника. </p>
  <blockquote id="wHpA">Хотя лояльность нашей аудитории позволяет набирать заметные охваты при публикации <strong>в любой день недели</strong>, ввиду производственного графика нам проще привязываться к началу рабочей недели в качестве даты публикации.</blockquote>
  <p id="YDNc">Текст статьи обычно вносится заранее в черновики на площадке, затем выставляется таймер отложенной публикации.</p>
  <figure id="fJi7" class="m_original">
    <img src="https://img4.teletype.in/files/f6/dd/f6dd778b-5205-4889-a986-4040bad9e56c.png" width="1367" />
    <figcaption>Так выглядит опубликованная статья в корпоративном блоге заказчика.</figcaption>
  </figure>
  <p id="M6gS">После публикации мы делаем анонс статьи в нашем канале, с указанием всех ссылок:</p>
  <figure id="xahf" class="m_original">
    <img src="https://img1.teletype.in/files/06/d6/06d61a85-3be9-4c4a-8e38-f7abc717ac4e.png" width="482" />
  </figure>
  <p id="gG2D">Такой же анонс делается и в остальных наших соцсетях, с учетом ваших пожеланий по степени запрещенности. При желании и/или необходимости, текст и время публикации анонса также согласовывается с вами. </p>
  <p id="2V54">При публикации коммерческой статьи в наших соцсетях (по согласованию), обязательно вставляется плашка спонсора, со ссылками:</p>
  <figure id="C4Wh" class="m_original">
    <img src="https://img1.teletype.in/files/09/4f/094f1b4c-61e7-4c99-83c6-00045fe13102.png" width="764" />
  </figure>
  <p id="BaZP"></p>
  <figure id="Ax1r" class="m_column">
    <img src="https://img1.teletype.in/files/48/01/4801544d-eec2-4981-bca6-384ddbe49776.png" width="1024" />
    <figcaption>Единственный работающий вид ИИ-контента.</figcaption>
  </figure>
  <h2 id="xOXw">Продвижение ИИ </h2>
  <p id="eQ9E">Ввиду непрерывного потока вопросов и предложений, касающихся продвижения генеративного ИИ, ИИ-агентов, сервисов на базе ИИ и всего прочего подобного, стоит объяснить почему <strong>мы таким не занимаемся</strong>.</p>
  <p id="AwuC">Повсеместное внедрение ИИ идет с очевидными перегибами:</p>
  <blockquote id="xOEJ">под непрерывным потоком рекламных статей о превосходстве искусственного над естественным, компании не менее непрерывно сокращают живой персонал. </blockquote>
  <p id="wwcW">Хотя сокращения происходят в первую очередь из-за <em>экономических</em> причин и глобальных мировых событий, широкой аудитории и инвесторам это подается как «оптимизация из-за внедрения ИИ».</p>
  <p id="sLEm">С чего простой народ звереет и «всех этих ИИ и роботов» откровенно ненавидит:</p>
  <figure id="X4c7" class="m_column">
    <img src="https://img1.teletype.in/files/00/10/00107ef4-fb87-41be-bc52-2896ed50f7f1.png" width="783" />
    <figcaption>Обратите внимание на количество лайков.</figcaption>
  </figure>
  <p id="xHvl">Переломить эту ситуацию с позиции автора <strong>не получится</strong> ни за какие выделяемые бюджеты:</p>
  <blockquote id="wQlE">не будет простой курьер, студент или работник охраны — коих большинство среди наших читателей, лениво листающий <s>Двач</s> Хабр после смены, восторгаться и лайкать ИИ, который «отбирает его работу».</blockquote>
  <p id="f9Vk">Да, мы пробовали.</p>
  <p id="2u2R">Поэтому вне зависимости от ваших бюджетов, рекламировать с нашей помощью что-либо связанное с ИИ не выйдет.</p>
  <p id="gUjt">Повторюсь:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="95WW">мы не являемся «ненавистниками ИИ» или «отрицателями прогресса», «не застряли в 90х» и не «не умеем этим пользоваться».</p>
  </section>
  <p id="Do8p">Просто есть определенные реалии и сложившаяся аудитория, которая не принимает такой контент, даже <a href="https://habr.com/ru/articles/889126/" target="_blank">написанный в нашем незабываемом стиле</a>.</p>
  <p id="W4Hf"> </p>
  <figure id="PRxz" class="m_column">
    <img src="https://img4.teletype.in/files/bf/f9/bff95509-71db-4fee-97a7-f09e13c9a1d0.jpeg" width="1376" />
    <figcaption>Смешно и задорно. И главное очевидно что использовался ИИ.</figcaption>
  </figure>
  <h2 id="IKzt">ИИ и контент</h2>
  <p id="TwVn">Несмотря на острое желание, наличие опыта и даже талантов — мы <strong>не используем ИИ</strong> при написании текстов. По одной простой, но очень веской причине:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="ya4Q"><strong>малейший намек</strong> на искусственность текста создает эффект «<a href="https://ru.wikipedia.org/wiki/%D0%97%D0%BB%D0%BE%D0%B2%D0%B5%D1%89%D0%B0%D1%8F_%D0%B4%D0%BE%D0%BB%D0%B8%D0%BD%D0%B0" target="_blank">зловещей долины</a>» и человек немедленно закрывает статью.</p>
  </section>
  <p id="3gvc">Нет, мы не знаем как это работает, но оно <strong>работает</strong>, надежно охраняя наше светлое авторское будущее и гонорары от нашествия роботов.</p>
  <p id="8IdW">Повторюсь:</p>
  <blockquote id="LxO0"><em>малейший признак</em>, речевой оборот или характерная для ИИ фраза в тексте и все летит в печь, а статья (вместе с автором) собирает негатив.</blockquote>
  <p id="NIIy">Единственный тип ИИ-контента, который отлично работает для массовой аудитории это смешные картиночки:</p>
  <figure id="7OXw" class="m_column">
    <img src="https://img2.teletype.in/files/9c/f6/9cf6e90d-9c27-4790-bceb-ddd3956b4be7.png" width="1280" />
  </figure>
  <p id="iQJC">Такой искусственный контент <strong>интересен</strong> своей абсурдностью и невозможностью показанной ситуации, вроде сцены из Форреста Гампа выше, где вместо главного героя на лавочке сидит Тони Сопрано с диснеевской принцессой.</p>
  <blockquote id="wfj7">Примерно на такой же идеи абсурда, возведенного в абсолют выезжает известный мультсериал «South Park».</blockquote>
  <p id="UqaI">Эти самые «боевые картиночки» мы ставим в качестве обоев, когда делаем иллюстрации к нашим статьям:</p>
  <figure id="9dnM" class="m_column">
    <img src="https://img2.teletype.in/files/53/6b/536bf391-cac2-4d70-b2e4-ef5e5eaf857c.gif" width="800" />
  </figure>
  <p id="QTyN">Таким образом, <strong>абсолютно весь</strong> текстовый и примерно 90% графического контента являются нашим собственным <em>уникальным контентом</em>, создаваемым вручную и специально для статьи.</p>
  <p id="uE02">Оставшиеся 10% приходятся (чаще всего) на фото известных персонажей или исторические хроники.</p>
  <p id="z0Wj"></p>
  <h2 id="nNU5">Цифры, отзывы и охваты</h2>
  <p id="HjaI">Самое важное, ключевое и главное: </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="iYoE">наши читатели нас сильно любят и ценят.</p>
  </section>
  <p id="62g6">Что выражается в невероятно малом количестве <strong>негатива</strong> и выражаемой ненависти под публикуемым контентом, только взгляните:</p>
  <figure id="qcuo" class="m_original">
    <img src="https://img1.teletype.in/files/c1/6f/c16fe21d-33b5-4691-b161-d850591cfa8c.png" width="555" />
    <figcaption><a href="https://habr.com/ru/companies/timeweb/articles/1035184/" target="_blank">Статья про Петон</a> на Хабре.</figcaption>
  </figure>
  <p id="2skU">Или другой пример:</p>
  <figure id="QPyh" class="m_original">
    <img src="https://img1.teletype.in/files/01/55/0155735a-14fe-472a-9961-803079d861bb.png" width="401" />
    <figcaption><a href="https://habr.com/ru/companies/timeweb/articles/1025590/" target="_blank">Статья про демосцену</a> на Хабре</figcaption>
  </figure>
  <p id="obmj">А ведь это <strong>тот самый</strong> Хабр, который славится своей злобностью токсичностью, где заказные статьи легко улетают в бан, где сливают карму и очень хорошо умеют в качественный троллинг.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="jdbx">Но по каким-то причинам наш контент там любят и ценят.</p>
  </section>
  <p id="DxM1">Хотя Хабр — не единственный пример площадки, где широкая аудитория по достоинству оценила наши работы, взгляните:</p>
  <figure id="56i5" class="m_original">
    <img src="https://img3.teletype.in/files/6b/cd/6bcd8832-7730-4fd2-8be7-09ec53107d3d.png" width="826" />
  </figure>
  <p id="XJNL">Почти <strong>300</strong> лайков на сугубо развлекательном портале «Пикабу» за <a href="https://pikabu.ru/story/cray_ozhivlenie_legendyi_14053753" target="_blank">серьезную статью про суперкомпьютеры Cray</a>, где типичный контент это обычно про пердеж и котиков..</p>
  <p id="4XHi">Помимо народной любви, наш контент отличает стабильность охватов:</p>
  <blockquote id="WWe2">практически каждая публикуемая статья <strong>набирает 10к</strong> и выше уникальных просмотров, как на Хабре так и на Пикабу.</blockquote>
  <p id="FZvT">Отдельные <a href="https://pikabu.ru/story/l9ec_volshebnyiy_patch_yadra_linux_14120415" target="_blank">шедевры</a> улетают сильно дальше:</p>
  <figure id="u58t" class="m_original">
    <img src="https://img1.teletype.in/files/05/30/05302d43-dd60-4dc1-8b1d-af29dead90bd.png" width="808" />
  </figure>
  <p id="ebFn">Практически под каждой статьей есть комментарии и активная дискуссия.</p>
  <p id="RbPo">Нас <a href="https://pikabu.ru/reply-stories/14053603" target="_blank">цитируют</a>:</p>
  <figure id="A2Ld" class="m_original">
    <img src="https://img2.teletype.in/files/18/ee/18eeac9e-8d79-4333-8752-707a407e4cf2.png" width="833" />
  </figure>
  <p id="MEyN">На нас ссылаются:</p>
  <figure id="LfQa" class="m_original">
    <img src="https://img2.teletype.in/files/92/44/9244ac1c-6997-4db4-ab1c-6d4507e24155.png" width="764" />
  </figure>
  <p id="T4Jw">И конечно практически все наши статьи, публикуемые на Хабре активно копируют на свои ресурсы различные фанаты, что суммарно дает аудиторию, сопоставимую со всей ИТ-индустрией в РФ.</p>
  <p id="uexI">Вливайтесь.</p>
  <p id="4TSr"></p>
  <p id="NZSI">Контакты автора не изменились:</p>
  <pre id="SSOr">ТГ/VK/Хабр/Пикабу/Дзен/LinkedIn/Youtube:  alex0x08 
Почта: alex3.145@gmail.com
MAX: +7 903 182 65 71</pre>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/watcom-hardcore-story-2026</guid><link>https://blog.0x08.ru/watcom-hardcore-story-2026?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/watcom-hardcore-story-2026?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>Легенда о хардкоре: Duke Nukem 3D, Watcom и FreeBSD</title><pubDate>Thu, 25 Jun 2026 16:59:24 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/08/81/08811c76-8d16-4a63-8dc6-92760ee9a72a.png"></media:content><category>experiments</category><description><![CDATA[<img src="https://img3.teletype.in/files/ab/bd/abbdfd65-eeef-43ad-858d-5dfdbdaff02f.gif"></img>Как утверждают психологи «все проблемы человека происходят из детства» — все что «недодали» родители в юном возрасте потом обязательно проявит себя во взрослой жизни.]]></description><content:encoded><![CDATA[
  <p id="OTQ0">Как утверждают психологи «все проблемы человека происходят из детства» — все что не дали родители в юном возрасте потом обязательно проявит себя во взрослой жизни.</p>
  <p id="bora">В моем, весьма специфическом случае такой нереализованной мечтой детства долгое время оставался.. <a href="https://en.wikipedia.org/wiki/Watcom_C/C%252B%252B" target="_blank">компилятор Watcom</a>, дорваться до которого удалось лишь спустя почти тридцать лет.</p>
  <p id="Gg2f">Рассказываю об этом удивительном проекте.</p>
  <figure id="pwXj" class="m_column">
    <img src="https://img3.teletype.in/files/ab/bd/abbdfd65-eeef-43ad-858d-5dfdbdaff02f.gif" width="800" />
    <figcaption>Сборка и запуск Duke Nukem 3D в самом неожиданном месте.</figcaption>
  </figure>
  <h2 id="w7To">Детская травма</h2>
  <p id="ZsTa">Хотя я уже неоднократно и красочно описывал <a href="https://habr.com/ru/articles/972622/" target="_blank">разные</a> <a href="https://habr.com/ru/articles/938120/" target="_blank">интересные</a> <a href="https://habr.com/ru/articles/1009104/" target="_blank">компиляторы</a> далекого (и не очень) прошлого, история с <a href="https://en.wikipedia.org/wiki/Watcom_C/C%252B%252B" target="_blank">Watcom C/C++</a> отличается:</p>
  <blockquote id="AsKh">о его существовании я узнал будучи еще совсем подростком.</blockquote>
  <p id="u0z4">Но поскольку жил тогда сильно далеко от столиц — найти такое чудо на местных <s>BBS</s> развалах CD-дисков было проблематично. </p>
  <p id="lg9Q">А когда заветные диски все же удалось раздобыть, возникла куда большая проблема — как в <strong>этом</strong> всем разобраться, в 16-то лет:</p>
  <figure id="0qtG" class="m_original">
    <img src="https://img2.teletype.in/files/dd/0d/dd0d81f2-88ac-4a3b-903d-c4e40e2d7bfe.png" width="640" />
    <figcaption>Так выглядела среда разработки <a href="https://winworldpc.com/product/watcom-c-c/110b" target="_blank">Watcom C/C++ 11</a>, 1995 год.</figcaption>
  </figure>
  <p id="0Gsl">Увы, но чуда тогда не случилось, <s>Цукерберг так и не позвонил</s> и моя карьера программиста ушла в сторону Java и серверов приложений, вместо нативной разработки на C++. Ну, а продукт от Watcom постепенно терял свои лидерские позиции среди инструментов разработки и уже к началу 2000х полностью пропал из актуальной повестки.</p>
  <p id="DU6I">Наверное теперь вы задаетесь вопросом: </p>
  <blockquote id="wNIM">откуда подросток из глухих сибирских краев вообще мог узнать о столь специфичной вещи, чтобы потом ее целенаправленно искать?</blockquote>
  <p id="9Te3">Все довольно просто и даже очевидно:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="0v1T">In the mid-1990s some of the most technically ambitious <a href="https://en.wikipedia.org/wiki/DOS" target="_blank">DOS</a> <a href="https://en.wikipedia.org/wiki/Computer_game" target="_blank">computer games</a> such as <em><a href="https://en.wikipedia.org/wiki/Doom_(1993_video_game)" target="_blank">Doom</a></em>,<em><a href="https://en.wikipedia.org/wiki/Descent_(video_game)" target="_blank">Descent</a></em>,<em><a href="https://en.wikipedia.org/wiki/Duke_Nukem_3D" target="_blank">Duke Nukem 3D</a></em>, <em><a href="https://en.wikipedia.org/wiki/Rise_of_the_Triad" target="_blank">Rise of the Triad</a></em>, and <a href="https://en.wikipedia.org/wiki/Tomb_Raider_(1996_video_game)" target="_blank">Tomb Raider</a> were built using Watcom C/C++ using the <a href="https://en.wikipedia.org/wiki/DOS/4GW" target="_blank">DOS/4GW</a> <a href="https://en.wikipedia.org/wiki/Protected_mode" target="_blank">protected mode</a> extender with the Watcom compiler.</p>
  </section>
  <p id="WKsc">Да да, те самые «компьютерные игоры», увлечение которыми в моем случае пошло сильно не туда — вместо того чтобы в них играть <s>и деградировать</s>, я начал их препари.. разбирать на части, в попытках понять как же оно устроено.</p>
  <p id="YyVW">Знаменитый <a href="https://en.wikipedia.org/wiki/DOS/4G" target="_blank">DOS/4GW</a> фигурировал в описании системных требований почти каждой компьютерной игры тех лет, а слово «Watcom» быстро нашлось при визуальном осмотре EXE-файла, из которого запускалась одна из самых любимых игр:</p>
  <figure id="KSGt" class="m_column">
    <img src="https://img1.teletype.in/files/cc/52/cc520ef8-abfe-42d0-bf1a-d4505f938986.png" width="763" />
    <figcaption>В EXE-файле известного Duke Nukem 3D.</figcaption>
  </figure>
  <p id="PmkI">Так я узнал, что на свете существуют компиляторы <a href="https://en.wikipedia.org/wiki/Watcom_C/C%252B%252B" target="_blank">Watcom</a>.</p>
  <h2 id="M4Cy">Легендарная мощь</h2>
  <p id="8nX4">Теперь серьезно. </p>
  <p id="lWD5">Набор оптимизирующих компиляторов и средств разработки Watcom C/C++ долгое время оставался <strong>одним из лучших</strong> инструментов для профессиональных программистов, в первую очередь из-за своей <em>производительности</em>: </p>
  <blockquote id="qU0x">In a February 1989 overview of optimizing C compilers, <em><a href="https://en.wikipedia.org/wiki/BYTE_(magazine)" target="_blank">BYTE</a></em> praised Watcom C 6.5&#x27;s &quot;unmatched execution speed&quot; and noted that it was the most <a href="https://en.wikipedia.org/wiki/ANSI_C" target="_blank">ANSI C</a>-compliant. </blockquote>
  <p id="lexo">Еще одной причиной народной любви к этому тулчейну была его <em>портабельность </em> — Watcom C/C++ поддерживал много разных платформ, причем как на хосте, так и в качестве целевых:  </p>
  <figure id="J2U0" class="m_original">
    <img src="https://img3.teletype.in/files/e2/f1/e2f1aa50-9c9e-45d4-9ba6-0591d290b7b6.png" width="397" />
    <figcaption>Из рекламного блока в <a href="https://gizmonaut.net/exe/exe-issues/EXE_Magazine_1995-10.pdf" target="_blank">журнале 1995 года</a>.</figcaption>
  </figure>
  <p id="5CIF">Собственно списком выше закрывались практически все потребности Windows-программистов тех лет, поскольку Watcom C/C++ поддерживал все актуальные на тот момент платформы и архитектуры. </p>
  <p id="jYp1">Еще это довольно редкий случай поддержки <a href="https://en.wikipedia.org/wiki/NetWare" target="_blank">Novell Netware</a> в качестве целевой платформы — не так много компиляторов позволяли подобное.</p>
  <figure id="k6ZL" class="m_column">
    <img src="https://img2.teletype.in/files/1d/c3/1dc324a0-d8ea-4814-80ed-a48ee2cd0bb6.png" width="812" />
    <figcaption>Рекламный блок про Watcom C/C++ из все того же <a href="https://gizmonaut.net/exe/exe-issues/EXE_Magazine_1995-10.pdf" target="_blank">журнала 1995 года</a>.</figcaption>
  </figure>
  <h2 id="2mkn">Печальная история</h2>
  <p id="yeC8">К сожалению Watcom пришлось повторить судьбу многих других легендарных проектов:</p>
  <blockquote id="0qAP">In 2000, <a href="https://en.wikipedia.org/wiki/Sybase" target="_blank">Sybase</a>, who owned Watcom International Corporation halted the commercial sale of the Watcom C/C++ and <a href="https://en.wikipedia.org/wiki/Fortran" target="_blank">Fortran</a> compilers.</blockquote>
  <p id="tUB7">Компанию-производителя, которая стояла за этим легендарным проектом банально купил более крупный игрок. </p>
  <p id="bRl3">Прекрасно понимаю что «бизнес есть бизнес», но по какой-то причине уникальные проекты, будучи поглощенными крупной компанией, неизменно проигрывают корпоративной бюрократии. После чего они скатываются, теряя свою уникальность, окончательно загибаясь в корпоративных застенках.</p>
  <p id="nx75">Так что печальная история Watcom C/C++ на самом деле весьма обыденна, но в данном случае это был еще не конец.</p>
  <h3 id="utNK">OpenWatcom</h3>
  <p id="ROU0">Цитируя википедию:</p>
  <blockquote id="QPtU">In 2003, SciTech Software Inc, a customer of Sybase, negotiated wth Sybase, to have the code for the compilers released as an open source project under a new name, OpenWatcom.<a href="https://en.wikipedia.org/wiki/Watcom_C/C%2B%2B#cite_note-2" target="_blank">[2]</a></blockquote>
  <p id="K9t7">Так на свет появился новый проект «<a href="https://web.archive.org/web/20160429054902/http://www.openwatcom.com/about.php" target="_blank">Open Watcom</a>» — открытый форк Watcom C/C++, разрабатываемый по открытой модели и с прицелом на сообщество энтузиастов. </p>
  <p id="nFy3">К сожалению компания <a href="https://en.wikipedia.org/wiki/SciTech_Software" target="_blank">SciTech</a>, организовавшая сей праздник щедрости несколько переоценила собственные возможности:</p>
  <blockquote id="86Od">проект компилятора это «серьезно и надолго», требует участия огромного количества высоквалифицированных программистов. </blockquote>
  <p id="fRY8">Которые разумеется бесплатно не работают.</p>
  <p id="T4Tu">Видимо именно от такого надрыва компания и закончила свои корпоративные дни в 2008 году, будучи <a href="https://web.archive.org/web/20110312075028/http://www.altrichmond.ca/" target="_blank">проданной канадской Alt Richmond Inc</a>. Которая ныне также не существует. </p>
  <p id="ALZQ">На фоне всех этих печальных событий, к середине 2010 года работы над проектом «Open Watcom» были свернуты:</p>
  <blockquote id="Thml">The last stable version endorsed by the original openwatcom.org team was <strong>1.9</strong>, released in June 2010.<a href="https://en.wikipedia.org/wiki/Watcom_C/C%2B%2B#cite_note-3" target="_blank">[3]</a><a href="https://en.wikipedia.org/wiki/Watcom_C/C%2B%2B#cite_note-OWRC-4" target="_blank">[4]</a></blockquote>
  <h3 id="Lh4I">OpenWatcom V2</h3>
  <p id="o9yQ">Но интерес к проекту OpenWatcom все же сохранился, поэтому уже к 2015 году «упавшее знамя» разработки было подхвачено <a href="http://openwatcom.org/" target="_blank">сообществом</a> — теми самыми энтузиастами, ради которых проект когда-то открывали:</p>
  <pre id="MLkQ">We are back!
Open Watcom is like a mythical bird Phoenix that never dies
and rises again from the ashes.
So do we.
The reports of our death are greatly exaggerated.</pre>
  <p id="wtNy">Так появился проект <a href="https://github.com/open-watcom/open-watcom-v2" target="_blank">OpenWatcom V2</a> — открытый форк открытой версии компилятора Watcom C/C++.</p>
  <p id="7238">Несмотря на столь бодрые заявления новой команды и обнадеживающий поток <a href="https://github.com/open-watcom/open-watcom-v2/commits/master/" target="_blank">свежих коммитов</a> в репозитории, ныне проект находится скорее в «цифровом чистилище», зависнув между возрождением и окончательной смертью:</p>
  <blockquote id="Z6sV">стабильных релизов как таковых <strong>нет</strong> с 2015 года и народ <a href="https://www.openwatcom.org/" target="_blank">выкладывает</a> «daily builds» — ежедневные сборки.</blockquote>
  <p id="WMXD">Поэтому как новая версия <em>2.0</em> так и устаревшая, но пока еще поддерживаемая <em>1.9 </em>на самом деле собираются из разных master-веток и с текущим набором коммитов.</p>
  <p id="bjDz">Вот такие привратности судьбы в стиле «Игры престолов» <a href="https://en.wikipedia.org/wiki/George_R._R._Martin" target="_blank">Дж. Мартина</a> — падение от «very popular compiler for high-end games» до дважды закрытого проекта, форкнутого на потеху энтузиастам.</p>
  <figure id="nTTw" class="m_original">
    <img src="https://img2.teletype.in/files/5b/fa/5bfa0472-1058-4a30-9875-476a5958ecd9.jpeg" width="4048" />
    <figcaption>Коллекционная сборка Watcom C/C++ 10 из 1994 года, <a href="https://blarg.ca/2017/12/23/exploring-watcom-c/" target="_blank">отсюда</a>.</figcaption>
  </figure>
  <h2 id="rCu7">Славные гусарские традиции и FreeBSD</h2>
  <p id="afPD">Как уже упоминал выше, Watcom и оба его продолжения — весьма портабельны, причем расширение списка поддерживаемых платформ является одним из постоянных направлений работ:</p>
  <blockquote id="kmhK">There is ongoing work to extend the targeting to Linux and modern BSD operating systems, running on x86, PowerPC, and other processors.</blockquote>
  <p id="PRlI">Все настолько <s>поехали</s> далеко зашло, что <a href="https://github.com/open-watcom/open-watcom-v2/blob/master/build.sh#L32" target="_blank">в скрипте сборки</a> присутствует даже <a href="https://en.wikipedia.org/wiki/Haiku_(operating_system)" target="_blank">Haiku</a> и <a href="https://www.dragonflybsd.org/" target="_blank">DragonFly</a>, хотя конечно есть определенные сомнения в стабильности работы на столь редких платформах .</p>
  <p id="e6rr">Как бы то ни было, компиляторы Watcom воспринимались программистами как инструмент в первую очередь Windows-разработки. </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="JT7B">Так что идея собрать «OpenWatcom v2» под FreeBSD, затем полученным компилятором собрать известный исторический проект под MS-DOS — показалась.. крайне забавной.</p>
  </section>
  <p id="t3aO">А когда закончим — сможете поцеловать компилятору.. например управляющий интерфейс, в честь славных гусарских традиций прошлого, ага. </p>
  <figure id="xmwp" class="m_column">
    <img src="https://img3.teletype.in/files/ef/53/ef53e67c-434f-4d1b-a237-ca599689ceb8.png" width="720" />
    <figcaption>Так выглядит оригинальный отладчик Watcom 10. <a href="https://blarg.ca/2017/12/23/exploring-watcom-c/" target="_blank">Отсюда</a>.</figcaption>
  </figure>
  <h3 id="NN5D">Справка для обывателей</h3>
  <p id="yP5W">Прежде чем снова погружать читателей во мрак хардкора со сборкой компиляторов из исходников <s>под звуки бубна</s>, стоит все же рассказать о <em>более легком</em> пути, который внезапно есть.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="L7K6">Десяток лет практики в C/C++ это конечно не заменит, но немного времени <s>и психического здоровья</s> вам точно сохранит.</p>
  </section>
  <p id="zHgt">Во-первых существуют готовые сборки OpenWatcom: <a href="http://openwatcom.org/ftp/source/ow_portable_v2_stable.zip" target="_blank">2.0</a>, <a href="http://openwatcom.org/ftp/source/ow_portable_daily.tar.bz2" target="_blank">1.9</a>, которые достаточно скачать и распаковать.</p>
  <blockquote id="ikWh">Каждая такая сборка содержит набор компиляторов для всех поддерживаемых платформ: MS-DOS, Windows, Linux и так далее, с разделением на 16, 32 и 64-битные версии, чем мы дальше будем активно пользоваться.</blockquote>
  <p id="AUcR">Но поддержки FreeBSD в готовых сборках разумеется нет.</p>
  <p id="nGf8">Во-вторых, если вдруг Бог наказал вас использованием <a href="https://archlinux.org" target="_blank">ArchLinux</a> вместо операционной системы, в<a href="https://wiki.archlinux.org/title/Open_Watcom" target="_blank"> AUR</a> есть готовые пакеты с OpenWatcom, как 2.0 так и 1.9 версий, которые достаточно «просто установить».</p>
  <p id="L4oh">Ну и само собой разумеется, для «Windows-бояр» ничего устанавливать не придется <s>само упадет</s>, достаточно распаковать и <a href="https://open-watcom.github.io/open-watcom-v2-wikidocs/c_readme.html#Installation" target="_blank">прочитать инструкцию</a>.</p>
  <h3 id="topP">Новые приключения неуловимых</h3>
  <p id="9L3m">Ну что ж, честно предупредив о возможных последствиях в виде потерянного времени <s>и сломаной психики</s>, можно наконец начинать выносить читателям мозг.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="eqbA">Для всех шагов ниже использовалась самая последняя на момент создания статьи FreeBSD 15.1. </p>
  </section>
  <p id="YK6G">Впрочем и на более ранних версиях особых проблем замечено не было. </p>
  <p id="06fK">Начнем с малоизвестного для простых обывателей факта:</p>
  <blockquote id="BM7G">для того чтобы собрать из исходников компилятор, нужен.. другой компилятор.</blockquote>
  <p id="l4vF">Который называется <a href="https://en.wikipedia.org/wiki/Bootstrapping_(compilers)" target="_blank">bootstrap compiler</a> и используется на начальных этапах сборки таких проектов.</p>
  <p id="tB9v">В качестве bootstrap-компилятора в моем случае использовался <code>gcc13</code>, который должен быть установлен в системе вместе со всем своим окружением. </p>
  <p id="PD30">Дополнительно, для отдельных стадий сборки, потребуется эмулятор <a href="https://cgit.freebsd.org/ports/tree/emulators/dosbox" target="_blank">Dosbox</a>, также доступный в портах.</p>
  <p id="pZqn">Ввиду особенности FreeBSD в виде приделывания номера версии к управляющим приложениям GCC, необходимо создать ссылку:</p>
  <pre id="leEW" data-lang="bash">ln -s /usr/local/bin/g++13 /usr/local/bin/g++</pre>
  <p id="QdLv">Альтернативный вариант это ручная правка скриптов сборки, с массовой заменой вызываемого <code>g++</code> на <code>g++13</code>, скрипты довольно большие и сложные, поэтому если захотите такое провернуть — правок будет много.</p>
  <p id="w2sV">Но вернемся к нашей сборке.</p>
  <h2 id="5Gaa">Сборка OpenWatcom</h2>
  <p id="PLRt">Ультимативно и не мелочась, забираем исходники OpenWatcom сразу из master-ветки:</p>
  <pre id="B9YM" data-lang="bash">git clone --depth 1 https://github.com/open-watcom/open-watcom-v2.git</pre>
  <p id="hLGd">История коммитов весьма объемна, поэтому стоит указать ключ <code>--depth 1</code>.</p>
  <p id="TasQ">Следующим шагом необходимо создать копию скрипта с настройками локального окружения, чтобы не было проблем со слиянием правок при обновлении репозитория:</p>
  <pre id="hDy8" data-lang="bash">cp setvars.sh local_setvars.sh</pre>
  <p id="8Mhn">Затем изменить локальную копию — необходимо найти и раскомментировать параметр <code>OWDOSBOX</code>, указывающий на название исполняемого файла эмулятора Dosbox: </p>
  <pre id="I4In" data-lang="bash">export OWDOSBOX=dosbox</pre>
  <p id="E9Fq">Дальше необходимо этот скрипт запустить, чтобы в окружении появились все заданные там переменные (для bash):</p>
  <pre id="ua0g" data-lang="bash">source ./local_setvars.sh</pre>
  <p id="aYLO">При запуске отобразится используемый bootstrap-компилятор:</p>
  <figure id="Zn2k" class="m_column">
    <img src="https://img4.teletype.in/files/78/6c/786c4773-33f6-45a7-b35c-46773cc3abfc.png" width="852" />
  </figure>
  <p id="Ftji">Теперь наконец запускаем саму сборку, <s>не забывая молиться</s>:</p>
  <pre id="C1un" data-lang="bash">./build.sh</pre>
  <p id="WrKx">Сразу предупреждаю, процесс сборки будет идти <strong>долго</strong> даже на мощном компьютере, сравнимо по времени со сборкой ядра Linux, OpenOffice и других крупных проектов. На диске должно быть <code>~4Гб</code> свободного места. </p>
  <p id="vDt4">Объясняется это тем, что в процессе будут собираться компиляторы и инструментарий под все поддерживаемые ОС и архитектуры.</p>
  <figure id="tx65" class="m_column">
    <img src="https://img4.teletype.in/files/3d/01/3d0145cb-e8cc-4aba-b5d8-70f57554f23d.gif" width="800" />
    <figcaption>Тот самый процесс, уникальный в своем безумии: так собирается OpenWatcom под FreeBSD.</figcaption>
  </figure>
  <p id="sbdl">Если вам повезет и сборка завершится успешно, следующим шагом будет необходимо собрать релизную версию:</p>
  <pre id="Joql" data-lang="bash">./build.sh rel</pre>
  <p id="ANEF">Который будет находиться в каталоге <code>rel</code>.</p>
  <figure id="i8K3" class="m_column">
    <img src="https://img4.teletype.in/files/74/1e/741e0e94-d7b5-49e5-9e5c-f3a21984f6a4.png" width="882" />
    <figcaption>Так выглядит завершенная релизная сборка OpenWatcom под FreeBSD.</figcaption>
  </figure>
  <p id="wQbf">Дальше копируем готовую релизную сборку в то <s>самое</s> место, откуда собираемся потом использовать:</p>
  <pre id="MBNh" data-lang="bash">mkdir /opt/app/watcom
cp -r rel/* /opt/app/watcom/ </pre>
  <p id="n5mB">Теперь создаем скрипт с переменными окружения, который будет необходимо подключать <strong>до</strong> начала использования OpenWatcom:</p>
  <pre id="32hx" data-lang="bash">#!/bin/sh
export WATCOM=/opt/app/watcom 
export PATH=$WATCOM/binb64:$PATH 
export INCLUDE=$WATCOM/h:$WATCOM/h/nt 
export EDPATH=$WATCOM/eddats 
export WIPFC=$WATCOM/wipfc</pre>
  <p id="jms4">Поскольку в переменную PATH добавляется каталог <code>binb64</code>, после применения скрипта будет использоваться <strong>нативная</strong> сборка OpenWatcom для FreeBSD, не для Linux или Windows:</p>
  <figure id="7xya" class="m_column">
    <img src="https://img2.teletype.in/files/de/32/de32f7ca-ac16-4806-b2dc-66766a6dfe54.png" width="922" />
    <figcaption>Так выглядит <strong>нативный</strong> компилятор OpenWatcom под FreeBSD. Теперь вы видели все.</figcaption>
  </figure>
  <p id="55oc">Тем не менее, нативная сборка, как оказалось, вполне неплохо справляется с задачами кросс-компиляции под DOS и даже Windows, что мы будем использовать далее.</p>
  <figure id="LWVj" class="m_original">
    <img src="https://img1.teletype.in/files/0b/bc/0bbc6244-e452-4e4f-9a36-70ea318101ff.png" width="1366" />
    <figcaption>Сборка <a href="https://en.wikipedia.org/wiki/Duke_Nukem_3D" target="_blank">Duke Nukem 3D</a> из исходников в IDE, с помощью собранного из исходников OpenWatcom. На FreeBSD. </figcaption>
  </figure>
  <h2 id="QCPs">辻斬り</h2>
  <blockquote id="MhYF"><strong><a href="https://ru.wikipedia.org/wiki/%D0%A6%D1%83%D0%B4%D0%B7%D0%B8%D0%B3%D0%B8%D1%80%D0%B8" target="_blank">Цудзигири</a></strong> (辻斬り или 辻斬, дословно: убийство на перекрестке, англ. Tsujigiri) — <a href="https://ru.wikipedia.org/wiki/%D0%AF%D0%BF%D0%BE%D0%BD%D0%B8%D1%8F" target="_blank">японская</a> практика, когда <a href="https://ru.wikipedia.org/wiki/%D0%A1%D0%B0%D0%BC%D1%83%D1%80%D0%B0%D0%B9" target="_blank">самурай</a>, получив новую <a href="https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D1%82%D0%B0%D0%BD%D0%B0" target="_blank">катану</a> или разрабатывая новый вид боя или оружия, испытывал его эффективность, нападая на случайного оппонента.</blockquote>
  <p id="i6e8">Катаны у меня <s>пока</s> нет, зато есть собранный из исходников компилятор и острое желание проверить его на <s>первом встречном</s> практике.</p>
  <p id="M7rI">Конечно можно было ограничиться <a href="https://github.com/open-watcom/open-watcom-v2/tree/master/bld/src/win" target="_blank">примерами</a>, которые идут в комплекте с OpenWatcom и на этом успокоиться, благо там весьма неплохая и функциональная подборка:</p>
  <figure id="BP1M" class="m_column">
    <img src="https://img3.teletype.in/files/ef/4c/ef4cf0f8-83fc-46a3-9201-956919160fe9.gif" width="800" />
    <figcaption>Классический &quot;Hello, world&quot; в виде приложения для 32-битной Windows NT, собрано и запущено под FreeBSD.</figcaption>
  </figure>
  <p id="1ZfF">Но подумав, что это будет слишком уж скучно для читателей <s>и недостойно упоминания в летописях</s>, собрал с помощью OpenWatcom действительно интересный исторический проект — тот самый «Duke Nukem 3D», с которого когда-то началось мое с ним знакомство.</p>
  <h2 id="wkLJ">Duke Nukem 3D</h2>
  <p id="Qj8o"><a href="https://dukenukem.fandom.com/wiki/Duke_Nukem_3D" target="_blank">Duke Nukem 3D</a> это такая древняя (1997 год) стрелялка, где инопланетные монстры, «свинокопы» с дробовиками, стрельба из ракетниц с двух рук и прочие милые подростковые радости:</p>
  <figure id="3A5l" class="m_column">
    <img src="https://img4.teletype.in/files/75/43/75431c3b-8a36-4813-bba1-bb9c505e3361.jpeg" width="1000" />
    <figcaption>&quot;<a href="https://dukenukem.fandom.com/wiki/Quotes_from_Duke_Nukem_3D" target="_blank">Come get some!</a>&quot; (ц)</figcaption>
  </figure>
  <p id="1lqa">Пока другие дети яростно резались в эту замечательную игру по сети, бодро отстреливая инопланетных монстров и друг друга, я <s>ковырял исходники</s> пытался делать <strong>карты</strong> в редакторе уровней <a href="https://advsys.net/ken/build.htm" target="_blank">Build</a>, создав в итоге с его помощью.. собственную школу!</p>
  <blockquote id="1eUL">В нынешние неспокойные времена беготня по виртуальному учебному заведению с пистолетом в руке конечно вызовет определенные вопросы и общественное порицание, но в мои школьные годы на такие шалости смотрели сильно проще. </blockquote>
  <p id="gy0O">Поэтому позже я продолжил интересную практику картостроения уже в серии игр Quake. </p>
  <p id="0phT">Но про мой замечательный опыт игростроя расскажу как-нибудь отдельно, благо это весьма интересная история, а пока вернемся к истории с Watcom и сборкой «Duke Nukem 3D» из исходников.</p>
  <p id="SuKy">Конечно же исходный код столь популярной и коммерчески успешной игры увидел свет далеко не сразу:</p>
  <figure id="nc2P" class="m_original">
    <img src="https://img1.teletype.in/files/80/48/804885ac-7748-483d-ab60-65cddee82f90.png" width="920" />
    <figcaption>Сохраненная <a href="https://web.archive.org/web/20141110202425/http://legacy.3drealms.com/news/2003/04/duke_nukem_3d_s_4.html" target="_blank">копия</a> ныне несуществующего сайта компании 3D Realms.</figcaption>
  </figure>
  <p id="VNKy">Целых <strong>семь лет</strong> фанаты донимали разработчиков, кивая в сторону ID Software, создавшую практику раскрытия исходников собственных игр. И наконец это случилось: </p>
  <blockquote id="dbyC">1 апреля 2003 года исходный код игры «Duke Nukem 3D» увидел свет. </blockquote>
  <p id="x2Yp">Но поскольку на дворе были 2000е и к тому времени появилась <strong>бесплатная</strong> версия OpenWatcom, разработчики решили помочь энтузиастам, переделав оригинальную сборку, чтобы игру можно было собрать обоими версиями компиляторов:</p>
  <pre id="F0pr">Duke was originally written with the Watcom 10.0 C/C++ compiler. 
This code has been updated to allow it to compile under the free version 
of the Watcom compiler available from their webpage 
(http://www.openwatcom.org).</pre>
  <p id="1KZP">Таким образом <a href="https://github.com/videogamepreservation/dukenukem3d" target="_blank">официальная версия</a> исходников Duke Nukem 3D, увидевшая свет в 2003м году поддерживала сборку с помощью OpenWatcom, но к сожалению его <em>первой версии</em>, которую затем форкнут энтузиасты.</p>
  <p id="eYkA">Поскольку 1.x версия OpenWatcom (включая даже последнюю в линейке 1.9) имеет проблемы совместимости с 2.0, для того чтобы собрать из исходников «Duke Nukem 3D» именно второй версией придется мигрировать проект — переделывать скрипты сборки и (немного) исходники.</p>
  <p id="AYCz">Хотя такая миграция и не представляет серьезной проблемы, делать ее вручную не придется, поскольку известный в узких кругах товарищ <a href="https://github.com/neozeed" target="_blank">neozeed</a> уже успел это сделать за нас, выложив в <a href="https://github.com/neozeed/duke3d-openwatcom2/" target="_blank">отдельном репозитории</a> версию исходников с поддержкой OpenWatcom 2.0.</p>
  <p id="X0Rl">Забираем:</p>
  <pre id="5jgE" data-lang="bash">git clone https://github.com/neozeed/duke3d-openwatcom2.git</pre>
  <p id="tMkK">Собир.. увы но нет, дальше начинаем думать, поскольку следующие шаги весьма нетривиальны.</p>
  <p id="OT9f">Ниже я покажу два варианта сборки:</p>
  <ul id="gyGK">
    <li id="s05z">из-под DOS с помощью Dosbox и DOS-версии OpenWatcom;</li>
    <li id="wd8R"><s>по боярски</s> из-под Wine и с помощью Watcom IDE.</li>
  </ul>
  <p id="StlO">Оба варианта по своему экстремальны, поскольку дело будет происходить на FreeBSD, но самое интересное вас ожидает как обычно в конце повествования.</p>
  <h2 id="VIxK">Чистый DOS</h2>
  <p id="Jk91">Как уже упоминал выше, при сборке OpenWatcom создаются версии компиляторов под все поддерживаемые платформы: </p>
  <figure id="54mr" class="m_column">
    <img src="https://img4.teletype.in/files/ba/1d/ba1d38ae-9a32-4e5b-a078-856a5476ce5a.png" width="762" />
  </figure>
  <p id="KWMD">Собирается по-умолчанию далеко не все, поэтому список ниже не полный:</p>
  <ul id="mwuE">
    <li id="ELFp">binb64 — 64-битная сборка под FreeBSD</li>
    <li id="sG8Q">binl — 32-битная сборка под Linux</li>
    <li id="jE8M">binl64 — 64-битная сборка под Linux, не собирается по-умолчанию</li>
    <li id="KEqH">binnt - 32-битная cборка для Windows</li>
    <li id="MuRK">binnt64 - 64-битная сборка для Windows</li>
    <li id="UKGH">binp — сборка для OS/2</li>
    <li id="SWi8">binw — 16-битная сборка для Windows и DOS</li>
  </ul>
  <p id="LjCJ">С учетом такого подхода, система сборки <code>wmake</code> в подкаталоге <code>binw</code> будет представлять собой приложение для DOS:</p>
  <figure id="GTvt" class="m_column">
    <img src="https://img1.teletype.in/files/c4/4b/c44bd9fa-602b-4ac9-a35d-cc9b930f87c3.png" width="772" />
  </figure>
  <p id="r6h8">А в версии для Windows — в подкаталоге <code>binnt</code> это будет уже Win32-приложение:</p>
  <figure id="7VLD" class="m_column">
    <img src="https://img2.teletype.in/files/9a/ba/9aba709c-71c0-4b93-a287-37243ac1efc8.png" width="772" />
  </figure>
  <p id="SnCa">Следующий важный нюанс заключается в том чтобы задать переменные окружения для работы с компилятором OpenWatcom, причем так <strong>чтобы их увидел эмулятор</strong> Dosbox.</p>
  <p id="ijcx">Создаем новый каталог <code>duke3d-work</code>:</p>
  <pre id="am7A" data-lang="bash">mkdir duke3d-work</pre>
  <p id="KOES">Линкуем внутрь каталог с Watcom, чтобы не иметь проблем с длинными путями каталогов:</p>
  <pre id="laC1" data-lang="bash">ln -s /opt/app/watcom ./watcom</pre>
  <p id="V0fu">Копируем исходники Duke Nukem 3D:</p>
  <pre id="W3IK" data-lang="bash">cp -R /opt/src/duke3d-openwatcom2/ ./duke3d</pre>
  <p id="v1b1">Теперь создаем в корне файл <code>env.bat</code> с таким содержимым:</p>
  <pre id="wvxS" data-lang="powershell">@ECHO OFF
SET WATCOM=C:\WATCOM
SET PATH=%WATCOM%\BINW;%PATH%
SET EDPATH=%WATCOM%\EDDAT
SET INCLUDE=%WATCOM%\H
REM SET LIB=
REM SET WWINHELP=%WATCOM%\BINW</pre>
  <p id="B7Xq">И стартуем Dosbox с указанием этого файла, обязательно из текущего каталога:</p>
  <pre id="3Afh">dosbox env.bat </pre>
  <p id="O6v7">В результате запустится эмулятор DOS с подготовленным окружением для сборки:</p>
  <figure id="7jG6" class="m_original">
    <img src="https://img4.teletype.in/files/bb/23/bb23aba1-ad7a-4dab-be7d-10d50de77a90.png" width="640" />
  </figure>
  <p id="usf8">Теперь переходим в каталог <code>DUKE3D</code> и запускаем сборку проекта:</p>
  <pre id="cuFX">CD DUKE3D
WMAKE</pre>
  <p id="1ne7">Надо отметить, что сборка происходит весьма неспешно — несмотря на небольшое количество файлов в проекте, исходного кода в каждом из них навалено с избытком: </p>
  <figure id="SIII" class="m_original">
    <img src="https://img2.teletype.in/files/10/a6/10a69eee-a045-4b4f-99b0-a31cf5fe60bb.png" width="640" />
    <figcaption>Так происходит сборка Duke Nukem 3D из исходников.</figcaption>
  </figure>
  <p id="z8tt">К сожалению сборка немного сломана, поэтому через какое-то время процесс прервется с ошибкой:</p>
  <figure id="ubHP" class="m_original">
    <img src="https://img2.teletype.in/files/d0/b1/d0b15b24-ad0f-49b1-baae-f29b3acd326c.png" width="640" />
  </figure>
  <p id="t3ff">Ошибки происходят из-за того что игра использует части движка Build (что логично), который необходимо собирать отдельно до самой игры.</p>
  <p id="87Zf">Так что переходим в каталог с движком и запускаем отдельную сборку:</p>
  <pre id="tauF">CD BUILD\SRC
WMAKE</pre>
  <p id="MgrD">Движок должен собраться без ошибок:</p>
  <figure id="Db5m" class="m_original">
    <img src="https://img4.teletype.in/files/36/3f/363f061c-1a0a-4b1b-9358-c3e337f2e03f.png" width="640" />
  </figure>
  <p id="bzpr">Теперь возвращаемся обратно в каталог с игрой и повторно запускаем сборку:</p>
  <pre id="EIjs">CD ..\..
WMAKE</pre>
  <p id="oIj0">Все требуемые файлы найдутся, кроме одного:</p>
  <figure id="Httg" class="m_original">
    <img src="https://img1.teletype.in/files/4a/af/4aaf6eb2-0d20-4f65-8efd-f53bb3d21200.png" width="640" />
  </figure>
  <p id="lxZS">Как именно получилось, что один из ключевых файлов движка оказался пропущен в скрипте сборки от neozeed гадать не берусь, но для исправления ситуации необходимо добавить новый блок в <code>build\src\makefile</code>:</p>
  <pre id="O6ft">mmulti.obj : mmulti.c
	wcc386 mmulti /4r /s /or</pre>
  <p id="IXFB">Затем выполнить сборку отдельно для этого файла, чтобы получить искомый <code>mmulti.obj</code>:</p>
  <pre id="nUI4">CD BUILD\SRC
WMAKE MMULTI.OBJ</pre>
  <p id="x6SX">В результате должен собраться этот пропущенный файл:</p>
  <figure id="ax8J" class="m_original">
    <img src="https://img4.teletype.in/files/31/a6/31a6fcf5-cffc-446c-97d8-4aca5a281414.png" width="640" />
  </figure>
  <p id="RZKo">Возвращаемся в каталог с игрой, удаляем <code>game.obj</code>, который окажется битым из-за пропущенного файла и заново запускаем сборку:</p>
  <pre id="v6aj">CD ..\..
DEL GAME.OBJ
WMAKE</pre>
  <p id="ejCO">На этот раз сборка должна завершиться успешно и даже сформируется заветный <code>DUKE3D.EXE</code>, но появится сообщение с ошибкой про отсутствующие инструменты для встраивания DOS4/GW:</p>
  <figure id="GrBt" class="m_original">
    <img src="https://img2.teletype.in/files/18/ec/18ecd599-e771-4354-b135-8a8348fc7000.png" width="640" />
  </figure>
  <p id="GY9A">Взять эти два файла можно например <a href="https://github.com/btb/dos4gwpro" target="_blank">тут</a>, их необходимо скопировать в каталог <code>binw</code>, где расположена DOS-версия OpenWatcom, после чего удалить недоделанный <code>DUKE3D.EXE</code> и перезапустить сборку:</p>
  <pre id="XKG9">DEL DUKE3D.EXE
WMAKE</pre>
  <p id="2C3U">Теперь наконец релизная сборка успешно завершится:</p>
  <figure id="vFBp" class="m_original">
    <img src="https://img4.teletype.in/files/f7/b1/f7b18765-28d9-43e7-ba9d-2b739d11f65b.png" width="640" />
  </figure>
  <p id="skqF">Файл <code>D3D.EXE</code> будет той самой релизной версией игры.</p>
  <p id="F6Cx">Но это все — скучные и непонятные «буковки на черном экране», все приличные программисты как известно используют такую штуку как «среда разработки» и у Watcom она очень даже есть.</p>
  <figure id="Rti5" class="m_original">
    <img src="https://img2.teletype.in/files/d9/cc/d9cc6f50-28e0-4171-8d2e-7014949ce0d4.png" width="1366" />
    <figcaption>Так выглядит Open Watcom IDE в работе, с открытым проектом Duke Nukem 3D.</figcaption>
  </figure>
  <h2 id="275m">Wine, Watcom и IDE</h2>
  <p id="vLza">Среда разработки официально называется <a href="https://en.wikipedia.org/wiki/Watcom_C/C%252B%252B" target="_blank">Watcom Integrated Development Environment</a> и собирается из исходников при сборке компилятора, к сожалению только для Windows-платформ. Использование требует предварительно заданных переменных окружения, поэтому ее запуск из-под Wine — весьма нетривиальное занятие.</p>
  <blockquote id="FEfP">К счастью, автор успел съесть целую стаю собак на нетривиальных проектах и история с Watcom на этом шаге не обрывается.</blockquote>
  <p id="0Gls">В корневом каталоге проекта, рядом с <code>env.bat</code>, который мы создавали ранее для сборки с помощью Dosbox, создаем еще один файл <code>env-nt.bat</code> с таким содержимым:</p>
  <pre id="RaSv">@ECHO OFF
SET WATCOM=z:\opt\app\watcom
SET PATH=%WATCOM%\BINNT;%PATH%
SET EDPATH=%WATCOM%\EDDAT
SET INCLUDE=%WATCOM%\H;%WATCOM\H\NT%
REM SET LIB=
REM SET WWINHELP=%WATCOM%\BINNT</pre>
  <p id="QrK9">Из интересного тут путь в переменной WATCOM, который должен указывать на каталог с релизной сборкой OpenWatcom, но при этом иметь том <code>Z:</code> и разделитель в стиле Windows.</p>
  <blockquote id="FyC1">Том <code>Z:</code> это специальная <s>уличная</s> магия из <a href="https://en.wikipedia.org/wiki/Wine_(software)" target="_blank">Wine</a> для бесшовного доступа к файловой системе хоста, с ее помощью можно указать путь к каталогу, который физически находится на диске FreeBSD, но должен использоваться из программы для Windows.</blockquote>
  <p id="NZ1E">Запуск также представляет определенную проблему, поскольку с недавних пор Wine для FreeBSD поставляется только 64-битной версии и для эмуляции 32-битных приложений используется специальный <s>цирк на конной тяге</s> запуск.</p>
  <p id="kED7">Вводим:</p>
  <pre id="Wx0H" data-lang="bash">wine wineconsole</pre>
  <p id="CJF1">Запустится новое приложение-терминал, аналог <code>cmd.exe</code>, работающий на базе Wine. Вводим уже в нем:</p>
  <pre id="GEYb">ent-nt.bat</pre>
  <p id="k8aY">Затем проверяем командой <code>set</code>, что переменная <code>WATCOM</code> указывает на нужный каталог:</p>
  <figure id="GCSA" class="m_original">
    <img src="https://img1.teletype.in/files/c8/d6/c8d6b8cb-1525-47c8-9158-936613db3b6b.png" width="657" />
  </figure>
  <p id="wvKS">Теперь наконец запускаем среду разработки:</p>
  <pre id="mALJ">ide.exe</pre>
  <p id="5GVK">Среда <strong>очень быстрая</strong>, хотя и весьма специфичная на нынешние времена, работает и сборка и отладка и запуск финального приложения, но разумеется в пределах возможностей Wine, поэтому запустить или отладить приложение для DOS, OS/2 или Win16 так просто не получится.</p>
  <p id="Hfms">Вот так выглядит сборка и запуск Win32-версии <a href="https://en.wikipedia.org/wiki/Conway&#x27;s_Game_of_Life" target="_blank">знаменитой игры «Life»</a>, которую можно найти в примерах для OpenWatcom:</p>
  <figure id="yYZF" class="m_original">
    <img src="https://img1.teletype.in/files/c7/e9/c7e97233-b860-440e-a640-bddce6a83808.png" width="1366" />
  </figure>
  <p id="T2fD">Теперь можно вернуться к проекту «Duke Nukem 3D» и собрать его наконец «по взрослому» — из среды разработки.</p>
  <p id="iJ1g">В меню <code>File-&gt;Open Project</code> выбираем файл <code>duke3d.wpj</code> и нажимаем кнопку <code>Open</code>:</p>
  <figure id="ZjEb" class="m_original">
    <img src="https://img4.teletype.in/files/b3/aa/b3aa3534-e444-43d2-b6c6-9d2c58fcbbc3.png" width="420" />
  </figure>
  <p id="lmDU">Откроется проект со списком файлов с исходниками , по двойному клику на файле запустится редактор, в котором собственно и происходит работа с исходным кодом:</p>
  <figure id="NOsY" class="m_column">
    <img src="https://img4.teletype.in/files/f8/49/f84907df-027a-4e33-a364-ee080ade05ff.png" width="938" />
    <figcaption>Вот так когда-то происходила разработка ваших любимых игр.</figcaption>
  </figure>
  <p id="j1w9">Собрать проект можно кнопкой «<code>Make current target</code>» на панели инструментов:</p>
  <figure id="aj7h" class="m_column">
    <img src="https://img2.teletype.in/files/53/c9/53c9ac47-1a5a-4871-9c27-9b120904a347.png" width="837" />
  </figure>
  <p id="q4pg">Сборка из среды довольно серьезно отличается от версии с <code>wmake</code>, поэтому при запуске появятся новые интересные ошибки:</p>
  <figure id="1e3V" class="m_column">
    <img src="https://img4.teletype.in/files/31/85/3185a96e-badb-49d6-8824-6da577593a77.png" width="834" />
  </figure>
  <p id="3lds">Не буду в очередной раз утомлять последовательным перечислением всех багов, найденных в процессе сборки из IDE и сразу расскажу как все это забороть:</p>
  <ul id="ud2l">
    <li id="rog1">копируем файлы из каталога <code>libs</code> в корень проекта;</li>
    <li id="pWCN">копируем файлы <code>mmulti.obj</code>, <code>cache1d.obj</code>, <code>engine.obj</code>,<code>a.obj</code> из каталога <code>build\src</code> в корень проекта.</li>
  </ul>
  <p id="4o0X">После этого сборка из IDE должна завершиться успешно:</p>
  <figure id="m3NC" class="m_column">
    <img src="https://img2.teletype.in/files/17/f9/17f92165-a965-444a-abff-07398bea7b06.png" width="833" />
    <figcaption>Надо добавить, что сборка из IDE не прикручивает расширитель DOS4/GW.</figcaption>
  </figure>
  <p id="Qqcz">Вот таким нехитрым способом (даже двумя) мы получили исполняемый файл знаменитой игры «Duke Nukem 3D», собранный из исходников с помощью компилятора Watcom — чего только не сделаешь из-за детских комплексов.</p>
  <p id="ZvlU">Самое время попробовать запустить.</p>
  <figure id="ubyj" class="m_original">
    <img src="https://img4.teletype.in/files/f7/a0/f7a03c3b-e32f-4a4a-96cc-acb392b815f8.jpeg" width="3840" />
    <figcaption>Одна из многочисленных &quot;пасхалок&quot; Duke Nukem 3D.</figcaption>
  </figure>
  <h2 id="610V">Грандиозный провал</h2>
  <p id="guLi">Ввиду прошлой известности и популярности, архивы с «Duke Nukem 3D» до сих пор можно легко найти в интернете. Ныне оригинальная игра является «abandonware» (заброшенным софтом), поэтому свободно доступна для скачивания с фанатских сайтов. </p>
  <p id="weiE">Скачиваем, например <a href="https://archive.org/details/duke-nukem-3d-atomic-edition-1.4-1996-atari-inc" target="_blank">отсюда</a>, распаковываем архив, заменяем <code>DUKE3D.EXE</code> на собственноручно собранную копию (<code>D3D.EXE</code> в случае сборки из-под DOS) и пробуем запустить с помощью Dosbox.</p>
  <p id="8cI8">И получаем.. <strong>грандиозный провал</strong>:</p>
  <figure id="WGcB" class="m_column">
    <img src="https://img1.teletype.in/files/87/04/87044b1d-6db9-4d15-be28-a4b35a694dfc.gif" width="800" />
    <figcaption>На самом деле это уже &quot;продвинутая&quot; версия Dosbox, называется <a href="https://dosbox-x.com/" target="_blank">Dosbox-X</a>. Но падает с таким же треском. </figcaption>
  </figure>
  <p id="7xPF">Думаю на этом месте многие читатели вздохнули с облегчением и обрадовались:</p>
  <blockquote id="Lq1u">«гусарский наскок» <s>с шашкой на танк</s> с нестабильными сборками из исходников под неподдерживаемой операционной системой закончился предсказуемо.</blockquote>
  <p id="MG2z">На <strong>пятнадцатой минуте</strong> статьи, после шагов по сборке компилятора, запуску и сборке самого Duke Nukem 3D из исходников, получился.. битый EXE-файл, попытка запуска которого вешает эмулятор.</p>
  <p id="kaeF">И наверное на этом печальном абзаце статья бы и закончилась, будучи списанной в утиль за столь позорный провал. Если бы автор был <s>нормальным</s> обычным человеком. </p>
  <p id="GBjz"></p>
  <figure id="9Aj3" class="m_column">
    <img src="https://img4.teletype.in/files/71/b2/71b264ce-3750-45d2-be72-b57cbf13abc6.jpeg" width="1280" />
    <figcaption>Та самая сцена из х\ф &quot;<a href="https://ru.wikipedia.org/wiki/%D0%A1%D0%B2%D1%8F%D1%82%D1%8B%D0%B5_%D0%B8%D0%B7_%D0%91%D1%83%D0%BD%D0%B4%D0%BE%D0%BA%D0%B0" target="_blank">Святые из Бундока</a>&quot;.</figcaption>
  </figure>
  <h2 id="atdS">И разразилась битва</h2>
  <p id="R6Mx">К несчастью для <s>окружающих</s> компилятора воспитывали и образовывали меня <strong>советские инженеры</strong>, привившие крайне специфическое отношение к компьютерной технике:</p>
  <blockquote id="1WqQ">cо времен получения инженерного диплома, все что ездит, плавает и летает считаю законной целью для своих экспериментов и сильно огорчаюсь когда машина делает не то что мне хочется.</blockquote>
  <p id="RMwG">Поэтому конечно автор не отступил и как уже можно было заметить по заглавной картинке к статье — все-таки повесил «отрубленную голову OpenWatcom» у себя над камином.</p>
  <p id="1PSO">Теперь рассказываю как это было.</p>
  <p id="p0KO">Первым делом я попробовал замедлить эмуляцию, задав более точную настройку CPU, соответствующую компьютерам тех лет в <code>~/.dosbox/dosbox-&lt;версия&gt;.conf</code>:</p>
  <pre id="YH5O">..
[cpu]
core=normal
cputype=pentium
cycles=fixed 30000
..</pre>
  <p id="zHVF">Там же полностью отключил звук, затем переключил <a href="https://www.dosbox.com/wiki/Dosbox.conf#.5Brender.5D" target="_blank">реализацию движка отрисовки</a> на более совместимую.</p>
  <p id="TDXo">К сожалению ничего из этого не помогло и собранная с таким трудом версия <code>DUKE3D.EXE</code> продолжала вешать эмулятор, тогда как оригинальная работала без каких-либо проблем.</p>
  <p id="0vfa">Пробовал и запуск в полной эмуляции оригинального MS-DOS 6.22 с помощью <a href="https://86box.net/" target="_blank">86Box</a>, пробовал и другую реализацию расширителя памяти <a href="http://dos32a.narechk.net/" target="_blank">dos32a</a> — с его помощью эмулятор перестал падать, но вместо картинки был лишь черный экран. </p>
  <p id="vSGc">Следующим шагом был отказ от собранной под FreeBSD версии OpenWatcom и проверка на готовом билде для Linux:</p>
  <figure id="F3k2" class="m_original">
    <img src="https://img4.teletype.in/files/35/bc/35bc119c-e2c5-4d09-b10d-77a2b40ceda4.png" width="1177" />
    <figcaption>Одна из готовых сборок OpenWatcom v2 под Linux.</figcaption>
  </figure>
  <p id="mBWI">Увы, но все это не помогло и собранная из исходников версия «Duke Nukem 3D» продолжала стабильно вылетать, <s>выбешивая автора</s> роняя эмулятор.</p>
  <p id="6xue">Следующим шагом был отказ от сборки, созданной для поддержки OpenWatcom v2 в пользу оригинальных исходников, раскрытых в 2003м году.</p>
  <p id="5i9W">Забрав оригинал из <a href="https://github.com/videogamepreservation/dukenukem3d" target="_blank">этого репозитория</a> на Github, я последовательно прошелся по всем правкам, созданным neozeed и добился таки сборки оригинальных исходников с помощью второй версии OpenWatcom.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="vLso">Но даже этот радикальный шаг <strong>не помог</strong> и собранная версия игры продолжала падать. </p>
  </section>
  <p id="ZtgD">Зато я заметил важную деталь:</p>
  <figure id="IQgu" class="m_original">
    <img src="https://img4.teletype.in/files/bd/fd/bdfd1064-3d2c-4fe3-8676-17dcbdabc998.png" width="563" />
    <figcaption>Каталог с оригинальными исходниками <a href="https://github.com/videogamepreservation/dukenukem3d/tree/master/source" target="_blank">на Github</a>.</figcaption>
  </figure>
  <p id="ZDuw">Даже в оригинальной версии почему-то присутствовали <strong>готовые объектные файлы</strong> (.OBJ), несмотря на наличие рядом исходного кода. </p>
  <blockquote id="Mu92">Это врядли могло быть недосмотром, поскольку перед выкладкой исходники специально чистили от лишнего мусора. </blockquote>
  <p id="kkhb">Как оказалось в дальнейшем, веская причина действительно была.</p>
  <p id="kV7b">Решив проверить, как поведет себя собранное приложение будучи слинкованным с готовыми объектными файлами из оригинальной версии 2003 года, я перекинул их в свою копию и собрал билд. </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="dqzw">Получившийся программный «франкенштейн».. внезапно заработал!</p>
  </section>
  <p id="yim2">Таким образом, поиск проблемного места сократился до четырех объектных файлов. Дальше все было совсем просто: </p>
  <blockquote id="Qvc6">методом исключения, последовательно подменяя исторические OBJ-файлы на собранные вручную, был наконец определен виновник сбоев. </blockquote>
  <p id="R32M">Все свелось к одному единственному файлу <code>A.OBJ</code> и его исходному коду <code>A.ASM</code>. </p>
  <figure id="Tk15" class="m_column">
    <img src="https://img4.teletype.in/files/72/07/72079635-550f-4ead-86e6-c47cf5b10946.jpeg" width="1280" />
    <figcaption>Когда в тему даже линк на группу.</figcaption>
  </figure>
  <h2 id="ahi9">Ассемблер наносит ответный удар</h2>
  <p id="9se7">Разумеется красочный рассказ выше про поиск причины сбоя можно было сильно сократить или вообще оставить за кадром, оставив лишь сухую сводку, из серии «проблема была решена». </p>
  <blockquote id="0ZLC">Но тогда у читателей осталось бы ошибочное представление о поиске решения столь нетривиальной проблемы как о чем-то простом и обыденном.</blockquote>
  <p id="e3iZ">В реальности это был весьма напряжненный процесс «кровавого ресерча», который закончился успехом практически случайно.</p>
  <p id="L8Qr">Но вернемся к нашему <code>A.OBJ</code>.</p>
  <p id="5qdj">Оказалось, что сей интересный файл содержит <strong>ключевую часть</strong> игрового движка Build, на котором работает «Duke Nukem 3D», а его исходный код <a href="https://github.com/videogamepreservation/dukenukem3d/blob/master/SRC/A.ASM" target="_blank">A.ASM</a> представляет собой ~2000 строк на чистом ассемблере. Что весьма немало для чистого ассемблера, не каждый <a href="https://en.wikipedia.org/wiki/Demoscene" target="_blank">демосценер</a> осилит столько наклепать.</p>
  <p id="om3s">Причем ассемблерный код написан так, что собрать его возможно только с помощью WASM из пакета OpenWatcom:</p>
  <pre id="6eUT">;Warning: IN THIS FILE, ALL SEGMENTS ARE REMOVED.  THIS MEANS THAT DS:[]
;MUST BE ADDED FOR ALL SELF-MODIFIES FOR MASM TO WORK.</pre>
  <p id="Bmfi">Поскольку ничем другим (TASM/MASM/JWASM) собрать действительно не получилось, я решил обратиться к <s>Марксу</s> первоисточникам, прочитав наконец <a href="https://github.com/neozeed/duke3d-openwatcom2/releases/tag/v_0_0" target="_blank">описание сборки</a>:</p>
  <blockquote id="JiIo">the assembly is built with version 10, and the audio library is version 11</blockquote>
  <p id="9Hn5">И все встало на свои места.</p>
  <p id="3fHU">Позже были найдены и другие <a href="https://forum.os2world.com/index.php?topic=3580.0;prev_next=next#new" target="_blank">интересные проблемы</a>, связанные со спецификой ассемблера от Watcom, затем подтвердились требуемые шаги по сборке Duke Nukem 3D <a href="https://forums.duke4.net/topic/10026-restoration-of-a-few-games-exes-versions/" target="_blank">строго определенной версией Watcom</a>:</p>
  <blockquote id="jn9K">For Duke3D v1.5, use Watcom C 10.0 and *not* any other version; Not even 10.0a or 10.0b. For any of Matt&#x27;s EXEs, use Watcom C 10.6a (and no other version)</blockquote>
  <p id="H18K">Это чудо, что мой «кавалерийский наскок» с нестабильной версией OpenWatcom v2 и под FreeBSD вообще позволил хоть что-то собрать.</p>
  <p id="DD0J">Был найден <a href="https://virtuallyfun.com/2012/12/05/compiling-duke-nukem-3d-from-source/" target="_blank">пост</a> с готовым Watcom-окружением для сборки Duke Nukem (у все того же neozeed), в приложенном <a href="http://vpsland.superglobalmegacorp.com/install/MS-DOS/duke3d/duke3ds.7z" target="_blank">архиве</a> находится все необходимое: </p>
  <blockquote id="ADr9">Watcom C/C++ 10 и оригинальные исходники Duke Nukem 1.5</blockquote>
  <p id="Hud6">Запустить сборку проще всего из Dosbox, распаковываем архив на диск и переходим в каталог, затем вводим:</p>
  <pre id="L8ls">dosbox .</pre>
  <p id="yDE5">Таким образом эмулятор запустится с текущим каталогом в качестве диска <code>С:</code> Затем вызываем скрипт для установки переменных окружения:</p>
  <pre id="A3o6">WATCOM\SETVARS.BAT</pre>
  <p id="eWRL">Переходим в каталог с исходниками движка и запускаем сборку проблемного <code>A.ASM</code>:</p>
  <pre id="uqxy">CD DUKE3D\BUILD\SRC
WASM A.ASM</pre>
  <p id="Zowi">Ошибок не будет и в результате появится тот самый <code>A.OBJ</code> — причина всех бед и несчастий при сборке Duke Nukem 3D.</p>
  <p id="c589">Так это выглядит в действии:</p>
  <figure id="xvGB" class="m_original">
    <img src="https://img4.teletype.in/files/f0/59/f059cee4-1dbd-4949-8c5c-169e1c409d0c.png" width="652" />
    <figcaption>Так выглядит сборка проблемного A.OBJ с помощью оригинального Watcom 10.</figcaption>
  </figure>
  <p id="PgiV">Все, дальше достаточно скопировать полученный <code>A.OBJ</code> к себе и пересобрать <code>DUKE3D.EXE</code> — получим наконец нормально работающую игру времен моего детства.</p>
  <figure id="s7jp" class="m_original">
    <img src="https://img4.teletype.in/files/33/f7/33f73915-786e-4924-ac44-4f57dd80f8df.gif" width="800" />
    <figcaption>Все герои в сборе.</figcaption>
  </figure>
  <h2 id="yJzh">Эпилог</h2>
  <p id="kE3q">На этом завершается «легенда о хардкоре» — удивительном компиляторе Watcom с непростой судьбой и туманными перспективами.</p>
  <p id="qtJe">Хотя статья создавалась в первую очередь ради знакомства читателей, не заставших «те времена» со этим интересным и уникальным проектом, прекрасно понимаю что игра «Duke Nukem 3D» также станет для многих открытием.</p>
  <blockquote id="D6tq">Если вам интересно «просто поиграть» в золотую классику — разумеется есть куда более простые способы это сделать, нежели сборка игры из ее исходников, тем более исторических и под FreeBSD.</blockquote>
  <p id="sZLo">Для примера, активно развивается проект <strong><a href="https://www.eduke32.com/" target="_blank">EDuke32 </a></strong>— современная версия движка «Build», поддерживающая не только «Duke Nukem 3D», но и многие другие игры, c поддержкой современных ОС, готовыми сборками и сильно улучшенной графикой — все как вы любите.</p>
  <p id="vCnj"></p>
  <figure id="PL6q" class="m_column">
    <img src="https://img2.teletype.in/files/1b/58/1b58d308-fd09-444d-b289-0f365f83d856.png" width="1320" />
    <figcaption>https://timeweb.cloud/</figcaption>
  </figure>
  <h2 id="QDAD">Спонсоры</h2>
  <section>
    <p id="4ZKX">Материал создан при поддержке компании <a href="https://timeweb.cloud/" target="_blank">Timeweb Cloud</a>, за что им огромная благодарность и всяческие респекты.</p>
  </section>
  <p id="LVAd">Оригинал статьи <a href="https://habr.com/ru/companies/timeweb/articles/1055488/" target="_blank">опубликован на Хабре</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/it-wrong-people-2026</guid><link>https://blog.0x08.ru/it-wrong-people-2026?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/it-wrong-people-2026?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>Про &quot;случайных&quot; людей в ИТ</title><pubDate>Sat, 30 May 2026 20:28:31 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/4a/91/4a91fd87-27f7-4dbc-a4f6-29135a1aeb83.png"></media:content><category>people</category><description><![CDATA[<img src="https://img2.teletype.in/files/de/f0/def0f49e-2c3f-4430-9407-05bccc40a7b3.jpeg"></img>Почему не стоит радоваться «очищению отрасли от случайных людей», что будет дальше и почему все это плохо кончится.]]></description><content:encoded><![CDATA[
  <p id="mxec">Почему не стоит радоваться «<a href="https://habr.com/ru/articles/1041348/" target="_blank">очищению отрасли от случайных людей</a>», что будет дальше и почему все это плохо кончится.</p>
  <p id="ygqv">На дворе непростой 2026, по всему миру волнами идут нехорошие события, что отражается и на нашем родном ИТ: </p>
  <blockquote id="42FW">массовые сокращения, повальное урезание бюджетов, закрытия и банкротства.</blockquote>
  <p id="76Oe">На фоне всех этих печальных событий, многие (даже опытные и достойные) люди сейчас теряют работу в ИТ, что вызывает у тех кто пока остался нездоровый энтузиазм и даже злорадство. </p>
  <p id="Ca3Z">Популярно объясняю, почему все же не стоит радоваться чужому горю.</p>
  <figure id="gHno" class="m_column">
    <img src="https://img2.teletype.in/files/de/f0/def0f49e-2c3f-4430-9407-05bccc40a7b3.jpeg" width="1920" />
    <figcaption>Спойлер на 2026 год.</figcaption>
  </figure>
  <h2 id="EcCk">Веселое прошлое</h2>
  <p id="G430">Если вы вдруг забыли, в 2008м году в мире тоже бушевал <a href="https://en.wikipedia.org/wiki/2008_financial_crisis" target="_blank">финансовый кризис</a>, который докатившись до России вызвал (кто бы мог подумать).. повальные сокращения в ИТ-отрасли. </p>
  <p id="nCnx">Ну потому что банки и финансовые организации были и остаются ключевым заказчиком для любых ИТ-компаний и большинства ИТ-продуктов.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="jc9d">Нет банков — нет заказов, нет заказов — 70% заказной разработки в стране сосут лапу, если не чего похуже.</p>
  </section>
  <p id="qImP">На фоне всех этих печальных событий, у автора с его тогдашним начальником состоялся весьма примечательный диалог:</p>
  <p id="BPrf">(нач. отдела)</p>
  <p id="0B9V"> — Кризис это на самом деле хорошо, всех этих недоучек, отбивающих пороги <s>приличных</s> компаний наконец-то смоет. А те кто останутся — вздохнут с облегчением. Можно будет спокойно работать, без авралов и головняков. </p>
  <p id="wKzP">— И просить повышения зарплаты.</p>
  <p id="etNI">Тут стоит заметить, что сидели мы тогда в банке и сама работа была не то чтобы сильно напряжной или плохо оплачиваемой.</p>
  <p id="DcmE">(автор) </p>
  <p id="znSd">— Если кризис затянется и отрасль окончательно загнется — будем заказывать разработку у индусов, как в каком-нибудь Гондурасе.  </p>
  <p id="vp0J">Понимаю что не нравится тратить время на собеседования идиотов, но они (идиоты) пока хотя бы есть. Есть этот «человеческий материал», из которого при желании можно что-то вылепить.</p>
  <p id="kCkJ">(нач. отдела)</p>
  <p id="2sgf">— Что ты там лепить собрался? Если человек приходит и даже не знает как работает многопоточность в джаве.. О чем с ним разговаривать?</p>
  <blockquote id="rcB5">Тут надо заметить, что сам автор тоже не знает как на самом деле работает многопоточность, несмотря на 26 лет практики и владение Java, C, C++, C# и кучей других языков и технологий. </blockquote>
  <p id="HO52">Просто чтобы это осознать ушло 26 лет, по началу-то я тоже заявлял, что все знаю и умею.</p>
  <p id="PMxX">(автор) </p>
  <p id="2jyZ">— А с индусами что будете делать? Хинди учить?</p>
  <p id="489L">(нач. отдела)</p>
  <p id="Cgbw">— Ну индусы нас точно не заменят, они далеко, имеют серьезные культурные различия и все такое. Так что жить мы с тобой будем только лучше, из-за снижения конкуренции. Что до остальных — туда им и дорога. Сами виноваты.</p>
  <p id="P0XV">(автор) </p>
  <p id="eA0j">— Не понимаю, если компания в которой человек просто работал обанкротилась — в чем его вина?</p>
  <p id="xMVq">(нач. отдела)</p>
  <p id="A6dj">— Ну ведь он сам туда устроился? Сам. Значит не умеет выбирать подходящие места для работы. Значит дурак. </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="CiH9">— А дураки в дикой природе не выживают.</p>
  </section>
  <p id="esHK">Тут надо отметить, что ни сам нач.отдела, высказавший столь «мудрую» мысль, ни тот банк хорошо не закончили. </p>
  <p id="L1hZ">Начальник через пару лет уволился и посчитав себя «серьезным специалистом» пошел работать.. обычным программистом в крупную иностранную компанию. Где в итоге и сгинул, никогда больше не занимав руководящих должностей.</p>
  <blockquote id="Gjtl">Ну а банк через несколько лет купили и поглотили конкуренты, полностью заменив весь ИТ-департамент.</blockquote>
  <p id="uBXp">Не то чтобы между высказанной дуростью и последующими событиями была прямая связь, но тем не менее.</p>
  <figure id="p5oy" class="m_column">
    <img src="https://img1.teletype.in/files/81/65/8165d57a-5ff7-4b5c-970f-956742a2345c.jpeg" width="2200" />
    <figcaption>Еще один спойлер на 2026й год. На осень.</figcaption>
  </figure>
  <h2 id="RG30">Веселое настоящее</h2>
  <p id="qy9U">Теперь вернемся в безумный 2026й год, где индусы, несмотря на культурные различия уже вовсю подметают улицы российских городов, «последних выживших» в ИТ заменяет искусственный интеллект, кругом санкции и блокировки а спокойные места остались только на кладбище.</p>
  <p id="KiAd">И то только по предварительной записи. </p>
  <p id="ltnn">Внезапно посреди всего этого апокалиптического угара вновь появляются интересные люди, практически <a href="https://habr.com/ru/articles/1041348/" target="_blank">дословно повторяющие</a> идеи моего бывшего начальника из 2008 года: </p>
  <blockquote id="eaGF">Но еще больше я рад за IT, потому что там стало одним случайным человеком меньше.</blockquote>
  <p id="7HI1">Предполагается, что озвучивает это состоявшийся профессионал, который давно и успешно работает в ИТ, а ныне радеет за чистоту <s>нации</s> отрасли.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="usX0">Да, такие люди в отрасли действительно есть, их много и подобные идеи весьма популярны. </p>
  </section>
  <p id="ApKa">Тогда, в далеком 2008м мне не удалось отстоять свою точку зрения, сказалась разница в возрасте и жизненном опыте. Ну и конечно  социальное положение — спорить с руководством занятие все же не особо перспективное.</p>
  <p id="q7IG">Но теперь, протянув в ИТ дольше большинства моих коллег и начальников, думаю имею полное право донести свои мысли широкой аудитории.</p>
  <p id="c59w">Поехали.</p>
  <figure id="NuNn" class="m_column">
    <img src="https://img2.teletype.in/files/1f/98/1f98cb01-de9a-4501-af20-5ce949159e29.jpeg" width="1920" />
    <figcaption>Тимлид, который вам рад.</figcaption>
  </figure>
  <p id="A3yr">Действительно, многим профессионалам <strong>не нравится</strong> повышенный интерес к ИТ-отрасли среди <s>плебеев</s> широких масс — в интернете куча статей, роликов и постов, высмеивающих недалеких «вкатунов в ИТ» и продавцов ИТ-курсов, откровенный глумеж над «джунами» и прочее подобное.</p>
  <p id="PgMZ">Все это понятно и предсказуемо, но есть нюанс: </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="K19e">99% потребителей околоайтишного контента — <strong>не</strong> работают в ИТ, не являются программистами, архитекторами, CTO и так далее.</p>
  </section>
  <p id="42U2">Я вижу это по <a href="https://blog.0x08.ru/digital-mars-cpp-on-dos" target="_blank">собственным</a> и чужим техническим статьям, где при десятках тысяч просмотров в обсуждении всегда мало комментариев <strong>по делу</strong>, от других опытных программистов, а основная масса сообщений  — бесполезный обывательский треп.</p>
  <p id="nLxg">Видно это далеко не только по Хабру, точно также дела обстоят и на других (в том числе англоязычных) площадках. </p>
  <p id="t6fH">Соотношение везде примерно одинаковое: </p>
  <blockquote id="jADR">на одного реального специалиста, который действительно работает по профилю приходится <strong>несколько тысяч</strong> заинтересованных «зрителей».</blockquote>
  <p id="Jnyn">Даже на профильных ресурсах, посвященных например <a href="https://www.betaarchive.com/forum/" target="_blank">ретро-компьютерам</a> или <a href="https://www.reddit.com/r/haskellquestions/" target="_blank">редким языкам программирования</a>, где по-идее должны обитать только самые упертые профи сохраняется такое же соотношение.</p>
  <p id="zmgt"></p>
  <h2 id="98va">Веселое будущее</h2>
  <p id="kwoi">Теперь представим, что интерес к ИТ и компьютерам среди обывателей внезапно угас  — нет больше всех этих «вкатунов», «джунов» и странных персонажей, работающих грузчиками или продавцами, но всегда имеющих свободное время для поиска точной цитаты из документации. </p>
  <blockquote id="Wzv5">Нет дурацких постов про «вкат в ИТ за месяц без образования» с сотнями комментариев и смешных мемов про <s>тупых</s> рекрутеров.</blockquote>
  <p id="ai4i">Представили? Обрадовались? Вздохнули с облегчением?</p>
  <figure id="0Njz" class="m_column">
    <img src="https://img2.teletype.in/files/9a/61/9a61b6c4-a7d7-4694-bc97-a8235e2275c1.jpeg" width="738" />
  </figure>
  <p id="5dDl">А теперь вопрос: </p>
  <blockquote id="2Jtf">что в таком случае станет с вами — профессионалами и ИТ-экспертами?</blockquote>
  <p id="NAGq">Кому будет нужна экспертиза, которая работает <strong>лишь в сравнении с</strong> обывателями и кто в принципе сможет оценить вашу гениальность в таких непростых условиях? Жена и мама? </p>
  <p id="LapV">Кому вы сможете доказать свою ценность <em>вне отрасли</em>? Кто заплатит за вашу работу, ценность которой внезапно стала сомнительной?</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="SMdc">Нет экспертизы — нет и достойного отношения, нет достойного отношения — нет приличных чеков. Все просто.</p>
  </section>
  <p id="FxBi">Понимаю, что для многих это станет открытием: </p>
  <blockquote id="sxU0">«экспертность» это всегда <strong>внешняя</strong> оценка, возможная только внутри своей отрасли. </blockquote>
  <p id="mcEO">Нет отрасли — не будет и экспертов.</p>
  <p id="UtmZ">А ведь утрата массового интереса к ИТ, разочарование и показательная «отмена» закончится именно этим —  отрасль просто перестанет существовать.</p>
  <p id="VG1I">И вот уже титулованный «сеньор-помидор» Василий, с резюме длиной с мою ногу вынужен идти работать простым дворником. Как в 90е происходило с образованными физиками-ядерщиками.</p>
  <p id="AjHN">Повторюсь для тех кто не осознал: </p>
  <blockquote id="XhBk">это происходит не потому что сам Василий — плохой, хреново учился или работал, просто обществу <strong>внезапно стали не нужны</strong> профессионалы в этом конкретном деле.</blockquote>
  <p id="vWrN">Как это было с физиками-ядерщиками, да.</p>
  <p id="hyC7">При всем этом (и вопреки попыткам изоляции), ИТ-сообщество в России все также тесно связано с остальным миром поэтому при дальнейшем усилении кризисных процессов, никаких собственных экспертов в РФ просто не останется — все окончательно разбегутся. </p>
  <p id="4tV3">Будет примерно как с футболом: </p>
  <blockquote id="eIb9">импортированные за безумные деньги иностранные игроки, выпускаемые на поле под российским флагом.</blockquote>
  <p id="TpjT">Собственно что-то подобное уже происходило в начале 90х — на заре развития отечественного ИТ, когда для любого сколь-нибудь серьезного проекта вызывали дорогих иностранных специалистов из IBM и Microsoft, а местным талантливым Василиям открыто говорили, что «ты только лаптем щщи хлебать умеешь».</p>
  <p id="cFQO">Хотя буквально за пять лет до этого самой массовой профессией в стране была профессия инженера.</p>
  <p id="C1kT">Так стоит все это повторять?</p>
  <p id="InJ8">Понимаю, что читающие эти строки врядли имеют заметное влияние в обществе и точно не принимают ключевых решений для целой отрасли, но может хотя-бы стоит перестать публично радоваться чужому горю?  </p>
  <p id="Mkq2">Сегодня вы — профессионал и эксперт <s>с мировым именем</s> восторгаетесь сокращениями и увольнениями «лишних людей» в ИТ-индустрии. А завтра вам же придется по работе иметь дело с колхозниками, не отличающими бит от байта, поскольку никаких других не останется. </p>
  <blockquote id="IHZ2">А послезавтра вы сами начнете работать в этом же колхозе <strong>за еду</strong>, поскольку вся ИТ-экспертиза и опыт перестанут чего-то стоить.</blockquote>
  <p id="Wj0R">Или такая перспектива еще не очевидна? </p>
  <figure id="JRHm" class="m_column">
    <img src="https://img4.teletype.in/files/79/22/79228a70-0ec8-431e-be6b-1083bb66b7c5.jpeg" width="1080" />
  </figure>
  <h2 id="4Q9R">Немного понимаю в компьютерах</h2>
  <p id="jV11">Представьте себе супермена со сверхчеловеческими способностями, умеющего летать <s>на пердючем пару</s> и стрелять лучами из глаз, но вся сила которого.. <strong>мгновенно пропадает</strong> стоит только окружающим перестать в него верить — вот это и есть та самая «экспертиза в ИТ»:</p>
  <blockquote id="Bkcf">полностью выдуманное, максимально далекое от работы лопатой действо, суть которого не получится объяснить обывателю.</blockquote>
  <p id="V05B">На этой вере в высокотехнологичное волшебство как ни крути все ИТ и держится, время от времени обновляя вывеску. </p>
  <p id="Rb06">Даже моя собственная деятельность — все эти <a href="https://blog.0x08.ru/cray-resurrection-part-1" target="_blank">крутые статьи на технические темы</a>, была бы невозможной без постоянного интереса к ИТ от простых обывателей — от тех самых «вкатунов», выпускников курсов, «джунов» и прочих слесарей-сантехников, для которых работа в ИТ так и осталась мечтой.</p>
  <p id="Uslz">Да, коллеги по отрасли тоже проявляют определенный интерес к моей работе, но при соотношении «1 профи на 10000 <s>идиотов</s> любителей» все это бы просто не имело никакого смысла.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="fyVJ">Без гоев нет гавваха. (ц)</p>
  </section>
  <p id="G45T">Поэтому вполне очевидно, что я выступаю и всегда буду выступать за популяризацию ИТ-отрасли и технологий подручными средствами, прекрасно понимая, что не всем суждено играть в высшей лиге. </p>
  <p id="SI9Q">Но дворовая игра в футбол это тоже футбол, пусть и любительский. И только из любительства появляются профессионалы.</p>
  <p id="vKvl">Хотите новых Роналду и Месси? — заставляйте всю страну играть в дворовый футбол. По-другому, увы, не работает.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/real-underground-modern-bbs-2026</guid><link>https://blog.0x08.ru/real-underground-modern-bbs-2026?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/real-underground-modern-bbs-2026?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>Настоящий андеграунд:  современные BBS</title><pubDate>Thu, 21 May 2026 11:42:04 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/10/b6/10b68d36-9110-430b-a5cf-09331472aba4.png"></media:content><category>it-history</category><description><![CDATA[<img src="https://img3.teletype.in/files/e6/1c/e61cdd4b-9256-4833-b87b-382e049f2fd1.gif"></img>За окном ночь и огни большого города, в кружке горячий кофе а на экране монитора медленно грузится стильная ASCII-заставка. Наконец появляется приглашение:  Welcome to Vortex BBS. Press a key.]]></description><content:encoded><![CDATA[
  <p id="bDFZ">За окном ночь и огни большого города, в кружке горячий кофе а на экране монитора медленно грузится стильная ASCII-заставка. Наконец появляется приглашение:  <code>Welcome to Vortex BBS. Press a key.   </code></p>
  <p id="7zcA">Нет, это не очередная история времен бурной молодости автора и на дворе все также 2026й год а не начало 90х. Но даже в 21м веке с ИИ, роботами и Илоном Маском в сети остались удивительные места, где время остановилось: </p>
  <blockquote id="3M37">в ходу консольные терминалы и модемы а экран украшает ASCII-графика. </blockquote>
  <p id="xxHP">Именно такие места мы сейчас посетим — добро пожаловать в удивительный мир современных BBS!</p>
  <figure id="ESHF" class="m_original">
    <img src="https://img3.teletype.in/files/e6/1c/e61cdd4b-9256-4833-b87b-382e049f2fd1.gif" width="800" />
    <figcaption>Аутентичное оформление. FreeBSD, BBS, 2026й год.</figcaption>
  </figure>
  <h2 id="CYll">Справка для непричастных</h2>
  <p id="y4WG">Цитируя <s>погибающую</s> <a href="https://ru.wikipedia.org/wiki/BBS" target="_blank">википедию</a>:</p>
  <blockquote id="hHlB"><strong>BBS</strong> (bulletin board system — <a href="https://ru.wikipedia.org/wiki/%D0%AD%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%B4%D0%BE%D1%81%D0%BA%D0%B0_%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9" target="_blank">электронная доска объявлений</a>, «борда») — широко использовавшийся во времена раннего интернета, способ общения пользователей компьютеров через <a href="https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D1%83%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D1%8B%D0%B9_%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF" target="_blank">коммутируемые телефонные сети</a>.</blockquote>
  <p id="7ANv">Сухое описание выше хотя и раскрывает суть явления, но не дает всей глубины картины, поскольку BBS в конце 80х — начале 90х стали культурным феноменом, сильно повлияв на процессы коммуникации между людьми.</p>
  <p id="rBFZ">Регистрация, модерация, личные переписки и публичные группы, концепция форумов — все это пошло именно отсюда.</p>
  <p id="G1Nt">Про эпоху BBS даже успели снять трехсерийный <a href="https://en.wikipedia.org/wiki/BBS:_The_Documentary" target="_blank">документальный фильм</a>, ныне <a href="https://archive.org/details/BBS_Documentary_DVD_Set" target="_blank">доступный</a> для свободного скачивания.</p>
  <figure id="PIEm" class="m_column">
    <img src="https://img3.teletype.in/files/e8/67/e8675415-1931-4ecb-a642-ca6cab19ea29.jpeg" width="1200" />
    <figcaption>Типичные пользователи BBS.</figcaption>
  </figure>
  <p id="LlLc">Исторически BBS служили двум важным целям: пообщаться с другими пользователями путем текстовых сообщений и обменяться файлами.</p>
  <p id="dnff">Не просто скачать что-то с борды, а именно обменяться: </p>
  <blockquote id="Fk5m">на скачивание выставлялся лимит, который можно было поднять что-то загрузив обратно, причем чтобы не заморачиваться — рейтинг считался от размера загруженного.</blockquote>
  <p id="0yNz">Чем пользовались самые ушлые из юзеров, заливая всякий мусор с сильным сжатием ради повышения рейтинга.</p>
  <h1 id="firstHeading">9600 бод и все-все-все</h1>
  <p id="M5K5">История BBS в нашей стране весьма обширна и тесно связана с <a href="https://neolurk.org/wiki/%D0%A4%D0%B8%D0%B4%D0%BE" target="_blank">ФИДО</a>, поскольку большая часть борд были одновременно фидошными нодами, а звонившие юзеры — пойнтами.</p>
  <blockquote id="Ek9z">И сама фидошка и некоторые действующие отечественные борды до сих пор <strong>существуют</strong>, но ввиду обширности этой темы — оставлю их для следующих интересных статей.</blockquote>
  <p id="l9aN">А пока можете насладиться <a href="https://neolurk.org/wiki/9600_%D0%B1%D0%BE%D0%B4_%D0%B8_%D0%B2%D1%81%D0%B5-%D0%B2%D1%81%D0%B5-%D0%B2%D1%81%D0%B5" target="_blank">бессмертными произведениями Андрея Щербакова</a>, неплохо передающими ту самую атмосферу.</p>
  <figure id="ddpd" class="m_column">
    <img src="https://img4.teletype.in/files/f0/29/f029059f-cf09-4e92-ba7e-506b81b12e52.png" width="874" />
    <figcaption>Логотип программы SyncTERM. Так выглядит &quot;старая школа&quot;.</figcaption>
  </figure>
  <h2 id="pICC">Подключение</h2>
  <p id="yLec">Чтобы с комфортом бороздить просторы терминального киберпространства, нужен специальный <s>лед</s> софт, поддерживающий дедовские трюки с терминалом и ASCII-графикой. </p>
  <p id="Pt4w">Конечно подключиться возможно и с помощью стандартного telnet или ssh-клиента, которые присутствуют в любой современной ОС, но тогда вместо стильной графики вы увидите лишь страшные «кракозябли».</p>
  <p id="vAdS">Типа таких:</p>
  <figure id="TPop" class="m_column">
    <img src="https://img1.teletype.in/files/43/f7/43f7d356-5a5b-4b4d-afb6-fbcc3bb2655f.png" width="720" />
    <figcaption>Хотя этот скриншот еще более уникален, поскольку это приглашение <a href="https://www.ipingthereforeiam.com/bbs/?step=detail&id=19554" target="_blank">китайской борды</a>, расположенной на Тайване. Так что это текстовые китайские ASCII-кракозябли.</figcaption>
  </figure>
  <p id="Qcrk">Для этой статьи автор использовал наверное самый популярный и известный <s>среди пожилых кибервоинов</s> <a href="https://syncterm.bbsdev.net/" target="_blank">терминал</a>:</p>
  <figure id="s5CH" class="m_original">
    <img src="https://img2.teletype.in/files/5a/d0/5ad0b3f5-b4ee-4d80-b671-070f26909af0.png" width="654" />
    <figcaption>Сочетание консольного интерфейса, списка BBS и 2026 года определенно разорвет многим шаблон.</figcaption>
  </figure>
  <p id="MKnP">Как шутят его авторы:</p>
  <blockquote id="HCPh"><a href="https://syncterm.bbsdev.net/" target="_blank">SyncTERM</a> — giving a fairly small group of people a huge amount of joy.</blockquote>
  <p id="RdPU">Терминал присутствует в виде готового пакета во многих дистрибутивах Linux и разумеется во всех BSD, одну из которых автор и использовал для создания этой замечательной статьи:</p>
  <figure id="paTf" class="m_column">
    <img src="https://img4.teletype.in/files/fa/ae/faae66a7-7efc-48eb-8ebb-a71c7c8c77e9.png" width="831" />
    <figcaption>Можно сказать <a href="https://www.freshports.org/comms/syncterm" target="_blank">коренной обитатель</a> портов, живет здесь с 2006 года.</figcaption>
  </figure>
  <p id="mhVy">Хотя разумеется существуют сборки и для более обывательских <a href="https://syncterm.bbsdev.net/SyncTERM-macOS-fat.zip" target="_blank">Mac</a> и <a href="https://syncterm.bbsdev.net/syncterm64.zip" target="_blank">Windows</a>, так что никто не уйдет огорченным. </p>
  <h3 id="UXpx">Простой случай</h3>
  <p id="SGHi">В самом простом случае для подключения к борде (BBS) нужно лишь вызвать программу-терминал, передав ей строку подключения:</p>
  <pre id="FI4e" data-lang="bash">syncterm telnet://www.theunderground.us:10023 </pre>
  <p id="clmA">Появится окно, в котором через какое-то время отобразится ASCII-лого удаленной BBS-системы со стильным приглашением:</p>
  <figure id="bVlA" class="m_original">
    <img src="https://img3.teletype.in/files/e2/c6/e2c67d76-7d79-4356-8fe2-557629f8a2e5.png" width="654" />
    <figcaption>Да, у сисопа (админа) тут действительно ник &quot;Крестный отец&quot;, это вам не попсовый <a href="https://www.rottentomatoes.com/m/hackers" target="_blank">Zero Cool</a>.</figcaption>
  </figure>
  <h3 id="pyab">Сложный случай</h3>
  <p id="x5As">В сложном случае придется обходить блокировку доступа для РФ, поскольку даже сисопы последних сохранившихся BBS почему-то принимают отечественных пользователей за злобных хакеров.</p>
  <p id="cCwX">Так что используем трюк с <code>ncat</code> из пакета известного сканера открытых портов <a href="https://nmap.org/" target="_blank">nmap</a>, сначала пробросив порт подключения через прокси:</p>
  <pre id="NBzv" data-lang="bash">ncat -l 127.0.0.1 2323 -c &quot;ncat --proxy-type socks5 --proxy xx.xx.xx.xx:3145 blackflag.acid.org 23&quot;</pre>
  <p id="b5Qb">А затем указав <code>syncterm</code> подключиться через этот порт:</p>
  <pre id="AlhH" data-lang="bash">syncterm telnet://127.0.0.1:2323</pre>
  <p id="hflR">Вот таким нехитрым способом попадаем в Зазеркалье для избранных, без всяких белых кроликов.</p>
  <figure id="UL9f" class="m_original">
    <img src="https://img1.teletype.in/files/4c/41/4c41e6b3-a73d-4505-90f5-f109d6ad6d1a.jpeg" width="2592" />
    <figcaption>Эталонная кибердека для элитного кибервоина 21-века, тотальный кастом. <a href="https://themechanicaltype.blogspot.com/2022/02/the-cyberdeck.html" target="_blank">Отсюда</a>. </figcaption>
  </figure>
  <h2 id="OHEt">Кибердека</h2>
  <p id="pJlr">Бороздить просторы терминального киберпространства в 21м веке с помощью нового и блестящего Mac считается <s>уделом плебеев</s> моветоном, настоящие кибер-ковбои собирают себе полностью кастомные девайсы из частей смартфонов и ноутбуков. Временами доводя глубину проработки до создания кастомных прошивок и даже отдельных плат.</p>
  <p id="s5BT">Иногда на свет появляются настоящие хтонические техношедевры <s>шального</s> инженерного воображения:</p>
  <figure id="Ajyk" class="m_column">
    <img src="https://img3.teletype.in/files/67/ce/67cec025-1970-4da0-95ca-a662df128bd3.jpeg" width="1080" />
    <figcaption>Готовый реквизит для кино про хакеров. Причем <a href="https://www.youtube.com/watch?v=gIWp_F9PPzI" target="_blank">аппарат</a> действующий.</figcaption>
  </figure>
  <p id="BNWJ">Судя по этой <a href="https://www.reddit.com/r/cyberDeck" target="_blank">группе Reddit</a> явление обрело немалый размах и популярность, познакомив тысячи юных подаванов с занимательным процессом создания кастомной электроники.</p>
  <p id="xZHa">Альтернативным вариантом кибердеки (из достойных) является использование редкого или винтажного железа в качестве терминала для подключения к BBS. Характерный пример:</p>
  <figure id="TXLN" class="m_column">
    <img src="https://img1.teletype.in/files/08/b5/08b5cf26-5140-4294-bf73-3f55b5f9afb2.png" width="3026" />
    <figcaption>Реплика Apple I 1976 года, с подключением к одной из современных BBS. <a href="https://tinkerdifferent.com/threads/im-in-the-apple-1-club.1865/" target="_blank">Отсюда</a>.</figcaption>
  </figure>
  <p id="UxV7">К сожалению автор <s>не имеет столько свободного времени</s> недостаточно элитен чтобы собрать собственную кибердеку, поэтому использовал один из своих винтажных ноутбуков с FreeBSD, на котором и создавалась эта статья. </p>
  <p id="N3zK">Так выглядит подключение к современной BBS с моего <a href="https://www.cnet.com/reviews/asus-f3ke-review/" target="_blank">боевого аппарата</a>, заставшего интернет без Цукерберга и его <s>позорного</s> детища:</p>
  <figure id="VV2S" class="m_original">
    <img src="https://img2.teletype.in/files/90/79/9079fb7d-6400-47f0-9c13-47e9363f9134.gif" width="600" />
    <figcaption>Спецэффекты добавлены для большего антуража.</figcaption>
  </figure>
  <p id="qxZc">Разобравшись с подключением и кибердеками, переходим к следующему важному этапу. </p>
  <h2 id="3shu">Регистрация</h2>
  <p id="Y3Yb">Почти все BBS после подключения требуют (пусть и условную) регистрацию, но ничего сложного тут нет и капчу проходить не придется:</p>
  <figure id="cbiV" class="m_original">
    <img src="https://img2.teletype.in/files/da/bf/dabfb580-58ee-43c8-94e8-36b74b778c68.png" width="654" />
    <figcaption>Практически на всех BBS процесс регистрации оформлен максимально стильно и необычно.</figcaption>
  </figure>
  <p id="sAtW">Весь этот движ только лишь ради уникального ника с паролем — чтобы админам было кого банить. Временами просят еще почту и <s>прописку</s> место жительства, однако никак их не проверяя.</p>
  <p id="lTQT">Так что смело вводим в поле адреса <a href="https://en.wikipedia.org/wiki/221B_Baker_Street" target="_blank">известное</a>:</p>
  <blockquote id="c1Pn">221B Baker Street</blockquote>
  <p id="7mmq">И не менее <a href="https://en.wikipedia.org/wiki/Epstein_files" target="_blank">известное</a> <code>jeevacation@gmail.com</code> в качестве почты — все будет замечательно работать.</p>
  <h2 id="S453">Списки BBS</h2>
  <p id="jUbe">Теперь наверное стоит рассказать откуда брать списки борд для подключения. Для начала существуют фанатские сайты, сильно напоминающие каталоги ссылок времен раннего интернета:</p>
  <figure id="Xw9D" class="m_column">
    <img src="https://img2.teletype.in/files/13/8d/138db991-0cb9-4c97-918d-53b124d5443d.png" width="948" />
    <figcaption>Список BBS от 8-Bit Boyz, разделы по типу <strong>железа</strong>, на котором работает BBS.</figcaption>
  </figure>
  <p id="Ehmq">Вот вам несколько таких сайтов-каталогов для начала погружения в терминальное киберпространство:</p>
  <ul id="yq2N">
    <li id="M66c"><a href="https://8bitboyz.com/bbs-directory/" target="_blank">8-Bit Boyz</a></li>
    <li id="pTUB"><a href="https://coan.net/bbslist/" target="_blank">MICHAEL&#x27;S BBS LIST</a></li>
    <li id="tJir"><a href="https://www.telnetbbsguide.com/bbs/list/brief/" target="_blank">Telnet BBS Guide</a></li>
  </ul>
  <p id="gzdP">Отдельно доставляет <a href="https://www.ipingthereforeiam.com/bbs/" target="_blank">этот сайт</a>, построенный в стиле корпоративного портала, но при этом целиком посвященный олдскульным бордам.</p>
  <p id="ymVE">Там же реализован виджет с отображением всех действующих BBS на планете:</p>
  <figure id="zB0B" class="m_column">
    <img src="https://img1.teletype.in/files/82/97/82979254-daf5-4538-be19-4d1856f13dac.gif" width="800" />
    <figcaption>Особенно доставляет обилие BBS в Австралии - кто бы мог подумать.</figcaption>
  </figure>
  <p id="pvmQ">Помимо каталогов, доступных из интернета, на каждой работающей BBS можно найти раздел со списком других борд, часто менее известных и с более редким контентом и обитателями. Так это выглядит:</p>
  <figure id="WDde" class="m_original">
    <img src="https://img3.teletype.in/files/ee/12/ee123689-9815-4ede-a1e4-461f3db51968.png" width="654" />
    <figcaption>Списки BBS бывают весьма длинными, тут такой список занял три экрана.</figcaption>
  </figure>
  <p id="ly3D">Теперь показываю что находится внутри современных BBS, поскольку мало у кого из читателей хватит времени и терпения для всех этих приседаний с <code>syncterm</code>, подключением и регистрацией.</p>
  <figure id="vo4g" class="m_column">
    <img src="https://img1.teletype.in/files/cb/1b/cb1bbd4b-cb8d-4d23-960f-7b3570ba58b7.png" width="958" />
    <figcaption>Практически у каждой BBS есть своя стильная заставка с ASCII-графикой.</figcaption>
  </figure>
  <h2 id="akOo">The Vortex</h2>
  <p id="4eym">              Название борды: <a href="https://www.ipingthereforeiam.com/bbs/?step=detail&id=17424" target="_blank">The Vortex</a><br />                   Подключение: Telnet<br />                                 Telnet: <code>telnet://vortexbbs.com</code><br />                                 Сисоп: Haakon &amp; Arelas<br />           Местонахождение: Charlotte, NC<br />                      Движок BBS: Mystic</p>
  <p id="AffN">                                   Сайт: http://vortexbbs.com<br /> </p>
  <p id="YLFj">Цитируя оригинальное описание:</p>
  <blockquote id="cZyH">An oldschool board from the 1997 art scene in the 864 area. Totally artd out and modded. Original in-house developed apps. Unique BBS experience, classic and modern..</blockquote>
  <p id="Nw0b">Борда забита под завязку олдскульным ASCII-артом, демо и всем подобным, а судя по активным перепискам — борда очень даже живая:</p>
  <figure id="JOFd" class="m_original">
    <img src="https://img1.teletype.in/files/c3/6a/c36a402d-52a6-45da-be05-95da843477dc.png" width="654" />
    <figcaption>&quot;Still alive sorry&quot; - лучшее описание всего явления.</figcaption>
  </figure>
  <p id="oi6A">К сожалению сисоп успел приделать некий аналог кармы на Хабре, поэтому чтобы попасть в раздел с файлами придется эту карму прокачивать: </p>
  <figure id="JRRB" class="m_original">
    <img src="https://img2.teletype.in/files/55/93/55930ccf-66ff-4d9f-bc5b-8c00f81fc602.png" width="654" />
  </figure>
  <p id="N9Tl">Так выглядит раздел с файлами, в который простых пользователей с порога не пускают:</p>
  <figure id="088X" class="m_original">
    <img src="https://img4.teletype.in/files/7d/18/7d18f3c2-0b1d-4acb-8eda-0b3b18d916ff.gif" width="652" />
    <figcaption>Чистый андеграунд, чистое искусство.</figcaption>
  </figure>
  <p id="mPk6">Из смешного и курьезного, нашлось вот такое сообщение времен выборов 2020 года в США:</p>
  <figure id="rf5t" class="m_original">
    <img src="https://img3.teletype.in/files/a3/5a/a35a9ae2-52ae-4f8b-9d51-1efa18baded6.png" width="654" />
  </figure>
  <p id="KG41">Веселое место, вход с российского IP кстати пока не блокируют, так что можно подключаться без приседаний с проксями.</p>
  <p id="gUle">Но едем дальше.</p>
  <figure id="pZkZ" class="m_original">
    <img src="https://img1.teletype.in/files/46/b2/46b27285-17d7-4ea2-ba99-62da3ada7108.png" width="648" />
    <figcaption>Одно из самых стильных приглашений что я видел.</figcaption>
  </figure>
  <h2 id="LmrB">DIGITAL WARFARE</h2>
  <p id="Q72v">                      Название:  <a href="https://www.telnetbbsguide.com/bbs/digital-warfare/" target="_blank">D i G i T A L WARFARE</a><br />               Подключение: Telnet<br />                             Telnet: <code>telnet://bbs.digital-warfare.net:1337</code><br />                            Сисоп:  CrackerTron<br />      Местонахождение:  Underground<br />                 Движок BBS:  Mystic<br /></p>
  <p id="fth1">Перед вами реинкарнация <a href="https://demozoo.org/bbs/10284/" target="_blank">старой</a> и известной борды начала 90х, переделанная на современные технологии.</p>
  <p id="ugIh">Так выглядит приветственное сообщение для новых юзеров:</p>
  <figure id="xL8r" class="m_original">
    <img src="https://img2.teletype.in/files/54/63/54638a2c-284b-48f8-b6f3-85bba4325e56.png" width="654" />
    <figcaption>Новейшая борда, заново открытая в 2025 году!</figcaption>
  </figure>
  <p id="b56X">Тут хранится 2 терабайта файлов времен расцвета сцены: </p>
  <blockquote id="CXGB">ASСII-арт, различные демо, электронные журналы и конечно варез тех лет.</blockquote>
  <p id="qcGi">К сожалению чтобы добраться до файлов нужно прокачивать рейтинг, моего гостевого не хватило чтобы туда попасть, так что скриншотов не будет.</p>
  <p id="FSlQ">В свои лучшие годы эта борда даже имела <a href="https://www.pouet.net/prod.php?which=85820" target="_blank">отдельное интро</a>:</p>
  <figure id="Rn7A" class="m_original">
    <img src="https://img4.teletype.in/files/77/e8/77e86b4f-ca56-47d8-8804-9037f60f9265.gif" width="638" />
    <figcaption>Интро 1992 года отлично работает в Dosbox до сих пор.</figcaption>
  </figure>
  <p id="nchO">Так выглядит статистика пользователя:</p>
  <figure id="EvQN" class="m_original">
    <img src="https://img2.teletype.in/files/d4/51/d451a3da-c9d8-40fa-9c4f-2632de5ec7c1.png" width="648" />
    <figcaption>Все оформление отрисовано вручную.</figcaption>
  </figure>
  <p id="UzlD">Главное меню борды:</p>
  <figure id="b5qR" class="m_original">
    <img src="https://img1.teletype.in/files/86/09/860926d5-423e-4bfa-906e-242eb3f84eb5.png" width="654" />
    <figcaption>Вся эта красота также отрисована вручную.</figcaption>
  </figure>
  <p id="djNK">Еще тут весьма активные переписки юзеров:</p>
  <figure id="u1i9" class="m_original">
    <img src="https://img2.teletype.in/files/5d/59/5d59f357-eed3-4294-9fa1-5ad2e793e582.png" width="654" />
    <figcaption>&quot;Re: Apple II Forever&quot; - где еще вам смогут ответить по технике конца 80х?</figcaption>
  </figure>
  <p id="mOdq">При должном уровне английского можно пообщаться с крайне интересными персонажами.</p>
  <p id="FL0H">С российских IP пока пускают, но в «intrusion attempts» уже замечают:</p>
  <figure id="D80d" class="m_original">
    <img src="https://img4.teletype.in/files/b9/d5/b9d5c254-ecbe-4cad-84fe-d00be7a74a4c.png" width="654" />
  </figure>
  <h2 id="CaYw">Adept BBS</h2>
  <p id="2m2R">                      Название:  <a href="https://8bitboyz.com/bbs-listing/adept-bbs/" target="_blank">Adept BBS</a><br />               Подключение: Telnet<br />                             Telnet: <code>telnet://adeptbbs.com</code><br />                            Сисоп:  Ragtop<br />      Местонахождение:  Louisville, KY<br />                 Движок BBS:  Worldgroup 3.3</p>
  <p id="3YbX">Оригинальное описание из BBS-списка:</p>
  <blockquote id="X6Ud">Old school Worldgroup board in Louisville, Ky. Original beta testers for MajorMUD along with many other games, including Tradewars and Swords of Chaos.</blockquote>
  <p id="ZbPq">Борда посвящена целиком текстовым онлайн-RPG — <a href="https://mud.fandom.com/wiki/MUD" target="_blank">MUD</a>, под эту тему тут и доступные файлы и все обсуждения.</p>
  <p id="KGye">Приветственное сообщение для новых юзеров:</p>
  <figure id="Vwlx" class="m_original">
    <img src="https://img2.teletype.in/files/5e/ff/5effa665-75e0-4091-8c4d-b9939c73c234.png" width="648" />
  </figure>
  <p id="1egH">Так выглядит главное меню:</p>
  <figure id="Zv8x" class="m_original">
    <img src="https://img1.teletype.in/files/07/6a/076afb5a-9463-41ee-b156-554cc706095a.png" width="648" />
  </figure>
  <p id="xyu9">Раздел с файлами:</p>
  <figure id="R6eN" class="m_original">
    <img src="https://img1.teletype.in/files/4a/ee/4aee7a1e-5ec3-4a3a-adab-f139eca5c0d3.png" width="648" />
  </figure>
  <h2 id="UD8j">Backwood Realm BBS</h2>
  <p id="F2Oh">                      Название:  <a href="https://8bitboyz.com/bbs-listing/backwood-realm-bbs/" target="_blank">Backwood Realm BBS</a><br />               Подключение: Telnet, SSH<br />                             Telnet: <code>telnet://bwrbbs.ddns.net</code></p>
  <p id="wcky">                                SSH: ssh<code>://bwrbbs.ddns.net</code><br />                            Сисоп:  Tim Wray<br />      Местонахождение:  Bedford, Indiana, USA<br />                 Движок BBS:  Synchronet</p>
  <p id="CSNY">Еще одна реинкарнация небольшой домашней борды 90х:</p>
  <figure id="lxdh" class="m_column">
    <img src="https://img2.teletype.in/files/98/3f/983f413c-e867-406e-a12f-e2b869e7be35.png" width="1790" />
    <figcaption>Из <a href="http://bbslist.textfiles.com/812/" target="_blank">списка всех BBS</a>, как действующих так и исторических.</figcaption>
  </figure>
  <p id="OtEx">Обновленная версия работает с 2008 года с доступом через telnet/ssh и посвящена <a href="https://mud.fandom.com/wiki/MUD" target="_blank">текстовым RPG</a>, собственно на борде установлены LORD и <a href="https://www.myabandonware.com/game/legend-of-the-red-dragon-ii-new-world-31a" target="_blank">LORD2</a>, выглядит это как-то так:</p>
  <figure id="Zcj3" class="m_original">
    <img src="https://img3.teletype.in/files/2c/3b/2c3bce11-bd14-47f6-b74d-0caa317be02f.png" width="640" />
  </figure>
  <p id="EPiZ">У борды есть даже <a href="https://www.facebook.com/bwrbbs/" target="_blank">собственная страничка на Фейсбуке</a>, довольно свежая.</p>
  <p id="pv5X">Так выглядит главное меню:</p>
  <figure id="qaEK" class="m_column">
    <img src="https://img1.teletype.in/files/81/c8/81c83ab8-0c77-4e2a-883c-a8370ec08ec1.png" width="748" />
  </figure>
  <p id="jdrV">Приветственное сообщение для новых юзеров:</p>
  <figure id="cGHI" class="m_column">
    <img src="https://img4.teletype.in/files/34/e4/34e4ae3f-0e0b-48f0-8d06-21721ef9934c.png" width="748" />
    <figcaption>Сисопы, BBS и 2026й год.</figcaption>
  </figure>
  <p id="JZGF">Раздел с файлами:</p>
  <figure id="ELoT" class="m_column">
    <img src="https://img1.teletype.in/files/c0/bb/c0bba885-02e9-4899-b5fc-bc2c37333837.png" width="748" />
    <figcaption>Откуда еще качать <s>несвежие</s> либы для Паскаля в 2026м году, кроме как с борд?</figcaption>
  </figure>
  <h2 id="168u">BLACK FLAG BBS</h2>
  <p id="e0cF">                       Название:  <a href="https://www.telnetbbsguide.com/bbs/black-flag-bbs/" target="_blank">BLACK FLAG BBS</a><br />               Подключение: Telnet<br />                             Telnet: <code>telnet://blackflag.acid.org</code><br />                            Сисоп:  Hawk Hubbard<br />      Местонахождение:  Hudson, Florida<br />                 Движок BBS:  Mystic<br />Вот оно:</p>
  <blockquote id="WsDw">For over 20 years it has been the lucky recipient of the finest working screens from the worlds best ANSi – Ascii and RIPScrip artists. We would like to list and thank those over the years that have contributed to the boards great success</blockquote>
  <p id="gWFX">Наконец-то перед вами настоящая тру-хардкор-андеграунд борда, из палаты мер и весов, можно сказать эталон.</p>
  <figure id="MZpu" class="m_original">
    <img src="https://img4.teletype.in/files/79/20/7920886b-d935-4394-a7f3-7e99e83053c9.gif" width="800" />
    <figcaption>И это только приглашение.</figcaption>
  </figure>
  <p id="gpQ6">Борда сама по себе — настоящее произведение искусства, при этом является центром притяжения для сценеров и арт-групп со всего мира.</p>
  <blockquote id="xgBb">The board is mainly an underground ACiD art show board since 1995 and a hub for various modding groups over the years.</blockquote>
  <p id="Fh0j">Записал небольшой ролик с демонстрацией внутренних интерфейсов:</p>
  <figure id="vBav" class="m_original">
    <img src="https://img2.teletype.in/files/53/75/5375f46f-5b21-43c9-a839-c616b0f414a4.gif" width="800" />
    <figcaption>Главное меню и переписка с сисопом.</figcaption>
  </figure>
  <p id="c8H7">К сожалению российские IP тут забанены и при попытке подключения из России борда обрывает соединение, поэтому придется использовать метод обхода с <code>ncat</code>, описанный выше. </p>
  <p id="C9gR">Зато целых две галереи с консольным артом сразу в главном меню:</p>
  <figure id="4enc" class="m_original">
    <img src="https://img3.teletype.in/files/ab/bd/abbde5dd-2361-4dbf-a7fd-2fec653ef609.png" width="654" />
  </figure>
  <p id="yDx5">Стрим новостей Fox News внутри терминальной BBS — теперь вы видели все:</p>
  <figure id="Upix" class="m_original">
    <img src="https://img4.teletype.in/files/33/b6/33b68e05-6a9a-49cd-bf4c-9c95191ba075.png" width="654" />
  </figure>
  <p id="GpdC">Так выглядит раздел с файлами:</p>
  <figure id="YBSg" class="m_original">
    <img src="https://img4.teletype.in/files/f6/e6/f6e65c12-c13d-4567-b4fa-04297ace6749.png" width="654" />
  </figure>
  <p id="oDDH">Самое неожиданное место для поиска материалов по Android:</p>
  <figure id="uexE" class="m_original">
    <img src="https://img1.teletype.in/files/83/65/8365ed5f-7346-4d7e-b971-92e391e3f9ae.png" width="654" />
  </figure>
  <p id="ld65">Капитанский журнал, где можно оставить сообщение:</p>
  <figure id="4iEG" class="m_original">
    <img src="https://img1.teletype.in/files/0b/db/0bdbb604-a27b-471c-9261-97408f201f25.png" width="654" />
  </figure>
  <p id="vH01">Одна из самых эпических работ:</p>
  <figure id="d0SO" class="m_original">
    <img src="https://img4.teletype.in/files/be/cf/becf868e-77a4-49e2-bbab-db237c7ad5bb.gif" width="640" />
    <figcaption>К сожалению влезло не все и сама картинка еще длиннее.</figcaption>
  </figure>
  <h2 id="FFMC">BlackICE</h2>
  <p id="Xjyr">                      Название:  <a href="https://8bitboyz.com/bbs-listing/blackice/" target="_blank">BlackICE</a><br />               Подключение: Telnet<br />                             Telnet: <code>telnet://blackice.bbsindex.de</code><br />                            Сисоп:  -<br />      Местонахождение:  Duesseldorf, Germany<br />                 Движок BBS:  Mystic</p>
  <p id="sC9f">Это первая борда на моей памяти, у которой есть <a href="https://www.youtube.com/@BBSindex" target="_blank">собственный канал на Youtube</a>:</p>
  <blockquote id="tTtr">The Newscenter is one of the special features of the BlackICE BBS. Read News, Tweets and much more. You can also send tweets from the Board! The FileArea counts more than 222.000 files and is one the biggest in the BBS Scene. WHQ BBSnet, DoorGames, Many MsgNetworks, Pointfriendly and more! The BlackICE BBS receives an average amount of 300+ calls per month and process 1000+ Messages per day.</blockquote>
  <p id="DY0y">Тусовочное место для киберэлиты с кучей интеграций в современный интернет, так выглядит приглашение для входа:</p>
  <figure id="xKKb" class="m_original">
    <img src="https://img2.teletype.in/files/52/22/522293f3-4fcf-42cf-9bda-b49eb55f9aa4.png" width="648" />
    <figcaption>Двуязычный текстовый интерфейс. На BBS.</figcaption>
  </figure>
  <p id="Immn">Приветственное сообщение для новых юзеров также на двух языках:</p>
  <figure id="Lqoz" class="m_original">
    <img src="https://img3.teletype.in/files/63/4a/634ab08b-ee7b-4e5e-8d7a-14f5eaf7dc78.png" width="654" />
  </figure>
  <p id="nbi9">Главное меню:</p>
  <figure id="KTwk" class="m_original">
    <img src="https://img2.teletype.in/files/df/11/df11b9c3-8363-4dd3-a38a-0f09f299cb16.png" width="654" />
    <figcaption>Да, у этих ребят <a href="https://oldbytes.space/@BlackICEBBS" target="_blank">есть</a> даже свой Mastodon!</figcaption>
  </figure>
  <p id="aozw">Так выглядит раздел с файлами, специально записал в динамике:</p>
  <figure id="fnj9" class="m_original">
    <img src="https://img4.teletype.in/files/7c/1c/7c1ca0d3-8dc9-4326-80b9-ede7be02230f.gif" width="800" />
    <figcaption>Игры, фильмы и софт - все как в былые времена.</figcaption>
  </figure>
  <p id="95kJ">Борда имеет множество точек присутствия в разных сетях, от такого изообилия дергается мой старый глаз, повидавший многое:</p>
  <figure id="gA3Y" class="m_original">
    <img src="https://img3.teletype.in/files/67/61/676110a5-3bbd-4fd6-959a-8b977d790c38.png" width="654" />
  </figure>
  <p id="5aIv">Прямо отсюда можно попасть на несколько других борд:</p>
  <figure id="1MQE" class="m_original">
    <img src="https://img4.teletype.in/files/b1/09/b1091afa-91d7-4c9f-9a7f-b3ac02e9276a.png" width="654" />
  </figure>
  <p id="CDOR">Есть даже встроенный терминал для подключения к другим системам:</p>
  <figure id="fgyu" class="m_original">
    <img src="https://img1.teletype.in/files/c6/b7/c6b76c0c-d60a-4d81-84fc-bd4e284ead32.png" width="654" />
  </figure>
  <p id="s5RE">С российских IP пускают, так что можно не заморачиваться проксями.</p>
  <h2 id="tLDt">Эпилог</h2>
  <p id="zVDG">Я показал тут лишь малую (и самую безобидную) часть всей этой BBS-тусовки, на самом деле действующих борд гораздо больше. На свете существуют <strong>тысячи</strong> разнообразных BBS с непугаными сисопами и самым отбитым контентом, который давным давно заблокирован в большом интернете.</p>
  <p id="vHvG">Ввиду разрозненности, скрытости и определенной технологической отсталости, на BBS фактически нет цензуры и нет влияния регуляторов — думаю нетрудно догадаться как все это влияет на контент и местных обитателей. </p>
  <p id="sVHk">Так что включайте свои кибердеки и вперед — покорять настоящий современный андеграунд!</p>
  <p id="lxyx"></p>
  <figure id="PL6q" class="m_column">
    <img src="https://img2.teletype.in/files/1b/58/1b58d308-fd09-444d-b289-0f365f83d856.png" width="1320" />
    <figcaption>https://timeweb.cloud/</figcaption>
  </figure>
  <h2 id="QDAD">Спонсоры</h2>
  <section>
    <p id="4ZKX">Материал создан при поддержке компании <a href="https://timeweb.cloud/" target="_blank">Timeweb Cloud</a>, за что им огромная благодарность и всяческие респекты.</p>
  </section>
  <p id="LVAd">Оригинал статьи <a href="https://habr.com/ru/companies/timeweb/articles/1039720/" target="_blank">опубликован на Хабре</a>.</p>
  <p id="gLel"></p>
  <figure id="yaS7" class="m_original">
    <img src="https://img2.teletype.in/files/1c/2e/1c2e4751-482c-4d2d-b62b-956bae87136b.jpeg" width="1280" />
    <figcaption>Альтернативный вариант для заставки к статье.</figcaption>
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/chrome-and-speed</guid><link>https://blog.0x08.ru/chrome-and-speed?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/chrome-and-speed?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>Хром и скорость</title><pubDate>Mon, 11 May 2026 13:22:28 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/9e/e1/9ee10fda-86f9-41b9-81b7-f83606c00c16.png"></media:content><category>experiments</category><description><![CDATA[<img src="https://img3.teletype.in/files/e4/54/e45432b6-a4b8-4ff7-a8db-81493c20773c.gif"></img>Подробное руководство по ускорению любимого браузера подручными средствами. В помощь домохозяюшкам, студентам и высшему руководству — всем у кого нет под рукой топового железа с 64Гб памяти для работы в современном интернете.]]></description><content:encoded><![CDATA[
  <p id="e8M4">Подробное руководство по ускорению любимого браузера подручными средствами. В помощь домохозяюшкам, студентам и высшему руководству — всем у кого нет под рукой топового железа с 64Гб памяти для работы в современном интернете. </p>
  <figure id="L8xs" class="m_column">
    <img src="https://img3.teletype.in/files/e4/54/e45432b6-a4b8-4ff7-a8db-81493c20773c.gif" width="800" />
    <figcaption>В качестве демонстрации. FreeBSD, но ниже будет и про ваши любимые Windows c Linux.</figcaption>
  </figure>
  <h2 id="l6Y2">Хром</h2>
  <p id="H19K">Браузер <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>, созданный и разрабатываемый корпорацией Google давно стал главным инструментом для большинства пользователей компьютерной техники:</p>
  <blockquote id="LtXz">в вашем телефоне, планшете, телевизоре, ноутбуке и стационарном компьютере в подавляющем большинстве случаев будет установлен именно этот браузер, либо что-то на его основе.</blockquote>
  <p id="ffaK">Исключения редки, это продукция Apple со своим собственным браузером <a href="https://www.apple.com/safari/" target="_blank">Safari</a>, <s>медленно умирающий</s> <a href="https://www.firefox.com/" target="_blank">Firefox</a> и совсем уж <a href="https://github.com/gosub-io/gosub-engine" target="_blank">сказочная альтернативщина</a>.</p>
  <p id="1vJg">Два вечных конкурента в виде браузеров <a href="https://www.opera.com/" target="_blank">Opera</a> и <a href="https://www.microsoft.com/en-us/download/internet-explorer" target="_blank">Internet Explorer</a> сдались и ныне используют под капотом одинаковый движок от Chrome.</p>
  <p id="LWoY">Так что Google это мировой монополист в области браузеростроения, Chrome — его самый популярный продукт и фактически главное приложение для большинства современных пользователей.</p>
  <p id="9MBK">Даже эта статья создавалась с помощью браузера Chrome:</p>
  <figure id="vt7k" class="m_column">
    <img src="https://img4.teletype.in/files/3c/31/3c313683-f5ce-4b35-8031-c25c582f7b8a.png" width="915" />
  </figure>
  <h2 id="H2kv">Скорость</h2>
  <p id="eRvP">Конечно высокооплачиваемые разработчики самого популярного браузера на планете, щедро финансируемые «<a href="https://en.wikipedia.org/wiki/Google" target="_blank">корпорацией добра</a>» —  <strong>не полные идиоты</strong> и разбираются в вопросах производительности собственного продукта гораздо лучше автора. </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="DmSN">Но только проблемы производительности на дешевом, устаревшем и тем более <strong>неподдерживаемом</strong> оборудовании сотрудников Google.. мягко говоря не очень волнуют.</p>
  </section>
  <p id="Jgxo">Поэтому в очередной раз простому пользователю, не желающему продавать почку ради современного компьютера придется заботиться о себе самостоятельно.</p>
  <p id="1qBS">Чем мы сейчас и займемся.</p>
  <h3 id="QSFd">Применимость</h3>
  <p id="ksU1">Описываемые ниже инструкции — для <strong>десктопной</strong> версии браузера Chrome и с учетом специфики трех разных операционных систем: Windows, Linux и FreeBSD. </p>
  <blockquote id="OHeN">Мобильная версия браузера довольно сильно отличается, но также поддается подобной настройке. Однако чтобы не раздувать статью — про тюнинг мобильной версии расскажу в следующий раз.</blockquote>
  <p id="vcJG">Замечу также, что эта статья — далеко не самый возможный максимум оптимизации и если Господь наградил вас знанием языка С++, дав в руки компилятор, то сотворить с браузером можно гораздо больше.</p>
  <p id="aLx5">Но тут все же для обычных людей, не обезображенных высшим техническим образованием и навыками системного программирования.</p>
  <h3 id="vHTb">Производительность</h3>
  <p id="FMYw">Я использую Chrome на ноутбуках с момента его появления и часто работаю «в поле» — от батареи и без подключения к розетке. Помимо браузера на машине постоянно присутствуют еще несколько тяжелых приложений — в первую очередь среды разработки и разнообразные редакторы.</p>
  <p id="Gr1P">Все это в итоге формирует следующий набор требований:</p>
  <ol id="9o9n">
    <li id="XIbR">браузер не должен <s>нападать на человека</s> отбирать себе все доступные ресурсы; </li>
    <li id="i9rA">браузер не должен «сжирать» батарею ноутбука;</li>
    <li id="wkTY">браузер должен продолжать работать с современными сайтами, сохраняя отзывчивость интерфейса.</li>
  </ol>
  <p id="qKep">Время «холодного запуска» и скорость отрисовки страниц при таких вводных разумеется могут пострадать, но будут оставаться в пределах разумного.</p>
  <h3 id="TQEt">Версии Хрома</h3>
  <p id="T3ol">Чтобы не было путаницы, стоит сразу прояснить ряд нюансов с названиями продуктов и используемыми терминами.</p>
  <p id="G6Ov">Официально браузер от Google называется «<a href="https://www.google.com/chrome/" target="_blank">Chrome</a>» и поставляется (даже для Linux) в виде готовой сборки с инсталлятором, т.е. это закрытый коммерческий продукт, хотя и бесплатный для пользователя.</p>
  <p id="RGW6">Именно эта версия доступна для скачивания с официального сайта и имеет максимальную интеграцию с сервисами и другими продуктами Google.</p>
  <p id="0n9l">Открытая часть браузера Chrome (движок) называется «<a href="https://www.chromium.org/getting-involved/download-chromium/" target="_blank">Chromium</a>» и с точки зрения обычного пользователя никак не поставляется, поскольку Chromium предназначен в первую очередь для <em>технических специалистов</em>, участвующих в процессе разработки и тестирования.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="peo2">Именно Chromium а не Chrome чаще всего установлен по-умолчанию в различных дистрибутивах Linux, в виде сборки от ментейнеров дистрибутива.</p>
  </section>
  <p id="ri8M">Chromium по-умолчанию имеет минимальную интеграцию с сервисами Google, что например не позволяет без дополнительных шагов устанавливать расширения из официального магазина.</p>
  <p id="OF5x">Наконец существует проект «<a href="https://ungoogled-software.github.io/" target="_blank">Ungoogled Chromium</a>», авторы которого постарались удалить из Chromium <strong>абсолютно все</strong> интеграции с сервисами Google и все закрытые инструменты сборки.</p>
  <p id="otqq">Ungoogled Chromium за последние годы набрал немалую популярность, поэтому активно используется в BSD-системах и дистрибутивах Linux, <a href="https://www.kali.org/" target="_blank">ориентированных на безопасность</a>.</p>
  <blockquote id="Ek6u">Поскольку использование сервисов Google в наше непростое время может приводить к непредсказуемым проблемам и сбоям подключения, я буду использовать для всех оптимизаций Ungoogled Chromium либо просто Chromium, но не официальный Google Chrome.</blockquote>
  <p id="0eFD">Тем не менее, для простоты повествования в статье используется термин «Chrome» в качестве обозначения браузера, поскольку описываемые методы оптимизации полностью совпадают и частично применимы и к другим браузерам на основе Chromium. </p>
  <h3 id="s7Is">Тестовая среда</h3>
  <p id="pKfG">Для статьи использовались современные 64-битные сборки браузера, с версиями начиная с 147 и выше:</p>
  <blockquote id="QISd">147.0.7727.101 (Official Build) (64-bit)</blockquote>
  <p id="5QQU">Ungoogled Chromium имеет свою собственную нумерацию версий,  для статьи использовались версии 137 и выше:</p>
  <figure id="wylp" class="m_original">
    <img src="https://img2.teletype.in/files/d5/0a/d50a1a5f-f945-4133-832c-0e0c2f29eb52.png" width="709" />
  </figure>
  <p id="PYK8">Версии разные под разными операционными системами, но самые последние на момент написания статьи.</p>
  <p id="Qbgp">Замечу, что описанные ниже настройки постоянно<strong> используются</strong> на всех моих ноутбуках, как мощных и современных, так и откровенно.. винтажных. </p>
  <p id="Uque">Разумеется разницу лучше всего видно на устаревшем оборудовании, поэтому в качестве тестовой среды будут использованы два «боевых пенсионера»:</p>
  <figure id="bhvQ" class="m_column">
    <img src="https://img3.teletype.in/files/a5/a4/a5a4e320-d743-441a-b6a6-acd1952a995c.jpeg" width="1280" />
    <figcaption><a href="https://specspro.net/laptops/6879-lenovo-ideapad-z580-2151/" target="_blank">Lenovo Z580</a>, 2013 года</figcaption>
  </figure>
  <p id="q7VR"></p>
  <figure id="xNsm" class="m_column">
    <img src="https://img4.teletype.in/files/ff/31/ff31474d-f129-4611-a453-4e3a4db7a612.jpeg" width="1280" />
    <figcaption><a href="https://gadgetaz.com/Laptop/ASUS_F3Ke--76" target="_blank">ASUS F3Ke</a>, 2007 год.</figcaption>
  </figure>
  <p id="yO85">Эти весьма устаревшие по любым меркам (особенно второй) машины станут отличным тестовым полигоном для демонстрации результатов всех моих <s>вивисекций</s> оптимизаций.</p>
  <h2 id="Hr05">Оптимизация</h2>
  <p id="Jccl">Поскольку целевая аудитория статьи — обычные пользователи, не владеющие с пеленок компилятором и отладчиком, ограничусь тремя вариантами оптимизации браузера, доступными без залезания непосредственно в код:</p>
  <blockquote id="cAdq">хитрые настройки, хитрые плагины и хитрое окружение. </blockquote>
  <p id="I0iD">Все ради того чтобы крутить ленту каких-нибудь Reddit/LinkedIn без зависания браузера и 100% загрузки системы.</p>
  <p id="ZAYY">Поехали.</p>
  <figure id="ipyX" class="m_column">
    <img src="https://img4.teletype.in/files/be/a8/bea87d17-5d82-4b4f-9fbe-8ca9042ddc6b.gif" width="800" />
    <figcaption>Так выглядит работа браузера со всеми оптимизациями на Ubuntu Linux и ноутбуке 2012 года.</figcaption>
  </figure>
  <h2 id="0Pmw">Linux-версия</h2>
  <p id="8G9L">Так исторически сложилось, что я использую множество разных Linux-дистрибутивов в своей непростой деятельности: </p>
  <blockquote id="jv3O"><a href="https://www.debian.org/" target="_blank">Debian</a>, <a href="https://ubuntu.com" target="_blank">Ubuntu</a>, <a href="https://manjaro.org/" target="_blank">Manjaro</a>, <a href="https://www.mageia.org/en/" target="_blank">Mageia</a>, <a href="https://www.calculate-linux.org/" target="_blank">Calculate</a>  — и это только на хосте.</blockquote>
  <p id="QTrx">Описанные ниже инструкции работают на всем этом зоопарке и по своей сути применимы для любого окружения на базе Linux, везде где используется браузер Chrome.  </p>
  <p id="fdgP">Замечу, что Calculate Linux (на базе Gentoo) использует <a href="https://wiki.gentoo.org/wiki/OpenRC" target="_blank">OpenRC</a> вместо <code>systemd</code>, поэтому там не используется трюк с <code>systemd-run</code>. </p>
  <p id="Ult1">Начнем со скрипта запуска браузера, в котором специальными параметрами включаются или отключаются разные хитрые опции, а также используется специальное окружение:</p>
  <pre id="X214" data-lang="bash">#!/bin/bash

systemd-run --user --slice=chromium.slice chromium \
    --enable-features=VaapiVideoDecoder,VaapiVideoEncoder \
    --enable-gpu-rasterization \
    --disable-gpu-compositing \
    --enable-zero-copy \
    --disable-background-networking \
    --disable-client-side-phishing-detection \
    --disable-prompt-on-repost \
    --disable-sync \
    --metrics-recording-only \
    --no-first-run \
    --safebrowsing-disable-auto-update \
    --ignore-gpu-blocklist \
    --renderer-process-limit=4 \
    --disable-smooth-scrolling \
    --wm-window-animations-disabled \
    --animation-duration-scale=0 \
    --disable-spell-checking \ 
    --disable-features=WhatIsNewPage,Promotions,LensOverlay \       
    --enable-unsafe-swiftshader &quot;$@&quot;</pre>
  <p id="LbDb">Сохраняете текст выше в какой-нибудь <code>/opt/own/bin/chrom</code>, выставляете бит запуска:</p>
  <pre id="0AyA" data-lang="bash">chmod +x /opt/own/bin/chrom</pre>
  <p id="LIt0">И используете этот скрипт для первого запуска браузера.</p>
  <p id="9Kti">Переназначать обработку всех HTML-страниц в рабочем окружении на этот скрипт не стоит, поскольку процессы браузера Chrome умеют общаться между собой и пока есть хоть один работающий процесс — его настройки будут использоваться для запуска новых копий.</p>
  <p id="Mpa4">Теперь рассказываю <s>страшную сказку</s> про «прожорливый» Chrome и пропавшую память, точнее про эту интересную строку:</p>
  <pre id="8lXf" data-lang="bash">systemd-run --user --slice=chromium.slice chromium</pre>
  <p id="DMog">Дело в том, что у браузера Chrome есть дурная привычка считать весь компьютер своей собственностью и захватывать максимум доступных ресурсов — всю свободную память и все доступные процессоры и ядра.</p>
  <blockquote id="AjFf">Пока вы работаете на <s>сервере</s> современной машине с кучей памяти, не держите открытыми сотни вкладок с 3D-графикой а конкуренцию браузеру за доступные ресурсы составляет только офисный пакет — проблемы нет.</blockquote>
  <p id="zqEb">Но стоит лишь немного просесть по мощности используемого оборудования или доступным ресурсам для более прожорливых программ (привет <a href="https://www.blackmagicdesign.com/products/davinciresolve" target="_blank">Davinci Resolve</a>) и любимый браузер от «корпорации добра» немедленно показывает <s>звериный оскал</s> свое истинное лицо.</p>
  <p id="Nbpg">В случае ноутбука (тем более мощного) проявляется еще один дурной эффект: </p>
  <blockquote id="4f92">скачки бесконтрольной нагрузки, создаваемой браузером очень быстро разряжают батарею.</blockquote>
  <p id="sXPQ">Так что становится жизненно необходимым сажать браузер на ресурсную диету с помощью <a href="https://systemd.io/" target="_blank">systemd</a> и функционала <a href="https://en.wikipedia.org/wiki/Cgroups" target="_blank">cgroups</a>.</p>
  <p id="C5pE">Делается это в современных Linux-дистрибутивах довольно просто, для начала создаем файл <code>~/.config/systemd/user/chromium.slice</code> со следующим содержимым:</p>
  <pre id="rKzX">[Slice]
MemoryAccounting=yes
MemoryHigh=1G
MemoryMax=1.5G
MemorySwapMax=3000M
CPUAccounting=true
CPUQuota=70%</pre>
  <p id="35WU">Помимо очевидных лимитов на объем используемой памяти (MemoryHigh и MemoryMax), тут еще задается квота на загрузку процессора (CPUQuota), что не дает поднять ее выше заданного лимита — 100% загрузку CPU от процессов Chrome вы больше не увидите.</p>
  <p id="eLOg">Теперь самое важное: </p>
  <blockquote id="baGm">все указанные лимиты применяются ко всем дочерним процессам, которые запускает Chrome во время работы.</blockquote>
  <p id="8MlT">По сути создается ограниченный по ресурсам контейнер, внутри которого запускается браузер.</p>
  <p id="Tiu7">Ну и сам запуск с помощью <s>черной магии</s> <code>systemd-run</code> и указания слайса:</p>
  <pre id="w7Zh" data-lang="bash">systemd-run --user --slice=chromium.slice chromium</pre>
  <p id="3wQw">Аналогичным образом можно ограничивать по ресурсам любые другие «жирные» приложения, например Telegram, который в последних версиях повадился генерировать 100% загрузку процессора по любому поводу.</p>
  <p id="Hbti">Замечу, что сей хитрый трюк работает и с приложениями, работающими внутри <a href="https://appimage.org/" target="_blank">AppImage</a> или <a href="https://snapcraft.io/snapd" target="_blank">snapd</a>-пакетов, так что с его помощью замечательно урезаются аппетиты версий Chrome/Chromium в Ubuntu/Manjaro, управляемые snapd.</p>
  <figure id="jCgR" class="m_column">
    <img src="https://img2.teletype.in/files/9a/25/9a25b63b-712a-4546-a497-f92d4efb2061.png" width="1280" />
    <figcaption>Отключение анимации в действии.</figcaption>
  </figure>
  <p id="vkmQ">Отключение анимации</p>
  <p id="tZW7">Существует одно <a href="https://chromewebstore.google.com/detail/animation-policy/ncigbofjfbodhkaffojakplpmnleeoee" target="_blank">интересное расширение</a> для Chrome, позволяющее <strong>отключать анимированные картинки</strong> на всех страницах:</p>
  <blockquote id="1Qzj">вместо мигающей <s>хтони</s> анимации будет отображаться один статичный кадр.</blockquote>
  <p id="73hB">Нетрудно догадаться, что этим сильно снижается нагрузка на CPU/GPU (особенно в случае устаревшего оборудования), с чего происходит серьезная экономия заряда батареи.</p>
  <p id="KBWL">Так что очень рекомендую к использованию.</p>
  <h3 id="YLt8">Ungoogled Chromium и установка расширений</h3>
  <p id="hioU">К сожалению для установки расширений из официального магазина для «левого» Ungoogled Chromium и (совсем недавно) официального Chromium стало необходимо <a href="https://github.com/NeverDecaf/chromium-web-store" target="_blank">специальное расширение</a>. </p>
  <p id="NLfl">Без которого вас обрадуют сообщением об ошибке:</p>
  <pre id="wrfB">CRX_REQUIRED_PROOF_MISSING</pre>
  <p id="uSKe">А кнопка установки в интерфейсе магазина окажется скрытой.</p>
  <p id="YZ1Z">В качестве альтернативного варианта можно использовать <a href="https://www.ungoogledextensions.com/" target="_blank">специальный сайт</a> от авторов расширения, который позволяет скачать пакет с расширением <code>.crx</code> и установить его локально в вашем браузере.</p>
  <p id="a6Ce">Теперь переходим к самому интересному — к параметрам запуска.</p>
  <h2 id="tSjc">Параметры Chrome</h2>
  <p id="dlY6">У браузера Chrome есть огромное количество разнообразных параметров запуска, как документированных так и не очень. </p>
  <p id="4ALE">Часть из них дублируется во внутреннем служебном интерфейсе <code>chrome://flags/</code> — может быть задана не из командной строки, а с помощью интерфейса браузера, часть — нет.</p>
  <figure id="E2bx" class="m_column">
    <img src="https://img4.teletype.in/files/79/92/7992248e-a6df-446b-813d-58addaa3901e.png" width="819" />
    <figcaption>Так выглядит служебный интерфейс с настройками браузера Chrome.</figcaption>
  </figure>
  <p id="kj0h">Поскольку прямого соответствия именований между параметром запуска и названием опции нет, я не стал описывать в статье еще и вариант настройки через переключение опций. </p>
  <blockquote id="sT6G">Тем более что ряд опций, доступных через служебный интерфейс не имеют отдельного параметра запуска.</blockquote>
  <p id="el31">Этих самых параметров настолько <strong>много</strong>, что энтузиастами был создан <a href="https://peter.sh/experiments/chromium-command-line-switches/" target="_blank">отдельный сайт</a>, посвященный только лишь их описанию, выгружаемому непосредственно из исходного кода браузера. </p>
  <p id="eNtO">Так выглядит их небольшая часть в динамике:</p>
  <figure id="3WZc" class="m_column">
    <img src="https://img1.teletype.in/files/4b/8a/4b8a7506-0800-45b7-9e36-3672ff6076c1.gif" width="800" />
    <figcaption>Показано менее 1% всех параметров</figcaption>
  </figure>
  <p id="2699">С учетом постоянного устаревания и регулярных ломающих изменений в функционале браузера нет ни возможности ни особого смысла описывать абсолютно все, поэтому ниже описаны только те параметры, которые постоянно используются на моих машинах в целях оптимизации.</p>
  <p id="RbCE">Поехали.</p>
  <pre id="bx23">--enable-features=VaapiVideoDecoder,VaapiVideoEncoder</pre>
  <p id="uULe">Ключ <code>--enable-features=</code> как нетрудно догадаться из названия используется для принудительного <strong>включения</strong> опций браузера. </p>
  <p id="R2zA">В данном случае принудительно включаются кодеки для аппаратного декодирования видео, работающие на базе <a href="https://en.wikipedia.org/wiki/Video_Acceleration_API" target="_blank">Video Acceleration API</a> (VAAPI).</p>
  <p id="XGhF">По-умолчанию, если библиотека VAAPI в системе не установлена либо работает неправильно, браузер автоматически переключится на медленный программный кодек, с чего будет сильно нагружаться процессор при проигрывании видео. </p>
  <blockquote id="MZHb">С данной настройкой, при проблемах с VAAPI браузер либо перестанет запускаться совсем, либо покажет явную заглушку вместо видео — таким образом появится однозначный сигнал о серьезной проблеме.</blockquote>
  <p id="SmbT">Комфортно смотреть видео даже на современном оборудовании без работающего VAAPI врядли получится из-за сильной загрузки процессора, поэтому настройка весьма актуальна для всех пользователей.</p>
  <pre id="bWDG">--enable-gpu-rasterization </pre>
  <p id="SPzu">Данный ключ <strong>принудительно</strong> включает <a href="https://www.chromium.org/developers/design-documents/chromium-graphics/how-to-get-gpu-rasterization/" target="_blank">аппаратную отрисовку</a> страниц с помощью GPU:</p>
  <blockquote id="mogG">Chrome 37 introduced a GPU rasterizer. When enabled, some paint workloads can go from 100ms/frame to 4-5ms/frame.</blockquote>
  <p id="tt11">Несмотря на то что опция является «экспериментальной» и вроде как работает не во всех случаях — ее включение это единственный вариант для комфортного использования современного браузера на устаревшем железе.</p>
  <pre id="yODg">--disable-gpu-compositing </pre>
  <p id="Tg7q">Принудительное отключение <a href="https://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome/" target="_blank">GPU-реализации композитора страниц</a>. </p>
  <p id="uEsh">Актуально для сильно устаревшего оборудования, вроде моего Asus F3KE, поскольку GPU-композитор на нем порождает визуальные артефакты и искажения:</p>
  <figure id="Uq0u" class="m_column">
    <img src="https://img2.teletype.in/files/1c/e0/1ce0449e-2035-4f3b-b396-1a0161c9f10b.gif" width="800" />
    <figcaption>Феерический баг.</figcaption>
  </figure>
  <pre id="v7cS">--enable-zero-copy </pre>
  <p id="RDUq">Согласно <a href="https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/common/switches.cc?q=kEnableZeroCopy&ss=chromium" target="_blank">строчке с описанием</a> в исходном коде браузера:</p>
  <blockquote id="6IVj">Enable rasterizer that writes directly to GPU memory associated with tiles.</blockquote>
  <p id="dZ4f">Немного ускоряет рендер страниц и снижает нагрузку на память, но <a href="https://github.com/nwjs/nw.js/issues/6581" target="_blank">может порождать визуальные артефакты</a>, так что включать стоит не всем.</p>
  <pre id="ezy6">--disable-background-networking </pre>
  <p id="F9rZ">Запрещает браузеру использовать фоновые сетевые запросы, например проверку обновлений для установленных расширений.</p>
  <pre id="mqZZ">--disable-client-side-phishing-detection </pre>
  <p id="Y5Bf">Отключает фоновую проверку сайтов на фишинг.  </p>
  <blockquote id="ARwC">Этот параметр <a href="https://issues.chromium.org/issues/41099515" target="_blank">вроде как удален</a> в новых версиях браузера, но все еще часто встречается в различных руководствах и материалах.</blockquote>
  <p id="ghsy">Фоновое обновление этих баз отнимает ресурсы а сама проверка плохо работает в современных реалиях разделенного интернета, поэтому отключаем.</p>
  <pre id="okkC">--disable-prompt-on-repost </pre>
  <p id="b7Ir">Отключает дурацкое предупреждение о повторной отправке формы:</p>
  <figure id="yTJ2" class="m_original">
    <img src="https://img4.teletype.in/files/36/26/36260562-e4aa-4420-8a9a-649ddd627258.png" width="585" />
  </figure>
  <pre id="mHhk"> --disable-sync </pre>
  <p id="EDZ5">Отключает облачную синхронизацию учетной записи Google.</p>
  <p id="qDJ5">Актуально только для обычного Chromium, для ungoogled-версии не используется, поскольку функционал глобальной учетной записи там вырезан.</p>
  <pre id="2Y6Y">--metrics-recording-only </pre>
  <p id="i14r">Указывает браузеру только записывать отчеты с метриками производительности, но запрещает отправлять их на сервера Google. </p>
  <p id="rMKM">Отчеты сохраняются в текущем профиле, актуальны при поиске проблем с медленной работой браузера или отдельных сайтов.</p>
  <pre id="d1AQ">--no-first-run </pre>
  <p id="t0qU">Отключает приветственный диалог при первом запуске браузера.</p>
  <pre id="rBDU">--safebrowsing-disable-auto-update </pre>
  <p id="zaV8">Отключает автоматическое фоновое обновление баз для «<a href="https://safebrowsing.google.com/" target="_blank">Safe Browsing</a>» — специального сервиса Google для защиты от фишинга и подозрительных сайтов. </p>
  <p id="OesA">Актуально для обычного Chromium, поскольку в ungoogled-версии функционал «Safe Browsing» удален.</p>
  <pre id="XieF">--ignore-gpu-blocklist </pre>
  <p id="2eCX">Натурально заставляет браузер «работать на дровах» — использовать неподдерживаемое и сильно устаревшее оборудование для аппаратного ускорения.</p>
  <p id="la9R">Очень важная опция, без указания которой браузер <s>тихо и цинично</s> включит программную отрисовку ничего не сказав пользователю, с чего скорость отображения страниц сильно упадет.</p>
  <pre id="pIqJ">--renderer-process-limit=2 </pre>
  <p id="OI5T">Еще один «магический» параметр, критически влияющий на производительность браузера и потребляемые ресурсы.</p>
  <p id="KrNV">Именно с его помощью переопределяется лимит на количество запущенных процессов отрисовки страниц — самых тяжелых процессов браузера, создающих основную нагрузку на систему.</p>
  <p id="y3qU">Количество таких процессов напрямую влияет на потребляемые ресурсы, поэтому в случае ограниченных ресурсов стоит выставить какое-то небольшое число. </p>
  <pre id="fAhu">--disable-smooth-scrolling </pre>
  <p id="LYEM">Просто «имба» за которую вы потом будете благодарить — параметр отключает плавную прокрутку в браузере, которая <strong>очень сильно</strong> влияет на скорость при работе на слабом или устаревшем оборудовании. </p>
  <p id="hCsi">Влияет настолько сильно, что разницу становится видно визуально после перезапуска.</p>
  <pre id="Qhga">--wm-window-animations-disabled </pre>
  <p id="F0GH">Отключает всю анимацию в интерфейсе браузера.</p>
  <pre id="qgSV">--animation-duration-scale=0 </pre>
  <p id="xRuU">Переопределяет длительность воспроизведения CSS-анимации, значение 0 означает полное отключение, но работает к сожалению только для элементов интерфейса самого браузера, не для страниц.</p>
  <pre id="V0IJ">--disable-spell-checking </pre>
  <p id="NiRe">Отключает фоновую проверку правописания, которая существенно влияет на скорость работы браузера (вплоть до подвисания страниц) и толком не работает для русского языка.</p>
  <pre id="m3CP">--enable-unsafe-swiftshader</pre>
  <p id="fqo7">Еще один важный параметр, который разрешает использование «небезопасного» <a href="https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/gpu/swiftshader.md" target="_blank">программного рендера WebGL</a>, что позволяет использовать 3D-графику в браузере даже на устаревшем оборудовании, которое не поддерживает современное <a href="https://en.wikipedia.org/wiki/Vulkan" target="_blank">Vulkan API</a>.</p>
  <pre id="cRDc">--disable-features=WhatIsNewPage,Promotions,LensOverlay,OptimizationGuideOnDeviceMode</pre>
  <p id="LPL5">Данный параметр по прямой аналогии с описанным в самом начале <code>--enable-features=</code> переопределяет опции браузера, которые необходимо <strong>отключить</strong>.</p>
  <p id="ju2C">В данном случае отключаем встроенную рекламу новых фич браузера, которые вылезают при обновлениях и очень сильно <s>беся</s>т отвлекают. </p>
  <p id="CzLv">Актуально только для обычного Chromium, поскольку в ungoogled-версии все эти радости вырезаны.</p>
  <figure id="wSdM" class="m_column">
    <img src="https://img1.teletype.in/files/4f/57/4f574d6a-1ff7-4843-9797-d56c678ddc88.gif" width="853" />
    <figcaption>Прокрутка ленты Reddit в качестве демонстрации, поскольку это один из самых тормозных сайтов на свете.</figcaption>
  </figure>
  <h2 id="MjWR">Хром и Windows </h2>
  <p id="eMgD">Я использую Windows 11, 10 и 7 на рабочих станциях а также множество разных виртуальных машин с серверными версиями Windows.</p>
  <p id="5jy0">Оптимизации актуальны только при использовании браузера на рабочей станции, поэтому в качестве тестовой среды будут выступать только три клиентских версии Windows: 11, 10 и 7.</p>
  <figure id="ulF0" class="m_original">
    <img src="https://img1.teletype.in/files/86/5a/865a6cc9-4d73-423d-a73c-200a04157e16.jpeg" width="1366" />
    <figcaption>Технические характеристики машины из ролика с лентой Reddit.</figcaption>
  </figure>
  <p id="Y0ef">Скрипт запуска выглядит следующим образом:</p>
  <pre id="ovyk" data-lang="powershell">chrome.exe --enable-features=VaapiVideoDecoder,VaapiVideoEncoder^
    --disable-features=WhatIsNewPage,Promotions,LensOverlay^
    --enable-gpu-rasterization^
    --disable-gpu-compositing^
    --enable-zero-copy^
    --disable-background-networking^
    --disable-client-side-phishing-detection^
    --disable-prompt-on-repost^
    --disable-sync^
    --metrics-recording-only^
    --no-first-run^
    --safebrowsing-disable-auto-update^
    --ignore-gpu-blocklist^
    --renderer-process-limit=4^
    --disable-smooth-scrolling^
    --wm-window-animations-disabled^
    --animation-duration-scale=0^
    --enable-unsafe-swiftshader %*</pre>
  <p id="UbGn">Сохраняете текст выше в файле <code>run.cmd</code>, кладете в каталог рядом с <code>chrome.exe</code> и используете для первого запуска.</p>
  <p id="8wd2">Используемые параметры браузера и их логика полностью совпадают с описанными выше для Linux, шаги по установке расширения для отключения анимации также полностью аналогичны описанным выше.</p>
  <blockquote id="ft7R">Замечу лишь что символ <code>^</code> — аналог <code>\</code> в UNIX-мире и используется для переноса длинных строк в командных скриптах под Windows.</blockquote>
  <p id="Yazb">Поскольку в последние версии и Chrome (и даже Chromium) под Windows авторы напихали <a href="https://search.google/ways-to-search/ai-mode/" target="_blank">AI-фич</a> под завязку, на моих рабочих станциях используются только и исключительно <a href="https://ungoogled-software.github.io/ungoogled-chromium-binaries/" target="_blank">Ungoogled-сборки</a>.</p>
  <figure id="5mtA" class="m_original">
    <img src="https://img4.teletype.in/files/33/a6/33a6d47a-0c3c-44aa-9672-3aabd78bc0c9.gif" width="600" />
    <figcaption>Ungoogled Chromium на Windows 7 со всем тюнингом. Справа менеджер задач и загрузка памяти.</figcaption>
  </figure>
  <h3 id="OM33">Chrome и старые Windows</h3>
  <p id="hgzr">Google <a href="https://support.google.com/chrome/thread/185534985/sunsetting-support-for-windows-7-8-8-1-and-windows-server-2012-and-2012-r2-in-early-2023?hl=en" target="_blank">перестала поддерживать работу на Windows 7</a> для Chrome/Сhromium начиная с 2023го года, поэтому если у вас еще осталась живая «семерка» и необходимо использовать современный браузер — ждите мою следующую статью, в которой описан процесс бекпортирования современной версии браузера в Windows 7.</p>
  <figure id="ecEx" class="m_original">
    <img src="https://img2.teletype.in/files/dd/91/dd911eb2-44c9-4bb7-9bf7-e8b30d221c53.png" width="1718" />
    <figcaption>Обратите внимание на версию браузера и дату сборки.</figcaption>
  </figure>
  <p id="8RKf">Цитируя одну известную шутку:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="WdN0">чем бы вы ни занимались — обязательно найдется <a href="https://github.com/e3kskoy7wqk" target="_blank">азиат</a>, который сделает еще круче.</p>
  </section>
  <p id="fiRF">В случае с бекпортированием Chrome на устаревшие версии Windows именно так и произошло:</p>
  <blockquote id="n8FX">стоило только начать изучать вопрос и подбирать варианты — немедленно нашелся репозиторий, с бекпортами последних версий Chrome.. под Windows XP!</blockquote>
  <p id="jx3G"><a href="https://en.wikipedia.org/wiki/Windows_XP" target="_blank">Windows XP</a> вышла в далеком 2001м году, если кто вдруг забыл и процесс бекпортирования под <strong>настолько старую</strong> ОС был сильно сложнее чем например под Windows 7.</p>
  <p id="ReZ8">Вот <a href="https://github.com/e3kskoy7wqk/Chromium-for-windows-7-REWORK/issues/37#issuecomment-4239159962" target="_blank">тут</a> выложены готовые сборки браузера под Windows XP с поддержкой аппаратного ускорения (!) — невероятный хардкор.</p>
  <p id="KkD2"></p>
  <figure id="j3DX" class="m_column">
    <img src="https://img3.teletype.in/files/69/f1/69f1d293-451c-4961-9881-aa3f806cdba6.gif" width="800" />
    <figcaption>Да, это современная сборка браузера Chrome, летающая на антикварном оборудовании. Без записи с экрана все работает еще быстрее.</figcaption>
  </figure>
  <h2 id="sYAP">Chrome и FreeBSD</h2>
  <p id="GUxF">Наконец последним разделом описываю то, с чего началась эта статья <a href="https://blog.0x08.ru/running-freebsd-on-really-old-hardware" target="_blank">в далеком 2023м году</a>:</p>
  <blockquote id="5U7G">оптимизация работы браузера Chrome под FreeBSD на <strong>очень сильно устаревшем</strong> оборудовании.</blockquote>
  <p id="1nFf">«Очень сильно устаревший» — про тот самый Asus F3KE из 2007 года, спасенный автором от достойного погребения:</p>
  <figure id="6K8m" class="m_column">
    <img src="https://img4.teletype.in/files/b4/a8/b4a88cd6-8f05-42bd-b0da-40de2937eee7.png" width="831" />
    <figcaption><a href="https://www.warhammer-community.com/en-gb/articles/iIP5RR4u/40-years-of-warhammer-even-in-death-i-still-serve/" target="_blank">Even In Death, I Still Serve</a> (ц)</figcaption>
  </figure>
  <p id="INPr">Конечно же для столь мощного эффекта пришлось провести немало нечистых <s>ритуалов</s> оптимизаций (начиная с кастомного ядра), но как минимум половина производительности — результат подбора правильных параметров браузера.</p>
  <p id="z712">Так выглядит скрипт запуска:</p>
  <pre id="G86p" data-lang="bash">#!/usr/local/bin/bash

source ~/.exports.sh

/usr/local/bin/ungoogled-chromium
    --enable-features=VaapiVideoDecoder,VaapiVideoEncoder \
    --enable-gpu-rasterization \
    --disable-gpu-compositing \
    --enable-zero-copy \
    --disable-background-networking \
    --disable-prompt-on-repost \
    --metrics-recording-only \
    --no-first-run \
    --ignore-gpu-blocklist --renderer-process-limit=2 \
    --wm-window-animations-disabled \
    --animation-duration-scale=0 \
    --enable-unsafe-swiftshader &quot;$@&quot;    </pre>
  <p id="CL71">Довольно давно в FreeBSD используется <a href="https://www.freshports.org/www/ungoogled-chromium/" target="_blank">ungoogled-версия</a> браузера, поэтому были убраны параметры для функционала из обычного Chromium, который <a href="https://github.com/ungoogled-software/ungoogled-chromium/blob/master/README.md#key-features" target="_blank">был вырезан в ungoogled-версии</a>.</p>
  <p id="gTdG">Строка: </p>
  <pre id="da9k" data-lang="bash">source ~/.exports.sh</pre>
  <p id="uSwd">на самом деле скрывает <s>портал в ад</s> отдельный механизм повторного использования сессии DBus, файл <code>~/.exports.sh</code> создается таким специальным скриптом:</p>
  <pre id="oYFz" data-lang="bash">#!/usr/local/bin/bash

FF=0

if [[ -z $DBUS_SESSION_BUS_ADDRESS ]]; then
    lines=$(pgrep &quot;dbus-daemon&quot; -u &quot;$USER&quot; | (while read -r line
    do
        echo $line
        exp=&#x60;procstat -h -e $line&#x60; 
        if [[ &quot;$exp&quot; == *&quot;DBUS_SESSION_BUS_ADDRESS=&quot;* ]]; then
	    echo &quot;DBus session found&quot;
	    exp2=&#x60;echo $exp |sed &#x27;s/.*DBUS_SESSION_BUS_ADDRESS=\([^ ]*\).*/\1/&#x27;&#x60;
    	    echo export DBUS_SESSION_BUS_ADDRESS=&quot;$exp2&quot; &gt; ~/.exports.sh
    	    FF=1
    	    break
        fi
    done; echo $lines) )
    echo $FF
    if [[ &quot;$FF&quot; = 8 ]]; then
       echo &quot;DBus session not found, starting..&quot;
       dbus_out=&#x60;dbus-launch&#x60;
       echo $dbus_out &gt; ~/.exports.sh
    fi
    if [[ -f ~/.exports.sh ]]; then
        source ~/.exports.sh
    fi
fi</pre>
  <p id="9VAQ">Этот скрипт натуральным образом ворует сессию работы с DBus, забираясь для этого в окружение запущенного процесса (да, так можно было) — все ради того чтобы ее не дублировать и не запускать процесс <code>dbus-launch</code> повторно.</p>
  <p id="jVAr">Помимо приседаний с параметрами, в версии для FreeBSD также используется описанное выше расширение браузера для отключения анимации, а вместо изоляции через <code>cgroups</code> используется более простой вариант со сниженным лимитом на количество запущенных процессов рендера:</p>
  <pre id="xjaT"> --renderer-process-limit=2</pre>
  <p id="KiBs">Чего вполне достаточно для комфортной работы.</p>
  <h2 id="8fID">За кадром</h2>
  <p id="x4qf">В качестве небольшого бонуса, ряд дополнительных параметров запуска браузера Chrome, которые остались за кадром.</p>
  <p id="9puY">Они также применимы ко всем версиям и вариациям браузера и работают на всех операционных системах.</p>
  <pre id="10Ch">--profile-directory=test-profile</pre>
  <p id="me8b">Указывает альтернативное название профиля, по-умолчанию он называется <code>Default</code> и <a href="https://superuser.com/questions/377186/how-do-i-start-chrome-using-a-specified-user-profile" target="_blank">находится в каталоге пользователя</a>.</p>
  <p id="GtH8">Актуально в первую очередь для тестов, но может влиять на системы защиты от ботов, поскольку данный ключ часто используют <a href="https://www.selenium.dev/documentation/webdriver/" target="_blank">системы автоматизации</a>, работающие поверх браузера.</p>
  <pre id="E5AI">--single-process</pre>
  <p id="1qvd">Заклинание чудовищной силы, которое заставляет браузер работать в одном единственном процессе:</p>
  <figure id="s1go" class="m_original">
    <img src="https://img4.teletype.in/files/7c/4b/7c4b3304-f9d5-448b-885c-39054c43bd91.png" width="1009" />
    <figcaption>Браузер Chrome, работающий в одном процессе.  Да, так тоже бывает.</figcaption>
  </figure>
  <p id="fjei">Этот весьма опасный (во всех смыслах) параметр переключает Chrome в нестандартный режим работы, при котором браузер не порождает отдельные процессы на каждую вкладку.</p>
  <p id="jFfZ">К сожалению такой режим работы является весьма нестабильным и браузер будет падать, особенно на сложном контенте и с большими расширениями вроде AdBlock.</p>
  <p id="rTKa">Тем не менее, это единственный известный мне способ заставить Chrome работать без порождения дополнительных процессов, что актуально для тестов и автоматизации.  </p>
  <pre id="nw3s">--disable-features=UseSkiaRenderer</pre>
  <p id="tOc7">Отключает современный бекэнд <a href="https://www.chromium.org/developers/design-documents/graphics-and-skia/" target="_blank">Skia Renderer</a>, используемый в браузере для отрисовки практически всей графики:</p>
  <blockquote id="gyi9">Chrome uses Skia for nearly all graphics operations, including text rendering. GDI is for the most part only used for native theme rendering; new code should use Skia.</blockquote>
  <p id="lGlO">К сожалению этот параметр является обязательным если вы собираетесь использовать <code>--single-process</code>, думаю очевидно что скорость отрисовки страниц при этом упадет.</p>
  <p id="2o8M"></p>
  <h2 id="VHr6">Эпилог</h2>
  <p id="wQqQ">Мой опыт оптимизации браузера весьма специфичный и далеко не глобальный, поскольку решаемая задача касается производительности на устаревшем оборудовании и не самых популярных операционных системах.</p>
  <p id="TrHX">Поэтому с радостью почитаю про ваш опыт и применяемые практики.</p>
  <figure id="PL6q" class="m_column">
    <img src="https://img2.teletype.in/files/1b/58/1b58d308-fd09-444d-b289-0f365f83d856.png" width="1320" />
    <figcaption>https://timeweb.cloud/</figcaption>
  </figure>
  <h2 id="QDAD">Спонсоры</h2>
  <section>
    <p id="4ZKX">Материал создан при поддержке компании <a href="https://timeweb.cloud/" target="_blank">Timeweb Cloud</a>, за что им огромная благодарность и всяческие респекты.</p>
  </section>
  <p id="LVAd">Оригинал статьи <a href="https://habr.com/ru/companies/timeweb/articles/1037426/" target="_blank">опубликован на Хабре</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/python-weird-tales-2026</guid><link>https://blog.0x08.ru/python-weird-tales-2026?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/python-weird-tales-2026?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>Интересные развлечения со змеей</title><pubDate>Thu, 23 Apr 2026 14:22:59 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/13/74/1374ee22-7c6c-4422-9712-b0c6bde0d124.png"></media:content><category>experiments</category><description><![CDATA[<img src="https://img1.teletype.in/files/05/70/0570d5cf-433a-419e-affb-2d22f530fb36.jpeg"></img>Снова рассказываю о развлечениях бородатых инженеров в суровых мужских коллективах, вдали от женского тепла и ласки.]]></description><content:encoded><![CDATA[
  <p id="GLwn">На этот раз у нас известный язык программирования <a href="https://www.python.org/" target="_blank">Python</a>, c двумя стилизованными змеями на <a href="https://www.python.org/community/logos/" target="_blank">логотипе</a>, интересные и необычные развлечения с которым были собраны в этой замечательной статье.</p>
  <figure id="7izU" class="m_column">
    <img src="https://img1.teletype.in/files/05/70/0570d5cf-433a-419e-affb-2d22f530fb36.jpeg" width="1365" />
    <figcaption>Все герои в сборе.</figcaption>
  </figure>
  <p id="Iutx"><a href="https://en.wikipedia.org/wiki/Python_(programming_language)" target="_blank">Python</a> — весьма занятный язык программирования с богатой историей, который сильно недооценивают многие серьезные программисты, напрасно полагая, что это «какие-то скрипты» для <s>детей</s> ML-щиков и тестировщиц.</p>
  <p id="cgjU">Надеюсь описанное ниже даст определенное понимание, что «змеиный язык» сильно сложнее чем кажется и несет в себе множество нетривиальных нюансов.</p>
  <h3 id="sNUr">Отказ от ответственности</h3>
  <p id="KmgA">Сам автор (несмотря на название статьи) всячески разделяет традиционные программистские ценности:</p>
  <blockquote id="xnRs">читаемость кода, адекватность реализации и радость применения</blockquote>
  <p id="a8L1">Поэтому заранее предупреждает, что попытка использовать описанные практики в реальном проекте может привести к серьезным проблемам со здоровьем и дальнейшим трудоустройством.</p>
  <p id="JcQt">Возможно с вами даже перестанут здороваться за руку. Когда отвяжут от батареи. </p>
  <h2 id="urRh">Развлечение первое: Змея и Си</h2>
  <p id="883S">Декабрьским вечером 2020 года, на <a href="https://www.reddit.com/" target="_blank">известном интернет-ресурсе</a>, в группе по программированию появился вот такой невинный <a href="https://www.reddit.com/r/learnprogramming/comments/kegalv/my_first_python_script_coming_from_c_feedback/" target="_blank">пост</a>:</p>
  <blockquote id="PHKS">Вчера начал изучать Python и пока мне все нравится. </blockquote>
  <blockquote id="8LTN">Хотя я давно пишу на С, некоторые вещи в Python уже кажутся проще чем в С. </blockquote>
  <blockquote id="PmUf">А ведь еще есть множество практик, которые легко перенести из С! Очень нравится, что тут есть циклы <code>while</code> и <code>for</code> прямо как в С. Боялся что придется опять все изучать с нуля, но оказалось что это не так. Единственное к чему пришлось привыкать, что выражения заканчиваются запятой а не точкой с запятой.</blockquote>
  <blockquote id="33H9">Как бы то ни было, вот <a href="https://tio.run/##rVNta9swEP7uX3E4DOzESZpkCyM0hTC20Q/dSl72pStCseVFzJaMJDeEst@enSQnIW3HxjaDsO65R7rn7nTVzmykGL2t1H6/b3GRFnXG4FKbjAvT21wF55i0UNDqt6FSrJuxtKCKgdlVTAMVGeS1SA2XQkO7HzxInk0gst4YpodNFEbWAe34IoyTAMMMxsS8wENPNBjHceRZo@EvWaOhZ1W10UiJtFExTKZg4zhupZBmCfafv0zBs8hwuaVS5FyVx2xcag9UcbouGPis6THNuzt7yf29vcVdlyBkpKGFxxrtDubPIRvYo40EhJzMBnT7gzImdI0Fz6XaUpX5mq9p@t1bqSwr1LXmBTc7K42XlVQGCMlrg@cIAarRqqg2hAStjOVcMPiwWq7m7@F2tlgeMWs0Dh9Z1gb1AbWxS2oMywBryMU3MBJ3GfptRDwOXnKkEwz1ZUZm848LQmLoXjX1gcljAPg1lss78kaPkFJmhDw9nGDm2fREEmyLqDdjLM4PJ/LvvqAFbVisbm5my@vPn2Dxbn59u4Q/@NzJf4lZl1BXQIsCzIaBoNgjWoCoyzVT2rqwtOMeLNGpmK4L08QEvZF1gZ1ncAEdGOAa4hrheo3rDa4xvp3hoPd/1PYPI499PcrLlSwxvJXontphQjlGvkiC7YbjrEQcLqcwft5y/0RCeJV9FWEC3DbREbidSm6z8m09eyQhIWF8mAXty/c7PW4SvaanGvEpn2YRuHByu@gBLzuBToeftPubUJ7fdFD1ucQmqSYnx0K1@58" target="_blank">мой скрипт</a> (на Python 3.8, это всего лишь игрушечный скрипт для тестов циклов for и while). Есть идеи как можно улучшить мой код и сделать его более читаемым?</blockquote>
  <p id="5BhN">Каждый открывший этот код <a href="https://tio.run/##rVNta9swEP7uX3E4DOzESZpkCyM0hTC20Q/dSl72pStCseVFzJaMJDeEst@enSQnIW3HxjaDsO65R7rn7nTVzmykGL2t1H6/b3GRFnXG4FKbjAvT21wF55i0UNDqt6FSrJuxtKCKgdlVTAMVGeS1SA2XQkO7HzxInk0gst4YpodNFEbWAe34IoyTAMMMxsS8wENPNBjHceRZo@EvWaOhZ1W10UiJtFExTKZg4zhupZBmCfafv0zBs8hwuaVS5FyVx2xcag9UcbouGPis6THNuzt7yf29vcVdlyBkpKGFxxrtDubPIRvYo40EhJzMBnT7gzImdI0Fz6XaUpX5mq9p@t1bqSwr1LXmBTc7K42XlVQGCMlrg@cIAarRqqg2hAStjOVcMPiwWq7m7@F2tlgeMWs0Dh9Z1gb1AbWxS2oMywBryMU3MBJ3GfptRDwOXnKkEwz1ZUZm848LQmLoXjX1gcljAPg1lss78kaPkFJmhDw9nGDm2fREEmyLqDdjLM4PJ/LvvqAFbVisbm5my@vPn2Dxbn59u4Q/@NzJf4lZl1BXQIsCzIaBoNgjWoCoyzVT2rqwtOMeLNGpmK4L08QEvZF1gZ1ncAEdGOAa4hrheo3rDa4xvp3hoPd/1PYPI499PcrLlSwxvJXontphQjlGvkiC7YbjrEQcLqcwft5y/0RCeJV9FWEC3DbREbidSm6z8m09eyQhIWF8mAXty/c7PW4SvaanGvEpn2YRuHByu@gBLzuBToeftPubUJ7fdFD1ucQmqSYnx0K1@58" target="_blank">по ссылке</a>, если он хоть немного понимал в программировании на Python — немедленно получал солнечный удар, разрыв мозга или сердечный приступ. </p>
  <p id="725d">И острое желание сжечь диплом инженера, поскольку этот замечательный код ставил под сомнение <s>границы реальности</s> компетенции практически любого Python-разработчика.</p>
  <p id="D9ta">Вот он целиком, сохранен для потомков:</p>
  <pre id="ba9b" data-lang="python">#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;

#/* pre-declare types and functions */
void: (type) = (type) (&quot;(void *)0&quot;),
int16_t: (type) = (type) (int(16))(),
int32_t: (type) = (type) (int(32))(),
puts: ((str) := void) = (print),
printf: ((str) := void) = (puts),

#/* confirm function and variable declarations */
[[void]] = (void),
[[total]] = (int32_t),
[[i]] = (int32_t),
[[puts]] = (puts),
[[printf]] = (printf),

#/* ensure forwards and backwards compatibility */
import __future__ as __past__
#define FUTURE PAST
#define PAST FUTURE

#/* output a formatted string to stdout */
def printf(s, __VA_ARGS__) -&gt; (void) :{
    (void) (puts((void).__mod__(s, __VA_ARGS__), end=((void).__new__)(void))),
}

#/*******************************************************
# * SUMMATION SCRIPT                                    *
# *******************************************************
# * Sum up all the natural numbers up to 6. The result  *
# * should be 0 + 1 + 2 + 3 + 4 + 5 + 6 = 21.           *
# *******************************************************/

#/* print numbers from 0 to 6 */
int32_t: i = 0,
while (i &lt;= 6) :{
    (void) (printf(&quot; %d\n&quot;, i)),
    (i := i + 1),
}

(void) (puts(&quot;__&quot;)),

#/* sum up numbers from 0 to 6 */
int32_t: total = 0,
int32_t: i = 0,
for (int32_t) in (i &lt;- 0, i &lt;= 6, ++i) :{
    (total := total + i),
}

(void) (printf(&quot;%d\n&quot;, total)),</pre>
  <p id="VHVJ">Упреждая очевидный вопрос:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="dYc0">да, оно работает.</p>
  </section>
  <p id="BKeA">Перед вами <strong>полностью рабочий</strong> код на языке Python, не на С.</p>
  <p id="En1l">К сожалению синтаксис успел немного поменяться с 2020го и попытка запуска на современной версии Python выдаст ошибку:</p>
  <figure id="yCG0" class="m_original">
    <img src="https://img2.teletype.in/files/5e/7f/5e7fbbe1-db81-4b52-b55a-0952970c1db8.png" width="673" />
    <figcaption>Вызов <code>python</code> довольно давно и повсеместно означает по-умолчанию 3.х версию, конкретно в этом случае - 3.11.</figcaption>
  </figure>
  <p id="5qlF">Ошибку тем не менее легко исправить, убрав скобки вокруг <code>str</code> в двух строках. Было:</p>
  <pre id="s70V" data-lang="python">puts: ((str) := void) = (print),
printf: ((str) := void) = (puts),</pre>
  <p id="654M">Стало:</p>
  <pre id="PEEA" data-lang="python">puts: (str := void) = (print),
printf: (str := void) = (puts),</pre>
  <p id="31bX">После правки все отлично запускается:</p>
  <figure id="XCeg" class="m_original">
    <img src="https://img2.teletype.in/files/dd/e8/dde870fd-fe24-4b7a-b214-883fcb40b7ec.png" width="673" />
    <figcaption>Подсчет всех натуральных чисел от 0 до 6, для проверки: 0 + 1 + 2 + 3 + 4 + 5 + 6 = 21.     </figcaption>
  </figure>
  <p id="VpYP">Теперь стоит рассказать как <strong>это</strong> чудовище инженерной мысли вообще работает, на случай если встретите подобное в <s>темной подворотне</s> реальном проекте.</p>
  <blockquote id="1XMw">Оригинальный разбор был также <a href="https://www.reddit.com/r/Python/comments/pqs9au/comment/hdgv0aw/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button" target="_blank">опубликован на Реддите</a>, ниже приведен вольный перевод самых интересных фрагментов.</blockquote>
  <p id="Nad4">Начнем с банального, но далеко не всем очевидного:</p>
  <pre id="FFlq" data-lang="python">#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;</pre>
  <p id="pyTJ">Строки выше — <strong>валидные</strong> инструкции препроцессора для языка С, но для Python они являются лишь текстовыми комментариями. Так что это чистый троллинг «змеелюбов» и строки выше никак не используются в логике программы.</p>
  <p id="hXU6">Следующая интересная конструкция уже сильно сложнее для понимания:</p>
  <pre id="YJvp" data-lang="python">void: (type) = (type) (&quot;(void *)0&quot;),</pre>
  <p id="j8gj">Тут происходит объявление переменной с именем <code>void</code> и значением в виде <a href="https://docs.python.org/3/reference/simple_stmts.html#type" target="_blank">типа строки</a>, но поскольку в конце стоит запятая — на самом деле получается <a href="https://typing.python.org/en/latest/spec/tuples.html" target="_blank">кортеж</a>.</p>
  <p id="i6I2">Вот такой хитрый финт ушами, хотя далеко не последний:</p>
  <pre id="M9lk" data-lang="python">int16_t: (type) = (type) (int(16))(),
int32_t: (type) = (type) (int(32))(),</pre>
  <p id="MF1S">Да это снова «троллинг-пародия» под код С, вызова <code>int32_t = int()</code> было бы достаточно. Но автор решил преобразовать 16 в <code>int</code>, получить тип, а затем вызвать его конструктор, что дало пустое значение этого типа. </p>
  <p id="KmK4">Вызов <code>int()</code> даёт 0, если кто не знает.</p>
  <pre id="PRcn" data-lang="python">puts: ((str) := void) = (print),
printf: ((str) := void) = (puts),</pre>
  <p id="4vQp">Эти две строчки идентичны, так что вся конструкция просто задаёт функцию с именем <code>puts</code>, которая равна <code>print</code>, и <code>printf</code>, которая также равна <code>print</code>.</p>
  <pre id="EGQh" data-lang="python">#/* confirm function and variable declarations */
[[void]] = (void),
[[total]] = (int32_t),
[[i]] = (int32_t),
[[puts]] = (puts),
[[printf]] = (printf),</pre>
  <p id="pJDY">Все строки выше на самом деле кортежи (из-за запятой в конце), а сама конструкция разворачивает их на уровень выше — становится возможным обратиться к переменной по имени в двойных квадратных скобках:</p>
  <figure id="8t7V" class="m_column">
    <img src="https://img2.teletype.in/files/d4/c3/d4c324ae-9b59-48bd-8088-1ae5b68a100d.png" width="747" />
    <figcaption>Последовательный вызов инструкций в интерактивном интерпретаторе Python.</figcaption>
  </figure>
  <p id="y5UI">Следующие интересные строки являются чистым, стопроцентным троллингом:</p>
  <pre id="DOvp" data-lang="python">#/* ensure forwards and backwards compatibility */
import __future__ as __past__
#define FUTURE PAST
#define PAST FUTURE</pre>
  <p id="N23h">Несмотря на то что в языке Python действительно присутствует <a href="https://docs.python.org/3/library/__future__.html" target="_blank">специальная конструкция</a>: </p>
  <pre id="vzGq" data-lang="python">from __future__ import feature</pre>
  <p id="EBCq">указывающая компилятору на использование конструкций языка, которые еще  не вошли в релизную версию, конечно же никаких «ensure forwards and backwards compatibility» <strong>нет</strong> и быть не может.</p>
  <p id="W0Gm">О чем и шутят пользователи Реддита, ссылаясь на «путешествия во времени»:</p>
  <figure id="K2yq" class="m_original">
    <img src="https://img2.teletype.in/files/56/00/5600eb9a-f3ae-40f8-93f5-fa0e3f658533.png" width="545" />
  </figure>
  <p id="SSoE">Следующий интересный блок, точно достойный разбора:</p>
  <pre id="uTPL" data-lang="python">#/* output a formatted string to stdout */
def printf(s, __VA_ARGS__) -&gt; (void) :{
    (void) (puts((void).__mod__(s, __VA_ARGS__), end=((void).__new__)(void))),
}</pre>
  <p id="gJwt">Тут переопределяется  <code>printf</code> в виде функции, которая  по идее должна возвращать строку из-за <code>-&gt; (void)</code>, но на самом деле возвращает <code>None</code>. </p>
  <p id="uR3I">Поскольку такая конструкция проходит проверку типов, функция вида:</p>
  <pre id="Y1SY" data-lang="python">def x() -&gt; str: 
  return None</pre>
  <p id="71qQ">вполне имеет право на существование и вернет тип <code>NoneType</code> при вызове.</p>
  <blockquote id="u26p">Еще из интересного тут происходит вызов метода <a href="https://docs.python.org/3/library/operator.html" target="_blank">__mod__</a> у <code>print</code>, что внезапно дает подстановку значения в шаблон вроде <code>&quot;%d\n&quot;</code>.</blockquote>
  <p id="H6Xf">Следующий мозговыносящий для питонистов блок:</p>
  <pre id="YSA6" data-lang="python">#/* print numbers from 0 to 6 */
int32_t: i = 0,</pre>
  <p id="II6S">Тут создается новая переменная <code>int32_t</code>, у которой в качестве типа стоит <code>i</code>. Поскольку <code>i</code> был распакован конструкцией выше — все это проходит проверку типов и <code>int32_t</code> становится равно кортежу <code>(0,)</code>.</p>
  <p id="AZkU">А теперь самое веселое:</p>
  <pre id="hKQG" data-lang="python">while (i &lt;= 6) :{
    (void) (printf(&quot; %d\n&quot;, i)),
    (i := i + 1),
}</pre>
  <p id="wD3S">Напоминаю, что это все еще <strong>стандартный</strong> Python, это не C и не Java.</p>
  <p id="ZjLb">Фигурные скобки тут на самом деле лишь для <s>красоты</s> ввода в заблуждение, поскольку будет работать и так:</p>
  <pre id="KiP8" data-lang="python">def func(self): {
        print(&quot;Yo braces!&quot;)
     }</pre>
  <p id="t7fP">И вот так:</p>
  <pre id="VNak" data-lang="python">def func(self): 
        print(&quot;Yo braces!&quot;)     </pre>
  <p id="gqOF">Теперь вы знаете чем <s>выбесить</s> порадовать интервьюера на собеседовании.</p>
  <p id="mNV6">Но вернемся к примеру с циклом.</p>
  <p id="HA4a">Перед нами стандартный цикл <code>while</code>, в котором за каждый проход создается набор (set) из двух элементов. Первый элемент это результат вызова <code>str(print( %d\n&quot;%i))</code>, второй — счетчик с именем <code>i</code>.</p>
  <p id="gWb2">После завершения цикла, у <code>i</code>  будет значение 7.</p>
  <p id="hBWL">Следующий блок кода, несмотря на внешнюю фантастичность, довольно простой: </p>
  <pre id="iqG6" data-lang="python">(void) (puts(&quot;__&quot;)),</pre>
  <p id="J7df">Это аналог вызова <code>str (print (__))</code>. , который просто печатает на экране символ <code>_</code>. И все.</p>
  <p id="rq7J">Зато тут уже настоящая жесть:</p>
  <pre id="NYFU" data-lang="python">int32_t: i = 0,
for (int32_t) in (i &lt;- 0, i &lt;= 6, ++i) :{
    (total := total + i),
}</pre>
  <p id="sxt2">Да, это все еще обычный Python, без DSL и модулей расширения. </p>
  <p id="p206">В примере выше создается кортеж вида <code>(False, False, 7)</code>, поскольку 7 больше нуля, не меньше или равно 6 а вызов ++7 дает 7. Так что вся конструкция на самом деле аналогична привычному <code>for _ in range(3):</code> </p>
  <p id="5QnY">Внутри цикла происходит увеличение значения переменной <code>total</code> на 7, 3×7 = 21, цикл отрабатывает три раза, создает три набора (set), которые равны значению <code>total</code>.</p>
  <p id="svsi">Ну и последнее:</p>
  <pre id="Bl0S" data-lang="python">(void) (printf(&quot;%d\n&quot;, total)),</pre>
  <p id="OMoK">Сия адская конструкция, будто бы прямиком из больного сознания старого LISP-программиста всего лишь.. выводит на экран значение переменной <code>total</code>. </p>
  <p id="WLuP">Работа безусловно «мощи великой», но это еще не конец.</p>
  <h2 id="O1YB">Развлечение второе:  Змея-оборотень</h2>
  <p id="xm5D">Следующим интересным примером и<s>збытка свободного времени</s> серьезных инженерных талантов является <a href="https://gist.github.com/chipx86/d471b828e0a64a8dd87502e3439a5be9" target="_blank">вот такой gist</a>, c воодушевляющим названием <code>evil.py.c</code>.</p>
  <p id="lk03">Привожу его код целиком:</p>
  <pre id="KB3i" data-lang="python">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;

#define __file__ __FILE__

#define import void*
#define def int
import codecs;
import os;
import subprocess;
import tempfile;

#if PYTHON
LANG = &#x27;Python&#x27;
FROM_C = globals().get(&#x27;FROM_C&#x27;, False)
START = None
END = None
PYTHON_CODE = lambda x: eval(compile(&#x27;if 1:\n%s&#x27; % x[2:-3], &#x27;&lt;string&gt;&#x27;, &#x27;exec&#x27;),
                             globals(), globals())
C_CODE = lambda *args: None
PRINT_PREFIX, PRINT_SUFFIX = (&#x27;printf(&quot;&#x27;, &#x27;\\n&quot;);&#x27;) if FROM_C else (&#x27;&#x27;, &#x27;&#x27;)
write = lambda s, *args: print(&#x27;%s%s%s&#x27; % (PRINT_PREFIX, s % args, PRINT_SUFFIX))
#else
# define LANG &quot;C&quot;
# define START int main() {
# define END }
# define PYTHON_CODE(x)
# define C_CODE(a, b, c) b
# ifdef FROM_PYTHON
#  define PRINT_PREFIX &quot;print(\&quot;\&quot;\&quot;&quot;
#  define PRINT_SUFFIX &quot;\&quot;\&quot;\&quot;)&quot;
#else
#  define PRINT_PREFIX
#  define PRINT_SUFFIX
#endif
# define write(x, ...) printf(PRINT_PREFIX x PRINT_SUFFIX &quot;\n&quot;, __VA_ARGS__)
#endif

START

PYTHON_CODE((&quot;&quot;&quot; &quot;
    if FROM_C:
        print(&quot;#include &lt;stdio.h&gt;&quot;)
        print(&quot;int main() {&quot;);
&quot; &quot;&quot;&quot;))

write(&quot;%s: %s: Hello, world!&quot;, LANG, __file__);

PYTHON_CODE((&quot;&quot;&quot; &quot;
    def decode_c(text):
        fd, out_file = tempfile.mkstemp()
        os.close(fd)

        try:
            subprocess.check_output([
                &#x27;clang&#x27;, &#x27;-x&#x27;, &#x27;c&#x27;,
                &#x27;-DFROM_PYTHON=1&#x27;,
                __file__, &#x27;-o&#x27;, out_file,
            ])
            result = subprocess.check_output(out_file)
            return result, len(result)
        finally:
            os.unlink(out_file)

    if FROM_C:
        print(&quot;}&quot;);
    else:
        codecs.register(lambda name: codecs.CodecInfo(lambda text: &quot;&quot;,
                                                      decode_c,
                                                      name=&#x27;c&#x27;))

        exec(codecs.decode(open(__file__, &#x27;r&#x27;), encoding=&#x27;c&#x27;))
&quot; &quot;&quot;&quot;))

C_CODE(&quot;&quot;&quot; &quot;,
#if !FROM_PYTHON
    fflush(stdout);

    popen(&quot;python3.8 -c \&quot;FROM_C=True ; __file__ = &#x27;&quot; __FILE__ &quot;&#x27;; &quot;
          &quot;exec(open(&#x27;&quot; __FILE__ &quot;&#x27;).read())\&quot;&quot;
          &quot;| clang -x c -o .generated-evil -&quot;,
          &quot;r&quot;);
    system(&quot;./.generated-evil&quot;);
    unlink(&quot;.generated-evil&quot;);
#endif
,&quot; &quot;&quot;&quot;)

END</pre>
  <p id="OAz2">Несмотря на устрашающее название, ничего действительно злого этот код не делает, так что можете отключать антивирусы.</p>
  <p id="iGEB">Как пишет сам автор:</p>
  <blockquote id="xtYB">I regret nothing.</blockquote>
  <p id="IBpQ">И я его не виню, поскольку перед нами отличный пример программы-оборотня, код которой валиден сразу для двух <strong>очень разных</strong> языков: Python и С.</p>
  <p id="MVz7">Так выглядит запуск в виде скрипта Python:</p>
  <figure id="t7eL" class="m_original">
    <img src="https://img2.teletype.in/files/d6/6f/d66fea0f-f6c3-41c0-b2ac-465cb1ca6109.png" width="673" />
    <figcaption>Python все также 3й, версии 3.11.</figcaption>
  </figure>
  <p id="nqgV">А это уже компиляция с помощью <code>clang</code> в виде кода на С:</p>
  <figure id="xypC" class="m_column">
    <img src="https://img1.teletype.in/files/07/93/07933f19-b513-40d1-9071-d8c9fe4b5747.png" width="828" />
    <figcaption>Поскольку нет каких-либо требований к версии и типу компилятора С, использовался обычный Clang 21.</figcaption>
  </figure>
  <p id="zF1p">Но это еще не все: </p>
  <blockquote id="hSLs">если вы чего-то понимаете в Python или С — могли заметить, что код выше <em>несколько сложноват</em> для простого вывода строки «Hello, world!»</blockquote>
  <p id="XVne">Даже с учетом специфики «программы с двойным дном», исходного кода все равно многовато, а еще и в описании есть загадочная строка:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="xhcF">Evil Python/C cross-language code <strong>generator</strong></p>
  </section>
  <p id="FznT">Генератор, ага.</p>
  <p id="ay0G">Так что код выше на самом деле выполняет два разных действия:</p>
  <ol id="ZPNo">
    <li id="bEeq">действительно печатает «Hello, world!»;</li>
    <li id="HPuq">генерирует <strong>код для второй части</strong>, компилирует и тут же запускает.</li>
  </ol>
  <p id="DYTT">Поэтому в выводе видны две строчки «Hello, world!» вместо одной, вторая — от запуска новой копии.</p>
  <p id="DdLJ">Добавлю, что в коде есть вот такое место:</p>
  <pre id="dL3a" data-lang="c">popen(&quot;python3.8 -c \&quot;FROM_C=True ; __file__ = &#x27;&quot; __FILE__ &quot;&#x27;; &quot;
          &quot;exec(open(&#x27;&quot; __FILE__ &quot;&#x27;).read())\&quot;&quot;
          &quot;| clang -x c -o .generated-evil -&quot;,
          &quot;r&quot;);</pre>
  <p id="aKMb">Тут вшита версия Python, актуальная на момент создания проекта, но скорее всего в вашей системе не будет устаревшего Python 3.8, поэтому скрипт при попытке запуска упадет с ошибкой.</p>
  <p id="VAa3">Для исправления либо замените в этом месте <code>python3.8</code> на просто <code>python3</code>, либо создайте символьную ссылку с нужным именем:</p>
  <pre id="y8BX" data-lang="bash">ln -s /usr/bin/python3 ~/.local/bin/python3.8</pre>
  <p id="MTHr">Вот такой интересный проект, <code>clang</code> вызываемый через <a href="https://bash.cyberciti.biz/guide/Pipes" target="_blank">пайплайн</a> автор до него не встречал.</p>
  <h2 id="m7bq">Развлечение третье:  Кошмар аудитора</h2>
  <p id="SdJX">На этот раз постарался известный LinkedIn, подбросив мне в <s>вентилятор</s> ленту <a href="https://www.linkedin.com/posts/marcin-albiniak-ph-d-215817259_dangerous-python-artifact-1-a-function-share-7435219064748400641-7IPQ?utm_source=social_share_send&utm_medium=member_desktop_web&rcm=ACoAAAxcoWUBXsgS8sZZv681aunuwBNOJwUzrDs" target="_blank">замечательный пост</a> с весьма необычным кодом:</p>
  <figure id="4UMP" class="m_column">
    <img src="https://img3.teletype.in/files/aa/94/aa94a019-d5ff-4a98-a1a5-6b13cc8f1c8d.jpeg" width="963" />
    <figcaption>Да это шапка поста, созданная для привлечения внимания в LinkedIn. </figcaption>
  </figure>
  <p id="RIF6">Удивительно, но код снова <strong>полностью рабочий</strong> и запускается на современной версии Python (3.13) без каких-либо правок:</p>
  <figure id="Nbst" class="m_column">
    <img src="https://img1.teletype.in/files/84/7a/847a051c-9aed-4dab-ad26-c236d580a467.png" width="828" />
    <figcaption>Символ &quot;омега&quot; вставлен юникодом, который Python давно и отлично поддерживает в коде.</figcaption>
  </figure>
  <p id="3dMI">Привожу исходный код c картинки выше, дабы было проще копировать и рассылать знакомым <s>змеелюбам</s> питонистам:</p>
  <pre id="CI4k" data-lang="python">def artifact():
  def f(x): return x+1

  def gate(x):
     if x == 7:
        f.__code__ = (lambda y: f&quot;Ω:{y*y}&quot;).__code__
     return f(x)
  return gate

g = artifact()
print(g(1),g(7),g(2))</pre>
  <p id="9yD9">То что тут происходит станет неприятным сюрпризом для всех, кто вынужден заниматься аудитом «змеиного кода»:</p>
  <blockquote id="yqrJ">In Python, every function has an attribute called <code>__code__</code>.<br />This is the bytecode, the actual execution engine of the function.<br />And it can be replaced while the program is running.</blockquote>
  <p id="mL2c">По условию <code>x == 7</code> происходит <strong>подмена</strong> байткода функции на лету — прямо в работающем приложении:</p>
  <pre id="PT3D" data-lang="python">if x == 7:
        f.__code__ = (lambda y: f&quot;Ω:{y*y}&quot;).__code__</pre>
  <p id="drbo">Разумеется в самой технике нет ничего нового, аналогичный функционал присутствует и в Java и в C#, но только <s>крестьянская</s> простота с которой это происходит в Python определенно станет сюрпризом.</p>
  <p id="VMgN">Заметить и отследить такое в реальном проекте весьма непросто.</p>
  <h2 id="mKNv">Развлечение четвертое:  Новый взгляд на ООП</h2>
  <p id="JuX5">Посмотрите на этот замечательный код, взятый из <a href="https://martinheinz.dev/blog/103" target="_blank">блога</a> очередного бородатого <a href="https://github.com/MartinHeinz" target="_blank">эксперта</a>, проведшего (судя по профилю на Github) много лет в интересных развлечениях со змеей:</p>
  <pre id="iGzs" data-lang="python">class A:
    def func(self):
        print(&quot;A&quot;)

class B:
    def func(self):
        print(&quot;B&quot;)

a = A()
a.func()  # A

a.__class__ = B
a.func()  # B</pre>
  <p id="ZdFf">В коде выше декларируются два разных, никак не связанных между собой класса: </p>
  <blockquote id="pkm9">нет общего предка и нет наследования. </blockquote>
  <p id="sYlD">Затем вызывается конструктор первого класса и получается экземпляр объекта, у которого затем вызывается тестовый метод — стандартные шаги, не вызывающие вопросов. </p>
  <p id="XPhM">Но вот дальше происходит «чудо чудесное»:</p>
  <pre id="XpGx" data-lang="python">a.__class__ = B</pre>
  <p id="k4YI">Перезаписывается специальный атрибут <a href="https://en.andreaminini.com/python/the-__class__-attribute-in-python-objects" target="_blank">__class__</a>  , в качестве значения устанавливается класс <code>B</code>, никак не связанный с <code>A</code>. </p>
  <blockquote id="7Xl2">Затем происходит вызов метода <code>func</code>, чья сигнатура полностью совпадает в обоих классах.</blockquote>
  <p id="4uZD">Да, это замечательно работает в Python, причем без каких-либо предупреждений:</p>
  <figure id="g9cQ" class="m_column">
    <img src="https://img1.teletype.in/files/c0/e4/c0e40738-3248-4077-b620-b962862c502b.png" width="801" />
    <figcaption>Вот так, одной строкой один объект внезапно стал другим.</figcaption>
  </figure>
  <p id="H3bl">Пикантности ситуации добавляет отсутствие явного вызова конструктора у класса B — представляете как весело такое ловить в реальном проекте?</p>
  <h2 id="TbWS">Развлечение пятое:  Змея и побитовый сдвиг</h2>
  <p id="t0JS">Самое интересное и шикарное я приберег на конец повествования, в качестве награды <s>выжившим</s> дочитавшим до этого места. </p>
  <p id="4Tma">Итак, перед вами <em>совершенно особенный</em> <a href="https://benkurtovic.com/2014/06/01/obfuscating-hello-world.html" target="_blank">код на Python</a>, на котором карьеру программиста можно спокойно завершать:</p>
  <pre id="6jC4" data-lang="python">(lambda _, __, ___, ____, _____, ______, _______, ________:
    getattr(
        __import__(True.__class__.__name__[_] + [].__class__.__name__[__]),
        ().__class__.__eq__.__class__.__name__[:__] +
        ().__iter__().__class__.__name__[_:][_____:________]
    )(
        _, (lambda _, __, ___: _(_, __, ___))(
            lambda _, __, ___:
                bytes([___ % __]) + _(_, __, ___ // __) if ___ else
                (lambda: _).__code__.co_lnotab,
            _ &lt;&lt; ________,
            (((_____ &lt;&lt; ____) + _) &lt;&lt; ((___ &lt;&lt; _____) - ___)) + (((((___ &lt;&lt; __)
            - _) &lt;&lt; ___) + _) &lt;&lt; ((_____ &lt;&lt; ____) + (_ &lt;&lt; _))) + (((_______ &lt;&lt;
            __) - _) &lt;&lt; (((((_ &lt;&lt; ___) + _)) &lt;&lt; ___) + (_ &lt;&lt; _))) + (((_______
            &lt;&lt; ___) + _) &lt;&lt; ((_ &lt;&lt; ______) + _)) + (((_______ &lt;&lt; ____) - _) &lt;&lt;
            ((_______ &lt;&lt; ___))) + (((_ &lt;&lt; ____) - _) &lt;&lt; ((((___ &lt;&lt; __) + _) &lt;&lt;
            __) - _)) - (_______ &lt;&lt; ((((___ &lt;&lt; __) - _) &lt;&lt; __) + _)) + (_______
            &lt;&lt; (((((_ &lt;&lt; ___) + _)) &lt;&lt; __))) - ((((((_ &lt;&lt; ___) + _)) &lt;&lt; __) +
            _) &lt;&lt; ((((___ &lt;&lt; __) + _) &lt;&lt; _))) + (((_______ &lt;&lt; __) - _) &lt;&lt;
            (((((_ &lt;&lt; ___) + _)) &lt;&lt; _))) + (((___ &lt;&lt; ___) + _) &lt;&lt; ((_____ &lt;&lt;
            _))) + (_____ &lt;&lt; ______) + (_ &lt;&lt; ___)
        )
    )
)(
    *(lambda _, __, ___: _(_, __, ___))(
        (lambda _, __, ___:
            [__(___[(lambda: _).__code__.co_nlocals])] +
            _(_, __, ___[(lambda _: _).__code__.co_nlocals:]) if ___ else []
        ),
        lambda _: _.__code__.co_argcount,
        (
            lambda _: _,
            lambda _, __: _,
            lambda _, __, ___: _,
            lambda _, __, ___, ____: _,
            lambda _, __, ___, ____, _____: _,
            lambda _, __, ___, ____, _____, ______: _,
            lambda _, __, ___, ____, _____, ______, _______: _,
            lambda _, __, ___, ____, _____, ______, _______, ________: _
        )
    )
)</pre>
  <p id="cL54">Серьезно:</p>
  <blockquote id="LWgL">если сможете что-то подобное написать — заканчивайте с программированием, круче уже не будет.</blockquote>
  <p id="FwWO">Конечно же такая работа не могла появиться случайно, а ее <a href="https://github.com/earwig" target="_blank">автор</a> — мягко говоря не новичок в программировании. </p>
  <p id="Cbm7">Работа заняла <strong>первое место</strong> в конкурсе <s>для особенных</s> по обфускации:</p>
  <blockquote id="mxIe">got first place in <a href="https://codegolf.stackexchange.com/q/22533" target="_blank">this Code Golf contest</a> to create the weirdest obfuscated program that prints the string “Hello world!”</blockquote>
  <p id="pPG7">Оригинальный код был создан еще в далеком 2014м году, для совсем забытого ныне Python 2.7. Много позже — в 2017м автор опубликовал обновленную версию для Python 3.x, которую я и запустил в современном окружении:</p>
  <figure id="yAJd" class="m_original">
    <img src="https://img2.teletype.in/files/55/58/55585454-ae5f-45dd-9da8-0da5018b546f.png" width="1365" />
    <figcaption>Запуск с результатом выполнения на фоне собственного исходного кода.</figcaption>
  </figure>
  <p id="mwzB">Несмотря на острое желание, все же не стану пересказывать тут шаги реализации этого шедевра, дабы статья не превратилась в эпическую сагу <s>о подвигах предков</s> — в <a href="https://benkurtovic.com/2014/06/01/obfuscating-hello-world.html" target="_blank">оригинальном посте</a> все подробно описано.</p>
  <p id="KSN4">Ограничусь лишь таким интересным скриншотом, демонстрирующим в работе одну из ключевых стадий создания:</p>
  <figure id="gxz6" class="m_column">
    <img src="https://img3.teletype.in/files/2b/6f/2b6f92bf-0277-47c7-ab04-a744e30efe1b.png" width="900" />
    <figcaption>Всем, кто занимался спортивным программированием, думаю идея будет очевидна.</figcaption>
  </figure>
  <p id="D7G0">Конечно мало шансов увидеть подобное в реальном приложении (что радует), если только вы не занимаетесь изучением <a href="https://en.wikipedia.org/wiki/Malware" target="_blank">малвари</a>. Но даже в этом случае, столь сильно обфусцированный код на Python — большая редкость.</p>
  <h2 id="gGgE">Еще больше диких змей</h2>
  <p id="b33P">Помимо описанных выше чудес, в сети еще есть много подборок дичи, связанной с особенностями языка Python. Но поскольку статья не резиновая, ниже буквально одной строкой описываю самое интересное.</p>
  <h3 id="Nnw8">Python&#x27;s horror show</h3>
  <p id="U1yy"><a href="https://github.com/pablogsal/python-horror-show" target="_blank">https://github.com/pablogsal/python-horror-show</a></p>
  <p id="4z9F">Содержит коллекцию примеров «змеиного кода» с подозрительным или нетривиальным поведением, с описанием причин:</p>
  <blockquote id="gasl">Strange and odd python snippets explained</blockquote>
  <p id="oHP2">Некоторые примеры определенно заставят икать даже опытных разработчиков:</p>
  <pre id="UgYI" data-lang="python">&gt;&gt;&gt; all([])
True
&gt;&gt;&gt; all([[]])
False
&gt;&gt;&gt; all([[[]]])
True</pre>
  <p id="WFht"></p>
  <h3 id="fDPo">WTF Python!</h3>
  <p id="tQFn"><a href="https://github.com/satwikkansal/wtfpython" target="_blank">https://github.com/satwikkansal/wtfpython</a></p>
  <p id="wNTn">Монументальная подборка отборной дичи, переведенная на 6 (шесть) языков: </p>
  <blockquote id="4BWm">Here&#x27;s a fun project attempting to explain what exactly is happening under the hood for some counter-intuitive snippets and lesser-known features in Python.</blockquote>
  <p id="1dPy">Это точно стоит держать в закладках, особенно если заставляют разгребать код на Python <s>за нейросетью</s> с горящими сроками.</p>
  <p id="ocsL">В качестве примера:</p>
  <figure id="wE9N" class="m_column">
    <img src="https://img3.teletype.in/files/ef/c0/efc0c9da-55b9-4a4a-a7e2-b83a89810dbf.png" width="988" />
    <figcaption>&quot;Specifically&quot; при таком поведении особенно радует.</figcaption>
  </figure>
  <p id="bZOa">Ну и в качестве «дембельского аккорда» показываю самое лютое:</p>
  <figure id="UNMJ" class="m_column">
    <img src="https://img2.teletype.in/files/9e/ea/9eeab166-5046-4956-87a6-ae387ec8d8e1.png" width="875" />
  </figure>
  <h3 id="YXww">International Obfuscated Python Code Competition</h3>
  <p id="3da4"><a href="https://pyobfusc.com/" target="_blank">https://pyobfusc.com/</a></p>
  <p id="6MAc">Отдельный <strong>конкурс</strong>, целиком посвященный обфускации кода на Python — прямой аналог классического <a href="https://www.ioccc.org/" target="_blank">IOCCC</a>!</p>
  <p id="O0wd">В качестве примера <a href="https://pyobfusc.com/submissions2023/1669075090/main.py" target="_blank">одна из работ-победителей</a>:</p>
  <pre id="oCHa" data-lang="python">&quot;&quot;&quot;ᐌ([ᐊ(ᐄ(ᐆ(&#x27;print&#x27;,ᐇ()),[ᐄ(ᐈ(ᐄ(ᐆ(&#x27;open&#x27;,ᐇ()),                   [ᐆ(&#x27;__file__                           &#x27;,ᐇ()),ᐃ(&#x27;r&#x27;
)],ᐉ),&#x27;read&#x27;,ᐇ()),ᐉ,ᐉ)],ᐉ)),ᐊ(ᐄ(ᐆ(&#x27;print&#x27;,ᐇ()),ᐉ,ᐉ)),             ᐂ([ᐁ(&#x27;conte&#x27;                         &#x27;xtlib&#x27;),ᐁ(
&#x27;io&#x27;),ᐁ(&#x27;operator&#x27;),ᐁ(&#x27;time&#x27;)]),Assign([ᐆ(&#x27;f&#x27;,ᐋ())],ᐄ(ᐈ(           ᐆ(&#x27;io&#x27;,ᐇ()),                       &#x27;StringIO&#x27;,ᐇ
()),ᐉ,ᐉ)),With([withitem(ᐄ(ᐈ(ᐆ(&#x27;contextlib&#x27;,ᐇ()),&#x27;redirect&#x27;         &#x27;_stdout&#x27;,ᐇ(                     )),[ᐆ(&#x27;f&#x27;,ᐇ(
))],ᐉ))],[ᐂ(                                   [ᐁ(&#x27;this&#x27;)])])        ,For(Tuple([                   ᐆ(&#x27;i&#x27;,ᐋ()),ᐆ
(&#x27;l&#x27;,ᐋ())],ᐋ                                     ()),ᐄ(ᐆ(&#x27;enum&#x27;       &#x27;erate&#x27;,ᐇ())                 ,[ᐄ(ᐈ(ᐄ(ᐈ(ᐆ(
&#x27;f&#x27;,ᐇ()),&#x27;g&#x27;                                      &#x27;etvalue&#x27;,ᐇ())       ,ᐉ,ᐉ),&#x27;spli&#x27;               &#x27;tlines&#x27;,ᐇ()
),ᐉ,ᐉ)],ᐉ),[                                       ᐎ(ᐒ(ᐏ(),ᐆ(&#x27;i&#x27;        ,ᐇ())),[ᐊ(ᐄ(             ᐆ(&#x27;print&#x27;,ᐇ(
)),[ᐓ([ᐃ(&#x27;H&#x27;                                       &#x27;ow does this&#x27;        &#x27; code do i&#x27;           &#x27;n terms of&#x27;
&#x27; &gt;&#x27;),ᐑ(ᐄ(ᐈ(                                       ᐆ(&#x27;l&#x27;,ᐇ()),&#x27;r&#x27;         &#x27;eplace&#x27;,ᐇ()         ),[ᐃ(&#x27;,&#x27;),ᐃ(
&#x27;&lt;&#x27;)],ᐉ),-1)                                      ,ᐃ(&#x27;?&#x27;)])],ᐉ))           ,ᐐ()],[ᐎ(ᐒ(ᐏ       (),ᐆ(&#x27;l&#x27;,ᐇ()
)),[ᐊ(ᐄ(ᐆ(&#x27;&#x27;                                     &#x27;print&#x27;,ᐇ()),ᐉ,            ᐉ)),ᐐ()],ᐉ)]     ),ᐊ(ᐄ(ᐆ(&#x27;pr&#x27;
&#x27;int&#x27;,ᐇ()),[                                    ᐍ(ᐅ(ᐆ(&#x27;comment&#x27;              ,ᐋ( )),ᐄ( ᐈ(   Dict([ᐃ(11),
ᐃ(12),ᐃ(13),                                 ᐃ(17),ᐃ(19)],[ᐃ(                 &#x27;no errors were silenced&#x27;
),ᐃ(&#x27;no err&#x27;                           &#x27;ors were thrown&#x27;),ᐃ(                   &#x27;everything is crystal&#x27;
&#x27; clear&#x27;),ᐃ(&#x27;for this code, never would have been better&#x27;)                      ,ᐃ(&#x27;does not apply&#x27;)]
),&#x27;get&#x27;,ᐇ()),[ᐆ(&#x27;i&#x27;,ᐇ())],ᐉ)),ᐄ(ᐈ(ᐓ([ᐃ(&#x27;\x1b[32m✔ &#x27;),ᐑ                           (ᐆ(&#x27;l&#x27;,ᐇ()),-1),ᐃ(
&#x27;\x1b[0m__#_&#x27;),ᐑ(ᐆ(&#x27;comment&#x27;,ᐇ()),-1),ᐃ(&#x27;.&#x27;)]),&#x27;re&#x27;                               &#x27;place&#x27;,ᐇ()),[ᐃ(
&#x27;_&#x27;),ᐃ(&#x27; &#x27;)],ᐉ),ᐓ([ᐃ(&#x27;\x1b[91m✘ &#x27;),ᐑ(ᐆ(&#x27;l&#x27;,ᐇ())                                     ,-1)]))],ᐉ)),
ᐊ(ᐄ(ᐈ(ᐆ(&#x27;time&#x27;,ᐇ()),&#x27;sleep&#x27;,ᐇ()),[ᐃ(0.3)],ᐉ                                          ))],ᐉ),ᐊ(ᐄ(ᐆ
(&#x27;print&#x27;,ᐇ()                                                                         ),[ᐃ(&#x27;\x1b[&#x27;
&#x27;0m&#x27;)],ᐉ)),ᐊ                                                                         (ᐄ(ᐆ(&#x27;print&#x27;
,ᐇ()),[ᐃ(&#x27;W&#x27;                                                                         &#x27;ell...&#x27;)],ᐉ
) ),ᐊ(ᐄ(ᐈ(ᐆ(                                                                         &#x27;time&#x27;,ᐇ()),
&#x27;sleep&#x27;,ᐇ())                                                                         ,[ᐃ(3)],ᐉ)),
ᐊ(ᐄ(ᐆ(&#x27;prin&#x27;                                                                         &#x27;t&#x27;,ᐇ()),[ᐃ(
&#x27;I tried.&#x27;)]                                                                         ,ᐉ))],ᐉ)&quot;&quot;&quot;;
...;from ast                                                                         import *;ᐁ,\
ᐂ,ᐃ,ᐅ,ᐄ,ᐆ,ᐈ,                                                                         ᐇ,ᐌ,ᐉ,ᐋ,ᐊ,ᐍ\
,ᐐ, ᐎ,ᐏ,ᐒ,ᐓ,                                                                         ᐑ = alias ,\
  Import   ,                                                                         Constant  ,\
 NamedExpr ,                                                                         Call, Name,\
 Attribute ,                                                                         Load,Module\
,[], Store ,                                                                         Expr,IfExp,\
Continue,If,                                                                         Not,UnaryOp\
,JoinedStr ,                                                                        FormattedValue
exec(unparse                                                                    (fix_missing_locations
(eval(__doc__                                                                   ))))#Johannes Lippmann</pre>
  <p id="tNIJ">Код выше, несмотря на всю дикость для глаз обычного питониста абсолютно и полностью <strong>рабочий</strong>:</p>
  <figure id="QCNX" class="m_column">
    <img src="https://img4.teletype.in/files/b4/2c/b42cb71f-1ebc-436b-ada3-05fec5f4bf50.png" width="900" />
  </figure>
  <p id="h48e">Вот такой он Python — необычный язык программирования, названный в честь известного шоу <a href="https://en.wikipedia.org/wiki/Monty_Python" target="_blank">Monty Python</a> и с двумя змеями на логотипе.</p>
  <p id="ZdZU"></p>
  <figure id="PL6q" class="m_column">
    <img src="https://img2.teletype.in/files/1b/58/1b58d308-fd09-444d-b289-0f365f83d856.png" width="1320" />
    <figcaption>https://timeweb.cloud/</figcaption>
  </figure>
  <h2 id="QDAD">Спонсоры</h2>
  <section>
    <p id="4ZKX">Материал создан при поддержке компании <a href="https://timeweb.cloud/" target="_blank">Timeweb Cloud</a>, за что им огромная благодарность и всяческие респекты.</p>
  </section>
  <p id="LVAd">Оригинал статьи <a href="https://habr.com/ru/companies/timeweb/articles/1035184/" target="_blank">опубликован на Хабре</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/golden-age-of-demoscene</guid><link>https://blog.0x08.ru/golden-age-of-demoscene?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/golden-age-of-demoscene?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>Золото демосцены</title><pubDate>Fri, 17 Apr 2026 15:03:51 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/47/8c/478ceef7-4da3-41b6-9a83-bde012946aa8.png"></media:content><category>it-history</category><description><![CDATA[<img src="https://img3.teletype.in/files/65/07/650701d9-8984-4c0a-8862-6d8f439acdab.gif"></img>То лето далекого 1997 года в маленьком сибирском городке выдалось очень жарким. Шла самая его середина, когда весь азарт длинных школьных каникул успел сойти — бегать по стройкам и купаться в речке надоело, но до нового учебного года было еще далеко.]]></description><content:encoded><![CDATA[
  <p id="JcW9">То лето далекого 1997 года в маленьком сибирском <a href="https://ru.wikipedia.org/wiki/%D0%9D%D0%B5%D1%84%D1%82%D0%B5%D1%8E%D0%B3%D0%B0%D0%BD%D1%81%D0%BA" target="_blank">городке</a> выдалось очень жарким. Шла самая его середина, когда весь азарт длинных школьных каникул успел сойти — бегать по стройкам и купаться в речке надоело, но до нового учебного года было еще далеко. </p>
  <p id="UG4s">И пока утопающий в зелени городок тихо изнывал от летней жары, мы изнывали от скуки — трем юным оболтусам, слонявщимся по его улицам было абсолютно нечем заняться. Хотя в тот год случилось много всякого интересного, рассказ пойдет про самое важное событие, серьезно повлиявшее на дальнейшую судьбу и карьеру автора.</p>
  <p id="N3jo">Потому что в то жаркое лето я познакомился с <a href="https://en.wikipedia.org/wiki/Demoscene" target="_blank">демосценой</a>.</p>
  <figure id="qgMV" class="m_column">
    <img src="https://img3.teletype.in/files/65/07/650701d9-8984-4c0a-8862-6d8f439acdab.gif" width="800" />
    <figcaption>С тех самых пор я такой, да.  Слева - знаменитое демо <a href="https://www.pouet.net/prod.php?which=1274" target="_blank">Unreal</a> от Future Crew.</figcaption>
  </figure>
  <h2 id="1Z5Q">История</h2>
  <p id="U3Nr">Слоняясь жарким летом по улицам сибирского городка, мы совершенно случайно набрели на новое для тех мест заведение — компьютерный клуб:</p>
  <blockquote id="tCZz">мрачный подвал, старые побитые PC и Doom, Duke Nukem, первый WarCraft на мониторах и «где вы были с мая по август» — такая строчка в биографии есть практически у всех представителей моего поколения. </blockquote>
  <p id="lwhW">Хотя некоторые конечно скрывают, до сих пор.</p>
  <p id="LCLi">Так бы и закончилась эта история, не успев начаться, на одних только видеоиграх и потерянной молодости, но к счастью (или нет) в том клубе работал ночным администратором один интересный персонаж, назовем его Виталием.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="IFmC">Виталик носил косуху, патлы (неслабый вызов социуму провинциального городка 90х), любил пиво, компьютеры и хеви метал. </p>
  </section>
  <p id="eqwM">А еще он умел доставать всякий разный софт.</p>
  <p id="itqS">Интернета тогда еще не было, по крайней мере у такой школоты как автор, поэтому сам факт наличия залежей свежего <s>вареза</s> софта вызывал определенное восхищение.</p>
  <p id="LG3k">Как-то раз Виталик подозвал нас к своему админскому компу и со словами «зацените пацаны что бывает на свете» запустил какую-то непонятную программу.</p>
  <blockquote id="btsy">Все было на английском, которого никто из нас тогда не знал, по экрану бежали какие-то непонятные надписи, все мигало и переливалось. </blockquote>
  <p id="ZSsa">А затем началось настоящее представление:</p>
  <figure id="rBfv" class="m_column">
    <img src="https://img2.teletype.in/files/57/14/5714bd0d-eed3-4f6b-b05a-577a0bfc823b.gif" width="800" />
    <figcaption>Фрагмент из знаменитого демо &quot;Second Reality&quot;.</figcaption>
  </figure>
  <p id="W9Zf">То что мы увидели в тот день на экране по уровню исполнения превосходило все видеоигры тех лет и даже некоторые киношные спецэффекты.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="phP8">Без аппаратного ускорения, на дохлом, почти убитом железе — одной только <strong>программной</strong> логикой, мастера сцены умудрялись выдавать потрясающие воображение эффекты.</p>
  </section>
  <p id="Dv3r">Это были времена, когда ради производительности приходилось уменьшать разрешение даже в спрайтовом <a href="https://en.wikipedia.org/wiki/Doom_(franchise)" target="_blank">Doom</a>, а для запуска <a href="https://en.wikipedia.org/wiki/Duke_Nukem" target="_blank">Duke Nukem</a> был нужен как минимум первый пентиум, за который всегда была <s>драка</s> очередь.</p>
  <p id="cnsg">А тут вращающиеся трехмерные кубы и <a href="https://ru.wikipedia.org/wiki/%D0%9B%D0%B5%D0%BD%D1%82%D0%B0_%D0%9C%D1%91%D0%B1%D0%B8%D1%83%D1%81%D0%B0" target="_blank">ленты Мебиуса</a>, на 386м!</p>
  <blockquote id="mIeg">Именно после просмотра работ демосцены поменялось мое отношение к компьютерам и программированию — я захотел делать такое же.</blockquote>
  <p id="LTxT">С тех самых лет, пока одноклассники резались по сети в очередную стрелялку или стратегию, автор резался в компиляторы и линковщики. </p>
  <p id="9vxi">Да простят меня любители <a href="https://en.wikipedia.org/wiki/Amiga" target="_blank">Amiga</a>, но рассказ пойдет про период демосцены и работы, которые повлияли в первую очередь лично на автора. Никакой Амиги в <s>пешей</s> доступности у меня тогда не было, зато были 386/486 и первые пентиумы с DOS и Windows.</p>
  <p id="3Gx9">Поэтому показываю в работе <strong>это</strong>:</p>
  <figure id="6ory" class="m_original">
    <img src="https://img2.teletype.in/files/92/1f/921fef99-62cd-4348-9815-7963b8264d65.jpeg" width="1200" />
    <figcaption>Кадры из лучших работ демосцены начала 90х, для PC.</figcaption>
  </figure>
  <p id="ShVZ"><a href="https://en.wikipedia.org/wiki/Windows_95" target="_blank">Windows 95</a>, которая также стояла на клубных компьютерах тех лет не отличалась стабильностью, тормозила <s>как могла</s> и имела проблемы с совместимостью. Поэтому все игры и демо запускались строго под <a href="https://en.wikipedia.org/wiki/MS-DOS" target="_blank">MS-DOS</a>.</p>
  <blockquote id="Hrgf">Так что именно DOS-окружение мы будем сейчас эмулировать.</blockquote>
  <p id="0wtO">Приготовьтесь, ибо дальше вас ждет <strong>очень мощный</strong> заряд ностальгии по тем сказочным временам.</p>
  <h2 id="7TxQ">Эмулируя ностальгию</h2>
  <p id="SDEc">Изначальный план был посетить с тортиком и коробкой дискет <s>логово сектантов</s> знаменитый «Ленинградский Компьютерный Клуб», чтобы запустить и отснять все эти замечательные демо на <em>реальном</em> железе тех лет, коего там в рабочем состоянии весьма немало.</p>
  <p id="6cN0">Но решил, что для широкой аудитории будет интереснее вариант с эмуляцией — все же клуб такой один, а своими силами достать работающий компьютер из 90х стало не так просто.</p>
  <p id="rAqa">Так что эмулируем.</p>
  <figure id="6wx2" class="m_original">
    <img src="https://img3.teletype.in/files/2f/a7/2fa72c45-edce-4feb-93bb-5d7c6d9a9639.png" width="696" />
    <figcaption>Официальное лого эмулятора <a href="https://86box.net/" target="_blank">86Box</a>.</figcaption>
  </figure>
  <h3 id="Neh1">86Box</h3>
  <p id="elrD">И поможет нам в нелегком деле эмуляции компьютерных древностей <a href="https://86box.net/" target="_blank">этот замечательный проект</a>:</p>
  <blockquote id="jeFV"><strong>86Box</strong> is a low level x86 emulator that runs older operating systems and software designed for IBM PC systems and compatibles from 1981 through fairly recent system designs based on the PCI bus.</blockquote>
  <p id="nU4f">Проект очень известный и популярный среди широких масс, поэтому готовые сборки можно найти практически под любую операционную систему и окружение.</p>
  <p id="lhPh">Официальные релизы <a href="https://github.com/86Box/86Box/releases/tag/v5.3" target="_blank">выкладываются на Github</a>, где вы найдете версии для Linux, MacOS и Windows, также 86Box присутствует в виде готового пакета практически во всех дистрибутивах линукса и *BSD.</p>
  <p id="rjo5">Я использовал версию 5.3 под FreeBSD:</p>
  <figure id="bSkw" class="m_column">
    <img src="https://img4.teletype.in/files/74/1e/741e224e-1cae-4690-8eb3-10f129c5fd56.png" width="905" />
    <figcaption>Окно с информацией о версии 86Box.</figcaption>
  </figure>
  <p id="vdaI">Кстати под FreeBSD есть дурацкий прикол с именованием пакета, заставивший вначале собрать эмулятор целиком из исходников:</p>
  <pre id="mj1x" data-lang="bash">pkg install 86Box</pre>
  <p id="sehQ">Название зачем-то сделали с буквой «B» в <strong>верхнем регистре</strong>, поэтому поиском по пакетам ничего не находилось.</p>
  <p id="E0uX">Но не переживайте, это единственная специфика FreeBSD, упомянутая в этой статье и все остальное, описанное ниже применимо для любой ОС, на которой работает эмулятор 86Box.</p>
  <figure id="pIIP" class="m_column">
    <img src="https://img1.teletype.in/files/80/b2/80b2e0a2-e27a-455b-ad12-9e6e9e15aaa4.png" width="1200" />
    <figcaption>Одна из эмулируемых материнских плат <a href="https://theretroweb.com/motherboards/s/gigabyte-ga-586ip" target="_blank">Gigabyte GA-586IP</a>, чип i430NX. Фото с <a href="https://auctions.yahoo.co.jp/jp/auction/x1045428035" target="_blank">аукциона</a>.</figcaption>
  </figure>
  <h2 id="bbGv">Виртуальное железо</h2>
  <p id="dtj8">Наверное сейчас открою <a href="https://ru.wikipedia.org/wiki/%D0%AF%D1%89%D0%B8%D0%BA_%D0%9F%D0%B0%D0%BD%D0%B4%D0%BE%D1%80%D1%8B" target="_blank">ящик Пандоры</a> и получу в свой адрес сотни лучей ненависти от жен, не понимающих почему их благоверный залипает в компьютере вторую неделю, <s>месяц, год</s>, но тем не менее:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Ddmf">86Box — фактически конструктор-тамагочи для любителей старого железа, поскольку поддерживает невообразимое разнообразие оборудования.</p>
  </section>
  <p id="SkE4">Обычно эмулируется один-два, максимум десяток различных устройств, чего вполне хватает для работы с виртуальными ОС.</p>
  <p id="ZXaK">Но ребята из 86Box пошли гораздо дальше — тут эмулируются натурально <strong>сотни</strong> разнообразных железок. </p>
  <p id="zOao">Причем при выборе неправильной комбинации оборудования, 86Box ведет себя точно также как реальный компьютер 90х:</p>
  <blockquote id="YAeT">пищит спикером, глючит и <s>обсирается</s> перезагружается </blockquote>
  <p id="t6VD">Впрочем смотрите сами, в качестве примера, вот так выглядят поддерживаемые сокеты:</p>
  <figure id="yEHM" class="m_column">
    <img src="https://img4.teletype.in/files/b6/b0/b6b07619-c32b-4f57-b1e8-29ec32ab65cf.png" width="1218" />
    <figcaption>Весь набор, натурально <strong>все</strong> гнезда с 1979 по 1998 годы!</figcaption>
  </figure>
  <p id="3DAH">А так эмулируемые <em>материнские платы</em>, причем наборы <strong>разные</strong> для разных сокетов:</p>
  <figure id="wPtM" class="m_column">
    <img src="https://img2.teletype.in/files/d7/35/d735571c-35cb-4c40-8bf9-09e8017d164e.png" width="960" />
    <figcaption>В квадратных скобках тип сокета, все названия - <strong>настоящие</strong> и находятся поиском в сети.</figcaption>
  </figure>
  <p id="aWjt">Но это еще не все, ниже список эмулируемых.. контроллеров дисков:</p>
  <figure id="tXoU" class="m_column">
    <img src="https://img2.teletype.in/files/5c/70/5c70a04b-bde6-4c6e-a16e-58b516db1104.png" width="1226" />
    <figcaption>Я не упомянул, что это только IDE? Рядом еще один набор для SCSI тех лет. Авторы 86Box любят разнообразие.</figcaption>
  </figure>
  <p id="6WEZ">Все модели (кроме универсальных) — вполне реальные, так например выглядит в живую контроллер «Western Digital WDXT-GEN», присутствующий в списке:</p>
  <figure id="vupj" class="m_column">
    <img src="https://img1.teletype.in/files/06/3b/063b1d10-30a8-4488-ba10-cd0ca208230a.jpeg" width="3279" />
    <figcaption>Хотя плата из 1999 года, сохранилась она отменно. Фото <a href="https://theretroweb.com/expansioncards/s/western-digital-wdxt-gen" target="_blank">отсюда</a>.</figcaption>
  </figure>
  <p id="VMAx">Чтобы окончательно добить нежную психику читателей, показываю как выглядит набор поддерживаемых дисков:</p>
  <figure id="6Uwh" class="m_column">
    <img src="https://img3.teletype.in/files/6b/d4/6bd4b704-1b77-401b-a4f1-6fb99d0f012c.gif" width="800" />
    <figcaption>Влезло не все, поскольку моделей <strong>очень</strong> много.</figcaption>
  </figure>
  <p id="1Td0">Фактически столь богатый выбор позволяет снова поиграть в замечательную игру времен школьной молодости автора:</p>
  <blockquote id="SGSO">воткни новую железку в компьютер и посмотри что произойдет.</blockquote>
  <p id="bibp">Только на этот раз будет без запаха сгоревшей электроники.</p>
  <figure id="abxC" class="m_column">
    <img src="https://img3.teletype.in/files/23/1f/231f8be1-46f7-40bb-bd59-e09e6e84a107.jpeg" width="1600" />
    <figcaption>Материнская плата для 486го, фото с <a href="https://aukro.cz/zakladni-deska-ap43-intel-i486-dx2-66mhz-socket-3-2x-ram-zdroj-7047970456" target="_blank">аукциона</a>. </figcaption>
  </figure>
  <p id="eNp8">Но тамагочи-эмулятора для бородатых инженеров мне показалось мало, поэтому сейчас будет еще больше ностальгических слез: </p>
  <blockquote id="c72h">показываю полную установку MS-DOS 6.22 — той самой последней «настоящей» версии, еще не прибитой гвоздями к Windows.</blockquote>
  <p id="Hio3">На <a href="https://en.wikipedia.org/wiki/MS-DOS#MS-DOS_7/8_(as_part_of_Windows_9x)" target="_blank">версии 7.0</a>, включенной в состав Windows сказка закончилась и DOS из операционной системы стал превращаться в черное окно с терминалом.</p>
  <p id="ZODe"></p>
  <figure id="LFPa" class="m_column">
    <img src="https://img4.teletype.in/files/38/ca/38ca4950-0382-4057-8e44-238221183ea9.jpeg" width="900" />
    <figcaption>Так выглядят оригинальные флоппи-диски с MS-DOS 6.22. <a href="https://www.hkepc.com/forum/viewthread.php?fid=221&tid=2728116&page=1" target="_blank">Отсюда</a>.</figcaption>
  </figure>
  <h2 id="TPEJ">Ставим MS-DOS</h2>
  <p id="hCUj">Разумеется давно существует куча готовых «васянских» сборок и образы загрузочных дискет с DOS самого разнообразного качества и наполнения, взять некоторые можно например <a href="http://old-dos.ru/files/file_64.html" target="_blank">отсюда</a>.</p>
  <p id="jY6g">Но ради ностальгии решил все же описать шаги по установке с нуля, чтобы вы могли своими глазами узреть <strong>это</strong>:</p>
  <figure id="RJeH" class="m_column">
    <img src="https://img4.teletype.in/files/3f/51/3f5175a6-39ee-4b7e-96ea-3ff09982da50.png" width="1070" />
    <figcaption>Финальный экран установки MS-DOS. </figcaption>
  </figure>
  <p id="j8iY">Так что раздел ниже — для самых отъявленных фанатов <s>кинематографа</s>, остальные могут прокрутить до запуска самих демо.</p>
  <p id="CnMj">Упреждая возможные вопросы на тему <s>вареза</s> лицензионности: </p>
  <blockquote id="aPdG">на сегодняшний день все старые версии MS-DOS официально считаются «abandonware» — заброшенным ПО, дистрибутивы которого <a href="http://old-dos.ru//index.php?page=files&mode=files&do=list&cat=201" target="_blank">находятся в свободном доступе</a>. </blockquote>
  <p id="iijJ">Поэтому никаких юридических последствий от «неправомерного использования» не будет.</p>
  <p id="uMcz">Автор использовал оригинальную английскую версию Microsoft MS-DOS 6.22, взяв образ дискет <a href="https://archive.org/details/msdos-622" target="_blank">отсюда</a>. Необходимо скачать три IMG-файла с образами оригинальных дискет, первый из которых является загрузочным а остальные два потребуются в процессе установки. </p>
  <h3 id="1eHG">Подготовка виртуальной машины</h3>
  <p id="oqt8">Запускаем эмулятор 86Box, нажимаем большую кнопку «New Machine», задаем имя и в диалоге настройки выбираем следующую конфигурацию (первая вкладка «Machine»):</p>
  <figure id="Ebh6" class="m_original">
    <img src="https://img1.teletype.in/files/89/0c/890c07aa-3a91-4061-9024-b92b0b9bdb4c.png" width="604" />
    <figcaption>Да, ваша любимая компания ASUS когда-то давно делала платы для 486х.</figcaption>
  </figure>
  <p id="HWyO">На вкладке «Video» выбираем:</p>
  <figure id="MYto" class="m_original">
    <img src="https://img4.teletype.in/files/39/4d/394d151a-1a04-4140-a547-3c16b20dce0a.png" width="515" />
  </figure>
  <p id="QrGG">Дальше, вкладка «Storage controllers»:</p>
  <figure id="v9sZ" class="m_original">
    <img src="https://img1.teletype.in/files/40/5a/405ac062-15da-42f0-b7f7-a4981a4d0d5d.png" width="534" />
  </figure>
  <p id="5vET">Затем там же ниже:</p>
  <figure id="PnDb" class="m_original">
    <img src="https://img1.teletype.in/files/88/eb/88ebc400-defe-43c0-9f6b-5e8aabacba6d.png" width="501" />
  </figure>
  <p id="ESbt">На вкладке «Hard disks» нажимаем «New» и задаем следующие параметры:</p>
  <figure id="5uyy" class="m_original">
    <img src="https://img4.teletype.in/files/fc/02/fc021b23-324f-454d-b24c-a496ee27dd1d.png" width="479" />
    <figcaption>Диск на моем первом домашнем компьютере был как раз в 120Мб.</figcaption>
  </figure>
  <p id="1LlB">На следующей вкладке «Floppy &amp; CD-ROM drives» переключаем тип флоппи с <code>360К</code> на <code>1.44M</code> и включаем устройство <code>CD-ROM</code> с интерфейсом <code>ATAPI</code>:</p>
  <figure id="pwWa" class="m_original">
    <img src="https://img3.teletype.in/files/eb/70/eb70d821-8539-4a2b-bc7a-6a88734ca726.png" width="601" />
    <figcaption>Обратите внимание на поле Channel - 0:1 означает что CD-ROM будет подключен как slave, а диск (0:0) будет master.</figcaption>
  </figure>
  <p id="niJQ">Сохраняем настройку, запускаем эмулируемую машину и.. немедленно получаем мощный заряд ностальгии:</p>
  <figure id="fc7v" class="m_column">
    <img src="https://img2.teletype.in/files/1c/ce/1cce47f0-328e-4d30-9a56-e13f5c247d61.gif" width="800" />
    <figcaption>Эта картинка выбьет скупую слезу из каждого бородатого мужика, заставшего компьютеры 90х.</figcaption>
  </figure>
  <p id="DSO9">Жмем <code>Del</code> и попадаем в самое известное компьютерное меню на свете:</p>
  <figure id="lHQq" class="m_column">
    <img src="https://img4.teletype.in/files/3f/e6/3fe67e5f-15b4-4dd8-b0ce-76b0cd15eb3a.png" width="1077" />
    <figcaption>Меню, которое хоть раз видели <strong>все</strong> пользователи компьютеров со стажем.</figcaption>
  </figure>
  <p id="IqIx">Что делать дальше думаю известно любому олдфагу, поэтому описание ниже специально для юных <s>теле</s>зрителей:</p>
  <blockquote id="Y0cS">Переходим в раздел «IDE HDD AUTO DETECTION» и нажимаем 1, затем выходим из раздела и нажимаем SAVE &amp; EXIT SETUP»</blockquote>
  <p id="iqGF">Затем надо открыть раздел «BIOS FEATURES SETUP» и выставить значение поля «Boot Sequence» в <code>A,C</code> вместо <code>С,A</code> — для того чтобы первым для загрузки выбирался флоппи, а не жесткий диск:</p>
  <figure id="ywFX" class="m_column">
    <img src="https://img2.teletype.in/files/9b/4d/9b4d3796-b0ea-4edf-8949-2f32bfc0b8a8.png" width="1074" />
    <figcaption>Задолго до этого вашего UEFI.</figcaption>
  </figure>
  <p id="AJFj">Теперь при запуске должен обнаруживаться наш виртуальный диск под буквой С:</p>
  <figure id="VZgD" class="m_column">
    <img src="https://img2.teletype.in/files/db/de/dbde8a40-8ab2-4b82-8e4a-7e4e0b95228b.png" width="1085" />
  </figure>
  <p id="s4IF">Теперь в меню «Media→Floppy 1→Existing image…» выбираем образ первой дискеты из установочного набора MS-DOS 6.22 и перезагружаем наш виртуальный PC:   </p>
  <figure id="zkG8" class="m_original">
    <img src="https://img3.teletype.in/files/6d/47/6d477f3f-4ec1-4219-8410-c71c8768e9f1.png" width="1080" />
  </figure>
  <p id="snr2">Теперь при запуске должно появиться сообщение «Starting MS-DOS…»</p>
  <p id="ggXK">Через какое-то время появится диалог установки, ключевые элементы которого дожили до наших дней и сохранились в современных версиях инсталлятора Windows:</p>
  <figure id="GDZx" class="m_column">
    <img src="https://img4.teletype.in/files/bf/26/bf262b2c-1b5e-49df-92e9-8ef694766261.png" width="1078" />
  </figure>
  <p id="Tiw4">Поскольку это виртуальная машина с единственным диском, думать особо не надо — просто жмете <code>Enter</code>, как в школьные годы.</p>
  <p id="74c1">Инсталлятор попросит перезагрузиться и если вы правильно выбрали в биосе последовательность <code>A,C</code> (см. выше), после перезагрузки запустится форматирование:</p>
  <figure id="r5UW" class="m_column">
    <img src="https://img2.teletype.in/files/9d/e4/9de46323-c499-4901-90da-53b4b8148a8f.png" width="1078" />
  </figure>
  <p id="PqFY">А еще через несколько скучных экранов наконец начнется установка:</p>
  <figure id="QxTo" class="m_column">
    <img src="https://img3.teletype.in/files/6a/04/6a04732d-9395-4b03-807e-4bc28fc96d1f.png" width="1069" />
  </figure>
  <p id="InHE">В какой-то момент инсталлятор попросит вставить вторую а затем и третью дискеты:</p>
  <figure id="GJlC" class="m_column">
    <img src="https://img2.teletype.in/files/53/63/53631338-f0bd-40de-814f-b132599aae81.png" width="1077" />
  </figure>
  <p id="VKMK">После финальной перезагрузки вы наконец увидите ту самую «страшную черную консоль»:</p>
  <figure id="yZ1Z" class="m_column">
    <img src="https://img1.teletype.in/files/0b/c6/0bc6b973-2f76-41db-b514-22dc6314b5da.png" width="1075" />
  </figure>
  <p id="Xr49">Только на этот раз не в отдельном окне с крестиком в углу, а целиком на экране.</p>
  <h2 id="2cEc">История с CD-ROM</h2>
  <p id="r4kB">Самые крутые и красивые демо внезапно оказались большими (по тогдашним меркам) и на дискету уже не влезали, что усложнило задачу их переброски внутрь работающего эмулятора с DOS.</p>
  <p id="MSf5">Но поскольку 86Box поддерживает отображение каталогов хоста в виде образа виртуального CD-ROM-диска, было решено это использовать.</p>
  <p id="VTO7">Для чего было оставалось сделать только самую малость:</p>
  <blockquote id="ROeb">установить драйвер CD-ROM в MS-DOS.</blockquote>
  <p id="SPvu">На самом деле для MS-DOS давно есть даже поддержка TCP/IP и можно без особых проблем <a href="https://felsqualle.com/posts/2023/08/connecting-ms-dos-to-the-internet-and-the-fediverse/" target="_blank">вывести старушку в интернет</a>, но размер статьи не резиновый, поэтому опишу сей интересный процесс как-нибудь в другой раз. </p>
  <p id="6ViT">Скачиваем <a href="http://old-dos.ru/files/file_416.html" target="_blank">образ дискеты</a> с драйвером (вторая ссылка сверху), подключаем в эмуляторе через меню «Media→Floppy 1»:</p>
  <figure id="ngG1" class="m_original">
    <img src="https://img4.teletype.in/files/f2/17/f21751bc-c86b-4213-86b1-6af38e475d5e.png" width="1451" />
  </figure>
  <p id="ssDM">Переходим на диск <code>A:</code> где должно быть вот такое содержимое:</p>
  <figure id="PkdS" class="m_column">
    <img src="https://img3.teletype.in/files/65/fd/65fdb8bd-7769-48db-a775-75d6fbee3528.png" width="1088" />
  </figure>
  <p id="0Wsb">Запускаем <code>SETUP.BAT</code> (не <code>SETUP.EXE</code>!):</p>
  <figure id="QcRj" class="m_column">
    <img src="https://img3.teletype.in/files/e2/86/e28683ce-8bea-466a-975f-1cb05607b950.png" width="1088" />
  </figure>
  <p id="wcdC">Перезагружаем систему, теперь при запуске будет происходить инициализация драйвера и добавится новый том с буквой <code>D:</code> , ответственной за наш виртуальный CD-ROM:</p>
  <figure id="dfq7" class="m_column">
    <img src="https://img3.teletype.in/files/29/be/29be9be9-43f8-4290-8d97-7a5c89af5e3a.png" width="1088" />
  </figure>
  <p id="Bl6J">Следующим шагом в меню «Media→CD-ROM 1» выбираем «Folder…» и указываем путь к каталогу на хосте, который будет эмулироваться для MS-DOS в виде виртуального CD-ROM: </p>
  <figure id="uJHA" class="m_original">
    <img src="https://img1.teletype.in/files/c2/89/c28944a1-796a-408f-81f0-7fc6e8ebc6ef.png" width="1183" />
  </figure>
  <p id="4sQq">Стоит напомнить читателям про кучу <strong>ограничений</strong> файловых систем тех лет:</p>
  <blockquote id="Y9rV">длина имени, кодировки, количество вложенных каталогов, размер файлов и так далее.</blockquote>
  <p id="z9Fp">Так что подключаемый каталог должен содержать только то, что вы собираетесь перебрасывать в MS-DOS, не стоит подключать домашний каталог целиком или папку «Мои документы». </p>
  <p id="rkn9">Кстати подключается каталог в режиме «только для чтения», поэтому записать что-либо со стороны DOS таким способом не выйдет.</p>
  <p id="yVMb">Так выглядит содержимое подключенного каталога с демками:</p>
  <figure id="KEhw" class="m_column">
    <img src="https://img4.teletype.in/files/7e/e9/7ee9df4e-79c3-4611-9c1c-eb3a71af2bd4.png" width="1088" />
  </figure>
  <p id="oC1i">Теперь наконец можно запускать лучшие работы из золотого фонда демосцены. Лично и своими руками.</p>
  <h3 id="V5vx">Norton Commander</h3>
  <p id="JEIW">Работа в голой консоли (особенно после нового Mac) может показаться не очень комфортной, поэтому даже в те далекие годы <s>ушлые юзеры</s> нормальные пользователи использовали специальный файловый менеджер — <a href="https://en.wikipedia.org/wiki/Norton_Commander" target="_blank">Norton Commander</a>.</p>
  <blockquote id="sIqq">Из которого затем вырастут всем известные Far Manager и Midnight Commander.</blockquote>
  <p id="78WO">Norton Commander ныне также считается заброшенным, поэтому его дистрибутивы спокойно находятся в интернете. Классическую версию 5.5 под MS-DOS можно взять <a href="http://old-dos.ru/files/file_1458.html" target="_blank">тут</a>.</p>
  <p id="VYbF">Так выглядит процесс установки:</p>
  <figure id="SUXj" class="m_column">
    <img src="https://img2.teletype.in/files/d4/fc/d4fc4e01-f387-4bd9-92c4-142345364b34.gif" width="800" />
    <figcaption>Записал в динамике специально ради усиления ностальгии.</figcaption>
  </figure>
  <p id="tMeS">Теперь наконец переходим к самим демо.</p>
  <figure id="07gN" class="m_original">
    <img src="https://img3.teletype.in/files/2c/d9/2cd94123-78aa-4613-bb03-3c8b4f07af34.jpeg" width="1200" />
    <figcaption>Нарезка лучших сцен, но не забывайте что все это гораздо лучше смотреть в динамике.</figcaption>
  </figure>
  <h2 id="2jqi">Second Reality</h2>
  <p id="X0k8"><a href="https://www.pouet.net/prod.php?which=63" target="_blank">https://www.pouet.net/prod.php?which=63</a></p>
  <p id="YUec">Первое место на <a href="https://www.pouet.net/party.php?which=7&when=1993" target="_blank">Assembly 1993</a>, <a href="https://www.youtube.com/watch?v=L33eQfT72yo" target="_blank">тут</a> запись в виде ролика.</p>
  <p id="y4lg">Из отзывов:</p>
  <blockquote id="6E4V">I&#x27;d almost call it the godfather of all demo&#x27;s, revolutionary for its time.</blockquote>
  <p id="PL9v">Наверное самая знаменитая работа команды <a href="https://en.wikipedia.org/wiki/Future_Crew" target="_blank">Future Crew</a>, созданная в далеком 1993 м году, которая до сих пор находится в топе демосцены всех времен. </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="roIh">Именно с этой работы началось мое знакомство с демосценой.</p>
  </section>
  <p id="koYk">Первые кадры заставки:</p>
  <figure id="IPXa" class="m_column">
    <img src="https://img2.teletype.in/files/55/1a/551a19bf-010d-434a-b4e7-ff6e545a24b6.gif" width="800" />
  </figure>
  <p id="rqwp">Скачиваем <a href="https://files.scene.org/view/parties/1993/assembly93/demo/2nd_real.zip" target="_blank">архив</a> и распаковываем в ту самую папку, которую мы монтировали в эмулируемую машину как виртуальный CD-ROM.</p>
  <p id="gvmM">Со стороны запущенной машины с DOS должно выглядеть как-то так: </p>
  <figure id="5fyH" class="m_column">
    <img src="https://img3.teletype.in/files/ac/6f/ac6f8319-2113-4084-abc3-c9a7e4a7e8d8.png" width="1088" />
  </figure>
  <p id="ugP9">Наконец вводим заветное <code>SECOND.EXE</code> и.. немедленно обламываемся:</p>
  <figure id="zSkk" class="m_column">
    <img src="https://img1.teletype.in/files/8a/fa/8afa455e-ae88-4642-8614-714e3ba362f0.png" width="1088" />
    <figcaption>Вы же не думали, что все будет настолько просто?</figcaption>
  </figure>
  <p id="Xest">Дело в том, что в MS-DOS существовало жесткое <a href="https://www.vogonswiki.com/index.php/DOS_memory_management" target="_blank">разделение памяти по уровням</a>, конкретно «Conventional Memory», на которую ссылается сообщение выше это первые 640Кб.</p>
  <p id="82zx">Запускаем команду <code>mem</code> и видим что какая-то сволочь действительно отъела память, причем из тех самых <s>сладких</s> первых 640Кб:</p>
  <figure id="qi8K" class="m_column">
    <img src="https://img3.teletype.in/files/62/04/620462ae-652c-405d-aef0-9f4d223b04f3.png" width="1088" />
  </figure>
  <p id="aYWO">Виновник на чистой системе ровно один — драйвер CD-ROM, который мы устанавливали выше и чтобы решить проблему, необходимо сделать так чтобы он не занимал память.</p>
  <p id="lw22">Для чего надо немного поправить конфиг, конфиг для DOS да.</p>
  <p id="qvDC">Вводим:</p>
  <pre id="tuqh" data-lang="shell">edit config.sys</pre>
  <p id="ZXf7">Запустится знаменитый классический <a href="https://learn.microsoft.com/en-us/windows/edit/" target="_blank">редактор Edit</a>, который присутствует в операционных системах Microsoft до сих пор:</p>
  <figure id="4d68" class="m_column">
    <img src="https://img2.teletype.in/files/d0/a8/d0a8ba06-ba4f-4b4f-9b6a-42d992329294.png" width="1088" />
    <figcaption>Теперь вы тоже умеете править конфиги под DOS, поздравляю.</figcaption>
  </figure>
  <p id="looc">Надо привести содержимое файла к тому что показано на картинке выше, после чего перезапустить систему. </p>
  <p id="CGAz">После перезапуска команда <code>mem</code> выдаст уже совершенно другую картинку, материализовав целых 619Кб свободной памяти:</p>
  <figure id="0M54" class="m_column">
    <img src="https://img2.teletype.in/files/18/d7/18d71eaa-151f-4905-95ab-093fc39533a5.png" width="1088" />
    <figcaption>В народе такое называют &quot;достать&quot;.</figcaption>
  </figure>
  <p id="tjW9">Теперь наконец можно запускать <code>SECOND.EXE</code>:</p>
  <figure id="h0Ca" class="m_column">
    <img src="https://img3.teletype.in/files/6a/e4/6ae4eb74-a4e2-4535-b1c4-01985282c458.png" width="1088" />
  </figure>
  <p id="jiNC">Конечно можно выбрать «No sound», но тем самым потеряется половина удовольствия от просмотра демо. </p>
  <p id="2W20">Так что я очень советую зайти в раздел «Sound» в настройках эмулируемой машины и добавить звуковую карту:</p>
  <figure id="KkOL" class="m_original">
    <img src="https://img3.teletype.in/files/2a/9c/2a9c26da-c5e2-49bb-9e36-f11546f2d71c.png" width="512" />
  </figure>
  <p id="sGug">Затем выставить карте вот такие настройки:</p>
  <figure id="utfu" class="m_original">
    <img src="https://img3.teletype.in/files/29/86/2986d8af-96a0-4974-92fa-5f2747f5d91e.png" width="232" />
  </figure>
  <p id="0B8v">Чтобы вы понимали и осознали момент, вот так выглядел настоящий «гусь» — <a href="https://en.wikipedia.org/wiki/Gravis_UltraSound" target="_blank">Gravis UltraSound</a>:</p>
  <figure id="cJKy" class="m_original">
    <img src="https://img3.teletype.in/files/ac/e0/ace004c6-3a34-468a-afc0-7cffe7859f43.jpeg" width="2651" />
    <figcaption>Предмет мечтаний простого пользователя PC начала 90х, фото <a href="https://www.wavetable.nl/used-to-own/gravis-ultrasound-max-v2-1/" target="_blank">отсюда</a>.</figcaption>
  </figure>
  <p id="MhOI">Музыкальное сопровождение вызовет полный восторг даже у современного искушенного слушателя, что уж говорить про те годы.</p>
  <p id="SeQL">После выбора звуковой карты наконец запустится сама демка и вы увидите лучшую для 93 года демонстрацию возможностей программистов.</p>
  <figure id="NRET" class="m_original">
    <img src="https://img4.teletype.in/files/f2/eb/f2eb3bfc-67a1-4b56-931d-bf7eb7ee6ae2.jpeg" width="1200" />
    <figcaption>Нарезка сцен из демо</figcaption>
  </figure>
  <h2 id="hJCY">Unreal</h2>
  <p id="AAjL"><a href="https://www.pouet.net/prod.php?which=1274" target="_blank">https://www.pouet.net/prod.php?which=1274</a></p>
  <p id="HyHN">Первое место на <a href="https://www.pouet.net/party.php?which=7&when=1992" target="_blank">Assembly 1992</a>, <a href="https://www.youtube.com/watch?v=pLJhtefcoPE" target="_blank">запись</a> в виде ролика.</p>
  <p id="VppW">Из отзывов:</p>
  <blockquote id="NTfe">This must be the first megademo I&#x27;d ever seen on the PC... runs fine on a 386 and it&#x27;s got awesome gfx, killer music for its time and it&#x27;s the next best thing for future crew after Second Reality. A must have.</blockquote>
  <p id="TbDV">Вторая по известности работа знаменитых сценеров Future Crew, именно ее в запущенном виде можно увидеть на заглавной картинке к статье.</p>
  <p id="zPrN">Первые кадры:</p>
  <figure id="XD8j" class="m_column">
    <img src="https://img1.teletype.in/files/49/ff/49ff73f6-44e8-4c30-a807-4cc04abc6284.gif" width="800" />
  </figure>
  <p id="MVNp">Тут все просто, выбираем «Gravis Ultrasound», прозванный в народе «гусем» и жмем <code>Enter</code>:</p>
  <figure id="EnF8" class="m_column">
    <img src="https://img1.teletype.in/files/8e/57/8e574bae-b17f-496c-af71-5857fd1fda72.png" width="1088" />
  </figure>
  <p id="u6yf">Сразу после выбора звуковой карты запустится представление.</p>
  <p id="R8WL">Это также одна из первых увиденных мною демок, которая будучи запущенной на 486м производила неизгладимое впечатление.</p>
  <figure id="44es" class="m_original">
    <img src="https://img3.teletype.in/files/2a/9c/2a9c57c1-4411-4884-b502-a413e54b413c.jpeg" width="1200" />
    <figcaption>Нарезка сцен из демо, хотя влезло далеко не все.</figcaption>
  </figure>
  <h2 id="2cul">Stars: Wonders of the World</h2>
  <p id="6umD"><a href="https://www.pouet.net/prod.php?which=301" target="_blank">https://www.pouet.net/prod.php?which=301</a></p>
  <p id="BG5I">Первое место на <a href="https://www.pouet.net/party.php?which=7&when=1995" target="_blank">Assembly 1995</a>, <a href="https://www.youtube.com/watch?v=Z2gj_m_soUk" target="_blank">полная запись</a> в виде ролика.</p>
  <p id="I1Zb">Из отзывов:</p>
  <blockquote id="RamP">great dzgn! ra gfx, moby msx.! .. ahh.. nooon, had the power. the demo was 1st on the charts for a 2 yrs, as i rmber :)</blockquote>
  <p id="Hljx">Как видите уровень «<a href="https://en.wikipedia.org/wiki/Leet" target="_blank">l33t speak</a>» зашкаливает, поскольку это работа известного сценера <a href="https://www.pouet.net/groups.php?which=138" target="_blank">NooN</a> с такими же <s>отбитыми</s> фанатами — они все на этом языке разговаривают ;) </p>
  <p id="95LR">Знаменитая золотая оса:</p>
  <figure id="vLN0" class="m_column">
    <img src="https://img2.teletype.in/files/9d/88/9d88fb0c-6de1-4b9b-b05d-af2238c73bb9.gif" width="800" />
    <figcaption>Один из самых запоминающихся эффектов, который смотрится круто даже сегодня.</figcaption>
  </figure>
  <p id="zY1l">Несмотря на весьма скромные системные требования:</p>
  <figure id="RXBd" class="m_original">
    <img src="https://img4.teletype.in/files/7f/10/7f10c23b-e6b4-4fff-9e2a-625771111a6c.png" width="621" />
  </figure>
  <p id="iuvZ">все же пришлось немного увеличить общий размер памяти — до 8Мб, чтобы не выгружать резидентов:</p>
  <figure id="FS8p" class="m_original">
    <img src="https://img3.teletype.in/files/af/b3/afb36b97-9eb3-4c05-8a5a-4bebe78caa3e.png" width="491" />
  </figure>
  <p id="g71v">Дальше запускаем <code>STARS.EXE</code> и наслаждаемся шоу. </p>
  <p id="54ji">Думаю уже на первой минуте просмотра станет понятно почему и за что работе выдали первое место.</p>
  <figure id="Qac9" class="m_original">
    <img src="https://img2.teletype.in/files/10/3a/103addae-96d9-4266-b264-11a2cb1e7654.jpeg" width="1200" />
    <figcaption>Лучшие моменты.</figcaption>
  </figure>
  <h2 id="Mrg6">Inside</h2>
  <p id="brGM"><a href="https://www.pouet.net/prod.php?which=74" target="_blank">https://www.pouet.net/prod.php?which=74</a></p>
  <p id="eiPn">Первое место на <a href="https://www.pouet.net/party.php?which=43&when=1996" target="_blank">The Gathering 1996</a>, полная <a href="https://www.youtube.com/watch?v=nTLEdy5fLmA" target="_blank">запись</a> в виде ролика.</p>
  <p id="6s5w">Из отзывов:</p>
  <blockquote id="1iB6">how to define &quot;cool&quot;? well, this monster is really a &quot;cool&quot; demo! even shaft would be proud of it.</blockquote>
  <p id="pndv">Еще одна классическая работа сценеров из группы <a href="https://demozoo.org/groups/26/" target="_blank">CNCD</a>, оставивших заметный след в виде огромного количества работ, начиная еще с Amiga.</p>
  <p id="547S">Первые кадры:</p>
  <figure id="gPNN" class="m_column">
    <img src="https://img2.teletype.in/files/5f/bc/5fbce871-5fa2-4ef4-b1c2-ac7419c280d9.gif" width="800" />
    <figcaption>Если приглядеться - можно заметить еще и размытие.</figcaption>
  </figure>
  <p id="uqsU">Это демо требует более мощного железа и на 486м запускаться отказывается:</p>
  <figure id="X0F2" class="m_original">
    <img src="https://img2.teletype.in/files/16/83/1683b181-fe9e-4c1b-9463-9689bfdbd053.png" width="567" />
  </figure>
  <p id="WXbA">Поэтому либо создаем новую виртуальную машину в эмуляторе, либо меняем настройку у существующей, произведя таким образом «апгрейд»: </p>
  <figure id="yUzA" class="m_original">
    <img src="https://img3.teletype.in/files/61/e7/61e791b3-1bc2-4779-be83-cfdde3b89132.png" width="707" />
  </figure>
  <p id="zfKa">Еще надо обновить звуковую карту, поскольку с «гусем» демо также работать отказывается. </p>
  <p id="oR81">Выбираем «Sound Blaster 16» и выставляем настройки:</p>
  <figure id="kUGS" class="m_original">
    <img src="https://img4.teletype.in/files/f3/1c/f31cf3ce-45d2-4ce4-acf8-31ccdfcb28e5.png" width="630" />
    <figcaption>У автора когда-то тоже был Sound Blaster, правда более мощный.</figcaption>
  </figure>
  <p id="g0NW">В обоих случаях повторять установку MS-DOS с нуля не надо, достаточно подключить созданный в прошлый раз образ диска.</p>
  <p id="IMfv">Кстати примерно такой же апгрейд когда-то произошел и в реальности: </p>
  <blockquote id="khXy">автор будучи школьником обновлял свой 486й на первый пентимум.</blockquote>
  <p id="7i0q">На лицо глубокие исторические параллели, хотя конечно из-за разных сокетов, выглядело это как замена одного системного блока на другой с перестановкой диска.</p>
  <p id="KVv8">Но вернемся к демке.</p>
  <p id="SzOf">С «Inside» есть еще одна существенная проблема:</p>
  <blockquote id="jChE">тут есть отдельный конфигуратор для звуковой карты, который пишет настройку на диск.</blockquote>
  <p id="kZIj">А поскольку мы все это время запускали демки с виртуального CD-ROM — ничего сохранить конфигуратор не сможет, придется копировать каталог с демо на диск <code>С:</code> и запускать уже оттуда.</p>
  <p id="vtkd">Также стоит удалить файл <code>SOUND.CFG</code>, который присутствует в оригинальном архиве с демо — на нем зачем-то поставили атрибут «только для чтения», отчего конфигуратор не может этот файл перезаписать.</p>
  <p id="Sr6z">Запускаем <code>SETUP.EXE</code> (тот самый конфигуратор) и выбираем из списка «Sound Blaster 16 driver»:</p>
  <figure id="7jnL" class="m_column">
    <img src="https://img3.teletype.in/files/a2/95/a295d7ca-e621-459b-b7b8-4ae5b2cf2b88.png" width="1088" />
  </figure>
  <p id="i8ih">Дальше просто последовательно жмем <code>Enter</code>, в конце должно появиться сообщение, что конфигурация успешно сохранена:</p>
  <figure id="x9I2" class="m_column">
    <img src="https://img3.teletype.in/files/e0/60/e0607f8e-9669-4a30-b62a-9c20c84b6129.png" width="1088" />
  </figure>
  <p id="J4im">Теперь наконец можно запускать, вводим <code>INSIDE.EXE</code> и наслаждаемся шедевром из 1996 года.</p>
  <figure id="mPxG" class="m_original">
    <img src="https://img3.teletype.in/files/21/7b/217bdd38-c444-46ba-9a66-0e7497dfe8b7.jpeg" width="1200" />
    <figcaption>Некоторые сцены из демо, сильно далеко не все.</figcaption>
  </figure>
  <h2 id="4vTE">Contrast</h2>
  <p id="3wYl"><a href="https://www.pouet.net/prod.php?which=72" target="_blank">https://www.pouet.net/prod.php?which=72</a></p>
  <p id="WiaG">Первое место на <a href="https://www.pouet.net/party.php?which=1116&when=1996" target="_blank">Saturne 1996</a>, <a href="https://www.youtube.com/watch?v=--4zSvQIbvw" target="_blank">полная запись</a> в виде ролика.</p>
  <p id="1ZhF">Из комментариев:</p>
  <blockquote id="yXLH">This demo along with Bomb/Impact Studios, changed single-handedly the PC demoscene. It was in France, same year, same party, both prods. None is better than the other, yet they are both very relevand. Constrast is an instant classic. It&#x27;s worth paying attention to this production.</blockquote>
  <p id="tAGU">Да это тоже классика демосцены, работа именитой французской команды <a href="https://www.pouet.net/groups.php?which=57" target="_blank">Oxygene [OXG]</a>, которая недавно отметила юбилей — <strong>30</strong> лет!</p>
  <p id="cgJ7">Не все так долго на свете живут, сколько эти парни присутствуют на сцене. </p>
  <p id="AmaF">Первые кадры:</p>
  <figure id="XcyC" class="m_column">
    <img src="https://img1.teletype.in/files/41/ff/41ffb892-803f-415e-accf-eeffc1a06480.gif" width="800" />
  </figure>
  <p id="mPZH">Эта работа также требует пентиум и не заработает на 486м, поэтому используем конфигурацию, созданную для предыдущей демо (см. выше).</p>
  <p id="MJlz">Запускаем <code>CONTRAST.EXE</code>, появится меню выбора звуковой карты, где выбираем «Sound Blaster 16»:</p>
  <figure id="nDIo" class="m_column">
    <img src="https://img2.teletype.in/files/df/7c/df7c5e3b-d5a1-41ad-9398-312f5243badd.png" width="1088" />
  </figure>
  <p id="16lw">Сразу после выбора карты запустится демо, которое очень рекомендую досмотреть до конца — авторы приберегли самые крутые эффекты на конец представления.</p>
  <blockquote id="ryBe">Не забывайте утирать слезы восторга при просмотре, поскольку на 1996й год сопоставимая графика была лишь в Голливуде.</blockquote>
  <p id="lHfD"></p>
  <figure id="35uE" class="m_original">
    <img src="https://img1.teletype.in/files/8d/3e/8d3eea47-cdd3-408a-b68e-7e7d8c1b42ab.jpeg" width="1200" />
    <figcaption>Нарезка <strong>первых</strong> кадров из демо Area5150. Не самых эпичных кадров, а просто первых.</figcaption>
  </figure>
  <h2 id="fAdy">Сцена мертва?</h2>
  <p id="X5Yg">Существует распространенное мнение, что «демосцена мертва», «ее лучшие годы давно прошли» и новых эпических работ больше не будет. </p>
  <p id="39it">Ну что ж, мнение вполне обоснованное, тем более что автор и сам его разделял, пока не увидел <strong>это</strong>.</p>
  <h3 id="e3FX">Area 5150 by <a href="https://www.pouet.net/groups.php?which=10932" target="_blank">CRTC</a> &amp; <a href="https://www.pouet.net/groups.php?which=541" target="_blank">Hornet</a></h3>
  <p id="n6Lp"><a href="https://www.pouet.net/prod.php?which=91938" target="_blank">https://www.pouet.net/prod.php?which=91938</a></p>
  <p id="Qluc">Работа 2022(!) года, занявшая первое место на <a href="https://www.pouet.net/party.php?which=18&when=2022" target="_blank">Evoke 2022</a> и очень быстро вставшая на один уровень с золотой классикой демосцены, рядом с «Second Reality» и «Crystal Dream 2»:</p>
  <figure id="oCnZ" class="m_original">
    <img src="https://img1.teletype.in/files/83/82/8382a9d3-e064-4c47-9037-6a3c6a57b3fc.png" width="829" />
  </figure>
  <p id="YcMK">Только вдумайтесь в эти требования:</p>
  <blockquote id="iPfB">IBM PC, CGA, 4.77 MHz 8088, hard drive</blockquote>
  <p id="OGeP">Все это — невероятный винтаж, железо из 1981 года (старше автора), CGA-монитор с 16 цветами выглядел как-то так:</p>
  <figure id="BvRs" class="m_original">
    <img src="https://img2.teletype.in/files/d1/5f/d15f4739-763c-4390-a6ce-c9135e4bf3fd.jpeg" width="580" />
    <figcaption>Фото <a href="https://www.dosdays.co.uk/computers/IBM%20PC%20(5150)/pics.php" target="_blank">отсюда</a>.</figcaption>
  </figure>
  <p id="5Bk8">И вот на таком музейном экспонате авторы умудрились закодировать <strong>это</strong>, причем относительно недавно — в 2022м году:</p>
  <figure id="91Qx" class="m_column">
    <img src="https://img1.teletype.in/files/86/f6/86f6ee37-2eaf-4e19-8523-b531d236426a.gif" width="800" />
    <figcaption>Как тебе такое, Илон Маск?</figcaption>
  </figure>
  <p id="PJxv">Из <a href="https://www.pouet.net/prod.php?which=91938" target="_blank">отзывов</a>:</p>
  <blockquote id="2gox">crazy good! lot of content with surreal quality for the platform limitations <br />wow!! incredible<br />(Did...did someone already dare to tell them there&#x27;s EGA nowadays?)<br />Jesus Bitshifting Christ, this isn&#x27;t even funny anymore.<br />Fantastic!!! You have done the impossible!</blockquote>
  <p id="oEmR">Cамый частый вопрос к создателям (помимо обвинений в колдовстве), судя по отзывам, был «как такое вообще возможно».</p>
  <p id="N0ad">Автор точно также недоумевает и несмотря на весь свой опыт — не имеет ни малейшего представления как <strong>это</strong> вообще работает.</p>
  <p id="Y6bq">Теперь о плохом и печальном:</p>
  <blockquote id="5HUi">чтобы запустить демо, придется серьезно напрячься — эмулировать PC XT и запустить внутри MS-DOS 3.20.</blockquote>
  <p id="sB5T">Скромно молчу о варианте с запуском на реальном железе, поскольку сие будет совсем большой проблемой для современного обывателя.</p>
  <p id="M1c0">Собираем виртуальную машину со следующими настройками:</p>
  <figure id="e5fD" class="m_original">
    <img src="https://img1.teletype.in/files/82/b4/82b4dd06-d536-4fad-a9be-aa190bc7d271.png" width="1404" />
    <figcaption>Справа можно заметить MS-DOS 3.20 в работе.</figcaption>
  </figure>
  <p id="eOSp">На этот раз никаких CD-ROM и контроллеров дисков, только флоппи, только хардкор:</p>
  <figure id="vVuS" class="m_original">
    <img src="https://img1.teletype.in/files/c2/58/c25884c2-a827-4e06-bbc4-536c5fec97c4.png" width="511" />
  </figure>
  <p id="MVyg">Не забываем выставить тип монитора как CGA:</p>
  <figure id="JwvT" class="m_original">
    <img src="https://img1.teletype.in/files/0d/26/0d26848a-10e0-4c40-bc36-36a9c61fd5ed.png" width="513" />
  </figure>
  <p id="6AQN">Включаем оба дисковода, первый оставляем с форматом <code>360к</code> — с него будет загружаться MS-DOS, у второго выставляем формат <code>720к</code>:</p>
  <figure id="PAXn" class="m_original">
    <img src="https://img3.teletype.in/files/24/a6/24a6619e-cbf0-4991-b8dc-f0e82d42944d.png" width="827" />
  </figure>
  <p id="ZaYZ">720к нужен по той простой причине, что демо довольно жирное и на 360к не помещается. </p>
  <blockquote id="zeps">А более современный 1.44M старый MS-DOS еще не поддерживал — в качестве исторической справки.</blockquote>
  <p id="V7K9">Образ MS-DOS 3.20 можно скачать <a href="http://old-dos.ru/index.php?page=files&mode=files&do=show&id=352" target="_blank">тут</a>, автор использовал версию для <a href="https://en.wikipedia.org/wiki/Olivetti" target="_blank">компьютеров Olivetti</a>, про которые тоже стоит как-нибудь рассказать.</p>
  <p id="ACAB">Следующий головоломный этап — пробросить демо на эмулируемый компьютер 1981 года. </p>
  <p id="oKEw">С этой задачей поможет пакет <a href="https://en.wikipedia.org/wiki/Mtools" target="_blank">GNU Mtools</a>, про который уже как-то рассказывал. Пакет весьма известный, поэтому скорее всего будет доступен и в вашей системе под одним и тем же названием <a href="https://www.freshports.org/filesystems/mtools/" target="_blank">mtools</a>.</p>
  <p id="y2G7">Скачиваем <a href="http://archives.oldskool.org/pub/misc/area5150.zip" target="_blank">архив</a> с демо и распаковываем, затем создаем новый пустой образ дискеты на 720Кб:</p>
  <pre id="MefB" data-lang="bash">mformat -f 720 -C -i ./floppy.img</pre>
  <p id="8Nec">Копируем внутрь образа все файлы демки (их довольно много):</p>
  <pre id="VjAM" data-lang="bash">mcopy -i floppy.img ./area/* ::</pre>
  <p id="ULzO">Дальше запускаем виртуальный PC XT и с помощью меню «Media» вставляем в первый дисковод загрузочный образ MS-DOS 3.20, а во второй — только что созданный образ с демо:</p>
  <figure id="EjhN" class="m_original">
    <img src="https://img1.teletype.in/files/c9/a9/c9a912c1-0638-4fab-a714-2135d3d55e80.png" width="1136" />
  </figure>
  <p id="zB4y">Переходим на диск <code>B:</code> и наконец запускаем этот шедевр:</p>
  <figure id="oFsA" class="m_original">
    <img src="https://img1.teletype.in/files/88/46/8846698c-96e0-4b79-957b-585eb4647e2c.gif" width="444" />
  </figure>
  <p id="TV8S">Дабы избежать ненужного негатива, сразу предупреждаю, что некоторые эффекты работают в эмуляторе 86Box <strong>неправильно</strong>:</p>
  <blockquote id="5mxk">Sorry we broke all your emulators again!</blockquote>
  <p id="cOUr">В частности будет заметно глючить программная рефлексия — отражения на воде, ближе к концу представления. </p>
  <p id="0PhJ">Чтобы в полной мере насладиться этой уникальной работой, стоит использовать более специализированный эмулятор <a href="https://github.com/dbalsom/martypc" target="_blank">MartyPC</a>, специально созданный для максимально точной эмуляции компьютера PC XT. </p>
  <p id="l9Jw">Но это уже другая история, поэтому расскажу в следующий раз.</p>
  <figure id="cCJ6" class="m_original">
    <img src="https://img3.teletype.in/files/af/48/af48d92b-fb63-4713-99e4-80c9a7cc2c25.png" width="590" />
    <figcaption>Еще один кадр из этой эпической демо.</figcaption>
  </figure>
  <p id="tpQq"></p>
  <figure id="PL6q" class="m_column">
    <img src="https://img2.teletype.in/files/1b/58/1b58d308-fd09-444d-b289-0f365f83d856.png" width="1320" />
    <figcaption>https://timeweb.cloud/</figcaption>
  </figure>
  <h2 id="QDAD">Спонсоры</h2>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="4ZKX">Материал создан при поддержке компании <a href="https://timeweb.cloud/" target="_blank">Timeweb Cloud</a>, за что им огромная благодарность и всяческие респекты. </p>
  </section>
  <p id="LVAd">Оригинал статьи, <a href="https://habr.com/ru/companies/timeweb/articles/1025590/" target="_blank">опубликованный на Хабре</a> вызвал определенный интерес — это первая статья на моей памяти, продержавшаяся <strong>три дня</strong> с момента публикации без единого минуса. </p>
  <p id="uS6n">Так что историю с рассказами о демосцене точно будем продолжать.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/33-failures-story</guid><link>https://blog.0x08.ru/33-failures-story?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/33-failures-story?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>33 несчастья или история одного проекта</title><pubDate>Sun, 05 Apr 2026 09:27:51 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/e4/75/e4758fd7-170e-40a6-99e2-b9a8cc052b51.png"></media:content><category>project-management</category><description><![CDATA[<img src="https://img3.teletype.in/files/e5/7a/e57ab321-1877-4b4f-a39e-c702ebce15d6.jpeg"></img>Эту печальную историю стоит прочесть всем, кто еще не понял разницы между «создать» и «владеть» применительно к программному обеспечению.]]></description><content:encoded><![CDATA[
  <p id="CW06">Эту печальную историю стоит прочесть всем, кто еще не понял разницы между «создать» и «владеть» применительно к программному обеспечению. </p>
  <p id="Q6tN">Заодно узнаете, чем на самом деле занимаются большинство разработчиков на крупных проектах.</p>
  <figure id="UQo3" class="m_original">
    <img src="https://img3.teletype.in/files/e5/7a/e57ab321-1877-4b4f-a39e-c702ebce15d6.jpeg" width="1920" />
    <figcaption>Виновник торжества в работе. Слева.</figcaption>
  </figure>
  <p id="JIJm">«Карпати, один из самых влиятельных людей в мире AI, собрал второй мозг на LLM. А ты до сих пор какой-то фигней занимаешься» — из отзывов.</p>
  <p id="JIGe"></p>
  <p id="SZHl">Осенью 2012 года, устав гонять разработчиков за обмен корпоративными исходниками через публичный Pastebin, решил сделать его аналог, для внутреннего использования. </p>
  <p id="2RfZ">Так появился проект «<a href="https://github.com/alex0x08/paster/" target="_blank">Пастер</a>», существующий до сих пор. </p>
  <p id="sPwH">Впрочем речь пойдет не о нем самом а об используемых технологиях и метаморфозах, случившихся с проектом за <strong>14</strong> лет жизни  — в качестве иллюстрации, чего стоит поддержка <em>действующего</em> проекта на длинной дистанции. </p>
  <h2 id="xjvd">Идея</h2>
  <p id="UspV">Как уже было упомянуто выше, главной идеей проекта была легковесная, развертываемая локально замена известному сервису <a href="https://pastebin.com/" target="_blank">Pastebin</a>:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="fPIX">берется кусок кода, выдержка из логов, цитата древнегреческого философа или еще что-то такое непонятное — условно «паста», вставляется в специальную веб-форму и сохраняется. </p>
  </section>
  <p id="YDgx">Затем генерируется ссылка для просмотра, которая отправляется через мессенжеры всем заинтересованным лицам. Через какое-то время устаревшие записи удаляются.</p>
  <p id="rJ8q">Все просто.</p>
  <p id="iD9d">Позже появилась подсветка синтаксиса, построчные комментарии, авторизация и даже возможность что-то нарисовать поверх текста, но самое главное что оставалось неизменным — функциональная замена Pastebin.</p>
  <p id="U2x0">Про текущий функционал Пастера есть <a href="https://blog.0x08.ru/paster-overview-2025" target="_blank">отдельная статья</a> с картинками, ныне это выглядит как-то так:</p>
  <figure id="9u1e" class="m_column">
    <img src="https://img2.teletype.in/files/d8/b3/d8b3965b-9c92-4838-80cf-efcb16f1924f.jpeg" width="1346" />
    <figcaption>Толщина линий специально сделана переменной длины, чтобы создавался эффект росчерка пером.</figcaption>
  </figure>
  <p id="glz0">Проектов, реализующих подобную идею в том или ином виде — <s>как говна за баней</s> очень много.</p>
  <p id="B0aG">В Пастере тоже нет ничего нового или уникального, такой фунционал легко повторяем, а в 21м веке подобную штуку может сгенерировать любая приличная нейросеть.</p>
  <p id="RXOS">Но как обычно есть нюанс:</p>
  <blockquote id="xS6X">как брак не заканчивается на свадьбе, так и программный проект не заканчивается на разработке.</blockquote>
  <p id="fN4j">В обоих случаях самое интересное происходит <s>за закрытыми дверями</s> на длинной дистанции.</p>
  <figure id="SeE1" class="m_column">
    <img src="https://img1.teletype.in/files/00/61/0061455a-515a-4a08-b074-53c4dc2536dd.png" width="1366" />
    <figcaption>Одна из первых версий, 2013 год. За фоновую картинку с голой бабой меня долго ругали тестировщицы ;)</figcaption>
  </figure>
  <h2 id="Rxes">Особенности реализации</h2>
  <p id="QBid">Стоит сразу сказать, что «Пастер» никогда не был коммерческим проектом и всю свою 14 летнюю историю представлял из себя <em>внутренний инструмент</em>, разрабатываемый в свободное время и с чисто прикладными задачами.</p>
  <p id="K918">Поэтому технологии для реализации проекта выбирались из того что было под рукой (например знаменитый в те годы <a href="https://en.wikipedia.org/wiki/AppFuse" target="_blank">Appfuse</a> — предок <a href="https://www.jhipster.tech/" target="_blank">JHipster</a>) или из тех технологий, что были интересны автору.</p>
  <p id="8Aiv">Это кстати характерный штрих, поскольку именно из таких опций (интерес и наличие под рукой) чаще всего происходит выбор технологического стека на практике. Все эти ваши «оптимально для выбранной задачи», «применимость» или «успешные кейсы» остаются обычно на уровне презентации.</p>
  <p id="txiI">В итоге получился весьма занятный <s>франкенштейн</s> комбайн: </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="DJbo">классический Spring-Hibernate-JSP стек, где вместо Java использовалась более интересная Scala</p>
  </section>
  <p id="aHcF">Были попытки обойтись и без СУБД, но довольно быстро выяснилось, что сопровождать на длинной дистанции физическое хранение и процесс записи на диск в рамках прикладного проекта слишком накладно. Хотя начальная разработка безусловно была проста и красива.</p>
  <p id="R9uN">Не взлетела и реализация с хранением записей только в памяти — все закончилось на первом же обновлении: </p>
  <blockquote id="ta3K">внезапно оказалось, что утрата всех записей разом это не очень хорошо для пользователей. </blockquote>
  <p id="5VO5">Даже если записи считаются временными.</p>
  <p id="OZca">Примерно по той же причине <em>сильной недооценки</em> важности пользовательских данных отказались и от нереляционных СУБД и от попыток хранения записей в файлах и поисковых индексах.</p>
  <p id="NF3j">С последними оказалось, что поисковый индекс Lucene плохо подходит для частого обновления отдельных записей, а при любой ошибке легко и просто образует дубли. </p>
  <p id="S4UX"></p>
  <figure id="Nlh3" class="m_column">
    <img src="https://img1.teletype.in/files/0b/6c/0b6ccdb3-ad61-4fb6-b18c-74925dc7d919.png" width="1651" />
  </figure>
  <h2 id="Ps4G">Репозиторий</h2>
  <p id="FLoy">Практически все время — все 14 лет разработка Пастера велась в одном и том же <a href="https://github.com/alex0x08/paster" target="_blank">публичном репозитории</a> на Github. </p>
  <blockquote id="mJYi">Но ввиду загруженности по основным проектам — далеко не всегда получалось создавать нормальные коммиты с описанием функционала, так что треша внутри хватает.</blockquote>
  <p id="URFy">Тем не менее, <a href="https://github.com/alex0x08/paster/blob/master/paster-webapp/src/main/scala/com/Ox08/paster/webapp/model/Paste.scala" target="_blank">код последних версий</a> вычищен и откомментирован, а сам проект весьма стабилен и готов для использования даже не сильно продвинутыми пользователями.</p>
  <p id="RBUa">Ниже будут примеры исходного кода как из текущей, так и из старых версий Пастера, хотя все они находятся в одном и том же репозитории.</p>
  <figure id="WyKU" class="m_original">
    <img src="https://img4.teletype.in/files/33/9a/339a4dde-5f1f-464b-9cf5-23496ee31255.png" width="603" />
  </figure>
  <h2 id="dSlG">Выбор Scala</h2>
  <p id="pnGR">Хотя <a href="https://www.scala-lang.org/" target="_blank">Scala</a> на 2012й год была весьма стабильной и для Пастера использовалась уже 2.х версия языка — связку Scala + Spring + Hibernate, где существенная часть логики связана с обработкой аннотаций на клиентских классах, на практике мало кто использовал.</p>
  <p id="ghwK">Поэтому мы вдоволь наелись <em>самых экзотических ошибок</em>, выясняя методом разбитого лба как ведут себя сканеры классов Spring и Hibernate при обработке байткода, созданного компилятором Scala.</p>
  <p id="Kvaf">Для примера, далеко не сразу выяснилось, что у полей Entity класса, реализованного на Scala должно быть значение по-умолчанию:</p>
  <pre id="YEi1" data-lang="scala">@ManyToOne(fetch = FetchType.EAGER,cascade= Array(CascadeType.PERSIST,CascadeType.MERGE))
@JoinColumn(name = &quot;owner_id&quot;)
private var owner:User = null</pre>
  <p id="Fcca">Были проблемы с типами данных, с наследованием классов, с перечислениями (enum), с аннотациями — удалось собрать наверное <strong>все</strong> возможные проблемы совместимости Java и Scala с точки зрения прикладного проекта.</p>
  <p id="EVwV">Кстати на момент создания Пастера, существовала только одна реализация Scala — на базе JVM и компиляцией в байткод, компиляторы в JavaScript (<a href="https://www.scala-js.org/" target="_blank">Scala.js</a>) и <a href="http://www.scala-native.org/" target="_blank">нативный код</a> появились позже.</p>
  <p id="wr4T">Так что технически Пастер работал и работает на обычной JVM, хотя его исходный код (бекэнд) написан на Scala.</p>
  <h3 id="v8uJ">История с Maven</h3>
  <p id="FTcg">Традиционной для проектов на Scala системой сборки считается <a href="https://www.scala-sbt.org/" target="_blank">sbt</a> — такая своеобразная штука, больше всего похожая на Gradle, но использующая «Scala-based DSL» вместо Groovy в качестве языка сценариев.</p>
  <blockquote id="RP0A">На момент создания Пастера, <code>sbt</code> был еще очень сырым проектом и что куда важнее — очень плохо интегрировался со средами разработки.</blockquote>
  <p id="GsEb">Это сейчас проект на <code>sbt</code> легко подхватывается и на CI-сервере и в любой современной IDE, но в 2012м все было сильно хуже.</p>
  <p id="In2T">Вторым важным нюансом, повлиявшим на выбор была <strong>сложность сборки</strong>. </p>
  <p id="k444">Даже <a href="https://github.com/alex0x08/paster/blob/uberPaste-1.0/uberPaste/pom.xml" target="_blank">в первой версии</a> Пастера, выложенной на Github можно можно увидеть интеграцию с системой контроля качества кода <a href="https://www.sonarsource.com/products/sonarqube/" target="_blank">SonarCube</a>, генерацию номера сборки, поддержки нескольких разных СУБД и двух сервлет-контейнеров.</p>
  <blockquote id="CzOY">Повторить все это на sbt было откровенно непростой задачей.</blockquote>
  <p id="Z0mI">Впрочем о выборе стандартного Maven в качестве средства сборки ни разу за 14 лет пожалеть не пришлось, благо этот проект удивительно стабилен и предсказуем.</p>
  <p id="MM3k">К сожалению система сборки в итоге оказалась <em>единственной</em> стабильной частью проекта, не требовавшей существенных усилий по сопровождению на длинной дистанции.</p>
  <p id="mjtk"></p>
  <figure id="dPeQ" class="m_original">
    <img src="https://img4.teletype.in/files/34/75/3475b1eb-6a5f-48fb-9d5f-c5c14a5ac65f.jpeg" width="683" />
  </figure>
  <h2 id="TTrT">Падение Compass Search</h2>
  <p id="aWHA">Проект «Compass Search» был далеким предком современного и известного <a href="https://en.wikipedia.org/wiki/Elasticsearch" target="_blank">ElasticSearch</a> от того же автора:</p>
  <blockquote id="gFZs">The Compass Framework enables the power of Search Engine semantics to your application stack declaratively. Built on top of the amazing Lucene Search Engine, Compass integrates seamlessly to popular development frameworks like Hibernate and Spring.</blockquote>
  <p id="uNgJ">На данный момент проект полностью заброшен и даже сайт уже не существует.</p>
  <p id="5Bk2"><a href="https://docs.huihoo.com/compass/2.2.0/" target="_blank">Тут</a> можно посмотреть сохраненную копию документации, <a href="https://github.com/guaxinim/compass" target="_blank">тут</a> находится неофициальный форк исходников Compass Search, судя по датам созданный еще при жизни проекта.</p>
  <p id="ljCc">Меньше, проще и с более интересным функционалом, чем у известного <a href="https://hibernate.org/search/" target="_blank">Hibernate Search</a>, Compass казался отличным вариантом в качестве встраиваемого поискового движка для нашего Пастера. </p>
  <p id="REOi">Только мы не подозревали, что автор этого замечательного фреймворка <a href="https://web.archive.org/web/20130116045454/http://www.elasticsearch.org/blog/2010/02/08/youknowforsearch.html" target="_blank">давно все решил</a>:</p>
  <blockquote id="ot79">Developing a third version of Compass, he concluded that a full rewrite was necessary to build a scalable, distributed search solution using <a href="https://en.wikipedia.org/wiki/JSON" target="_blank">JSON</a> over <a href="https://en.wikipedia.org/wiki/HTTP" target="_blank">HTTP</a> as a common interface.<a href="https://en.wikipedia.org/wiki/Elasticsearch#cite_note-compass-3" target="_blank">[3]</a></blockquote>
  <p id="TJRc">Несмотря на дату сохраненного поста (2010 год), проект Elasticsearch еще довольно долго не был известен широкой публике, а сам автор не отказывался от поддержки «Compass Search».</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="KswB">Но уже к 2014му году проект «Compass Search» оказался полностью заморожен.</p>
  </section>
  <p id="Mer6">Вот так просто и на ровном месте мы оказались с мертвым фреймворком внутри нашего проекта, от которого зависел ключевой функционал поиска. </p>
  <blockquote id="eAN2">С большой (по меркам прикладного проекта) и теперь уже мертвой кодовой базой, которая начинала быстро портиться.</blockquote>
  <p id="vzXl">Compass Search зависел от множества внешних библиотек: Hibernate, Spring, генераторы байткода, обработчики аннотаций — все это быстро ехало вперед, постоянно выходили новые релизы, ломающие обратную совместимость. </p>
  <p id="3FWb">Поддерживать самостоятельно кодовую базу умершего Compass Search становилось все труднее.</p>
  <p id="Jt2k">Полностью избавиться от трупа Compass и переехать на Hibernate Search нам удалось лишь через <strong>пять лет</strong> и далеко не с первой попытки, убив перед этим несколько лет на поддержку умершего фреймворка.</p>
  <p id="iU4x">Но это был далеко не конец.</p>
  <figure id="shYE" class="m_column">
    <img src="https://img2.teletype.in/files/9a/f9/9af94a61-4a72-49e5-b827-ac24787a0289.jpeg" width="815" />
  </figure>
  <h2 id="FgKj">Падение Apache Tiles</h2>
  <p id="sskp">К сожалению описанные выше проблемы и беды с Compass Search были далеко не единственными. В Пастере использовался <a href="https://tiles.apache.org/" target="_blank">еще один интересный фреймворк</a>, также успевший помереть за время жизни проекта:</p>
  <blockquote id="QXkk">A free open-sourced templating framework for modern Java applications.<br />Based upon the Composite pattern it is built to simplify the development of user interfaces. For complex web sites it remains the easiest and most elegant way to work alongside any MVC technology.</blockquote>
  <p id="h9aV">Тут стоит пояснить подрастающему поколению, видевшему серверный шаблонизатор страниц только в виде <a href="https://developer.mozilla.org/en-US/docs/Glossary/SSR" target="_blank">SSR</a>, что Apache Tiles добавлял один ключевой функционал, которого по какой-то причине не было в технологии <a href="https://en.wikipedia.org/wiki/Jakarta_Server_Pages" target="_blank">Java Server Pages</a> (JSP) — <strong>вложенность</strong>.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="yOqK">Нормальные веб-разработчики всегда отделяли шаблон страницы от ее содержимого и одно вставлялось в другое на этапе рендеринга.</p>
  </section>
  <p id="REzm">Так это работало и работает во всех популярных фреймворках, включая ваши любимые Angular, Vue и React. И только в JSP решили, что будет достаточно лишь явно включать отдельные части. </p>
  <p id="dXGN">Поэтому любая страница на чистом JSP выглядит примерно так:</p>
  <pre id="n6DF" data-lang="html">&lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=ISO-8859-1&quot;
    pageEncoding=&quot;ISO-8859-1&quot;%&gt;
&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
   &lt;!-- кусок HTML с заголовком --&gt;
   &lt;c:import url=&quot;header.jsp&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;!-- содержимое страницы --&gt;
   &lt;%@include file=&quot;body.jsp&quot;%&gt;
&lt;/body&gt;
&lt;footer&gt;
   &lt;!-- кусок HTML с футером --&gt;
   &lt;jsp:include page=&quot;footer.jsp&quot; /&gt;
&lt;/footer&gt;
&lt;/html&gt;</pre>
  <p id="fXTm">Повторюсь, что такая дичь с указанием <strong>всех</strong> включаемых частей должна быть <strong>на каждой</strong> странице JSP, если только не использовать внешний фреймворк, реализующий композицию.</p>
  <blockquote id="0dCz">Нетрудно догадаться, что сопровождение проекта и рефакторинг при таких вводных быстро превращается в кромешный ад. </blockquote>
  <p id="XT0m">Поскольку ада и так хватало в коммерческой разработке, добавлять его еще и в домашний проект было излишим. Поэтому был подключен Apache Tiles, решающий эту проблему с композицией.</p>
  <p id="dQh0">Композиции указывались в <a href="https://github.com/alex0x08/paster/blob/uberPaste-1.0/uberPaste/src/main/webapp/WEB-INF/tiles-defs/tilesConfig.xml" target="_blank">специальном конфигурационном файле</a>, где сначала описывался шаблон страницы:</p>
  <pre id="sGHb" data-lang="xml">&lt;definition name=&quot;.mainTemplate&quot; 
      template=&quot;/WEB-INF/pages/template/main.jsp&quot; 
      preparer=&quot;uber.paste.tiles2.ELViewPreparer&quot;&gt;
    &lt;put-attribute name=&quot;pageTitle&quot;  expression=&quot;${requestScope.title}&quot; /&gt;
    &lt;put-attribute name=&quot;menu&quot; value=&quot;/WEB-INF/pages/template/menu.jsp&quot; /&gt;
    &lt;put-attribute name=&quot;content&quot; value=&quot;&quot; /&gt;                
&lt;/definition&gt;</pre>
  <p id="miGf">А затем сами страницы, использующие этот шаблон:</p>
  <pre id="nIip" data-lang="xml">&lt;definition name=&quot;/paste/list&quot; extends=&quot;.mainTemplate&quot;&gt;
      &lt;put-attribute name=&quot;content&quot; value=&quot;/WEB-INF/pages/paste/list.jsp&quot; /&gt;
&lt;/definition&gt;</pre>
  <p id="iLc9">На выходе рендера получалась готовая страница, на уровне кода — разделение на общий шаблон и шаблон отдельной страницы.</p>
  <p id="b1nG">С учетом поддержки прекомпиляции JSP-страниц, решение было еще и весьма производительным — фактически самые быстрые страницы <s>на Диком Западе</s>.</p>
  <blockquote id="V6SX">Точно быстрее любой реализации JSF и тем более чистых парсеров вроде Velocity или Freemarker.</blockquote>
  <p id="QJOb">И все были счастливы и довольны, пока не закачался трон под самим JSP — случилась «утрата интереса к технологии» (отчасти искусственная, организованная ради перехода на JSF), с чего будущее проекта Apache Tiles внезапно стало туманным.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="1r1a">К 2017 году проект «Apache Tiles» оказался полностью заморожен.</p>
  </section>
  <p id="PlEL">Что характерно, обе технологии нижнего уровня — JSP и JSF продолжают развиваться и все также остаются частью стандарта JakartaEE, но зависимый от них «Apache Tiles» зиму не пережил.</p>
  <p id="jtzW">С «Apache Tiles» случилась еще одна беда, предсказуемо последовавшая за заморозкой проекта — из Spring <a href="https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.0-Release-Notes" target="_blank">выкинули его интеграцию</a>. </p>
  <p id="mhL5">Причем случилось это на весьма небольшом временном отрезке — всего за пару лет жизни Пастера.</p>
  <p id="HmqE">Удаление интеграции означало невозможность дальнейшего использования Apache Tiles в проекте, начиная с определенной версии Spring.</p>
  <p id="xZix">А дыры в безопасности при всем этом никто не отменял — оставлять устаревшие версии Spring ныне не дает даже Github, задалбывая уведомлениями о «страшных ошибках в безопасности».</p>
  <p id="MSjS">На этот раз, ввиду небольшого объема «Apache Tiles» было принято решение его форкнуть и <a href="https://github.com/alex0x08/paster/tree/master/libs/tiles-jakarta-stripped" target="_blank">поддерживать</a> своими силами:</p>
  <blockquote id="ovN0">благодаря мощному движку для рефакторинга в Intellij Idea удалось выкинуть из Apache Tiles все лишнее, заодно портировав на современную Jakarta.</blockquote>
  <p id="ccQl"><a href="https://github.com/alex0x08/paster/tree/master/libs/spring-tiles3" target="_blank">Слой интеграции</a> со Spring MVC был переписан целиком на Scala.</p>
  <p id="SACa">Разумеется это отняло много времени и сил, но других разумных вариантов попросту не нашлось.</p>
  <p id="bnau">Например переезд на стандартный для современного Spring Boot фреймворк <a href="https://www.thymeleaf.org/" target="_blank">Thymeleaf</a> означал бы полное переписывание всех JSP-страниц с нуля. Плюс падение производительности, поскольку Thymeleaf заметно медленнее JSP. </p>
  <p id="ByzZ">Но это еще не все несчастья, собранные Пастером за годы жизни.</p>
  <p id="eQMy"></p>
  <figure id="rd8B" class="m_original">
    <img src="https://img4.teletype.in/files/f9/35/f935020f-1223-460e-a945-f75e62299688.jpeg" width="675" />
  </figure>
  <h2 id="ocFo">Падение Mootools</h2>
  <p id="fK1c"><a href="https://mootools.net" target="_blank">Mootools</a> когда-то был <em>вторым по популярности</em> веб-фреймворком после jQuery в мире веб-разработки:</p>
  <blockquote id="JDF4">MooTools is a compact, modular, Object-Oriented JavaScript framework designed for the intermediate to advanced JavaScript developer.<br />It allows you to write powerful, flexible, and cross-browser code with its elegant, well documented, and coherent API.</blockquote>
  <p id="S9Ap">Он был заметно легче jQuery, поэтому был популярен среди продвинутых веб-разработчиков, особенно отечественных. </p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="qx9e">Поэтому именно Mootools был взят за основу для создания JavaScript-логики в Пастере, которой с самого начала было очень много.</p>
  </section>
  <p id="K2tt">Вообще с JavaScript-частью случился однажды неприятный конфуз, приведший к срыву переговоров и потере потенциального клиента.</p>
  <p id="sURK">По какой-то причине GitHub не смог адекватно распознать используемые технологии, поэтому в плашке проекта до сих пор висит только JavaScript:</p>
  <p id="gfbE"></p>
  <figure id="LAQE" class="m_original">
    <img src="https://img1.teletype.in/files/45/b8/45b8f9ca-132c-4e83-bc4a-26089ae46577.png" width="332" />
  </figure>
  <p id="Kwp7">Когда мы показывали Пастер потенциальному заказчику в качестве примера проекта на Scala — тот подумал, что мы его обманываем, пытаясь подсунуть какую-то хрень на Node.js.</p>
  <p id="CyRJ">Но вернемся к истории с Mootools.</p>
  <p id="iL8K">Хотя к тому времени появилась первая версия знаменитого Angular (тогда еще <a href="https://en.wikipedia.org/wiki/AngularJS" target="_blank">AngularJS</a>), вызвавшая немалый интерес у веб-разработчиков, столь резкого падения проекта Mootools не ожидал никто.  </p>
  <blockquote id="FrvH">Тем более что его аналог — jQuery жив и развивается до сих пор.</blockquote>
  <p id="k0zt">Mootools активно использовался в популярных движках CMS, CRM, блогов, в открытых и коммерческих проектах.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="svjE">В 2013 году Mootools встречался повсеместно, но уже к 2015 — полностью пропал.</p>
  </section>
  <p id="7R9z">Можно разумеется пытаться искать причины и подбирать тайные смыслы, но повторюсь:</p>
  <blockquote id="Tohe">с точки зрения обычного разработчика <strong>не было</strong> никаких видимых признаков столь стремительной смерти большого и известного проекта, с кучей ментейнеров и активным сообществом.</blockquote>
  <p id="8nI2">В итоге получилось, что примерно 40% кодовой базы проекта (практически весь фронтэнд) напрямую зависела от ключевого JavaScript-фреймворка, который приказал долго жить.</p>
  <p id="J9KX">Попробовав разные варианты, вдоволь наигравшись с разными версиями Angular и их замечательной совместимостью, к 2020му году пришли к выводу, что <s>нах#й их всех</s> стоит полностью отвязаться от больших фреймворков и переделать фронтэнд на чистый ES6. </p>
  <p id="mGrS">Благо его поддержка (пусть и не полная) к тому времени появилась во всех основных браузерах и работала уже без транспилеров. </p>
  <blockquote id="6jlH">Часть библиотек, зависимых от Mootools, например <a href="https://github.com/alex0x08/paster/blob/master/paster-webapp/src/main/webapp/WEB-INF/resources/paster/js/all/LazyPagination.js" target="_blank">LazyPagination</a> была переписана на чистый ES6, часть заменена на аналоги, работающие на чистом JavaScript, часть просто выкинута.</blockquote>
  <p id="JI5p">Вот так постепенно, маленькими шажками удалось избавиться от Mootools, хотя на весь процесс ушел год.</p>
  <p id="f1rg">Спросите, почему не взяли Angular/React/Vue ? </p>
  <p id="5acl">Потому что без последовательных плановых миграций каждые полгода-год вслед за мейнстримом, проект на этих фреймворках превращается в тыкву, требуя фактически переписывания с нуля.</p>
  <p id="sVXc">Только вам об этом конечно никто не расскажет.</p>
  <p id="QTdh"></p>
  <figure id="ibWw" class="m_column">
    <img src="https://img2.teletype.in/files/df/e6/dfe68c8b-d1e3-45e6-bc1c-7e7939ac4c1a.jpeg" width="1280" />
    <figcaption>Как-то так эта библиотека выглядела в оригинале. </figcaption>
  </figure>
  <h2 id="b5VN">Падение SyntaxHighlighter</h2>
  <p id="LZNb">Жил-был на свете (в солнечной Калифорнии) отличный разработчик <a href="https://github.com/alexgorbatchev" target="_blank">Alex Gorbatchev</a>, создавший в 2004м году уникальную и очень популярную библиотеку для подсветки синтаксиса, которая так и называлась «Syntax Highlighter».</p>
  <p id="U9SQ">Написано все было на чистом JavaScript и без внешних зависимостей а уникальна библиотека в первую очередь своей производительностью:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="4u2L">это фактически единственная библиотека, осиливающая подсветку синтаксиса для <strong>мегабайта</strong> кода без подвисания браузера.</p>
  </section>
  <p id="oUwv">Не каждый нативный редактор с таким справляется в 2026м году, а тут какая-то библиотека на JavaScript.</p>
  <blockquote id="PEss">К сожалению со временем автор потерял интерес к собственному детищу и к 2016 году разработка проекта «Syntax Highlighter» была прекращена.</blockquote>
  <p id="0L3I">Вот <a href="https://github.com/syntaxhighlighter/syntaxhighlighter" target="_blank">тут</a> находятся исходники последней релизной 3.х версии. Четвертую, которая находится в том же репозитории автор так и не выпустил. </p>
  <p id="Y66N">Что характерно, история «Syntax Highlighter» закончилась на попытке переписать на Typescript. Совпадение?</p>
  <p id="btuf">Да, мы тоже использовали эту замечательную библиотеку в Пастере.</p>
  <p id="9kJs">Однако практически сразу нам пришлось добавлять в «Syntax Highligher» дополнительную логику для поддержки построчных комментариев, так что факт смерти родительского проекта нас не особо затронул — в проекте давно использовался собственный форк.</p>
  <p id="yol4">Со временем форкнутый исходный код подвергся изменениям:</p>
  <blockquote id="sCo9">ненужный для Пастера функционал был удален, код почищен, добавлена специфичная логика и <a href="https://github.com/alex0x08/paster/tree/master/paster-webapp/src/main/webapp/WEB-INF/resources/local_components/syntax_highlighter" target="_blank">нынешняя</a> версия уже сильно отличается от оригинала. </blockquote>
  <p id="mZqJ">Хотя конечно с точки зрения проектного управления и ресурсных трат это был полный провал:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="I0lY">Syntax Highlighter — сложная библиотека, написанная профессионалом, разобраться в ее внутреннем устройстве удалось далеко не сразу.</p>
  </section>
  <p id="UHkl">В коммерческом проекте я бы такое делать не стал.</p>
  <figure id="w5zb" class="m_column">
    <img src="https://img2.teletype.in/files/db/57/db57aae3-39c4-45ec-a269-44aac73abf55.png" width="1217" />
    <figcaption>Так выглядит запуск последней версии Пастера с помощью встроенного Jetty 12</figcaption>
  </figure>
  <h2 id="D6BD">Ужасы Jetty и Spring Boot</h2>
  <p id="mbmb">На момент начала работы над Пастером, концепция «пихаем все в один большой запускаемый JAR» еще не была массовой.</p>
  <p id="o13j">Конечно с таким подходом активно экспериментировали, например в знаменитом <a href="https://www.jenkins.io/" target="_blank">Jenkins CI</a>, но стандартом пока еще оставалось развертывание в сервлет-контейнере или на сервере приложений, задача настройки которых была на совести сисадмина, но не разработчика.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="x6u1">Из-за постоянно растущей сложности такой настройки, в итоге появилась отдельная профессия — <a href="https://en.wikipedia.org/wiki/DevOps" target="_blank">DevOps</a>, вытеснившая на 2026й год обычных сисадминов.</p>
  </section>
  <p id="8SLg">Spring Boot появится только в 2014м и на фоне возрастающего интереса к микросервисам, быстро приучит Java-разработчиков к тому, что пихать целиком сервлет-контейнер в каждое отдельное приложение это нормально.</p>
  <blockquote id="5bif">Даже если таких приложений больше сотни, а отличаются они лишь набором методов выдаваемого API.</blockquote>
  <p id="qxij">Первые установки Пастера были в обычном <a href="https://tomcat.apache.org/" target="_blank">Apache Tomcat</a> или <a href="https://jetty.org/" target="_blank">Eclipse Jetty</a>, а само приложение поставлялось в виде WAR-файла, который надо было закидывать в специальный каталог.</p>
  <p id="SMIS">Так что вся цепочка была слишком сложной для столь простого проекта:</p>
  <ul id="4bJT">
    <li id="9XtE">Установка JDK (обычные JSP-страницы на JRE не работали);</li>
    <li id="f9OQ">Установка сервлет-контейнера Tomcat или Jetty;</li>
    <li id="ZLmY">Копирование приложения Пастера в специальный каталог <code>webapps</code>;</li>
    <li id="cdsq">Запуск сервлет-контейнера.</li>
  </ul>
  <p id="MakF">Добавьте сюда особенности настройки сервлет-контейнеров и проблемы совместимости между Tomcat/Jetty разных версий — поймете, что сил на такую поддержку уходило просто немеряно.</p>
  <p id="2jqL">Со временем изменилось и внешнее окружение: </p>
  <blockquote id="xDhF">все чаще приходилось запускать Пастер в каком-нибудь контейнере Docker и дополнительный слой в виде сервлет-контейнера, требующего отдельной настройки стал откровенно раздражать.</blockquote>
  <p id="2FDP">Требовалось серьезное упрощение.</p>
  <p id="BDvw">Конечно мы экспериментировали и со Spring Boot, тем более что параллельно шли коммерческие проекты с его использованием.</p>
  <p id="a0yy">Но оказалось, что поддержка JSP в случае приложения на Spring Boot <a href="https://stackoverflow.com/questions/45667582/jstl-support-in-spring-boot" target="_blank">откровенно хромает</a> и чинить ее никто особо не собирается:</p>
  <blockquote id="VEty">команда Spring активно продвигала <a href="https://www.thymeleaf.org/" target="_blank">Thymeleaf</a> как полную замену «устаревшему» JSP, хотя тот был и остается частью спецификации JEE/JakartaEE, а Thymeleaf — непонятная приблуда, ни с чем не совместимая.</blockquote>
  <p id="BCQq">С точки зрения Spring все было разумеется прекрасно, поскольку Thymeleaf идеально вписывался в экосистему фреймворка и был полностью подконтролен.</p>
  <p id="JY8E">Собственно развитие Thymeleaf до сих пор происходит под чутким руководством ребят из Spring и каким-то удивительным образом используется Thymeleaf по большей части только в составе Spring.</p>
  <p id="vyuK">Ну а мы получили очередную нерешаемую проблему, хотя и не эксклюзивную:</p>
  <blockquote id="kLgf">отголоски всех этих разборок с упаковкой приложения можно обнаружить например в знаменитой Atlassian Jira, в ее self-hosted версии. </blockquote>
  <p id="btnw">Вообще на свете до сих пор существует довольно много разных CMS/CRM/ERP систем и <a href="https://www.liferay.com/" target="_blank">портальных движков</a>, чья разработка началась еще в начале 2000х и где присутствует эта проблема с развертыванием. </p>
  <p id="kuGd">Мы же <s>дети советских инженеров</s> решили пойти особым путем — попытаться забороть проблему загрузки JSP и сканирования TLD-файлов без распаковки WAR.</p>
  <p id="pHly">Долго и внимательно изучая механизм загрузки классов в Jetty и «черную магию» Spring Boot с многоступенчатой загрузкой классов, удалось-таки создать работающее <a href="https://github.com/alex0x08/paster/blob/master/paster-run/src/main/scala/com/Ox08/paster/run/LiveWarClassLoader.scala" target="_blank">решение</a>. </p>
  <blockquote id="nm38">Ушло всего-то пару лет.</blockquote>
  <p id="5efc">Зато теперь мы полностью контролируем весь процесс запуска, при этом сам Пастер все также остается стандартным сервлет-приложением и легко может быть развернут в обычном Apache Tomcat.</p>
  <p id="C4JR"></p>
  <figure id="1mrj" class="m_column">
    <img src="https://img4.teletype.in/files/f9/71/f97123b3-232a-4196-8e98-f0adf8601056.png" width="1048" />
    <figcaption>Так выглядел Пастер в 2014м году, кастомизацию фона с тех пор решили убрать.</figcaption>
  </figure>
  <h2 id="zktS">Мертвые фичи</h2>
  <p id="WgSj">За годы работы Пастера, добавлялись и удалялись самые разные фичи, часто уводившие проект сильно далеко от основной задачи.</p>
  <p id="pbc3">Думаю рассказ о том, какой функционал «не пережил зиму», оказавшись неактуальным на длинной дистанции будет весьма показателен — уверяю в вашем проекте причины удаления той или иной фичи будут похожими. </p>
  <h3 id="U3Q8">Отображение в офисные форматы</h3>
  <p id="421k">В Spring MVC еще с тех лет, когда разработка Пастера только начиналась существует интересный <a href="https://docs.spring.io/spring-framework/reference/web/webmvc-view/mvc-document.html" target="_blank">функционал</a>, позволяющий выдавать из слоя View (V — в аббревиатуре MVC) не только стандартные HTML, XML или JSON, но и другие форматы данных: PDF, DOCX, XLS и так далее. </p>
  <p id="Qzbz">С его помощью были реализованы <a href="https://github.com/alex0x08/paster/blob/uberPaste-1.1/uberPaste/src/main/scala/uber/paste/controller/PasteDocxView.scala" target="_blank">генераторы в docx</a> для записей и в <a href="https://github.com/alex0x08/paster/blob/uberPaste-1.1/uberPaste/src/main/scala/uber/paste/controller/PasteExcelView.scala" target="_blank">xlsx</a> для списков и поиска — да, можно было получить результат поиска и фильтрации сразу в виде документа Microsoft Excel.</p>
  <p id="sS0D">Почему не взлетело:</p>
  <blockquote id="Oe8Z">простой текст, вставленный в подготовленный шаблон документа Microsoft Word оказался мало актуальным а полноценное превращение текста в документ — с абзацами и форматированием требовало слишком больших ресурсов.</blockquote>
  <p id="yU1s">Та же самая история повторилась и с форматом Excel — без существенных затрат на разработку сложного шаблона с типами данных, статистикой и аггрегацией полей все это не имело практического смысла.</p>
  <p id="46q2">Но фича красивая да.</p>
  <h3 id="j7W4">Интеграция с почтой</h3>
  <p id="M53G">Пользователи присылают вопросы, жалобы и предложения на почту, специальный адаптер их выгребает и загружает в Пастер.</p>
  <p id="TVIV">Получается альтернативный сценарий использования.</p>
  <p id="zyjy">Почему не взлетело:</p>
  <blockquote id="oG5e">Внезапно оказалось, что на некоторые письма надо отвечать, для чего пришлось бы городить отдельную интеграцию с SMTP и логику хранения ответов.</blockquote>
  <p id="XQN1">Про ответы часто забывают когда дело доходит до почты, слишком многие разработчики привыкли использовать ее только в одну сторону — для отправки оповещений. </p>
  <h3 id="n7la">Итеграция со Skype</h3>
  <p id="isCV">С помощью неофициального API, имитирующего веб-клиент, были реализованы оповещения о новых записях Пастера в Skype — некий аналог современного Телеграм-бота.</p>
  <p id="wAUy">Почему не взлетело:</p>
  <blockquote id="Fsy4">Если получатель не сидел в скайпе постоянно, при входе его засыпало недоставленными однотипными уведомлениями, что быстро надоело. </blockquote>
  <p id="6T1k">К тому же к 2018 году пришел Телеграм, в который очень бысто перетекла вся переписка, а сам скайп стал постепенно умирать.</p>
  <p id="dVxF">Телеграм принес с собой новую культуру отказа от раздражителей и теперь любые оповещения стали восприниматься как отвлекающий фактор.</p>
  <p id="d2WB">Поэтому на сегодня мы от них полностью отказались. </p>
  <h3 id="LtCn">Авторизация через социальные сети</h3>
  <p id="GleS">Когда-то в Spring был <a href="https://docs.spring.io/spring-social/docs/current/reference/htmlsingle/index.html" target="_blank">дочерний проект</a>, посвященный авторизации через социальные сети:</p>
  <blockquote id="Zqq4">The Spring Social project enables your applications to establish Connections with Software-as-a-Service (SaaS) Providers such as Facebook and Twitter to invoke APIs on behalf of Users.</blockquote>
  <p id="3J84">Даже по описанию, в котором фигурируют устаревшие названия социальных сетей думаю понятно, что дело было давно. Ныне проект заморожен и использовать его с современным Spring уже не получится.</p>
  <p id="apz9">Мы использовали Spring Social в Пастере для авторизации через социальные сети: Google, VK, LinkedIn и это даже работало, включая связывание разных профилей.</p>
  <p id="YuwL">Почему не взлетело:</p>
  <blockquote id="zBTS">Использование Spring Social было частью концепции облачного использования Пастера для публичных проектов — хотели сделать что-то типа Github в плане коллаборации. </blockquote>
  <p id="2gvY">Но логика облачной авторизации с годами только усложнялась, появлялись обязательные MFA и дополнительные проверки безопасности, при этом установки Пастера оставались локальными — в облако никто особо не хотел.</p>
  <p id="t0XG">Смерть проекта Spring Social окончательно похоронила эту идею и возвращаться к ней в современных реалиях откровенно бессмысленно.</p>
  <p id="SET1"></p>
  <h3 id="0Iy0">Интеграция с Jira</h3>
  <p id="kOGn">Одна из самых долгоживущих интеграций была с знаменитым багтрекером Atlassian Jira.</p>
  <p id="bybW">Специальный плагин, устанавливаемый в Jira подтягивал на странице детализации записи из Пастера, связанные с просматриваемой задачей.</p>
  <p id="Gcnw">Таким образом сам трекер не захламлялся кусками логов и трассировками ошибок.</p>
  <p id="dFyb">Почему не взлетело:</p>
  <blockquote id="RGDW">Проектов, использующих Jira становилось все меньше, а там где она еще использовалась — нам не давали доступ для установки плагина.</blockquote>
  <p id="AKEJ">Нашим внутренним трекером постепенно стал Redmine, так что интеграция потеряла всякую актуальность.</p>
  <p id="ED82"></p>
  <figure id="BWCm" class="m_column">
    <img src="https://img3.teletype.in/files/a9/09/a9091738-9775-4a8d-a8ee-448138ad13f6.png" width="777" />
  </figure>
  <h3 id="UdmG">Интеграция с файловым хранилищем</h3>
  <p id="6qRF">Помимо обмена кусками кода через публичные сервисы, с разработчиками была еще одна проблема — постоянное перекидывание файлов через публичные сервисы.</p>
  <p id="EFj8">Народ запросто выкладывал фактически в публичный доступ бинарные сборки, скрипты, библиотеки, логи и конфиги.</p>
  <p id="piUU">По аналогии с Пастером и примерно в то же время был запущен проект внутреннего хранилища файлов, с аналогичной целью — сделать устанавливаемую локально замену публичным сервисам.</p>
  <p id="Wkk9">Поскольку оба проекта работали одновременно, логично было их интегрировать. Что в итоге и произошло: </p>
  <blockquote id="dnUG">со стороны Пастера появился специальный виджет, позволяющий цеплять файлы к записи, либо просматривать существующие.</blockquote>
  <p id="5rqM">Со стороны хранилища работала версионность, поэтому можно было легко отслеживать изменения.</p>
  <p id="VUDz">Почему не взлетело:</p>
  <blockquote id="Tq0R">со временем концепция обмена файлами при командной разработке поменялась и мы в итоге пришли к <a href="https://blog.0x08.ru/teleporta" target="_blank">Телепорте</a></blockquote>
  <p id="7qE0">Проект файлового хранилища в виде приложения с веб-интерфейсом был признан устаревшим и похоронен, интеграцию с ним соответственно из Пастера удалили.</p>
  <p id="oyWi">Исходники этого проекта <a href="https://github.com/alex0x08/paster/tree/uberShareApp-1.4/shareService/webapp" target="_blank">находятся</a> в одном репозитории с Пастером и все еще доступны в старых версиях.</p>
  <p id="4wii"></p>
  <h2 id="rbju">Туманное будущее</h2>
  <p id="wrrD">На момент написания этой статьи готовится новый релиз Пастера — с переездом на Jakarta 11, обновлением всех используемых библиотек и мелким рефакторингом.</p>
  <p id="syfR">Немедленно выяснилось, что в Spring 7 решили полностью отказаться от логики «Content Negotiation» — переключение типа выдаваемых данных в зависимости от расширения файла (одна из ключевых фишек Пастера) будет полностью похоронено.</p>
  <p id="BFWl">Никакаких альтернатив разработчиками Spring предложено не было и что теперь с этим делать не очень понятно.</p>
  <p id="7kek">Одновременно с этим разработчики Scala грозятся похоронить 2.х ветку и начать переводить всех в принудительном порядке на Scala3 — фактически другой язык.</p>
  <p id="AJsH">Конечно же без альтернативных вариантов.</p>
  <h2 id="YJ7w">Эпилог</h2>
  <p id="nRQi">Перед вами история небольшого внутреннего проекта, поддерживаемого пусть и по остаточному принципу, но на протяжении последних <strong>14</strong> лет. В его разработке никогда не участвовало больше трех человек одновременно, функционал весьма ограничен а решаемая задача проста и очевидна.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="erTc">Тем не менее, даже при таких вводных поддержка на длинной дистанции превратилась в остросюжетный боевик <s>про зомби и апокалипсис</s>.</p>
  </section>
  <p id="6PmA">Может показаться, что автор — какой-то неудачник и не умеет выбирать инструменты, коль столько раз подряд налетал на умирание ключевой технологии. Но только ровно такой же процесс быстрого и непредсказуемого умирания по любому поводу постоянно происходит во всей индустрии, в том числе на крупных и известных проектах.</p>
  <p id="aS2M">Ни предсказать ни как-то защититься от такого исхода без серьезных усилий не выйдет, поэтому при подобных проблемах «большие парни» просто закапывают весь проект целиком, воссоздавая его на более современных технологиях.</p>
  <p id="WwtU">Зато думаю теперь вы понимаете, зачем большие компании сами собирают весь свой инструментарий из исходников, почему у Google есть свои компиляторы, а у Яндекса — свои ключевые фреймворки.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/small-temperature-mon-x11</guid><link>https://blog.0x08.ru/small-temperature-mon-x11?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/small-temperature-mon-x11?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>Мой маленький мониторинг</title><pubDate>Wed, 25 Mar 2026 12:21:31 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/fc/a2/fca20c7e-24d1-4f65-a3e3-6aa786b15f40.png"></media:content><category>software-development</category><description><![CDATA[<img src="https://img3.teletype.in/files/2f/9b/2f9b466b-da5b-42a6-a20c-d7202b06dd84.jpeg"></img>Делюсь очередной полезной штукой из личных разработок, на этот раз на тему мониторинга температуры в компьютере.]]></description><content:encoded><![CDATA[
  <p id="7lsg">Делюсь очередной полезной штукой из личных разработок, на этот раз на тему мониторинга температуры в компьютере. </p>
  <p id="U4Ed">~120 строк на Python.</p>
  <figure id="xmoR" class="m_original">
    <img src="https://img3.teletype.in/files/2f/9b/2f9b466b-da5b-42a6-a20c-d7202b06dd84.jpeg" width="1366" />
    <figcaption>Правый верхний угол, старая версия - с прозрачным фоном.</figcaption>
  </figure>
  <h2 id="0VH0">Задача</h2>
  <p id="LwgK">Честно говоря, задача мониторинга температуры это такой своеобразный «неуловимый Джо» — <s>ненужная</s> мелкая ерунда, реализуемая в больших системах для галочки и по остаточному принципу.</p>
  <blockquote id="GKlv">Ну и конечно отображение температуры с датчиков персонального компьютера давным давно реализовано и присутствует в виде виджета во всех основных графических окружениях и для любых ОС. </blockquote>
  <p id="8FXZ">Чаще всего это выглядит как-то так:</p>
  <figure id="nHgT" class="m_column">
    <img src="https://img3.teletype.in/files/2d/f7/2df7a631-06db-40c8-98b7-c25043eae516.jpeg" width="720" />
    <figcaption>Найдите тут температуру.</figcaption>
  </figure>
  <p id="cWHl">Это все к вопросу об уникальности, важности и полезности решения, как бы заранее отвечая на самый важный вопрос <s>бытия</s>: «нах#я я все это читаю».</p>
  <p id="e9kz">Кстати одна из первых разработанных автором систем была как раз на тему мониторинга температуры у парка серверов. </p>
  <blockquote id="Ztac">Дело было давно и сервера (как и сетевое оборудование) стояли не в охлаждаемых и чистых серверных, а где придется. </blockquote>
  <p id="nBWu">С соответствующими последствиями по перегреву.</p>
  <p id="ui3W">Выглядело оно как-то так: </p>
  <figure id="ZK0v" class="m_column">
    <img src="https://img3.teletype.in/files/65/b1/65b113be-bfa0-4c05-a63c-11a26322d64f.png" width="1366" />
    <figcaption>Данные тестовые, разумеется а сам мониторинг запущен в режиме отладки, локально. </figcaption>
  </figure>
  <p id="H5lA">Так выглядит виновник сегодняшнего торжества:</p>
  <figure id="JTRJ" class="m_original">
    <img src="https://img3.teletype.in/files/6e/cd/6ecdf107-8105-4c25-92ed-612254a6a1e7.gif" width="180" />
  </figure>
  <p id="7Qp0">Исходный код можно посмотреть чуть ниже в статье или вот <a href="https://gist.github.com/alex0x08/8f743382cc1563c3140ac86cb9e36ed0" target="_blank">тут</a> в виде gist.  Теперь рассказываю подробнее как оно все работает.</p>
  <blockquote id="OBY3">Кстати думаю для многих станет сюрпризом, что X-сервер позволяет рисовать графические элементы и текст в <strong>чужих окнах</strong>.</blockquote>
  <p id="RRlU">Без предупреждения, без индикации, без каких-то отдельных прав и тд.</p>
  <p id="NDFa">Очко сотрудников СБ только что заиграло новыми красками.</p>
  <h2 id="9ICQ">Реализация</h2>
  <p id="3DuB">Поскольку у автора используется тот еще зоопарк разных систем, хотелось сделать максимально переносимое решение.</p>
  <p id="IwQi">Хардкодить все на чистом С я посчитал излишним, поэтому был взят Python и библиотека Xlib, которая есть везде, куда еще не добрались проклятые зумеры со своим Wayland.</p>
  <blockquote id="FUwM">К моему великому сожалению, оказалось что знаменитая связка Tcl/Tk не умеет работать с root window, поэтому использовать их не получится. </blockquote>
  <p id="6BF4">Именно поэтому был взят петон, да.</p>
  <p id="KnTb">Собственно <a href="https://pypi.org/project/python-xlib/" target="_blank">эта библиотека</a> является единственной внешней зависимостью в этом проекте, для FreeBSD устанавливается вот так:</p>
  <pre id="AdvT" data-lang="bash">pkg install py311-python-xlib</pre>
  <p id="8O2x">Аналогичные пакеты есть в любом линуксе и BSD. Теперь стоит рассказать про сами датчики.</p>
  <p id="G88B">Датчики температуры в случае FreeBSD отдают свои значения через <code>sysctl</code> и требуют подгрузки специального модуля ядра. </p>
  <p id="LDup">Чаще всего это будет <a href="https://man.freebsd.org/cgi/man.cgi?coretemp(4)" target="_blank">coretemp</a>:</p>
  <pre id="ILaX" data-lang="bash">kldload coretemp</pre>
  <p id="cHmk">Чтение значений датчиков будет выглядеть как-то так:</p>
  <figure id="dx4j" class="m_original">
    <img src="https://img1.teletype.in/files/cc/be/ccbe6519-66bc-4304-abae-278b6c9f8dfc.png" width="812" />
  </figure>
  <p id="8VqE">Для процессоров AMD есть отдельный модуль <a href="https://man.freebsd.org/cgi/man.cgi?amdtemp(4)" target="_blank">amdtemp</a>:</p>
  <pre id="DvKG" data-lang="bash">kldload amdtemp</pre>
  <p id="xb6E">Названия датчиков отличаются, поэтому для чтения используется немного другой паттерн:</p>
  <pre id="1PjZ">sysctl dev.amdtemp.0 |grep core</pre>
  <p id="HK26">В случае линукса температуру с датчиков можно получить из специальной виртуальной файловой системы <code>/dev</code>:</p>
  <pre id="Zspy">cat /sys/class/thermal/thermal_zone*/temp</pre>
  <p id="fSHQ">Так это выглядит в работе:</p>
  <figure id="ExYP" class="m_original">
    <img src="https://img3.teletype.in/files/2e/6b/2e6bec8e-0b0c-47a1-976c-386fc7d528da.jpeg" width="1280" />
    <figcaption>В работе на процессоре AMD</figcaption>
  </figure>
  <h2 id="UzUS">Исходный код</h2>
  <p id="uxYm">Ниже представлен полный исходный код моей утилиты, технически это <a href="https://en.wikipedia.org/wiki/Shebang_(Unix)" target="_blank">shebang</a> — самозапускаемый скрипт на Python, поэтому его нужно сохранить с расширением <code>.sh</code> и поставить бит запуска.</p>
  <p id="OcLv">Собственно код:</p>
  <pre id="ILtr" data-lang="python">#!/usr/bin/env python3

import Xlib
from Xlib import display, X   # display и X - не импортируются автоматически
import subprocess,time,logging

#настройки логирования
logging.basicConfig(level=logging.INFO)
#logging.basicConfig(level=logging.DEBUG)

# координаты на экране для отображения
POS_X = 150
POS_Y = 50
# для FreeBSD и машины с AMD
PATTERN = &#x27;sysctl dev.amdtemp.0 |grep core&#x27;
# для FreeBSD с модулем coretemp
#PATTERN = &#x27;sysctl dev.cpu |grep temperature&#x27;
# для Linux
#PATTERN = &quot;cat /sys/class/thermal/thermal_zone*/temp | awk &#x27;{ print \&quot;temp: \&quot; ($1 / 1000) \&quot;C\&quot; }&#x27;&quot;
# шрифт
FONT = &#x27;-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1&#x27;
# период обновления
REFRESH_SECS = 15

last_dim = [0,0]

# определение рабочего стола
# d - display (экран)s
def get_root_window(d):
    
    screen = d.screen()
    # root window - рабочий стол по-умолчанию
    root = screen.root

    # Получаем ID всех окон верхнего уровня
    windowIDs = root.get_full_property(d.intern_atom(&#x27;_NET_CLIENT_LIST&#x27;), 
                                                  X.AnyPropertyType).value
    logging.debug(&#x27;Found %d windows.&#x27;,len(windowIDs))

    for windowID in windowIDs:
        # Create a window object from the ID to access its properties
        window = d.create_resource_object(&#x27;window&#x27;, windowID)

        try:
            # Get the window title (WM_NAME or _NET_WM_NAME)
            # Use get_wm_name() for simplicity, 
            # or look up EWMH properties for better compatibility
            window_name = window.get_wm_name()
            if window_name:
                # в продвинутых DE вроде KDE/Xfce за рабочий стол отвечает
                # отдельное окно и рисовать придется в нем
                if &#x27;Desktop&#x27; in window_name:
                    logging.debug(&quot;Found desktop ID: %d - Name: %s&quot;,
                                                 windowID,window_name)
                    return window
            else:
                # Бывает, что у окна нет заголовка
                logging.debug(&quot;ID: %d - Name: None (no WM_NAME property)&quot;,
                                                 windowID)

        except X.BadWindow:
            # Обработка ситуации, когда считываемое окно больше не существует
            logging.debug(&quot;ID: %d - Window no longer exists&quot;,windowID)
    # если отдельного окна с именем Desktop не обнаружено - рисуем
    # прямо на root window 
    return root

# очистка области
def clear_rect(msg):
    global last_dim
    # если есть сохраненные размеры - используем их
    if last_dim[0] &gt; 0:	
    	root.fill_rectangle(gc2, POS_X,POS_Y-last_dim[1], 
    	                         last_dim[0]-20, last_dim[1]+5)
    else:
        # расчет размеров надписи в пикселях
        text_extents = font.query_text_extents(msg)
        tw = text_extents.overall_width
        th = text_extents.font_ascent + text_extents.font_descent
        # очистка происходит через отрисовку черного прямоугольника
        # clear_area плохо работает с KDE
        root.fill_rectangle(gc2, POS_X,POS_Y-th, tw-20, th+5)
        # запоминаем размеры надписи для следующей очистки
        last_dim = [tw,th]

# отрисовка сообщения на экране
# msg - текст сообщения
def draw_message(msg):
    # очистка области
    clear_rect(msg)
    # отрисовка текста
    root.draw_text(gc, POS_X, POS_Y, msg)
    display.flush()

# инициализация подключения к Х-серверу
display = Xlib.display.Display()
screen = display.screen()
root = get_root_window(display)

# Access the window ID (an integer)
root_id = root.id

logging.debug(&quot;Root window ID: %d&quot;,root_id)
# для реакции на события
root.change_attributes(event_mask=X.ExposureMask)  # &quot;adds&quot; this event mask
# создание графического контекста, белый текст на черном фоне
gc = root.create_gc(foreground = screen.white_pixel, 
                    background = screen.black_pixel)
# дополнительный контекст для заливки области черным
colormap = screen.default_colormap
color = colormap.alloc_named_color(&#x27;black&#x27;) 
gc2 = root.create_gc(foreground=color.pixel)

# загружаем шрифт, которым будет отрисовываться текст
# если шрифт с таким названием не будет найден - вылетит ошибка
try:
    font = display.open_font(FONT)
    gc.font = font.id
except Exception as e:
    logging.exception(e)
    exit(1)

try:
    # бесконечный цикл, в котором происходит все действо
    while 1:
            # запуск процесса для получения значений датчиков
            process = subprocess.Popen(PATTERN, 
                    shell=True, text=True,
                    stdout=subprocess.PIPE)
            # в этой переменной будет массив строк со значениями   
            stdout_list = process.communicate()[0].split(&#x27;\n&#x27;)

            out = &#x27;&#x27;
            # делаем чистку
            for s in stdout_list:
                # убираем ошибочные строки, если нет : - нет и значения
                if &#x27;:&#x27; not in s: continue
                kv = s.split(&#x27;:&#x27;)
                # добавляем запятую в качестве разделителя 
                if len(out) &gt; 0: out+= &#x27;,&#x27;
                # добавляем значение датчика в строку
                out+= kv[1]

            logging.debug(out)
            # отрисовываем полученную строку
            draw_message(out.encode())
            # задержка между итерациями
            time.sleep(REFRESH_SECS)
            
except KeyboardInterrupt:
        # при нажатии Ctrl-C делаем очистку области экрана, где
        # происходила отрисовка виджета
        x = POS_X // 2
        y = POS_Y // 2
        root.clear_area(x,y,last_dim[0]+x,last_dim[1]+y,True)
        display.flush()</pre>
  <p id="cyyR">Как видите тут нет ООП и нет многопоточности — реализация максимально упрощена. Также не стал городить считывание параметров, поэтому ключевые настройки находятся в самом скрипте.</p>
  <p id="aGEx">Настройка логирования:</p>
  <pre id="qN5c" data-lang="python">logging.basicConfig(level=logging.INFO)
#logging.basicConfig(level=logging.DEBUG)</pre>
  <p id="47Wx">Координаты для отображения на экране (левый нижний угол):</p>
  <pre id="rYKw" data-lang="python">POS_X = 150
POS_Y = 50</pre>
  <p id="9vzy">Выбор паттерна для считывания значений датчиков:</p>
  <pre id="s9Ri" data-lang="python"># для FreeBSD и машины с AMD
PATTERN = &#x27;sysctl dev.amdtemp.0 |grep core&#x27;
# для FreeBSD с модулем coretemp
PATTERN = &#x27;sysctl dev.cpu |grep temperature&#x27;
# для Linux
PATTERN = &quot;cat /sys/class/thermal/thermal_zone*/temp | awk &#x27;{ print \&quot;temp: \&quot; ($1 / 1000) \&quot;C\&quot; }&#x27;&quot;</pre>
  <p id="Vy3j">Шрифт, которым будут отображаться значения температуры, указывается в <a href="https://wiki.archlinux.org/title/X_Logical_Font_Description" target="_blank">специальном формате</a>:</p>
  <pre id="HTaj" data-lang="python">FONT = &#x27;-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1&#x27;</pre>
  <p id="vSBF">Частота обновлений в секундах:</p>
  <pre id="au26" data-lang="python">REFRESH_SECS = 15</pre>
  <p id="SNwc">Так виджет выглядит на Ubuntu и Xfce:</p>
  <figure id="CSi5" class="m_original">
    <img src="https://img2.teletype.in/files/94/20/9420f876-89dc-4e5c-87cf-2071ba733948.png" width="1366" />
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.0x08.ru/marktext-on-freebsd</guid><link>https://blog.0x08.ru/marktext-on-freebsd?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08</link><comments>https://blog.0x08.ru/marktext-on-freebsd?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=alex0x08#comments</comments><dc:creator>alex0x08</dc:creator><title>Запускаем MarkText на FreeBSD</title><pubDate>Mon, 16 Mar 2026 08:09:51 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/74/c8/74c8dee6-b3d2-4572-9bd4-f5a00d4bb89c.png"></media:content><category>unix</category><description><![CDATA[<img src="https://img1.teletype.in/files/8e/79/8e79d902-53d0-46cb-9db4-687d19661c6a.jpeg"></img>Очередные ужасы из тяжкой жизни пользователей BSD или что делать, когда нужная программа ненавидит вашу операционную систему.]]></description><content:encoded><![CDATA[
  <p id="zl7H">Очередные ужасы из тяжкой жизни пользователей BSD или что делать, когда нужная программа ненавидит вашу операционную систему. </p>
  <p id="14Ta">В помощь начинающему, продолжающему и заканчивающему автору. </p>
  <figure id="hNuH" class="m_original">
    <img src="https://img1.teletype.in/files/8e/79/8e79d902-53d0-46cb-9db4-687d19661c6a.jpeg" width="1920" />
  </figure>
  <h2 id="VoHB">Очко электрона</h2>
  <p id="7P1e">Следующим по уровню безнадежности занятием на FreeBSD, после <a href="https://blog.0x08.ru/bitnet-running-on-freebsd" target="_blank">нейросетей</a> и <a href="https://blog.0x08.ru/dotnet-on-freebsd-yeee" target="_blank">разработки на .NET</a> является работа с приложениями на <a href="https://www.electronjs.org/" target="_blank">Electron</a>.</p>
  <p id="qPCM">Широкие народные массы требуют <a href="https://github.com/electron/electron/issues/3797" target="_blank">это</a> и уже очень давно:</p>
  <figure id="iuyL" class="m_original">
    <img src="https://img4.teletype.in/files/7d/9f/7d9f3aef-f71e-4f39-9608-eae6d312afd5.png" width="927" />
  </figure>
  <p id="zMDY">Но ввиду разных причин (в первую очередь идеологических), официальной поддержки все также нет. </p>
  <p id="ewMb">И скорее всего не будет никогда.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="UFXL">Зато есть <a href="https://github.com/tagattie/FreeBSD-Electron" target="_blank">неофициальный форк</a>, который успешно заехал в пакетную базу и довольно давно там живет.</p>
  </section>
  <p id="G2Ym">Форк очень даже живой:</p>
  <figure id="KdAO" class="m_original">
    <img src="https://img1.teletype.in/files/07/0d/070d2612-7d1e-40d4-9b2e-557989154dcb.png" width="1337" />
  </figure>
  <p id="aW04">Как можно заметить из истории коммитов выше — идет активная разработка и прием пул-реквестов.</p>
  <p id="QQMP">Но как обычно есть нюанс:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="N9fD">Electron это <strong>фреймворк</strong> для построения десктоп-приложений с помощью одноименного движка.</p>
  </section>
  <p id="PEQp">Но портировали на FreeBSD только движок Electron, без средств сборки конечных приложений на нем. </p>
  <p id="Awdh">Речь в первую очередь про <a href="https://www.electron.build/" target="_blank">electron-builder</a>: </p>
  <blockquote id="R7wn">A complete solution to package and build a ready for distribution <a href="https://electronjs.org/" target="_blank">Electron</a>, <a href="https://proton-native.js.org/" target="_blank">Proton Native</a> app for macOS, Windows and Linux with “auto update” support out of the box. </blockquote>
  <p id="DoG4">Это не означает, что приложение на Electron не будет работать на FreeBSD совсем, но и не значит, что полноценная разработка таких приложений там возможна. </p>
  <p id="Yg7e"><strong>Немного работает</strong> — так это обычно описывают.</p>
  <figure id="QVY5" class="m_original">
    <img src="https://img3.teletype.in/files/61/ec/61ecfbd3-1a52-4e99-9c06-5ec6ea883040.png" width="834" />
  </figure>
  <h2 id="QFT1">MarkText</h2>
  <p id="t4Oj"><a href="https://marktext.me/" target="_blank">MarkText</a> это такой редактор для <a href="https://en.wikipedia.org/wiki/Markdown" target="_blank">Markdown</a>-разметки, один из самых лучших, известных и популярных:</p>
  <blockquote id="qLiR">A simple and elegant open-source markdown editor that focused on speed and usability.</blockquote>
  <p id="opZ0">Именно его я использую для верстки своих статей и документации.</p>
  <p id="aLJL">К сожалению редактор построен на том самом Electron, поэтому для нормальных людей, не отягощенных двумя десятилетиями разработки нет вариантов его использования на FreeBSD — ни в Wine, ни с помощью <a href="https://docs.freebsd.org/en/books/handbook/linuxemu/" target="_blank">слоя совместимости с Linux</a> эта штука не работает.</p>
  <p id="CJdx">Хотя пожелания <a href="https://github.com/marktext/marktext/issues/3505" target="_blank">есть</a>:</p>
  <figure id="CH4u" class="m_original">
    <img src="https://img4.teletype.in/files/34/d9/34d98528-19de-40c4-8f8d-095b4b5744b4.png" width="974" />
  </figure>
  <h2 id="ThSk">Скотская сборка</h2>
  <p id="Zolt">Как бы это ни было удивительно, но Node.js и npm давно и успешно работают во FreeBSD, поэтому все спокойно устанавливается из пакетов:</p>
  <pre id="F1ka" data-lang="bash">pkg install node25 electron37 npm-node25 </pre>
  <p id="QElG">Забираем исходники редактора:</p>
  <pre id="T7qR" data-lang="bash">git clone --depth 1 https://github.com/marktext/marktext.git</pre>
  <p id="gP9f">Активная разработка по какой-то причине остановлена, народ <a href="https://github.com/marktext/marktext/issues/4132" target="_blank">начинает беспокоиться</a>, поэтому я не стал заморачиваться релизными версиями и собирал из текущей ветки. </p>
  <p id="CosU">Сборка использует еще один пакетный менеджер — <a href="https://yarnpkg.com/" target="_blank">yarn</a>, который необходимо установить с помощью <code>npm</code>:</p>
  <pre id="PNCL" data-lang="bash">npm -g i yarn</pre>
  <p id="cYtr">Дальше начинается первый нюанс:</p>
  <blockquote id="mJd3">необходимо отключить скачивание бинарной сборки Electron, поскольку ее не существует для FreeBSD.</blockquote>
  <p id="9Yxu">Перед запуском скачивания зависимостей, необходимо выставить <a href="https://www.electronjs.org/docs/latest/tutorial/installation" target="_blank">специальную переменную</a>:</p>
  <pre id="Pbgp" data-lang="bash">export ELECTRON_SKIP_BINARY_DOWNLOAD=1 
yarn install</pre>
  <p id="qwhd">Через какое-то время (скачивание зависимостей в проекте на Node.js — <strong>очень</strong> долгий и болезненный процесс) в корневом каталоге должна появиться папка <code>node_modules</code> откровенно скотских размеров:</p>
  <figure id="EMbk" class="m_original">
    <img src="https://img4.teletype.in/files/3f/dc/3fdc4fab-3b1b-4512-a356-304bd0cec9cc.png" width="1025" />
  </figure>
  <p id="KQxp">Следующим шагом необходимо убрать искусственную заглушку, вставленную автором MarkText для того чтобы редактор не пытались запускать там где не надо — частая практика для проектов на Electron.</p>
  <p id="mkpH">В файле <code>src/main/index.js</code>есть вот такой замечательный код:</p>
  <pre id="Pu7i" data-lang="javascript">// NOTE: We only support Linux, macOS and Windows but not BSD nor SunOS.
if (!/^(darwin|win32|linux)$/i.test(process.platform)) {
  process.stdout.write(&#x60;Operating system &quot;${process.platform}&quot; is not supported! Please open an issue at &quot;https://github.com/marktext/marktext&quot;.\n&#x60;)
  process.exit(1)
}</pre>
  <p id="6qSa">Не представляю кто смог упороться до такой степени, чтобы гонять десктоп-приложение на Electron на Солярисе, но думаю не будет откровением, что вызов <code>process.exit(1)</code> необходимо закомментировать для продолжения банкета.</p>
  <p id="v8Pk">Теперь переходим к собственно сборке.</p>
  <p id="8BmT">Штатно сборка MarkText происходит вызовом команды <code>yarn build</code>, но если посмотреть внутрь файла <code>package.json</code>, в котором находятся все команды сборки, увидим:</p>
  <pre id="MLA4" data-lang="javascript">..
&quot;build&quot;: &quot;node .electron-vue/build.js &amp;&amp; electron-builder&quot;,
..</pre>
  <p id="N0Qg">Вызов <code>electron-builder</code> очевидно упадет, поскольку он не был портирован на FreeBSD и плотно завязан на готовые бинарные части и ветвления логики под конкретную поддерживаемую ОС.</p>
  <p id="wU5P">Так что вызываем лишь первую часть, причем вручную (без всяких yarn):</p>
  <pre id="1Pj5" data-lang="bash">node .electron-vue/build.js</pre>
  <p id="Nmmd">Должен отработать webpack, sass и в каталоге dist будет находиться готовое к запуску приложение на Electron.</p>
  <p id="8FB7">К сожалению в «обнаженном» виде, без прилепленного рантайма, что однако никак не мешает его запустить:</p>
  <pre id="taDC" data-lang="bash">electron37 dist/electron/main.js</pre>
  <p id="U7VA">Так выглядит запущенный MarkText на FreeBSD, в работе над английскими версиями статей:</p>
  <figure id="k2mc" class="m_original">
    <img src="https://img1.teletype.in/files/85/36/8536f375-91a9-4870-bf7b-ffe040ec6627.png" width="1322" />
  </figure>
  <p id="u6Ms">Для удобства использования можно перенести каталоги <code>dist</code> и <code>node_modules</code> в отдельное место:</p>
  <figure id="EDts" class="m_original">
    <img src="https://img4.teletype.in/files/7f/f8/7ff80e71-80bc-47a3-ad86-15295a32e5c5.png" width="1085" />
  </figure>
  <p id="IfKc">И запускать вот таким скриптом:</p>
  <pre id="MFPd" data-lang="bash">#!/bin/sh

/usr/local/bin/electron37 dist/electron/main.js</pre>
  <p id="DeiR">Готовый <a href="https://t.me/alex0x09/2665" target="_blank">архив со сборкой</a> можно скачать в нашем Телеграм-канале.</p>
  <p id="oDlB"></p>
  <h3 id="U9h4">Update 02.05.2026</h3>
  <p id="kI4n">С момента написания статьи в FreeBSD появилась обновленная версия Electron 3.9, <strong>несовместимая</strong> с 3.7, пакет с которой еще и удалили.</p>
  <p id="bQp7">Что еще печальней, сам Marktext работает с еще более старой версией, зависящей от устаревшей Node.js 18, биндинги к которой более не совместимы с 25 и выше в новом Electron.</p>
  <p id="KpJY">Поэтому собирать придется с помощью Node 22:</p>
  <pre id="11pf" data-lang="bash">pkg install node22 electron39 npm-node22 </pre>
  <p id="JBNX">Второй печальный нюанс — блокировка ресурсов ElectronJS для доступа из РФ, поэтому для сборки, во время которой присходит скачивание заголовков Node.js необходимо выставить прокси:</p>
  <pre id="tBCj">yarn config set httpsProxy 103.131.232.9:8080</pre>
  <p id="8ONi">Для отладки:</p>
  <pre id="uu5t" data-lang="bash">export DEBUG=electron-rebuild</pre>
  <p id="mIVM">Для проверки скачивания архива с заголовками:</p>
  <pre id="v49a" data-lang="bash">wget -e use_proxy=yes -e https_proxy=103.131.232.9:8080 https://artifacts.electronjs.org/headers/dist/v18.0.4/node-v18.0.4-headers.tar.gz</pre>
  <p id="ZBMF">Но это еще не все.</p>
  <p id="D0rF">Собранная с таким трудом сборка упадет при запуске с вот такой ошибкой:</p>
  <pre id="ZpfZ">TypeError: features.isDesktopCapturerEnabled is not a function</pre>
  <p id="bkTt">Чтобы ее увидеть надо задать две переменные окружения:</p>
  <pre id="59aW"> export ELECTRON_ENABLE_LOGGING=1
 export ELECTRON_ENABLE_STACK_DUMPING=1</pre>
  <p id="rGJP">Для исправления необходимо закомментировать два блока в конце файла <code>@electron/remote/dist/src/common/module-names.js</code>:</p>
  <pre id="GmaA" data-lang="typescript">const features = get_electron_binding_1.getElectronBinding(&#x27;features&#x27;);
/*if (!features || features.isDesktopCapturerEnabled()) {
    exports.browserModuleNames.push(&#x27;desktopCapturer&#x27;);
}*/
/*if (!features || features.isViewApiEnabled()) {
    exports.browserModuleNames.push(&#x27;ImageView&#x27;);
}*/</pre>
  <p id="TNbn">которые и порождают ошибку.</p>
  <p id="No0R">Конечно это адский костыль и времененное решение, но обновлять Marktext целиком на новую версию Electron — сил не хватит.</p>

]]></content:encoded></item></channel></rss>