Files
kam-mobile/README.md
T
admin_d 7063d1b1c9
Sync changed files to Google Drive / sync (push) Successful in 1h45m13s
sync: restore source from Google Drive
2026-09-12 16:50:30 +05:00

220 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 потребует отдельно настроенной эмуляции; это не основной путь этого теста.
```bash
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-версии игры:
1. Получает официальный Docker-образ инструментов CGE. При первом запуске фиксирует его неизменяемый digest в `config/toolchain.lock.json`; при следующих использует его же.
2. Загружает **только текстовые исходники** KaM по commit `962fb850324b79bbe5480e1c2087d98f83a60917` и исходники PascalScript по gitlink из этого commit. Полный checkout, история Git, release-архивы и игровые ресурсы не скачиваются.
3. Создаёт 15 изолированных Android-проектов: компилирует и полностью линкует каждый, продолжая остальные проверки после ошибки одной подсистемы.
4. По умолчанию упаковывает три ключевых проекта в APK, когда их линковка успешна: `platform`, `core_types`, `integration`.
5. Сохраняет результаты, конкретные ошибки, версии инструментов, идентификаторы исходников и архив журналов без содержимого ресурсов.
**Системные инструменты сборки — бинарные программы и будут скачаны 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. Результаты и коды возврата
Начинайте с:
```text
reports/LATEST-SUMMARY.md
reports/LATEST.json
```
Полный результат конкретного запуска:
```text
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
```
При успешной упаковке:
```text
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:
```bash
./build-android.sh --local
```
`--local` означает использовать инструменты сервера; **target остаётся Android**. `castle-engine`, `fpc`, Java, Android SDK/NDK и cross-compiler должны быть согласованно настроены. Стенд не устанавливает SDK через root и не изменяет системную конфигурацию.
Повторный запуск с уже загруженным и проверенным кодом:
```bash
./build-android.sh --no-fetch
```
Только проверка Android shell и типов:
```bash
./build-android.sh --profiles platform,core_types
```
Получить APK для каждой успешно слинкованной пробы:
```bash
./build-android.sh --package-all
```
Другие Android ABI, отдельные запуски:
```bash
./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. Ресурсы — позже, на вашем сервере
Для исходной проверки сборки этот раздел можно полностью пропустить.
Положите рядом каталоги установленной игры, сохранив имена и регистр:
```text
/srv/kam-r16020/
data/
SpriteResource/
Maps/
MapsMP/
Campaigns/
Tutorials/
```
Содержимое собираете вы из соответствующих установок. Стенд не получает игровые файлы из сети. В Docker папка монтируется read-only; в отдельные сборочные каталоги помещаются её точные копии.
```bash
./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-устройством:
```bash
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. Проверка самого стенда
```bash
./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. Структура
```text
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 through `KaM_Remake.inc`; forcing it globally also changed Castle Game Engine units and broke `CastleLocalizationGetText` before any KaM code was compiled.
- Source inventory now reads Pascal files with `utf-8-sig`, so UTF-8 BOM files such as `src/game/KM_Game.pas` are recognized.
- Added regression tests for both failures.