KaM r16020 — Android Architecture Probe 0.3.1
Кодовый тест архитектуры: KaM core + Free Pascal + Castle Game Engine → Android.
Здесь нет desktop target, готовой игры, игровых бинарных ресурсов или собственного заменителя KaM core. Тест не требует data/ для проверки компиляции и линковки. Он проверяет, какие настоящие исходные модули r16020 можно включить в Android-библиотеку вместе с Castle и где возникают конкретные препятствия.
Архив содержит код стенда и автоматизацию, не заранее собранный APK. Во время подготовки проверены Python-скрипты и их контрольные сценарии. Настоящая компиляция Pascal/Android здесь не выполнялась: FPC, Castle, Docker и ADB в среде подготовки отсутствовали. Подробнее: reports/preparation/VALIDATION.md.
1. Запуск на сервере — без ресурсов
Требуются Linux x86_64 или Linux-среда WSL2, Bash, Python 3.10+, работающий Docker и доступ в интернет. Папка проекта должна быть доступна на запись. На сервере ARM64 Docker-образ Linux/amd64 потребует отдельно настроенной эмуляции; это не основной путь этого теста.
unzip kam-android-architecture-probe-r16020.zip
cd kam-android-architecture-probe-r16020
chmod +x build-android.sh test-harness.sh
./build-android.sh
Команда выполняет весь Android ARM64 цикл, а не сборку Linux-версии игры:
- Получает официальный Docker-образ инструментов CGE. При первом запуске фиксирует его неизменяемый digest в
config/toolchain.lock.json; при следующих использует его же. - Загружает только текстовые исходники KaM по commit
962fb850324b79bbe5480e1c2087d98f83a60917и исходники PascalScript по gitlink из этого commit. Полный checkout, история Git, release-архивы и игровые ресурсы не скачиваются. - Создаёт 15 изолированных Android-проектов: компилирует и полностью линкует каждый, продолжая остальные проверки после ошибки одной подсистемы.
- По умолчанию упаковывает три ключевых проекта в APK, когда их линковка успешна:
platform,core_types,integration. - Сохраняет результаты, конкретные ошибки, версии инструментов, идентификаторы исходников и архив журналов без содержимого ресурсов.
Системные инструменты сборки — бинарные программы и будут скачаны Docker на сервере. Запрет на скачивание игровых бинарных ресурсов соблюдён; полностью автономный комплект SDK/NDK/FPC в этот ZIP не вложен. Полный оригинальный код KaM также не вложен: его автоматически получает серверный загрузчик по фиксированному commit. В архиве нет ссылок на изменяемый master KaM.
config/toolchain.lock.json появляется при первом реальном получении Docker-образа, а не содержит выдуманный digest. Для одинакового окружения на другом сервере перенесите этот lock вместе с проектом. Сам первый выбор CGE-образа зависит от даты запуска; KaM всегда зафиксирован на r16020.
2. Что проверяется
| Проба | Реальные модули / граница | По умолчанию |
|---|---|---|
platform |
CGE + FPC: Android shell, системные потоки, файловые пути, zlib, изображение, input, audio API | Compile + native link + APK |
core_types |
KM_CommonTypes, KM_Points; настоящие функции координат |
Compile + native link + APK |
core_streams |
KM_CommonClasses; настоящая сериализация и зависимости |
Compile + native link |
mission_tokens |
KM_MissionScript |
Compile + native link |
mission_info |
KM_MissionScript_Info |
Compile + native link |
terrain_io |
KM_TerrainUtils |
Compile + native link |
sprite_loader |
KM_ResSprites и его реальные зависимости |
Compile + native link |
terrain_pathfinding |
KM_Terrain и его реальные зависимости |
Compile + native link |
mission_world |
KM_MissionScript_Standard |
Compile + native link |
simulation |
KM_Game как исходный модуль, не desktop executable |
Compile + native link |
script_vm |
uPSCompiler, uPSRuntime из закреплённого PascalScript |
Compile + native link |
scripting |
KM_ScriptingEvents |
Compile + native link |
legacy_render |
KM_Render, диагностика прежнего backend |
Compile + native link; необязательная проба |
legacy_audio |
KM_Sound, диагностика прежнего backend |
Compile + native link; необязательная проба |
integration |
Основные корни KaM вместе с Castle в одной Android-библиотеке | Compile + native link + APK |
Никаких test_shims, пустых KM_*.pas вместо оригиналов или самостоятельно переписанных MAP/RXX readers в сборочных проектах нет. Модули с транзитивными зависимостями компилируются как есть; их ошибка не скрывается.
Используется один уже существующий upstream define: DBG_SKIP_SECURE_AUTH. Он отключает необязательный приватный модуль аутентификации multiplayer, недоступный в обычном исходном комплекте. Это локальный Android-проект, не тест сетевого сервиса. Define записывается в каждый соответствующий target.json. Остальные игровые подсистемы не отключаются для получения зелёного отчёта.
Линковка не отключена через -Cn. Стенд запрашивает пересборку (-B), отключает smart linking/удаление неиспользуемых секций и включает проверку undefined symbols. Это намеренно более строгая проверка зависимостей, чем пустой вызов одной функции с выброшенным остальным кодом. Проверяются свежие корневые .ppu, ELF нужного ABI, отсутствие DT_TEXTREL, структура APK и его native dependencies. Если упаковщик удалил только debug symbols, библиотека сопоставляется по неизменным allocated sections и program headers, а не ошибочно отклоняется из-за другой полной SHA-256. Подпись APK проверяется apksigner, когда он найден; иначе проверка подписи помечена NOT_RUN.
3. Результаты и коды возврата
Начинайте с:
reports/LATEST-SUMMARY.md
reports/LATEST.json
Полный результат конкретного запуска:
reports/runs/<build-id>/SUMMARY.md
reports/runs/<build-id>/result.json
reports/runs/<build-id>/<profile>/compile-link.log
reports/runs/<build-id>/<profile>/package.log
reports/runs/<build-id>/source-inventory.json
reports/runs/<build-id>/evidence.zip
При успешной упаковке:
dist/<build-id>/kam_probe_platform-aarch64-debug.apk
dist/<build-id>/kam_probe_core_types-aarch64-debug.apk
dist/<build-id>/kam_probe_integration-aarch64-debug.apk
dist/LATEST.json
Каждый APK появляется только если соответствующая проба действительно собрана и упакована. Ошибка integration не удаляет успешно полученный platform APK. Старые артефакты лежат в своих каталогах build-id и не засчитываются в новый результат.
| Итог | Exit code | Значение |
|---|---|---|
ANDROID_BUILD_GATE_PASS |
0 | Все обязательные Android compile/link-пробы и три обязательных APK прошли. Runtime ещё не подразумевается. |
NOT_BUILDABLE_AS_IS |
1 | Обязательная проба встретила ошибку компиляции, линковки или упаковки. Смотреть конкретный журнал. |
BLOCKED |
2 | Проверке мешает отсутствующий инструмент, исходник, окружение или другой незавершённый этап. Не успех. |
PARTIAL_SELECTION |
2 | Выбрана лишь часть профилей. Даже успешный platform APK не считается подтверждением всего core. |
Отдельные неудачи legacy_render/legacy_audio не требуют сохранения старых backend и не проваливают gate сами по себе. Но если эти зависимости реально входят в обязательный KaM-корень, ошибка будет видна и заблокирует этот корень.
PASS означает только указанную проверку. Компиляция KM_Game не означает, что экономика/AI уже запущены, и ошибка Graphics не означает «весь KaM нужно переписать». Результат даёт конкретную точку для небольшого Android-адаптера, доработки или подключения существующей библиотеки. Матрица интерпретации есть в SUMMARY.md и docs/COVERAGE.md.
4. Другие режимы
Уже установленный CGE/FPC Android toolchain, без Docker:
./build-android.sh --local
--local означает использовать инструменты сервера; target остаётся Android. castle-engine, fpc, Java, Android SDK/NDK и cross-compiler должны быть согласованно настроены. Стенд не устанавливает SDK через root и не изменяет системную конфигурацию.
Повторный запуск с уже загруженным и проверенным кодом:
./build-android.sh --no-fetch
Только проверка Android shell и типов:
./build-android.sh --profiles platform,core_types
Получить APK для каждой успешно слинкованной пробы:
./build-android.sh --package-all
Другие Android ABI, отдельные запуски:
./build-android.sh --cpu arm
./build-android.sh --cpu x86_64
Android x86_64 — вариант для соответствующего Android-устройства/эмулятора, не десктопная сборка. Успех одного ABI не засчитывается за другой.
Пути к дополнительному исходному пакету или Android native libraries задаются в config/extra-paths.json. Пути относительно корня проекта предпочтительны, чтобы одинаково работать внутри Docker и снаружи. По умолчанию списки пусты. Стенд не подставляет другую библиотеку автоматически и не принимает extra path, который обнаруженно перекрывает оригинальный KaM unit.
5. Ресурсы — позже, на вашем сервере
Для исходной проверки сборки этот раздел можно полностью пропустить.
Положите рядом каталоги установленной игры, сохранив имена и регистр:
/srv/kam-r16020/
data/
SpriteResource/
Maps/
MapsMP/
Campaigns/
Tutorials/
Содержимое собираете вы из соответствующих установок. Стенд не получает игровые файлы из сети. В Docker папка монтируется read-only; в отдельные сборочные каталоги помещаются её точные копии.
./build-android.sh --assets /srv/kam-r16020
Это добавляет ресурсы в упаковываемые KaM-пробы (core_types, integration, либо выбранные с --package-all). Независимый platform остаётся без игровых ресурсов. Для каждой копии на сервере проверяется SHA-256. При запуске Android получает файлы из assets и копирует в приватный каталог приложения для обычных TFileStream-путей, проверяя размер копии. Никакой конвертации .map/.dat/.rxx нет.
Добавление файлов не запускает миссию автоматически. Этот режим проверяет доставку данных и нативные файловые пути, а не полноценное декодирование/создание мира. Runtime checksum оригинальных ресурсов и штатные загрузки мира не заявлены как выполненные проверки этого стенда. Большой комплект может заметно увеличить APK, время инициализации и занятое место; для проверки сборки он не нужен.
Не передавайте проприетарные файлы через публичный Git. private-assets/, vendor/, build/, dist/ исключены в .gitignore. В evidence.zip содержимого ресурсов нет, но имена/размеры/хеши могут присутствовать в metadata — просмотрите их перед публичной публикацией.
6. Запуск APK на Android — дополнительный этап
Для ответа «собирается ли выбранная архитектура?» достаточно серверного compile/link/package-отчёта. Проверка запуска — отдельное свидетельство.
На машине с ADB и одним авторизованным Android-устройством:
python3 tools/device.py --profile platform --exercise-lifecycle
python3 tools/device.py --profile core_types --exercise-lifecycle
python3 tools/device.py --profile integration --exercise-lifecycle
Указывать профиль имеет смысл только после получения его APK. Несколько устройств: добавьте --serial <serial>. Скрипт устанавливает/обновляет только выбранное тестовое приложение, запускает его и читает приватный отчёт через run-as. Старый runtime.json этого теста удаляется перед запуском; ресурсы, настройки игры и сохранения не очищаются. ADB не запускается внутри стандартного Docker build-контейнера.
В APK: процедурная клеточная картинка, drag/pinch/tap, кнопки сохранения отчёта и звука. Автоматически проверяются ABI, native-файлы/seek, FPC zlib, поток и frame callbacks. В профильных APK вызываются настоящие KMPoint/KMPointRight; в core_streams и integration — TKMemoryStreamBinary. Успешное достижение UI также показывает, что unit initialization импортированного набора не прервало запуск.
Вывод находится в reports/device/<timestamp>/. Видимое изображение, удобство жестов и слышимый звук требуют наблюдения: возвращение SoundEngine.Play не подменяет проверку звука. КаМ-terrain, здания и симуляция этим APK не изображаются.
7. Проверка самого стенда
./test-harness.sh
Это Python unit/integration tests инструментария без сети, Docker и ресурсов. Они проверяют выбор исходников, пути, gate, генерацию проектов, ELF/APK parser, отказ при старом/неверном артефакте, отказ при пустом выводе компилятора, продолжение после ошибки и приватность evidence.
Сквозные контрольные тесты используют явно помеченные временные test doubles компилятора/ELF/APK. Это тестирование управления сборкой, не эмуляция настоящего KaM и не доказательство компиляции Pascal. Test doubles существуют только в TemporaryDirectory; в реальные targets и результаты Android они не попадают.
8. Структура
build-android.sh Единственная точка входа сборки
code/ Общий Android/CGE runtime стенда
tools/ Загрузка исходников, 15 targets, сборка, аудит, ADB
config/profiles.json Корни проверяемых подсистем
config/upstream.json Зафиксированная база
config/extra-paths.json Явно добавленные зависимости (изначально пусто)
tests/ Тесты инструментария; не игровое ядро
reports/preparation/ Проверки, реально выполненные при подготовке ZIP
docs/ Границы доказательств, источники, разбор ошибок
vendor/ Источники появляются при запуске на сервере
private-assets/ Необязательное закрытое место ваших данных
CastleEngineManifest.xml, ProbeBuild.pas, ProbeImports.pas создаются отдельно для каждого профиля в build/<build-id>/<profile>/. Корень ZIP сам по себе не является одним CGE-проектом; запускайте build-android.sh, а не castle-engine compile без target из корня.
Полноценный порт не требуется для этого теста. Следующее решение принимается по реальному серверному отчёту: устранить обнаруженный общий блокер и повторить те же Android-пробы, не переписывать работающие игровые подсистемы заранее.
0.3.1 — correction after first server report
- Removed global FPC
-Mdelphi. KaM units already select Delphi mode throughKaM_Remake.inc; forcing it globally also changed Castle Game Engine units and brokeCastleLocalizationGetTextbefore any KaM code was compiled. - Source inventory now reads Pascal files with
utf-8-sig, so UTF-8 BOM files such assrc/game/KM_Game.pasare recognized. - Added regression tests for both failures.