Complete BigTask
Sync changed files to Google Drive / sync (push) Successful in 1m34s

This commit is contained in:
admin_d committed 2026-09-14 20:47:20 +05:00
1 parent 15a968a2f7
commit b52921e171
38 files changed
+564 -2956

No files matched your search

+38 -198
View File
@@ -1,219 +1,59 @@
# KaM r16020 — Android Architecture Probe 0.3.1
# KaM Remake Mobile
**Кодовый тест архитектуры: KaM core + Free Pascal + Castle Game Engine → Android.**
This repository is the Android development baseline for the KaM Remake r16020 port. Its upstream authority is KaM Remake r16020, commit `962fb850324b79bbe5480e1c2087d98f83a60917`. It is the permanent single-application build, source, and resource baseline for later port work; it is not yet a complete playable game.
Здесь нет desktop target, готовой игры, игровых бинарных ресурсов или собственного заменителя KaM core. Тест не требует `data/` для проверки компиляции и линковки. Он проверяет, какие **настоящие исходные модули r16020** можно включить в Android-библиотеку вместе с Castle и где возникают конкретные препятствия.
## Build
**Архив содержит код стенда и автоматизацию, не заранее собранный 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 потребует отдельно настроенной эмуляции; это не основной путь этого теста.
The one supported entrypoint is:
```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-версии игры:
Supported options are `--local`, `--cpu {aarch64,arm,x86_64}`, `--no-fetch`, and `--timeout <positive seconds>`.
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. Сохраняет результаты, конкретные ошибки, версии инструментов, идентификаторы исходников и архив журналов без содержимого ресурсов.
- `--local` uses host tooling while keeping the Android target unchanged.
- `--cpu` selects an ABI for the same application identity.
- `--no-fetch` requires the pinned vendor source to already be present and verified.
- `--timeout` is the per-external-tool-invocation timeout.
**Системные инструменты сборки — бинарные программы и будут скачаны Docker на сервере. Запрет на скачивание игровых бинарных ресурсов соблюдён; полностью автономный комплект SDK/NDK/FPC в этот ZIP не вложен.** Полный оригинальный код KaM также не вложен: его автоматически получает серверный загрузчик по фиксированному commit. В архиве нет ссылок на изменяемый `master` KaM.
Each build is one permanent Castle application transaction. Read `out/current/build.json` for its finalized state. On `PASS`, the current package is described by `out/current/package.json` and is at `out/current/kam-mobile.apk`.
`config/toolchain.lock.json` появляется при первом реальном получении Docker-образа, а не содержит выдуманный digest. Для одинакового окружения на другом сервере перенесите этот lock вместе с проектом. Сам первый выбор CGE-образа зависит от даты запуска; KaM всегда зафиксирован на r16020.
`build/<build_id>/` is transient working state. Its useful logs are `build/<build_id>/logs/compile.log`, `build/<build_id>/logs/package.log`, and, when apksigner is available and invoked, `build/<build_id>/logs/signature.log`.
## 2. Что проверяется
## Source and resources
| Проба | Реальные модули / граница | По умолчанию |
|---|---|---|
| `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 |
Pinned vendor source is at `vendor/kam_remake`. Project-owned source adaptation and registration are centralized, in order, in `config/extra-paths.json` and `tools/source_resolution.py`. Do not edit generated working manifests for source paths. `code/` is the permanent project-owned application source root; Pascal units enter through normal dependency closure from `GameInitialize`.
Никаких `test_shims`, пустых `KM_*.pas` вместо оригиналов или самостоятельно переписанных MAP/RXX readers в сборочных проектах нет. Модули с транзитивными зависимостями компилируются как есть; их ошибка не скрывается.
Private runtime-resource contents live under `private-assets/`. `config/runtime-resources.json` owns selection and `tools/resource_staging.py` owns staging. Selected files preserve their exact relative paths into Castle data. Proprietary game contents are not committed to public Git, and this baseline neither converts nor repacks them.
Используется один уже существующий upstream define: **`DBG_SKIP_SECURE_AUTH`**. Он отключает необязательный приватный модуль аутентификации multiplayer, недоступный в обычном исходном комплекте. Это локальный Android-проект, не тест сетевого сервиса. Define записывается в каждый соответствующий `target.json`. Остальные игровые подсистемы не отключаются для получения зелёного отчёта.
The permanent application definition is `app/CastleEngineManifest.xml`: `kam_mobile`, `org.kammobile.kamremake`, and `GameInitialize`.
Линковка не отключена через `-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`.
## Optional device helper
## 3. Результаты и коды возврата
After a successful current build, optionally run:
Начинайте с:
```bash
python3 tools/device.py [--serial <device-serial>]
```
It validates the current metadata and APK, selects the authorized device, installs, and launches the application.
## Current versus historical state
`out/current/**` is the only current finalized application/package state. `reports/**` and `dist/**` are frozen Task-1 historical evidence; files named `LATEST` there are historical pointers, not current build or package locators. Do not use them when the current build is missing or failed.
## Repository structure
```text
reports/LATEST-SUMMARY.md
reports/LATEST.json
app/ permanent application definition
code/ permanent project-owned application source
config/ source and runtime-resource owners
tools/ build, source-resolution, resource-staging, and device tools
private-assets/ private runtime-resource contents
vendor/ pinned vendor source
build/ generated transient working state
out/ generated current finalized state
reports/ frozen Task-1 history
dist/ frozen Task-1 history
```
Полный результат конкретного запуска:
```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.