Автор: demensdeum

  • maimat: массовое сжатие и изменение размеров изображений

    maimat (Mass Images Manipulation Tool) — это инструмент с открытым исходным кодом, предназначенный для пакетной обработки изображений: изменения размеров и сжатия. Приложение написано на Python 3.10+ и использует ImageMagick в качестве движка обработки.

    Ссылки

    https://github.com/zefir1990/maimat

  • 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 градусов.

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

  • Aleka — кроссплатформенное приложение для рисования на Flutter

    Aleka — это лёгкое, быстрое приложение для рисования, написанное на Flutter. Оно работает везде: в браузере, на десктопе (Windows, macOS, Linux) и на мобильных устройствах (iOS, Android).

    Под капотом — чистый Dart, Material 3 и внимание к деталям.

    Возможности

    • Рисование от руки: плавные штрихи с квадратичной интерполяцией Безье.
    • Палитра из 15 цветов: быстрый выбор с визуальной индикацией.
    • Размер кисти: регулируется слайдером от 1 до 30 px.
    • Отмена (Undo): шаг назад по вашим штрихам.
    • Очистка холста: одним нажатием.
    • Заливка (Flood Fill): BFS с tolerance для сглаженных краёв.
    • Сохранение: формат .aleka (JSON).
    • Загрузка: открывайте ранее сохранённые рисунки и продолжайте.
    • Экспорт PNG: захват холста в 3x разрешении.
    • 🎬 Режим анимации: покадровая анимация с временной шкалой:
      • Добавление и удаление кадров, каждый со своим рисунком.
      • Длительность кадра от 50 мс до 5 с.
      • Смена FPS: 6, 8, 12, 15, 24, 30 или 60.
      • Экспорт в MP4 (через ffmpeg на десктопе, ffmpeg.wasm в браузере).
    • Тёмная и светлая тема: Material 3, следует за системой.

    Почему Flutter?

    Flutter позволяет писать одно приложение для шести платформ без дублирования кода. Aleka использует только нативные возможности Dart и Flutter SDK и минимум сторонних зависимостей: file_picker, image для работы с пикселями при заливке, ffmpeg_wasm для экспорта видео в браузере.

    Архитектура

    Проект придерживается принципов чистой архитектуры и SOLID:

    • PaintCanvasController — управляет состоянием штрихов и заливки через паттерн Listener/Observer.
    • PaintToolbar — UI-компонент палитры, ползунка и кнопок.
    • AlekaFile — сериализация/десериализация в JSON, захват PNG.
    • MovieController — модель кадров и состояния анимации.
    • VideoExport — инкапсулирует логику кодирования MP4 (десктоп/веб).

    Функции ввода-вывода (saveStrokes, loadStrokes, capturePng и др.) сделаны injectable — их можно заменять на моки при тестировании. В проекте 79 тестов: проверка сериализации, отмены, загрузки/сохранения, экспорта PNG и видео, модели кадров и временной шкалы.

    Формат файла .aleka

    Файл .aleka — это читаемый JSON, который можно открыть в любом текстовом редакторе:

      "aleka": "1.0",
      "strokes": [
        {
          "color": 4278190080,
          "strokeWidth": 3.0,
          "points": [[100.0, 200.0], [150.0, 250.0]]
        }
      ]
    }
    

    Каждый штрих хранит цвет (ARGB32), толщину и массив точек. Формат версионирован полем aleka.

    Режим анимации

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

    Алгоритм экспорта перебирает все кадры, захватывает их через RepaintBoundary, собирает PNG-байты и передаёт в энкодер. На десктопе вызывается системный ffmpeg, в браузере используется ffmpeg.wasm — полноценный порт ffmpeg в WebAssembly, работающий прямо в песочнице браузера.

    Заливка (Flood Fill)

    Реализация заливки использует поиск в ширину (BFS) с допуском по цвету (_kFillTolerance = 1000). Это позволяет корректно обрабатывать сглаженные края штрихов — заливка не вытекает за контур, но захватывает полупрозрачные пиксели на границе. Для пустого холста создаётся сплошная заливка без лишних вычислений.

    Попробовать

    Aleka доступна в вебе и как нативное приложение:

    demensdeum.com/software/aleka/

    Исходный код открыт под лицензией MIT:

    github.com/demensdeum/Aleka

  • Mama Calendar — кроссплатформенное приложение для напоминаний

    Mama Calendar — это кроссплатформенное приложение для событий и напоминаний, написанное на React Native (Expo) с двумя реализациями бэкенда: Node.js + MongoDB и PHP + MariaDB.

    Приложение позволяет создавать события с эмодзи-категоризацией, выбирать тип повторения (однократно, ежегодно, ежемесячно, еженедельно, ежедневно) и просматривать важные события на ближайшие 3 дня на отдельной вкладке «Important Events».

    Стек технологий

    Фронтенд написан на React Native 0.86 через Expo SDK 57 с TypeScript, Expo Router для навигации и react-native-reanimated для анимаций. Для иконок используется expo-symbols (SF Symbols на iOS, Material иконки на Android/Web).

    Бэкенд реализован в двух вариантах:

    • Node.js: Express 4, MongoDB 8 через нативный драйвер, самописная аутентификация с scrypt + salt, ручное управление токенами. Docker Compose поднимает клиент (nginx), сервер и MongoDB.
    • PHP: PHP 8.2 без фреймворков, PDO + MariaDB 11, bcrypt для хеширования паролей, свой роутер и PSR-4 автолоадинг через Composer.

    Функции приложения

    • Регистрация и авторизация: простая система с username/password и Bearer-токенами
    • CRUD событий: создание, просмотр, редактирование и удаление событий с датой, эмодзи и типом повторения
    • Умная фильтрация: вкладка Important Events показывает события на ближайшие 3 дня с учетом правил повторения. Например, ежегодные события показывают ближайшее годовое вхождение, ежемесячные — по дню месяца, еженедельные — по дню недели
    • Эмодзи-пикер: 20 предустановленных эмодзи для быстрой категоризации событий
    • Подсветка сегодняшних событий: события на сегодня выделяются красным фоном (#B71C1C)
    • Тёмная тема: автоматическое определение системной цветовой схемы с отдельными палитрами для светлой и тёмной темы
    • Интернационализация: русский и английский языки через React Context
    • Анимации: анимированный сплэш-скрин с Keyframe API и упругой интерполяцией, анимированная иконка приложения с вращающимся свечением
    • Админ-эндпоинты: управление пользователями, токенами и очистка базы через мастер-токены

    Почему две реализации бэкенда?

    Node.js версия является основной, но PHP вариант существует как альтернатива для более классического хостинга. API полностью идентичен, что позволяет переключаться между ними без изменения клиентского кода.

    Инфраструктура

    Весь стек поднимается через Docker Compose: клиент собирается через мультистейдж билд (Expo export → nginx alpine), сервер на Node.js, MongoDB 8. Для PHP-версии есть отдельный compose-файл с MariaDB 11 и phpunit для тестов.

    Сборка веб-версии автоматизирована PowerShell-скриптом, который патчит API_URL перед expo export и восстанавливает оригиналы после.

    Вывод

    Mama Calendar — это полнофункциональное кроссплатформенное приложение, которое покрывает полный цикл: от мобильного и веб-фронтенда на React Native до двух вариантов серверной части. Проект интересен своей архитектурой, использованием современных возможностей Expo SDK и двойной реализацией бэкенда.

    Ссылки

    https://github.com/zefir1990/Mama-Calendar
    https://demensdeum.com/software/mama-calendar/events

  • Портирование 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

  • Donki Hills

    Donki Hills — это приключенческий комедийный хоррор от первого лица, в котором игроку предстоит погрузиться в загадочную историю, сочетающую напряженную атмосферу с элементами неожиданного юмора.
    Главный герой Джеймс отправляется на поиски своей интернет-знакомой Марии, связь с которой внезапно оборвалась. Единственной уликой является случайная фотография, указывающая на отдаленную деревню Доньки Хиллс в Новосибирской области. Движимый желанием докопаться до истины, Джеймс начинает собственное расследование, чтобы выяснить все обстоятельства исчезновения Марии.

    Игра доступна в Steam:
    https://store.steampowered.com/app/3476390/Donki_Hills/

  • Masonry AR

    Masonry AR — это геолокационная многопользовательская игра с элементами дополненной реальности (AR), погружающая вас в мир тайных обществ. Исследуйте улицы вашего города, собирайте масонские книги знаний, основывайте собственные ложи и соревнуйтесь за влияние на карте реального мира.

    Ключевые особенности

    • Геолокационный геймплей: передвигайтесь в реальном мире, используя GPS вашего устройства для поиска секретных книг и ресурсов.
    • Режим автоходьбы (Autowalk): если доступ к GPS ограничен, вы можете запустить режим автоходьбы, выбрав в качестве отправной точки одну из мировых столиц.
    • Создание лож: основывайте масонские ложи на реальной карте и расширяйте влияние вашего ордена.
    • Внутриигровая экономика: зарабатывайте игровую валюту (MOS), развивайте свои территории и делитесь реферальными ссылками с друзьями.
    • Кроссплатформенность: игра работает непосредственно в веб-браузерах на мобильных устройствах и ПК благодаря игровому движку Flame Steel Engine 2 с рендерингом на базе Three.js.

    Играть:
    https://demensdeum.com/games/masonry-ar/client/

    GitHub:
    https://github.com/zefir1990/Masonry-AR

  • Teflecher


    Teflecher — это быстрое, интерактивное, кроссплатформенное приложение-квиз, созданное на основе Kotlin Multiplatform (KMP) и Compose Multiplatform. Оно позволяет пользователям интуитивно загружать викторины из локальных JSON-файлов или удаленных URL-адресов, отвечать на вопросы с несколькими вариантами ответа, мгновенно видеть обратную связь о правильности ответов и отслеживать свои результаты.

    Web:
    https://demensdeum.com/software/teflecher/

    GitHub:
    https://github.com/zefir1990/teflecher

    Также редактор квизов формата Teflecher Editor на основе технологий Ionic + Capacitor

    Web:
    https://demensdeum.com/software/teflecher-editor/

    GitHub:
    https://github.com/zefir1990/teflecher-editor

  • Ghost Contacts


    Ghost Contacts — это простое веб-приложение, созданное с целью скрыть ваши контакты от стандартных системных API и телефонных книг. Вся информация хранится исключительно локально в вашем браузере и не передается на внешние сервера.

    Основные возможности

    • Скрытие от системных API: Ваши контакты не синхронизируются со стандартными системными API контактов и телефонной книгой устройства.
    • Экстренный пароль (Panic Password): Специальный пароль, при вводе которого вся база контактов моментально и безвозвратно удаляется.
    • Импорт и экспорт: Удобный перенос базы контактов через файлы формата CSV для создания резервных копий.

    Приложение онлайн:
    https://demensdeum.com/software/ghost-contacts/

    GitHub:
    https://github.com/demensdeum/GhostContacts

  • Cube Art Project 2

    Добро пожаловать в Cube Art Project 2 — медитативный трехмерный холст, где вы можете дать волю своему воображению. Создавайте воксельные картины, экспериментируйте с цветами и воплощайте уникальные 3D-модели прямо в вашем браузере.

    Что такое Cube Art Project 2?

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

    Ключевые особенности

    • Трехмерное рисование: расслабляющий творческий процесс, сфокусированный на создании воксельного искусства и 3D-геометрии.
    • Палитра цветов: точная настройка оттенков каждого блока с помощью удобных RGB-слайдеров.
    • Свобода перемещения: исследуйте свои картины под любым углом с помощью удобного управления камерой.
    • Сохранение холстов: сохраняйте ваши работы в файлы и возвращайтесь к рисованию в любое время, либо делитесь своими работами с другими.

    Управление

    • WASD — перемещение камеры
    • Мышь — вращение камеры и осмотр
    • Интерфейс (GUI) — выбор и настройка цвета

    Играть:
    https://demensdeum.com/software/cube-art-project-2/

    GitHub:
    https://github.com/zefir1990/cube-art-project-2

  • Raiden Video Ripper

    Raiden Video Ripper — это проект с открытым исходным кодом, предназначенный для редактирования видео и конвертации форматов. Он создан с использованием Qt 6 (Qt Creator) и позволяет осуществлять монтаж и конвертировать видео в форматы MP4, GIF и WebM. Вы также можете извлекать аудио из видео и конвертировать его в формат MP3.

    Microsoft Store:
    https://apps.microsoft.com/detail/9nvzjs98smgc

    GitHub:
    https://github.com/demensdeum/RaidenVideoRipper/releases

  • Mars Miners

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

    Что такое Mars Miners?

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

    Ключевые особенности

    • Тактическая стратегия: планируйте развитие базы и захват территории, просчитывая ходы соперников наперед.
    • Автономные юниты: координируйте действия роботов-добытчиков и настраивайте их логику для максимальной эффективности.
    • Разнообразные режимы: оттачивайте свои навыки на одиночных учебных полигонах или соревнуйтесь с другими колонистами в многопользовательском режиме.
    • Продвинутый ИИ: ведите борьбу за ресурсы против умных автоматонов, которые не прощают тактических ошибок.

    Играть в Mars Miners

  • Flame Steel: Death Mask 2

    В бескрайних, залитых холодным светом коридорах индустриальной мегаструктуры вас ждет новое испытание. Мы рады представить Flame Steel: Death Mask 2 — трехмерный dungeon crawler, сочетающий классическую эстетику с современным игровым процессом в реальном времени.

    Что такое Flame Steel: Death Mask 2?

    Представьте, что вы просыпаетесь в процедурно генерируемом лабиринте, где за каждым поворотом может скрываться враждебная сущность «Фильтр». В Flame Steel: Death Mask 2 вы примерите на себя роль Искателя, исследующего мир, построенный на движке Flame Steel Engine 2 (с графическим рендером Three.js).

    Ключевые особенности

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

    Технологии под маской

    Игра создана для браузера и использует:

    • Frontend: чистый JavaScript и движок Flame Steel Engine 2 (с графическим рендером Three.js) для плавного трехмерного рендеринга.
    • Backend: Node.js для работы серверной части.
    • Инфраструктура: MongoDB для постоянного хранения данных и Redis для пространственного индексирования в реальном времени.

    Играть в Flame Steel: Death Mask 2

  • Ushki Radio

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


    https://demensdeum.com/software/ushki-radio

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

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

    Технически проект построен на React Native и Expo, поэтому работает как в браузере, так и в виде нативного приложения. Под капотом используется expo-av для воспроизведения аудио, а пользовательские настройки хранятся локально. Есть поддержка нескольких языков, включая русский и английский.

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

    GitHub:
    https://github.com/demensdeum/Ushki-Radio

    Google Play:
    https://play.google.com/store/apps/details?id=com.demensdeum.ushkiradio

  • Glazki TV: Современный плеер для интернет-телевидения

    Glazki TV — это современный, высокопроизводительный плеер для интернет-телевидения (IPTV), построенный на базе React Native и Expo. Проект ориентирован на простоту использования и скорость работы, предоставляя удобный интерфейс для просмотра IPTV-каналов как на мобильных устройствах, так и в браузере.

    Основные возможности

    • Просмотр каналов: Просматривайте тысячи каналов, разделенных по категориям для удобной навигации.
    • Поиск: Быстро находите нужные каналы по названию.
    • Избранное: Сохраняйте любимые каналы для быстрого доступа (данные сохраняются локально).
    • Deep Linking: Делитесь прямыми ссылками на каналы, которые открываются автоматически.
    • Поддержка тем: Интерфейс автоматически адаптируется к системной темной или светлой теме.
    • Веб-поддержка: Плеер полностью функционален в браузере с синхронизацией URL.

    Технологический стек

    В основе проекта лежат современные инструменты разработки:

    • Framework: React Native + Expo
    • Video Player: expo-video (замена устаревшему expo-av)
    • UI Toolkit: react-native-paper
    • Playlist Parser: iptv-playlist-parser

    Веб версия:
    https://demensdeum.com/software/glazki-tv/

    Google Play версия:
    https://play.google.com/store/apps/details?id=com.demensdeum.glazkitv

  • Zefir1990


    Zefir1990 — Илья Прохоров, являюсь разработчиком с более чем 15-летним стажем коммерческой разработки. Основатель студии Demens Deum, занимающейся разработкой игр и приложений для мобильных, веб, десктоп систем. Первая 3D OpenGL ES 2 игра Mad Racer на Android 2 была выпущена в 2010 году, на проекте был программистом и дизайнером игры, также привлек к разработке композитора Антона Дмитриева (coolspotdreamer), после успешного запуска игры занимался заказной разработкой full-time и проектной в рамках контрактов. В числе клиентов — Декатлон, Playboy, Fitbit.

    Также являюсь автором статей на тему разработки программного обеспечения, игр, паттернов проектирования, алгоритмов, AI, в планах написать книгу об энтропии программного обеспечения.

    Предпочитаемые языки программирования: ASM, C, C++, ObjC, Python, Kotlin, Swift, Java, Rust, Go, TypeScript, JavaScript, C#, Dart, PHP.

    LinkedIn: linkedin.com/in/zefir1990
    GitHub: github.com/zefir1990
    Telegram: t.me/zefir1990
    Email: ceo@demensdeum.com
    Twitch: twitch.tv/zefir1990
    Youtube: youtube.com/zefir1990