Рубрика: Заметки

  • Donki Hills has officially been on Steam for over a year!

    Donki Hills уже больше года в Steam!

    Ровно год назад проект появился на странице Steam, и с тех пор игра прошла большой путь. За это время было много экспериментов, изменений и поисков того самого направления, в котором Donki Hills должна развиваться.

    Работа над геймплеем продолжается, и сейчас проект постепенно приобретает своё настоящее лицо. Donki Hills начинает превращаться в то, чем она задумывалась — Comedy First Person Roguelike Parody Survival Horror.

    Странное приключение, где хоррор встречается с юмором, исследованием и неожиданными ситуациями. Вам предстоит отправиться в город, искать предметы, разгадывать загадки и постепенно раскрывать тайну, которая приведёт вас к Марии.

    Ниже — свежие скриншоты с очередного плейтеста прототипа. Это ещё не финальный вид игры, но уже можно почувствовать атмосферу города и направление, в котором движется проект.

    Очень интересно услышать вашу реакцию! 👀
    Как вам новое направление? Какие впечатления от атмосферы и идеи игры?

    Спасибо всем, кто добавил Donki Hills в список желаемого, следит за разработкой и поддерживает проект ❤️

    Впереди ещё много экспериментов, новых механик и странных приключений.

    https://store.steampowered.com/app/3476390/Donki_Hills/

  • Обходим троттлинг на процессорах игровых лаптопов

    Производители современных игровых ноутбуков часто настраивают системы так, что процессор под нагрузкой прогревается до 90 градусов и даже доходит до 100 градусов Цельсия. Особенно остро эта проблема проявляется в летний период при запуске требовательных игр или тяжелых рабочих задач.

    Из-за экстремального нагрева активируется троттлинг (сброс частот процессора для предотвращения его физического повреждения), что приводит к резкой потере производительности, фризам и падению FPS. Существует немало способов борьбы с перегревом (от использования охлаждающих подставок до андервольтинга), однако в этой заметке я опишу самый простой и быстрый метод, актуальный для Windows 11 и более ранних версий операционной системы.

    Метод заключается в ограничении максимального состояния процессора через настройки схемы электропитания:

    1. Откройте настройки электропитания через поиск Windows или панель управления.
    2. В активной схеме питания перейдите в раздел изменения дополнительных параметров.
    3. Найдите ветку Processor power management (Управление питанием процессора).
    4. Раскройте параметр Maximum processor state (Максимальное состояние процессора).
    5. Для пункта Plugged In (От сети) измените значение со 100% на 80% или меньше.

    После применения этих настроек процессор перестанет автоматически разгоняться до предельных частот, выделяющих избыточное тепло. Несмотря на то, что максимальная пиковая производительность снизится примерно на 20%, процессор перестанет перегреваться. Стабильная работа на сниженной частоте без троттлинга ГОРАЗДО лучше и комфортнее для системы, чем постоянные резкие скачки производительности из-за перегрева при температурах под 100 градусов.

    Каждый ноутбук уникален, поэтому я рекомендую пользователям поэкспериментировать и самостоятельно найти оптимальный баланс (процентаж), который обеспечит нужную производительность без перегрева.

  • Портирование Surreal Engine C++ на WebAssembly

    В этой заметке я опишу то как я портировал игровой движок Surreal Engine на WebAssembly.
    https://demensdeum.com/demos/SurrealEngine/»
    Surreal Engine – игровой движок который реализует большую часть функционала движка Unreal Engine 1, известные игры на этом движке – Unreal Tournament 99, Unreal, Deus Ex, Undying. Он относится к классическим движкам, которые работали преимущественно в однопоточной среде выполнения.
    Изначально у меня была идея взяться за проект который я не смогу выполнить в какой-либо разумный срок, таким образом показав своим подписчикам на Twitch, что есть проекты которые не могу сделать даже я. В первый же стрим я внезапно понял что задача портирования Surreal Engine C++ на WebAssembly с помощью Emscripten выполнима.

    Спустя месяц я могу продемонстрировать свой форк и сборку движка на WebAssembly:
    https://demensdeum.com/demos/SurrealEngine/
    Управление как и в оригинале, осуществляется на стрелках клавиатуры. Далее планирую адаптацию под мобильное управление (тачи), добавление корректного освещения и прочие графические фишки рендера Unreal Tournament 99.

    С чего начать?

    Первое о чем хочется сказать, это то что любой проект можно портировать с C++ на WebAssembly с помощью Emscripten, вопрос лишь в том насколько полным получится функционал. Выбирайте проект порты библиотек которого уже доступны для Emscripten, в случае Surreal Engine очень сильно повезло, т.к. движок использует библиотеки SDL 2, OpenAL – они обе портированы под Emscripten. Однако в качестве графического API используется Vulkan, который на данный момент не доступен для HTML5, ведутся работы по реализации WebGPU, но он также находится в стадии черновика, также неизвестно насколько простым будет дальнейший порт из Vulkan на WebGPU, после полной стандартизации оного. Поэтому пришлось написать свой собственный базовый OpenGL-ES / WebGL рендер для Surreal Engine.

    Сборка проекта

    Система сборки в Surreal Engine – CMake, что тоже упрощает портирование, т.к. Emscripten предоставляет свои нативные сборщики – emcmake, emmake.
    За основу порта Surreal Engine брался код моей последней игры на WebGL/OpenGL ES и C++ под названием Death-Mask, из-за этого разработка шла гораздо проще, все необходимые флаги сборки были с собой, примеры кода.
    Один из важнейших моментов в CMakeLists.txt это флаги сборки для Emscripten, ниже пример из файла проекта:

    set(CMAKE_CXX_FLAGS "-s MIN_WEBGL_VERSION=2 
    -s MAX_WEBGL_VERSION=2 
    -s EXCEPTION_DEBUG 
    -fexceptions 
    --preload-file UnrealTournament/ 
    --preload-file SurrealEngine.pk3 
    --bind 
    --use-preload-plugins 
    -Wall 
    -Wextra 
    -Werror=return-type 
    -s USE_SDL=2 
    -s ASSERTIONS=1 
    -w 
    -g4 
    -s DISABLE_EXCEPTION_CATCHING=0 
    -O3 
    --no-heap-copy 
    -s ALLOW_MEMORY_GROWTH=1 
    -s EXIT_RUNTIME=1")
    

    Сам сборочный скрипт:

    clear
    emmake make -j 16
    cp SurrealEngine.data /srv/http/SurrealEngine/SurrealEngine.data
    cp SurrealEngine.js /srv/http/SurrealEngine/SurrealEngine.js
    cp SurrealEngine.wasm /srv/http/SurrealEngine/SurrealEngine.wasm
    cp ../buildScripts/Emscripten/index.html /srv/http/SurrealEngine/index.html
    

    Далее подготовим index.html, который включает в себя прелоадер файловой системы проекта. Для выкладывания в веб я использовал Unreal Tournament Demo версии 338. Как можно увидеть из файла CMake, распакованная папка игры была добавлена с сборочную директорию и прилинкована как preload-file для Emscripten.

    Основные изменения кода

    Затем предстояло поменять игровой цикл игры, запускать бесконечный цикл нельзя, это приводит к зависанию браузера, вместо этого нужно использовать emscripten_set_main_loop, об этой особенности я писал в своей заметке 2017 года “Портирование SDL C++ игры на HTML5 (Emscripten)
    Код условия выхода из цикла while меняем на if, далее выводим основной класс игрового движка, который содержит игровой луп, в глобальный скоп, и пишем глобальную функцию которая будет вызывать шаг игрового цикла из глобального объекта:

    #if __EMSCRIPTEN__
    #include <emscripten.h>
    Engine *EMSCRIPTEN_GLOBAL_GAME_ENGINE = nullptr;
    void emscripten_game_loop_step() {
    	EMSCRIPTEN_GLOBAL_GAME_ENGINE->Run();
    }
    #endif
    

    После этого нужно убедиться что в приложении отсутствуют фоновые потоки, если они есть, то приготовьтесь к переписываю их на однопоточное выполнение, либо использование библиотеки phtread в Emscripten.
    Фоновый поток в Surreal Engine используется для проигрывания музыки, из главного потока движка приходят данные о текущем треке, о необходимости проигрывания музыки, либо ее отсутствии, затем фоновый поток по мьютексу получает новое состояние и начинает проигрывать новую музыку, либо приостанавливает. Фоновый поток также используется для буферизации музыки во время проигрывания.
    Мои попытки собрать Surreal Engine под Emscripten с pthread не увенчались успехом, по той причине что порты SDL2 и OpenAL были собраны без поддержки pthread, а их пересборкой ради музыки я заниматься не хотел. Поэтому перенес функционал фонового потока музыки в однопоточное выполнение с помощью цикла. Удалив вызовы pthread из C++ кода, я перенес буферизацию, проигрывание музыки в основной поток, чтобы не было задержек я увеличил буфер на несколько секунд.
    Далее я опишу уже конкретные реализации графики и звука.

    Vulkan не поддерживается!

    Да Vulkan не поддерживается в HTML5, хотя все рекламные брошюры выдают кроссплатформенность и широкую поддержку на платформах как основное преимущество Vulkan. По этой причине пришлось написать свой базовый рендер графики для упрощенного типа OpenGL – ES, он используется на мобильных устройствах, иногда не содержит модных фишек современного OpenGL, зато он очень хорошо переносится на WebGL, именно это реализует Emscripten. Написание базового рендера тайлов, bsp рендеринга, для простейшего отображения GUI, и отрисовки моделей + карт, удалось за две недели. Это, пожалуй, была самая сложная часть проекта. Впереди еще очень много работы по имплементации полного функционала рендеринга Surreal Engine, поэтому любая помощь читателей приветствуется в виде кода и pull request’ов.

    OpenAL поддерживается!

    Большим везением стало то, что Surreal Engine использует OpenAL для вывода звука. Написав простой hello world на OpenAL, и собрав его на WebAssembly c помощью Emscripten, мне стало ясно насколько все просто, и я отправился портировать звук.
    После нескольких часов дебага, стало очевидно что в OpenAL реализации Emscripten есть несколько багов, например при инициализации считывания количества моно каналов, метод возвращал бесконечную цифру, а после попытки инициализации вектора бесконечного размера, падает уже C++ с исключением vector::length_error.
    Это удалось обойти сделав хардкод количества моно каналов на 2048:

    		alcGetIntegerv(alDevice, ALC_MONO_SOURCES, 1, &monoSources);
    		alcGetIntegerv(alDevice, ALC_STEREO_SOURCES, 1, &stereoSources);
    
    #if __EMSCRIPTEN__
    		monoSources = 2048; // for some reason Emscripten's OpenAL gives infinite monoSources count, bug?
    #endif
    
    

    А сеть есть?

    Surreal Engine сейчас не поддерживает сетевую игру, игра с ботами поддерживается, но нужен кто-то кто напишет ИИ для этих ботов. Теоретически реализовать сетевую игру на WebAssembly/Emscripten можно с помощью Websockets.

    Заключение

    В заключение хочется сказать что портирование Surreal Engine получилось достаточно гладким из-за использования библиотек для которых есть порты Emscripten, также мой прошлый опыт реализации игры на C++ для WebAssembly на Emscripten. Ниже ссылки на источники знаний, репозиториев по теме.
    M-M-M-MONSTER KILL!
    Также если вы хотите помочь проекту, желательно кодом рендера WebGL/OpenGL ES, то пишите мне в Telegram:
    https://t.me/demenscave

    Ссылки

    https://demensdeum.com/demos/SurrealEngine/

    https://github.com/demensdeum/SurrealEngine-Emscripten

    https://github.com/dpjudas/SurrealEngine

  • Проброс портов между клиентами через Chisel: урезанный тоннель без L3

    Когда два устройства находятся за NAT или строгими фаерволами и не могут «увидеть» друг друга напрямую, стандартным решением кажется VPN. Но полноценный L3-тоннель (вроде WireGuard или OpenVPN) часто избыточен: он требует root-прав, настройки виртуальных интерфейсов и может конфликтовать с существующими маршрутами.

    В таких случаях удобно использовать Chisel — TCP/UDP тоннель, работающий поверх HTTP и использующий WebSockets для передачи данных. В этой заметке я покажу, как «прокинуть» порт от одного клиента к другому через промежуточный сервер.

    Как это работает?

    Представьте ситуацию: у вас есть Клиент А (например, ваш домашний сервер), Клиент Б (ваш рабочий ноутбук) и VPS с публичным IP-адресом. Клиенты А и Б могут обращаться к VPS, но не друг к другу.

    Схема проброса будет выглядеть так:
    1. Клиент А подключается к VPS и открывает «обратный» (reverse) порт на сервере. Теперь всё, что приходит на порт X сервера, попадает на порт Y Клиента А.
    2. Клиент Б подключается к VPS и пробрасывает порт Z со своей локальной машины на порт X сервера.
    3. В итоге Клиент Б обращается к localhost:Z и попадает на Клиент А:Y.

    Такой подход — одно из решений в случаях, когда связь с VPS не реализует L3-слой или отсутствует возможность настройки маршрутизации между клиентами. Мы работаем исключительно на уровне приложений и портов.

    Шаг 1: Запуск сервера

    На вашей VPS достаточно запустить Chisel в режиме сервера. Флаг --reverse обязателен, чтобы разрешить клиентам открывать порты на стороне сервера.

    chisel server --port 8080 --reverse
    

    Шаг 2: Подключение Клиента А (Источник)

    Допустим, Клиент А хочет открыть доступ к своему локальному веб-серверу на порту 3000. Он подключается к VPS и говорит: «зарезервируй на сервере порт 2000 и перенаправляй его мне на 3000».

    chisel client vps-ip:8080 R:2000:127.0.0.1:3000
    

    Теперь порт 2000 на VPS (на loopback интерфейсе) ведет к Клиенту А.

    Шаг 3: Подключение Клиента Б (Потребитель)

    Теперь Клиент Б хочет получить доступ к этому ресурсу. Он подключается к той же VPS и пробрасывает свой локальный порт 8080 на порт 2000 сервера.

    chisel client vps-ip:8080 8080:127.0.0.1:2000
    

    Готово! Теперь открыв http://localhost:8080 на Клиенте Б, вы увидите сервис, запущенный на Клиенте А.

    Безопасность и нюансы

    Chisel поддерживает аутентификацию через флаг --auth, что крайне рекомендуется при работе через публичные сервера. Также можно использовать TLS-сертификаты для шифрования трафика.

    Главное преимущество такого подхода — отсутствие необходимости в TUN/TAP устройствах и сложных таблицах маршрутизации. Это «урезанный» тоннель, который делает ровно одну вещь: связывает порты через WebSocket-соединение. Это работает даже через корпоративные прокси, если настроить Chisel на работу через 443 порт.

    Вывод

    Chisel — это утилита для специфических сетевых задач. Когда нужно прокинуть порты между изолированными узлами без настройки полноценного VPN, связка из прямого и обратного тоннелей через релей-сервер оказывается вполне жизнеспособным решением.

    Ссылки

    https://github.com/jpillora/chisel

  • Почему никак не получается исправить баг?

    Вы часами сидите над кодом, перебираете гипотезы, правите условия, но баг все равно воспроизводится. Знакомо? Это состояние фрустрации часто называют «охотой на призраков». Кажется, что программа живет своей жизнью, игнорируя ваши исправления.

    Одной из самых частых — и самых обидных — причин такой ситуации является поиск ошибки совершенно не в том месте приложения.

    Ловушка «ложных симптомов»

    Когда мы видим ошибку, наше внимание приковано к месту, где она «выстрелила». Но в сложных системах место проявления бага (crash или некорректное значение) — это лишь финал длинной цепочки событий. Пытаясь починить финал, вы боретесь с симптомами, а не с болезнью.

    Именно здесь на помощь приходит концепция блок-схемы.

    Как это работает в реальности

    Конечно, прямо составлять (рисовать) блок-схему на бумаге каждый раз не обязательно, но важно иметь её в голове или под рукой как архитектурный ориентир. Блок-схема позволяет визуализировать работу приложения как дерево исходов.

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

    Результат: Вы тратите часы на «идеальное» исправление кода в одной части алгоритма, что, естественно, никак не исправляет проблему в другой его части, где на самом деле происходит сбой.


    Алгоритм победы над багом

    Чтобы перестать биться в закрытую дверь, нужно изменить подход к диагностике:

    • Найдите состояние в дереве исходов: Прежде чем писать код, нужно точно определить путь, по которому прошло приложение. В какой точке логика свернула не туда? Какое именно состояние (State) привело к проблеме?
    • Воспроизведение — это 80% успеха: Обычно это делается силами тестировщиков и автотестов. Если баг «плавающий», к процессу подключается разработка для совместного поиска условий.
    • Используйте максимум информации: Для локализации важны логи, версия ОС, параметры устройства, тип подключения (Wi-Fi/5G) и даже конкретный оператор связи.

    «Фотография» момента ошибки

    В идеале для исправления нужно получить полное состояние приложения в момент воспроизведения бага. Также критически важны логи взаимодействия: они показывают не только финальную точку, но и весь путь пользователя (какие действия предшествовали сбою). Это помогает понять, как воссоздать подобное состояние снова.

    Совет на будущее: Если вы столкнулись со сложным кейсом, добавьте в этот участок кода расширенную отладочную информацию (debug logging) на случай, если ситуация повторится.


    Проблема «неуловимых» состояний в эпоху AI

    В современных системах, использующих LLM (Large Language Models), классический детерминизм («один вход — один выход») часто нарушается. Вы можете передать абсолютно те же входные данные, но получить другой результат.

    Это происходит из-за недетерминированности современных продакшн-систем:

    • Параллелизм на GPU: Операции с плавающей запятой в GPU не всегда ассоциативны. Из-за параллельного выполнения потоков порядок сложения чисел может незначительно меняться, что влияет на результат.
    • Температура GPU и троттлинг: Скорость выполнения и распределение нагрузки могут зависеть от физического состояния «железа». В огромных моделях эти микроскопические различия накапливаются и могут привести к выбору другого токена на выходе.
    • Динамический батчинг: В облаке ваш запрос объединяется с другими. Разный размер пакета (batch size) меняет математику вычислений в ядрах.

    В таких условиях воспроизвести «то самое состояние» становится практически невозможно. Здесь спасает только статистический подход к тестированию.


    Когда логика бессильна: Проблемы с памятью

    Если вы работаете с «unsafe» языками (C или C++), баг может возникать из-за разрушения памяти (Memory Corruption).

    Это самые тяжелые случаи: ошибка в одном модуле может «затереть» данные в другом. Это приводит к совершенно необъяснимым и единичным сбоям, которые невозможно отследить по обычной логике приложения.

    Как защититься на уровне архитектуры?

    Чтобы избежать таких «мистических» багов, стоит использовать современные подходы:

    • Паттерны многопоточного программирования: Четкая синхронизация исключает состояние гонки (race conditions).
    • Языки с безопасной многопоточностью: Инструменты, гарантирующие безопасность памяти еще на этапе компиляции:
      • Rust: Система владения (Ownership) исключает ошибки памяти.
      • Swift 6 Concurrency: Строгие проверки изоляции данных.
      • Erlang: Полная изоляция процессов через модель акторов.

    Резюме

    Исправление бага — это не про написание нового кода, а про понимание того, как работает старый. Помните: вы можете тратить время на правку ветки, в которую управление даже не заходит. Фиксируйте состояние системы, учитывайте фактор AI-недетерминированности и выбирайте безопасные инструменты.

  • Почему документация — ваш лучший друг

    (и как создавать решения, которые продолжают работать после обновлений)

    «Apps may only use public APIs and must run on the currently shipping OS.» Apple App Review Guidelines

    Если вы когда-либо начинали работу с новым фреймворком и ловили себя на мысли: «Сейчас всё сам пойму, читать документацию — это слишком долго», вы точно не одиноки. У многих из нас срабатывает естественный исследовательский инстинкт: сначала попробовать, и только потом — заглядывать в инструкции. И это совершенно нормально.

    Однако на этом этапе бывает легко увлечься и оказаться в ситуации, где код работает замечательно, но, возможно, опирается на неочевидные особенности системы.

    Почему просто «разобраться самому» иногда бывает недостаточно?

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

    * не описаны в публичной документации;
    * не гарантируют сохранения поведения в будущем;
    * могут измениться с выходом новых версий;
    * могут содержать известные разработчикам особенности, которые пока не исправлены.

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

    Документация — это не ограничение, а надежная опора

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

    * стабильность;
    * поддержку;
    * предсказуемое поведение системы.

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

    Эксперименты? Конечно. Но с пониманием границ.
    Любопытство — прекрасная черта разработчика. Исследовать и пробовать новое абсолютно необходимо. Но здесь есть небольшое пожелание:

    Экспериментировать комфортнее всего с опорой на best practices.

    Документация — это карта, которая показывает, какие пути наиболее безопасны и поддерживаются создателями.

    Взгляд со стороны: советы экспертов

    Часто мы учимся у опытных коллег:

    * они проводят полезные курсы,
    * выступают на конференциях,
    * пишут замечательные книги и блоги,
    * делятся своим уникальным видением.

    Многие из них делятся действительно ценным опытом. Но стоит помнить: если авторские подходы идут вразрез с официальной документацией, они могут оказаться хрупкими.

    Такие «эмпирические паттерны» порой:

    * работают только на конкретной версии фреймворка;
    * чувствительны к обновлениям;
    * могут вести себя непредсказуемо в нестандартных ситуациях.

    Учиться у сообщества — здорово и полезно. Но любые, даже самые авторитетные советы, всегда стоит аккуратно сверять с официальными мануалами.

    Немного о SOLID

    Три идеи из принципов SOLID отлично дополняют этот подход:

    * Open/Closed Principle: старайтесь расширять поведение через публичные API и по возможности не зависеть от скрытой реализации.
    * Liskov Substitution Principle: полагайтесь на контракт, а не на конкретную реализацию. Иначе изменения под капотом могут привести к неожиданным сложностям.
    * Dependency Inversion: стройте зависимости на абстракциях, а не на деталях.

    На практике это значит, что привязка к внутренним, недокументированным деталям фреймворка делает систему хрупкой.
    Опираясь на публичные интерфейсы и контракты, мы получаем:

    * лучшую изоляцию кода от изменений во фреймворке;
    * удобство в тестировании;
    * предсказуемость и надежность архитектуры.

    А если встретился баг?

    Случается и так, что всё сделано по правилам, но результат не соответствует ожиданиям. Фреймворки развиваются и не всегда идеальны. В таких случаях:

    * Соберите минимальный пример, на котором воспроизводится проблема.
    * Убедитесь, что используются только задокументированные API.
    * Отправьте баг-репорт — команда разработчиков наверняка оценит ваш труд и постарается помочь.

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

    Как выжать максимум из фреймворка

    * Обращайтесь к документации.
    * Придерживайтесь гайдов и рекомендаций авторов.
    * Экспериментируйте в пределах описанного функционала.
    * Сверяйте советы из сети с официальными источниками.
    * Локализуйте баги с уважением к контрактам фреймворка.

    Заключение

    Фреймворки — это мощные инструменты со своими правилами игры. Забывая о них, мы рискуем сделать наш код излишне уязвимым. А ведь всем нам хочется, чтобы созданные продукты жили долго и не требовали срочных исправлений после каждого минорного апдейта.

    Мануалы и документация — это отличная поддержка, которая помогает создавать по-настоящему надежные решения.

    Источники

    https://developer.apple.com/app-store/review/guidelines/
    https://en.wikipedia.org/wiki/SOLID
    https://en.wikipedia.org/wiki/API
    https://en.wikipedia.org/wiki/RTFM

  • Сборка C++ SDL приложения для iOS на Linux

    В данной заметке я опишу процедуру сборки C++ SDL приложения для iOS на Linux, подпись ipa архива без платной подписки Apple Developer и установку на чистое устройство (iPad) с помощью macOS без Jailbreak.

    Для начала установим тулчейн сборки для Linux:
    https://github.com/tpoechtrager/cctools-port

    Тулчейн нужно выгрузить из репозитория, далее по инструкции на сайте Godot Engine закончить установку:
    https://docs.godotengine.org/ru/latest/development/compiling/cross-compiling_for_ios_on_linux.html

    На данный момент требуется скачать Xcode dmg и скопировать оттуда sdk для сборки cctools-port. Данный этап проще проходить на macOS, достаточно скопировать из установленного Xcode необходимые файлы sdk. После успешной сборки, в терминале будет путь к тулчейну кросскомпилятора.
    Далее можно приступать к сборке SDL приложения для iOS. Откроем cmake и добавим необходимые изменения для сборки C++ кода:

    SET(CMAKE_SYSTEM_NAME Darwin)
    SET(CMAKE_C_COMPILER arm-apple-darwin11-clang)
    SET(CMAKE_CXX_COMPILER arm-apple-darwin11-clang++)
    SET(CMAKE_LINKER arm-apple-darwin11-ld)
    
    

    Теперь можно собирать с помощью cmake и make, но не забудьте прописать $PATH к тулчейну кросскомпилятора:

    
    PATH=$PATH:~/Sources/cctools-port/usage_examples/ios_toolchain/target/bin
    
    

    Для корректной линковки с фреймворками и SDL прописываем их в cmake, зависимости игры Space Jaguar для примера:

    
    target_link_libraries(
    ${FSEGT_PROJECT_NAME}
    ${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/libclang_rt.ios.a
    ${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/libSDL2.a
    ${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/libSDL2_mixer.a
    ${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/libSDL2_image.a
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/CoreServices.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/ImageIO.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/Metal.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/AVFoundation.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/GameController.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/CoreMotion.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/CoreGraphics.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/AudioToolbox.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/CoreAudio.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/QuartzCore.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/OpenGLES.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/UIKit.framework"
    "${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}/scripts/buildScripts/ios/resources/libs/Foundation.framework"
    )
    
    

    В моем случае библиотеки SDL, SDL_Image, SDL_mixer скомпилированы в Xcode на macOS заранее для статичной линковки; Фреймворки скопированы из Xcode. Также добавлена библиотека libclang_rt.ios.a, которая включает в себя специфические рантайм вызовы iOS, например isOSVersionAtLeast. Включен макрос для работы с OpenGL ES, отключение неподдерживаемых функций в мобильной версии, по аналогии с Android.
    После решения всех проблем сборки, вы должны получить собранный binary для arm. Далее рассмотрим запуск собранного бинарика на устройстве без Jailbreak.
    На macOS произведите установку Xcode, зарегистрируйтесь на портале Apple, без оплаты программы для разработчиков. Добавьте аккаунт в Xcode -> Preferences -> Accounts, создайте пустое приложение и соберите на реальном устройстве. Во время сборки устройство будет добавлено к бесплатному аккаунту разработчика. После сборки и запуска, нужно произвести сборку архива, для этого выберете Generic iOS Device и Product -> Archive. По окончанию сборки архива достаньте из него файлы embedded.mobileprovision, PkgInfo. Из лога сборки на устройство найдите строку codesign с корректным ключом подписи, путь к файлу entitlements с расширением app.xcent, скопируйте его.
    Скопируйте папку .app из архива, замените бинарик в архиве на собранный кросскомпилятором в линуксе (например SpaceJaguar.app/SpaceJaguar), далее добавляем в .app необходимые ресурсы, проверьте сохранность PkgInfo и embedded.mobileprovision файлов в .app из архива, скопируйте заново если необходимо. Переподписываем .app с помощью команды codesign – codesign требует на вход ключ для sign, путь к файлу entitlements (можно переименовать с расширением .plist)
    После переподписывания создайте папку Payload, перенесите туда папку с расширением .app, создайте zip архив с Payload в корне, переименуйте архив с расширением .ipa. После этого в Xcode откройте список устройств и сделайте Drag’n’Drop нового ipa в список приложений устройства; Установка через Apple Configurator 2 для данного способа не работает. Если переподписывание произведено корректно, то приложение с новым бинариком будет установлено на iOS устройство (например iPad) с 7 дневным сертификатом, на период тестирования этого достаточно.

    Источники

    https://github.com/tpoechtrager/cctools-port

    https://docs.godotengine.org/ru/latest/development/compiling/cross-compiling_for_ios_on_linux.html

    https://jonnyzzz.com/blog/2018/06/13/link-error-3/

    https://stackoverflow.com/questions/6896029/re-sign-ipa-iphone

    https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html

  • Сборка для Windows под Ubuntu MinGW CMake

    В данной заметке я опишу процесс сборки библиотек и приложений для Windows с помощью тулчейна MinGW32 на Ubuntu.
    Установим wine, mingw:

    sudo apt-get install wine mingw-w64
    

    После этого уже можно собирать C/C++ приложения под Windows:

    # C
    i686-w64-mingw32-gcc helloWorld.c -o helloWorld32.exe      # 32-bit
    x86_64-w64-mingw32-gcc helloWorld.c -o helloWorld64.exe    # 64-bit
     
    # C++
    i686-w64-mingw32-g++ helloWorld.cc -o helloWorld32.exe     # 32-bit
    x86_64-w64-mingw32-g++ helloWorld.cc -o helloWorld64.exe   # 64-bit
    

    Собранные exe можно проверить с помощью wine.
    Далее рассмотрим изменения сборки CMake, файла CMakeLists.txt, добавляем MinGW специфичные вещи к файлу сборки:

    if (MINGW32)
    set(CMAKE_SYSTEM_NAME Windows)
    SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
    SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
    SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
    set(CMAKE_RANLIB i686-w64-mingw32-ranlib)
    endif()
    
    // для сборки shared dll
    elseif (MINGW32)
    add_library(FlameSteelEngineGameToolkit.dll SHARED ${SOURCE_FILES})
    else()
    
    // обязательно линкуем со всеми зависимостями
    if (MINGW32)
    target_link_libraries(
                            FlameSteelEngineGameToolkit.dll 
                            -static-libgcc
                            -static-libstdc++
                            SDL2 
                            SDL2_mixer 
                            /home/demensdeum/Sources/cube-art-project-bootstrap/FlameSteelFramework/FlameSteelCore/FlameSteelCore.dll
                            /home/demensdeum/Sources/cube-art-project-bootstrap/FlameSteelFramework/FlameSteelBattleHorn/FlameSteelBattleHorn.dll
                            /home/demensdeum/Sources/cube-art-project-bootstrap/FlameSteelFramework/FlameSteelCommonTraits/FlameSteelCommonTraits.dll)
    
    set_target_properties(FlameSteelEngineGameToolkit.dll PROPERTIES
            PREFIX ""
            SUFFIX ""
            LINK_FLAGS "-Wl,--add-stdcall-alias"
            POSITION_INDEPENDENT_CODE 0 # this is to avoid MinGW warning; 
            # MinGW generates position-independent-code for DLL by default
    )
    else()
    

    Собираем:

    cmake -DMINGW32=1 .
    make
    

    На выходе будет dll или exe, смотря что вы собираете. За рабочим примером можете смотреть в репозиторий нового проекта Cube-Art-Project и его библиотеки:
    https://gitlab.com/demensdeum/cube-art-project

    https://gitlab.com/demensdeum/FlameSteelEngineGameToolkitFSGL

    https://gitlab.com/demensdeum/cube-art-project-bootstrap

    Источники
    https://arrayfire.com/cross-compile-to-windows-from-linux/

  • Сборка macOS приложений под Ubuntu OSXCross CMake

    В этой заметке я опишу сборку кросплатформенных C++ приложений для macOS на сборочной машине Ubuntu с использованием CMake и osxcross.
    Для начала устанавливаем тулчейн osxcross:
    https://github.com/tpoechtrager/osxcross
    Установка происходит в 3 этапа, загрузка зависимостей:

    cd tools
    ./get_dependencies.sh
    

    Загрузка XCode.xip с официального сайта Apple, далее выгрузка SDK из XCode:

    ./gen_sdk_package_pbzx.sh /media/demensdeum/2CE62A79E62A4404/LinuxSupportStorage/xcode111.xip
    

    Надеюсь вы прочитали лицензионное соглашение XCode на прошлом шаге? Далее сборка тулчейна с нужным префиксом:

    INSTALLPREFIX=/home/demensdeum/Apps/osxcross ./build.sh 
    

    Теперь можно пользоваться osxcross из директории-префикса прошлого шага. Добавим новый макрос сборки для CMake, пропишем все необходимо:

    if (OSXCROSS)
    SET(CMAKE_SYSTEM_NAME Darwin)
    SET(CMAKE_C_COMPILER o64-clang)
    SET(CMAKE_CXX_COMPILER o64-clang++)
    SET(CMAKE_C_COMPILER_AR x86_64-apple-darwin19-ar)
    SET(CMAKE_CXX_COMPILER_AR x86_64-apple-darwin19-ar)
    SET(CMAKE_LINKER x86_64-apple-darwin19-ld)
    SET(ENV{OSXCROSS_MP_INC} 1)
    endif()
    

    Динамическая линковка мне не удалась, поэтому экспортируем библиотеки статически:

    if (OSXCROSS)
    add_library(FlameSteelCore STATIC ${SOURCE_FILES})
    else()
    

    Далее вы можете столкнуться с фактом того что у вас нет необходимых библиотек для osxcross, с этим я встретился при использовании SDL2. osxcross поддерживает готовые пакеты библиотек – macports. Для примера установка SDL2-mixer:

    osxcross-macports -v install libsdl2_mixer
    

    После этого можно приступать к сборке библиотек/приложений как обычно в связке cmake-make, не забудьте прописать статическую линковку библиотек если необходимо.

    Ручная сборка библиотек

    На текущий момент я встретился с проблемой некорректной архивации библиотек при статической линковке, при сборке итогового приложения получаю ошибку:

    file was built for archive which is not the architecture being linked (x86_64)
    

    Очень похоже на этот тикет, удалось реализовать workaround в результате чего сборка завершается корректно. Разархивируем статическую библиотеку и соберем ее по новой с помощью архиватора osxcross:

    ar x ../libFlameSteelCore.a
    rm ../libFlameSteelCore.a
    x86_64-apple-darwin19-ar rcs ../libFlameSteelCore.a *.o
    

    Также одной из проблем лично я считаю отсутствие возможности запуска приложений macOS сразу на убунту (хотябы с частью функционала), конечно есть проект darling, но поддержка оставляет пока желать лучшего.

    Источники

    https://github.com/tpoechtrager/osxcross

  • Локальная генерация изображений: ComfyUI и модель FLUX

    В наше время не обязательно полагаться на облачные сервисы: вы можете генерировать высококачественные изображения полностью на своем железе. В этой заметке я опишу, как запустить современную модель FLUX локально на вашем компьютере с помощью ComfyUI.

    ComfyUI использует узловую (node-based) архитектуру. Это позволяет:
    — Тотально контролировать каждый этап генерации.
    — Легко обмениваться готовыми «рабочими процессами» (workflows)

    FLUX — модель крупная, поэтому требования к железу выше, чем у SD 1.5 или SDXL:
    Видеокарта (GPU): Nvidia RTX с 12 ГБ VRAM и выше (для комфортной работы). Если у вас 8 ГБ или меньше, придется использовать квантованные версии (GGUF или NF4).
    Оперативная память (RAM): минимум 16 ГБ (лучше 32 ГБ и выше).
    Место на диске: около 20–50 ГБ для моделей и компонентов.

    Самый простой способ запустить FLUX — использовать готовый шаблон. Просто найдите flux text to image в окне workflows и установите.

    Напишите промпт на английском языке в узле `Text to Image (Flux.1 Dev)`, выберите разрешение (FLUX отлично справляется с 1024×1024 и даже выше) и нажмите RUN.

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

    https://github.com/comfyanonymous/ComfyUI

  • Локальный Vibe-кодинг: LM Studio, VS Code и Continue

    Если у вас было желание использовать нейросети для помощи в написании кода (так называемый Vibe-кодинг), и у вас достаточно мощный компьютер, например с видеокартой Nvidia RTX, то вы можете развернуть всю среду абсолютно бесплатно на своей машине. Это решает проблемы с платными подписками и позволяет спокойно работать с проектами под NDA, так как ваш код никуда не отправляется. В этой заметке я опишу, как собрать локальную связку из LM Studio, VS Code и расширения Continue.

    Инструменты для локального Vibe-кодинга

    Для комфортной работы нам понадобятся три основных компонента:
    LM Studio: удобное приложение для загрузки и запуска локальных LLM. Оно берет на себя всю сложность работы с GGUF-моделями и поднимает локальный сервер, совместимый с API OpenAI.
    VS Code: популярный и привычный редактор кода.
    Continue: расширение для VS Code, которое интегрирует нейросети прямо в рабочую среду. Позволяет общаться в чате, выделять код для рефакторинга и поддерживает автодополнение (autocomplete).

    Требования к железу

    Локальные языковые модели требовательны к памяти:
    Видеокарта (GPU): Nvidia с 8 ГБ VRAM и выше (для комфортной работы с моделями на 7-8 миллиардов параметров). Для более тяжелых моделей потребуется от 16 ГБ VRAM.
    Место на диске: около 500 ГБ для хранения разных скачанных моделей.

    Настройка связки

    Процесс настройки достаточно прост и не требует сложных манипуляций в терминале:
    1. Скачайте и установите LM Studio. Во встроенном поиске найдите легковесную модель, например Qwen Coder или gemma3:12b.
    2. В LM Studio перейдите во вкладку Local Server и нажмите Start Server. По умолчанию он запустится на `http://localhost:1234/v1`.
    3. Откройте VS Code и установите расширение Continue из магазина плагинов.
    4. Откройте конфигурационный файл Continue и добавьте новую модель, указав провайдера `openai` и адрес вашего локального сервера из LM Studio.

    После этого вы сможете общаться с локальной LLM прямо в сайдбаре Continue, задавать вопросы по вашему коду и генерировать новые компоненты.

    Почему это работает?

    Как я уже писал ранее, LLM лучше справляются с плоской структурой и WET-кодом (Write Everything Twice). Локальные модели параметров могут уступают гигантам вроде GPT-4 в проектировании сложных архитектур, но для генерации шаблонного кода, рефакторинга простых функций и быстрого прототипирования их возможностей более чем достаточно.

    Кроме того, при локальном Vibe-кодинге ваш код не покидает пределы машины. Это делает такую связку идеальной для корпоративной разработки и работы с чувствительными данными.

    Вывод

    Локальные нейросети не способны полноценно заменить программиста или спроектировать сложную систему. Тем не менее, связка LM Studio + VS Code + Continue дает независимость от облачных сервисов и сохраняет приватность. Это вполне рабочий вспомогательный инструмент для рутинных задач, если вы готовы мириться с ограничениями небольших моделей и самостоятельно контролировать архитектуру проекта.

    Ссылки

    https://code.visualstudio.com/
    https://lmstudio.ai/
    https://continue.dev/

    Источники

    https://youtu.be/IqqCwhG46jY
    https://www.youtube.com/watch?v=7AImkA96mE8

  • Локальная генерация видео: ComfyUI и LTX-2.3

    Раньше создание видео с помощью нейросетей было прерогативой облачных сервисов вроде Runway или Luma. Сегодня, если у вас есть современная видеокарта Nvidia, вы можете генерировать качественные ролики прямо на своем компьютере. В этой заметке я расскажу, как настроить локальную генерацию видео с помощью ComfyUI и эффективной модели LTX-2.3.

    Инструменты для видео-генерации

    Для работы нам понадобятся:
    ComfyUI: мощный интерфейс с узловой архитектурой, который позволяет гибко настраивать процесс генерации.
    LTX-2.3: современная модель от Lightricks, оптимизированная для создания плавных и детализированных видео при относительно умеренных требованиях к видеопамяти.

    Требования к железу

    Генерация видео — процесс куда более ресурсоемкий, чем работа с изображениями:
    Видеокарта (GPU): Nvidia RTX с 8 ГБ VRAM — это необходимый минимум для разрешения 768×512. Для комфортной работы и более высоких разрешений крайне желательно иметь 16–24 ГБ VRAM.
    Оперативная память (RAM): минимум 32 ГБ. Видео-модели и VAE занимают много места при загрузке.
    Место на диске: около 500 ГБ для самой модели и сопутствующих компонентов.

    Настройка и запуск

    Процесс запуска LTX-2.3 в ComfyUI выглядит следующим образом:
    1. Обновите ComfyUI: Модель относительно новая, поэтому убедитесь, что у вас установлена последняя версия интерфейса.
    2. Установите Workflow: Самый простой способ — найти готовый JSON-шаблон для LTX Video. Модель требует специфических узлов для работы с латентным пространством видео.
    3. Промпт и параметры: Введите описание сцены на английском языке. Обратите внимание, что LTX-2.3 хорошо понимает движение (например, «camera orbits around», «fast movement»).

    Почему стоит выбрать LTX-2.3?

    LTX-2.3 примечательна тем, что она дает результат, сопоставимый с закрытыми облачными сервисами, но работает локально. Это дает вам:
    Полную приватность: ваши промпты и сгенерированные видео не уходят на чужие сервера.
    Контроль: вы можете экспериментировать с частотой кадров (FPS), разрешением и силой влияния промпта без необходимости платить за каждую попытку.

    Локальная генерация видео всё еще находится в стадии активного развития, и LTX-2.3 — это отличный входной билет в мир «домашнего Голливуда».

    Ссылки

    https://github.com/comfyanonymous/ComfyUI
    https://huggingface.co/Lightricks/LTX-Video

  • Локальная генерация музыки: ComfyUI и модель ACE-Step-1.5

    В наше время не обязательно полагаться на облачные сервисы для создания контента: вы можете генерировать высококачественную музыку полностью на своем железе. В этой заметке я опишу, как запустить современную модель ACE-Step-1.5 локально на вашем компьютере с помощью ComfyUI.

    ComfyUI использует узловую (node-based) архитектуру. Это позволяет:
    — Тотально контролировать каждый этап генерации аудио.
    — Легко обмениваться готовыми «рабочими процессами» (workflows).

    ACE-Step-1.5 — это продвинутая модель для генерации музыки, требующая значительных вычислительных ресурсов. Требования к железу выше, чем у многих простых синтезаторов:
    Видеокарта (GPU): Nvidia RTX с 8 ГБ VRAM и выше (рекомендуется 12 ГБ+) для комфортной работы при высоком качестве.
    Оперативная память (RAM): минимум 16 ГБ (лучше 32 ГБ и выше).
    Процессор (CPU): Современный многоядерный процессор с хорошей поддержкой AVX/CUDA вычислений.
    Место на диске: около 20–50 ГБ для моделей и компонентов.

    Самый простой способ запустить ACE-Step-1.5 — использовать готовый шаблон аудиогенерации. Просто найдите music text to audio в окне workflows и установите.

    Напишите промпт, описывающий жанр и настроение (например, «uplifting synthwave track with heavy bass»), в узле `Prompt Input`. Укажите желаемую длительность и нажмите RUN.
    Первая генерация может занять время, так как модели будут загружаться в память видеокарты и обрабатывать сложные акустические паттерны.

    https://github.com/comfyanonymous/ComfyUI
    https://www.youtube.com/watch?v=UAlLD5fS7-c

  • Локальные нейросети с помощью ollama

    Если у вас было желание запустить подобие ChatGPT и у вас достаточно мощный компьютер, например с видеокартой Nvidia RTX, то тогда вы можете запустить проект ollama, который позволит использовать одну из готовых LLM моделей, на локальный машине, абсолютно бесплатно. ollama обеспечивает возможность общения с LLM моделями, на манер ChatGPT, также в последней версии объявлена возможность прочтения изображений, форматирование выходных данных в формат json.

    Сам проект я запускал также и на макбуке с процессором Apple M2, и мне известно что поддерживаются последние модели видеокарт от AMD.

    Для установки на macOS зайдите на сайт ollama:
    https://ollama.com/download/mac

    Нажмите «Download for macOS», у вас загрузится архив вида ollama-darwin.zip, внутри архива будет Ollama.app который нужно скопировать в «Applications». После этого запускайте Ollama.app, скорее всего при первом запуске произойдет процесс установки. После этого в трее вы увиделе иконку ollama, трэй это справа сверху рядом с часами.

    После этого запускайте обычный терминал macOS, и набирайте команду загрузки, установки и запуска любой модели ollama. Список доступных моделей, описания, их характеристик можно увидеть на сайте ollama:
    https://ollama.com/search

    Выбирайте модель с наименьшим количеством параметров, если она не влезает в вашу видеокарту на запуске.

    Для примера команда запуска модели llama3.1:latest:

    ollama run llama3.1:latest
    

    Установка для Windows и Linux в целом похожа, в одном случае будет установщик ollama и дальнейшая работа с ней через Powershell.
    Для Linux установка производится скриптом, однако я рекомендую использовать версию конкретно вашего пакетного менеджера. В Linux ollama запустить также можно через обычный терминал bash.

    Источники
    https://www.youtube.com/watch?v=Wjrdr0NU4Sk
    https://ollama.com

  • Стабилизация видео с помощью ffmpeg

    Если вы хотите стабилизировать видео и убрать дрожание камеры, инструмент `ffmpeg` предлагает мощное решение. Благодаря встроенным фильтрам `vidstabdetect` и `vidstabtransform`, можно добиться профессионального результата без использования сложных видеоредакторов.

    Подготовка к работе

    Прежде чем начать, убедитесь, что ваш `ffmpeg` поддерживает библиотеку `vidstab`. В Linux это можно проверить командой:

    bash  
    ffmpeg -filters | grep vidstab  
    

    Если библиотека не установлена, её можно добавить:

    sudo apt install ffmpeg libvidstab-dev  
    

    Установка для macOS через brew:

    brew install libvidstab
    brew install ffmpeg
    

    Теперь перейдём к процессу.

    Шаг 1: Анализ движения

    Сначала нужно провести анализ движения видео и создать файл с параметрами стабилизации.

    ffmpeg -i input.mp4 -vf vidstabdetect=shakiness=10:accuracy=15 transfile=transforms.trf -f null -  
    

    Параметры:

    shakiness: Уровень дрожания видео (по умолчанию 5, можно увеличить до 10 для более сложных случаев).
    accuracy: Точность анализа (по умолчанию 15).
    transfile: Имя файла для сохранения параметров движения.

    Шаг 2: Применение стабилизации

    Теперь можно применить стабилизацию, используя файл трансформаций:

    ffmpeg -i input.mp4 -vf vidstabtransform=input=transforms.trf:zoom=5 output.mp4
    

    Параметры:

    input: Указывает на файл с параметрами трансформации (созданный на первом шаге).
    zoom: Коэффициент масштабирования для устранения черных краев (например, 5 — автоматическое увеличение до устранения артефактов).

  • Вычислительные машины Тьюринга

    Представляю вашему вниманию перевод первых страниц статьи Алана Тьюринга – “О ВЫЧИСЛИМЫХ ЧИСЛАХ С ПРИЛОЖЕНИЕМ К ПРОБЛЕМЕ РАЗРЕШЕНИЯ” 1936 года. Первые главы содержат описание вычислительных машин, которые в дальнейшем стали основой для современной вычислительной техники.

    Полный перевод статьи и пояснение можно прочитать в книге американского популяризатора Чарлза Петцольда, под названием “Читаем Тьюринга. Путешествие по исторической статье Тьюринга о вычислимости и машинах Тьюринга” (ISBN 978-5-97060-231-7, 978-0-470-22905-7)

    Оригинальная статья:
    https://www.astro.puc.cl/~rparra/tools/PAPERS/turing_1936.pdf

    О ВЫЧИСЛИМЫХ ЧИСЛАХ С ПРИЛОЖЕНИЕМ К ПРОБЛЕМЕ РАЗРЕШЕНИЯ

    А. М. ТЬЮРИНГ

    [Получено 28 мая 1936 г. — Прочитано 12 ноября 1936 г.]

    «Вычислимые» (computable) числа могут быть кратко описаны как действительные числа, выражения которых в виде десятичных дробей исчислимы (calculable) конечным числом средств. Хотя на первый взгляд в данной статье как вычислимые рассматриваются именно числа, почти так же легко определять и исследовать вычислимые функции целой переменной, действительной переменной, вычислимой переменной, вычислимые предикаты и тому подобное. Однако же, фундаментальные проблемы, связанные с указанными вычислимыми объектами, в каждом случае одни и те же. Для детального рассмотрения в качестве вычислимого объекта я выбрал именно вычислимые числа потому, что методика их рассмотрения наименее громоздкая. Надеюсь в скором времени описать взаимоотношения вычислимых чисел с вычислимыми функциями и так далее. При этом будут проведены исследования в области теории функций действительной переменной, выраженной в терминах вычислимых чисел. По моему определению, действительное число является вычислимым, если его представление в виде десятичной дроби может быть записано машиной.

    В параграфах 9 и 10 я привожу некоторые доводы, чтобы показать, что вычислимые числа включают в себя все числа, которые естественно считать вычислимыми. В частности, я показываю, что некоторые большие классы чисел вычислимы. Они включают, например, действительные части всех алгебраических чисел, действительные части нулей функций Бесселя, числа π, e и прочие. Однако вычислимые числа включают в себя не все определимые числа, в подтверждение чего приведен пример определимого числа, которое не является вычислимым.

    Хотя класс вычислимых чисел очень велик и во многих отношениях похож на класс действительных чисел, он все же поддается перечислению, то есть является перечислимым (enumerable). В §8 я рассматриваю определенные доводы, которые, казалось бы, доказывают обратное предположение. При корректном применении одного из этих доводов делаются выводы, на первый взгляд, аналогичные выводам Геделя*. Данные результаты имеют чрезвычайно важные способы применения. В частности, как показано ниже (§11), не может иметь решения проблема разрешения.

    В своей недавней статье Алонзо Черч** представил идею «способности поддаваться эффективному исчислению» (effective calculability), которая эквивалентна моей идее «вычислимости» (computability), но имеет совершенно иное определение. Черч также приходит к аналогичным выводам относительно проблемы разрешения. Доказательство эквивалентности «вычислимости» и «способности поддаваться эффективному исчислению» изложено в приложении к настоящей статье.

    1. Вычислительные машины

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

    Сопоставим человека в процессе вычисления действительного числа с машиной, которая способна выполнять только конечное число условий q1, q2, …, qR; назовем эти условия «m-конфигурациями». Данная (то есть так определенная) машина снабжена «лентой» (аналогом бумаги). Такая лента, проходящая через машину, разделена на секции. Назовем их «квадратами». Каждый такой квадрат может содержать какой-то «символ». В любой момент существует и при том только один такой квадрат, скажем, r-й, содержащий символ который находится «в данной машине». Назовем такой квадрат «отсканированным символом». «Отсканированный символ» — это единственный такой символ, о котором машина, образно выражаясь, «непосредственно осведомлена». Однако при изменении своей m-конфигурации машина может эффективно запоминать некоторые символы, которые она «увидела» (отсканировала) ранее. Возможное поведение машины в любой момент определяется m-конфигурацией qn и отсканированным символом***. Назовем данную пару символов qn, «конфигурацией». Обозначенная таким образом конфигурация определяет возможное поведение данной машины. В некоторых из таких конфигураций, в которых отсканированный квадрат является пустым (т. е. не содержит символа), данная машина записывает новый символ на отсканированном квадрате, а в других из таких конфигураций она стирает отсканированный символ. Данная машина также способна перейти к сканированию другого квадрата, но так она может переместиться лишь на соседний квадрат вправо или влево. В дополнение к любой из этих операций можно изменить m-конфигурацию машины. При этом некоторые из записанных символов сформируют последовательность цифр, являющуюся десятичной частью вычисляемого действительного числа. Остальные из них представят собой не более чем неточные отметки с тем, чтобы «помочь памяти». При этом стиранию могут подвергаться лишь вышеупомянутые неточные отметки.

    Я утверждаю, что рассматриваемые здесь операции включают в себя все те операции, которые используются при вычислении. Обоснование данного утверждения легче понять читателю, имеющему представление о теории машин. Поэтому в следующем разделе я продолжу развивать рассматриваемую теорию, опираясь на понимание значения терминов «машина», «лента», «отсканированный» и т. д.

    *Гедель «О формально неразрешимых предложениях «Принципов математики» (опубликованных Уайтехдом и Расселом в 1910, 1912 и 1913 гг.) и родственных систем, часть I», журнал по мат. физике, ежемесячный бюллетень на немецком языке № 38 (за 1931 год , стр. 173-198.
    ** Алонзо Черч, «Неразрешимая проблема элементарной теории чисел», American J. of Math., («Американский журнал математики»), № 58 (за 1936 год), стр. 345-363.
    *** Алонсо Черч, «Замечание о проблеме разрешения», J. of Symbolic Logic («Журнал математической логики»), №1 (за 1936 год), стр. 40-41