Эксплуатационное руководство: умения, взаимодействия с миром, объекты, добыча, ремесло и жильё

Консолидированный источник для эксплуатации. Состояние сверено с исходным кодом и numbered migrations на 2026-07-15. Если после этой даты код, SQL или wire-контракты изменятся, они имеют приоритет над этим текстом; руководство следует обновить вместе с изменением.

1. Назначение, охват и текущий статус

Документ предназначен для разработчика, release-инженера и оператора GameServer/client content. Он описывает единую вертикаль: skills/effects, contextual actions и World Interaction (WI), интерактивные объекты, corpse loot, craft, labor/actability, skill plots, farming, housing, quest/item/spawn integration, протокол, БД, конфигурацию, упаковку и эксплуатационное восстановление.

Текущий статус: implementation-complete в заявленном scope и statically reviewed. Это не означает, что система собрана, протестирована, мигрирована, наполнена production content, проверена в runtime или готова к production.

2. Архитектурный контракт

2.1 Авторитетность client/server

Сервер является единственным источником истины для eligibility, target, range, area/layer, phase, ownership, permissions, inventory, money, labor, cooldowns, quest state, loot participants, craft products, placement geometry и результата commit. Клиент показывает server-issued DTO и отправляет намерение с opaque token; local SQLite, mesh, resource path, template ID или UI state не дают права mutation.

Общий lifecycle мутации:

Validate -> Reserve -> Revalidate -> Commit -> Publish

2.2 Владение потоками

Физический WorldMutationLane — единственный BNF SessionProcessThread, последовательно потребляющий session_queue_. I/O и DB workers передают immutable DTO/completion; они не меняют gameplay objects. CArea — логический owner domain, не отдельный thread:

AreaOwnerKey = (serverInstanceId, zoneId, areaId, areaEpoch)

areaEpoch меняется для новой incarnation/load area. Timer хранит IDs и expected state, а callback лишь ставит команду owner lane. Долгоживущие CPC*, CNPC*, CItem*, object pointers и lambdas с ними в queue/timer/DB payload запрещены.

2.3 Identity, generation, revision и epoch

Поле Назначение
runtimeId:u64 Opaque process/server-instance identity; не NPC index, pointer, template или persistent ID.
generation:u32 Runtime incarnation; 0 недопустим. Защищает от reuse/stale handle.
persistentId:u64 PostgreSQL identity durable object.
persistentGeneration:u32 Durable incarnation при delete/recreate.
revision:u32 Начинается с 1, растёт после gameplay-visible committed mutation; проверяется перед commit.
areaEpoch Incarnation logical area owner; late completion старой area отбрасывается.
object snapshotEpoch:u64 Client cache scope для Object v2+; marker предшествует CREATE/STATE/REMOVE.

Generation не заменяет revision, revision не заменяет identity. При угрозе wrap объект выводится из публикации и получает новую incarnation; переход через 0 запрещён.

2.4 Транзакции, reservations, идемпотентность и recovery

3. Подсистемы

3.1 Skills и effects

3.2 Context actions и WI

Family 1 выдаёт bounded server-issued action list: semantic, target incarnation, opaque session token, icon/content, localization slots, enabled/reason, priority, expiry/range. Клиент не вычисляет доступность. Execution повторно проверяет descriptor session, generation/revision, world/area/layer/range, lease и action allowlist.

Native WI operations (Use, Loot, CraftStart, CraftAct, Build и подключённые farming operations) выбираются явным registry. Persisted WorldInteractionContentId — opaque numeric ID; string reflection и автоматическое group-to-handler mapping запрещены. Unsupported mapping не исполняется.

3.3 Интерактивные объекты

Immutable templates и phase graph загружаются из SQLite, валидируются по references/cycles/bounds и публикуются atomic snapshot. Runtime manager владеет IDs, phase, permissions, timers, revision, persistence и area recovery. Static spawn identity использует устойчивую пару t_npc_regen.a_index + slot, а не runtime ID.

Create проходит PendingCreate -> durable commit -> Active/revision 1 -> publish. Delete отзывает tokens/timers, выполняет tombstone CAS и только затем remove/unregister/free. Persistence failure не маскируется исчезновением объекта.

3.4 Corpse/container loot

Monster death идёт через единый generation sink: main/job/all/raid/event/hardcoded/quest/money. В capability-gated area создаётся отдельный corpse runtime object, не удаляемый CNPC*. Personal quest entries отделены. Party policy: RANDOM/BATTLE — nearby roll, FIRSTGET — first-get, OPENBOX — loot master; default без специальных настроек — server-side roll среди nearby eligible участников.

Действия: «Поднять всё» (LootAll) и «Просмотреть» (LootBrowse); окно поддерживает individual take, take-all, close и updates. Take-all — bounded набор независимых per-entry commits, поэтому возможен PARTIAL_SUCCESS. Corpse mode включается лишь для allowlisted NPC template и при unanimity family 1+2+3 в area; иначе используется ровно один legacy ground path. Одна смерть никогда не генерирует оба вида loot.

3.5 Craft

Recipe разрешён только через current workbench lease, range, generation/revision, pack membership и rollout gate. Материалы планируются по всем usable non-worn stacks; grade policy поддерживает exact/upper/wildcard и main-grade inheritance. Products могут быть multiple/probabilistic; rolls фиксируются один раз server-side на iteration.

До delay и перед commit проверяются money, level, proficiency, materials, output stacking/slots и labor. Repeat ограничен 1..20, каждая iteration имеет новый key и отдельный commit. Cancel/death/logout/zone transfer освобождают hold. Quest/proficiency/appellation/log публикуются после irreversible commit. Converted recipe не исполняется через legacy 90/13.

3.6 Labor и actability

Существуют раздельные account и character current/max/recovery pools. Debit: character first, account remainder. Проверка суммы атомарна; compensation возвращает exact исходный split. Family 7 синхронизирует оба pools; client bars — presentation, не authority. Expert ranks берутся из expert_limits; gains применяются только после committed operation.

3.7 Plots

skills.plot_id NULL/0 сохраняет linear legacy skill. Allowlisted plot исполняет validated graph; events/end публикуются family 5. WI nodes требуют family 1 и конкретный authoritative adapter. Delay/cancel принадлежат одному lifecycle.

3.8 Farming

Legacy NPC_CROPS подключается только при exact template binding; иначе остаётся legacy produce fallback. Growth/climate/cutdown, water/feed, planted persistence и harvest/butcher rewards требуют explicit empty-by-default rows. Deadlines durable UTC, recovery bounded; harvest reward и quest event защищены outbox/exactly-once. Missing probabilistic/loot-pack binding — content-disabled, не implicit reward.

3.9 Housing и land plots

Housing использует общую object state machine, PostgreSQL plots/journals и operator-reviewed deployment geometry. Placement требует Housing v2+, Object v3 (а v3+ Housing — Object v4), accepted client/server visual catalog и server-issued catalog row. Preview ничего не резервирует; commit заново проверяет polygon, exclusions, runtime object/NPC/terrain collision, owner limits и DB state.

Build stages/materials, permission, decoration recovery, protection, tax, demolition и recovery имеют durable boundaries. States: 1 UnderConstruction, 2 Complete, 3 Demolished (финальный tombstone). Housing v5 несёт allowedPermissionMask; current permission может не входить в destinations mask.

Action value 2 (ReservedAddDecoration) зарезервирован и не публикуется: отсутствуют authoritative decoration bounds и server-issued item/template placement catalog. Клиентские IDs/radius принимать запрещено.

3.10 Quests, items, spawn, admin и hardening

4. Справочник протокола

4.1 Transport и envelope

Текущий endpoint ContractRevision = 12 в обеих копиях WorldInteractionWireContract.h.

outerType       u8  = 90 (MSG_CUSTOM_MESSAGE)
customType      i32 = 14 (MSG_WORLD_INTERACTION_PROTOCOL)
envelopeVersion u8  = 1
family          u8
familyVersion   u16
messageKind     u8
requestId       u32
payloadLength   u16
payload         byte[payloadLength]

Little-endian, без raw structs/bool/size_t/pointers. Полный packet ≤6000, payload ≤5984, minimum envelope 16 bytes. payloadLength обязан точно совпасть; trailing bytes запрещены. Gameplay requestId ненулевой и per-connection monotonic; 0 — negotiation/unsolicited events.

4.2 Families, versions, dependencies и kinds

ID Family Versions Dependency Message kinds
0 Control 1 0 HELLO, 1 OFFER, 2 SELECT, 3 RESULT
1 Interaction 1 0 ActionList, 1 ActionRequest, 2 ActionResult, 255 Error
2 Object 1–4 Interaction 1 0 Create, 1 State, 2 Remove, 3 SnapshotEpoch, 255 Error
3 Loot 1 Interaction 1 + Object 1 0 Appear, 1 Update, 2 Disappear, 3 OpenRequest, 4 OpenList, 5 TakeRequest, 6 TakeResult, 7 CloseRequest, 8 CloseResult, 9 RollRequest, 10 RollResult, 255 Error
4 Craft 1 Interaction 1 0 CatalogRequest, 1 Catalog, 2 StartRequest, 3 Start, 4 Progress, 5 Result, 6 CancelRequest, 7 Cancel, 8 RepeatRequest, 9 Repeat, 255 Error
5 SkillPlot 1 независим; WI node требует Interaction 1 0 Event, 1 End, 255 Error
6 Housing 1–5 Interaction 1 + Object 1; visual constraints ниже 0 SnapshotRequest, 1 Snapshot, 2 PreviewIntent, 3 PreviewResult, 4 CommitRequest, 5 PlacementResult, 6 ManagementRequest, 7 ManagementResult, 8 CatalogRequest, 9 Catalog, 255 Error
7 Labor 1 0 Snapshot, 1 Update, 255 Error

Object: v1 без epoch; v2 добавляет epoch; v3 revision-based visual catalog; v4 catalog identity. Housing: v1 только snapshot/management compatibility; v2 placement catalog/revision; v3 identity; v4 preview correlation; v5 permission destinations mask. Housing v2 требует Object ≥3; Housing v3–v5 требуют Object 4 и server-issued catalog.

4.3 Semantic IDs

ID Значение
1 Pickup
2 QuestAccept
3 QuestTurnIn
4 NpcUse
5 ObjectUse
6 LootAll
7 LootBrowse
8 HousingManage/OpenHousing
9 HousingPlace

8/9 baseline-disabled: они требуют синхронную доставку client/server revision 12, SQLite 0059, ready deployment/backend и reviewed source rows. Их нельзя включать только из-за наличия UI.

4.4 Legacy ABI и fallback

Negotiation RESULT statuses: 0 SELECTED, 1 NOT_OFFERED, 2 NO_COMMON_VERSION, 3 DEPENDENCY_MISSING, 4 SERVER_DISABLED, 5 INVALID_FLAGS. Gameplay errors: 0 OK, 1 MALFORMED_PACKET, 2 UNSUPPORTED_ENVELOPE_VERSION, 3 UNSUPPORTED_FAMILY_VERSION, 4 CAPABILITY_REQUIRED, 5 UNKNOWN_MESSAGE_KIND, 6 INVALID_REQUEST, 7 NOT_FOUND_OR_EXPIRED, 8 STALE_REVISION, 9 NOT_AUTHORIZED, 10 OUT_OF_RANGE_OR_CONTEXT, 11 CONFLICT_OR_BUSY, 12 RATE_LIMITED, 13 INVENTORY_OR_CAPACITY, 14 SERVER_UNAVAILABLE, 15 PARTIAL_SUCCESS.

5. Точная карта исходников

Client

Server

EntitiesMP, XML и tools

6. PostgreSQL lc_game/0001..0046

Порядок строго lexical внутри только lc_game. db_migrate — PostgreSQL-only runner с schema_migrations; он не обслуживает SQLite. Ниже purpose соответствует filename/DDL scope.

Exact file Назначение
0001 0001_schema_migrations.sql Локальная PostgreSQL history table.
0002 0002_character_progress_tables.sql Ability/quest/buff/quickslot/stash/inventory/wear progression persistence.
0003 0003_character_pets_and_runtime_tables.sql Pets, pet inventory/AI, cooldown/timer/runtime auxiliary rows.
0004 0004_social_event_appellation_tables.sql Friends/block/notices/events и appellation state.
0005 0005_guild_core_tables.sql Guild/member/stash/notice/mark/tax/battle core.
0006 0006_commerce_express_trade_agent_tables.sql Express, trade agent, item info/likes/returns.
0007 0007_world_castle_trigger_tables.sql Castle/join/guards/towers/reinforce/dungeon/trigger persistence.
0008 0008_event_ranking_cube_tables.sql Event/ranking/cube/ball data and backups.
0009 0009_subhelper_ops_tables.sql Extended slots, reserved GM commands, GM operation rows.
0010 0010_event_raid_misc_tables.sql Remaining event/raid/misc legacy persistence.
0011 0011_character_core_table.sql t_characters core and indexes.
0012 0012_character_aux_runtime_tables.sql Character auxiliary runtime state.
0013 0013_character_actability_and_premium_logs.sql Actability/expert and premium logs.
0014 0014_character_birthday_event_table.sql Birthday event state.
0015 0015_royal_rumble_log_table.sql Royal-rumble log.
0016 0016_chat_log_table.sql Chat log.
0017 0017_rock_paper_scissors_tables.sql RPS event state/logs.
0018 0018_combo_creation_log_table.sql Combo creation audit.
0019 0019_ranking_backup_history_keys.sql Ranking backup/history keys.
0020 0020_inventory_socket_column.sql Inventory socket persistence extension.
0021 0021_legacy_2007_event_tables.sql Legacy 2007 event tables.
0022 0022_teacher_list_integer.sql Teacher-list integer compatibility.
0023 0023_legacy_defaults.sql Legacy-compatible defaults.
0024 0024_interactive_object_state.sql Durable interactive object identity/state/revision/deadline.
0025 0025_authoritative_labor_pools.sql Account/character labor pools и holds.
0026 0026_farming_object_state.sql Farming object lifecycle/persistence.
0027 0027_housing_plot_state.sql Housing plot ownership/geometry/state.
0028 0028_housing_lifecycle_and_recovery.sql Permissions, lifecycle, journals/outbox/recovery; требуется для persisted Family membership.
0029 0029_quest_item_spawn_integration.sql Committed quest WI, item-spawn action/object integration.
0030 0030_farming_lifecycle_rewards.sql Farming rewards/outbox/exactly-once lifecycle.
0031 0031_housing_economy_adapters.sql Tax/build/demolition economy persistence adapters.
0032 0032_labor_special_effect_idempotency.sql Labor special-effect idempotency.
0033 0033_housing_demolition_command_identity.sql Durable demolition command identity.
0034 0034_craft_request_idempotency_session.sql Craft request/session idempotency.
0035 0035_durable_craft_operation_journal.sql Craft operation journal/reservations.
0036 0036_durable_craft_recovery.sql Recovery claims/leases/compensation metadata.
0037 0037_character_state_revision_save_fence.sql Character revision/save-generation fence.
0038 0038_durable_craft_progression_outbox.sql Durable progression/appellation/log publication.
0039 0039_durable_craft_quest_publication.sql Concrete quest intent/result outbox.
0040 0040_durable_craft_operation_lease.sql Operation lease fencing.
0041 0041_character_authoritative_owner.sql DB-generated owner generation/token и login ownership.
0042 0042_housing_character_state_revision_fence.sql Housing mutation vs character state revision fence.
0043 0043_housing_recovery_scheduler_backoff.sql Housing retry timestamps/errors/backoff.
0044 0044_housing_durable_intent_descriptor.sql Canonical durable housing intent descriptor.
0045 0045_housing_object_permission_mode.sql Explicit object permission mode/principal.
0046 0046_housing_plot_finite_bounds.sql Finite/non-inverted persisted plot bounds constraints.

Специальные preconditions

  1. 0001..0046 применяются по порядку; feature binary не запускается до требуемой schema.
  2. Перед 0039: остановить новые craft starts, drain старым совместимым binary, read-only подтвердить 0 pending legacy kind-1 rows без concrete intent. Не синтезировать intent.
  3. До binary с lease fencing применить 0040; перед 0041 остановить старых writers. Authoritative-owner binary запрещён до 0041.
  4. 0042..0046 — NOT APPLIED prerequisites для housing recovery/current binary; old writers остановить.
  5. 0044 маркирует legacy journal intent как невосстановимый и replay fail-closed.
  6. 0045 обязана fail на invalid Family/Guild principal; не заменять Public fallback.
  7. 0046 обязана fail на non-finite/inverted existing bounds; auto-repair запрещён.

Source-verified PostgreSQL runner interface (пример не запускался; connection string — только <PLACEHOLDER>):

db_migrate.exe --conn "<PLACEHOLDER>" --dir "E:\LC\Unchained\Project\Server\Sources\db\migrations\lc_game" --dry-run
db_migrate.exe --conn "<PLACEHOLDER>" --dir "E:\LC\Unchained\Project\Server\Sources\db\migrations\lc_game"

7. Server SQLite manual stream 0001..0060

Важно: db_migrate SQLite не поддерживает. Нет runner/history/checksum/status/adoption. Все scripts применяет оператор вручную/offline, строго один раз и по номеру, к одной writable staging copy при остановленных GameServer/SubHelper/всех consumers. До работы — byte-for-byte backup и staging; после — integrity review и упаковка единственного artifact.

Exact file Назначение
0001 0001_add_wi_groups.sql WI group identities.
0002 0002_add_wi_group_wis.sql WI group-to-content memberships.
0003 0003_add_wi_details.sql Distance/labor/proficiency execution policy.
0004 0004_add_doodad_almighties.sql Interactive-object templates.
0005 0005_add_doodad_func_groups.sql Object phase/function groups.
0006 0006_add_doodad_func_uses.sql Concrete use-action payload.
0007 0007_add_doodad_func_timers.sql Timed phase-transition payload.
0008 0008_add_doodad_funcs.sql Polymorphic action graph; explicit discriminator registry.
0009 0009_add_doodad_phase_funcs.sql Phase-to-function graph.
0010 0010_add_item_grade_distributions.sql Loot item-grade distributions.
0011 0011_add_loot_packs.sql Loot pack roots.
0012 0012_add_loots.sql Loot entries.
0013 0013_add_loot_groups.sql Loot groups and zone-group policy.
0014 0014_add_loot_actability_groups.sql Actability-gated loot grouping.
0015 0015_add_loot_pack_dropping_npcs.sql NPC-template to loot-pack mapping/default pack.
0016 0016_add_matcher_impl_sql_wheres.sql Stored matcher predicates; text хранится, но не исполняется как SQL.
0017 0017_add_matcher_impl_operators.sql Matcher operator payloads.
0018 0018_add_matchers.sql Matcher tree/parent identities.
0019 0019_add_drop_rules.sql Drop rules.
0020 0020_add_drop_rule_loot_packs.sql Rule-to-pack links.
0021 0021_add_doodad_func_loot_items.sql Object function direct-item reward payload.
0022 0022_add_doodad_func_loot_packs.sql Object function loot-pack payload.
0023 0023_add_gain_loot_pack_item_effects.sql Loot-pack item effect payload.
0024 0024_alter_crafts_add_catalog_metadata.sql Extend existing crafts with catalog/WI/workbench metadata.
0025 0025_alter_craft_categories_add_catalog_metadata.sql Add workbench-only flags to existing category tables.
0026 0026_alter_craft_materials_add_grade_metadata.sql Add main/upper-grade roles to existing materials.
0027 0027_add_craft_lines.sql Craft catalog lines.
0028 0028_add_craft_line_components.sql Line/rank recipe components.
0029 0029_add_craft_packs.sql Workbench craft packs.
0030 0030_add_craft_pack_crafts.sql Pack-to-recipe memberships.
0031 0031_add_doodad_func_craft_packs.sql Object workbench function payload.
0032 0032_add_plots.sql Skill-plot identities.
0033 0033_add_plot_events.sql Plot events.
0034 0034_add_plot_conditions.sql Reusable plot conditions.
0035 0035_add_plot_event_conditions.sql Event-to-condition links.
0036 0036_add_plot_aoe_conditions.sql Event-to-AoE-condition links.
0037 0037_add_plot_effects.sql Polymorphic plot-effect links.
0038 0038_add_plot_next_events.sql Directed event edges/branches.
0039 0039_alter_skills_add_plot_id.sql Optional skills.plot_id; NULL keeps linear behavior.
0040 0040_add_climates.sql Climate identities.
0041 0041_add_zone_climates.sql Zone-climate policy rows.
0042 0042_add_zone_climate_elems.sql Zone-to-climate element links.
0043 0043_add_zones.sql Zone climate-policy contract.
0044 0044_add_doodad_func_growths.sql Growth function payload.
0045 0045_add_doodad_func_climate_reacts.sql Climate reaction payload.
0046 0046_add_doodad_func_cutdownings.sql Cutdown/harvest lifecycle payload.
0047 0047_add_housing_sizes.sql Housing footprint-size rows.
0048 0048_add_housings.sql Housing templates/categories/limits.
0049 0049_add_housing_groups.sql Housing groups and tax-delay policy.
0050 0050_add_housing_areas.sql Logical activated housing areas; geometry остаётся config data.
0051 0051_add_housing_group_categories.sql Group/category construction limits.
0052 0052_add_quest_world_interaction_objectives.sql Quest condition slot to committed WI/phase event binding.
0053 0053_add_recipe_unlock_sources.sql Trusted quest-turn-in/item-consumption recipe unlock sources.
0054 0054_add_farming_content_bindings.sql Item placement and object-action farming rollout bridges.
0055 0055_add_housing_economy_bindings.sql Economy, construction stages/materials and recovery items.
0056 0056_add_interactive_object_visual_bindings.sql Server visual catalog revision and object-phase visual IDs.
0057 0057_add_interactive_object_housing_collision_bindings.sql Explicit object-phase housing collision authority.
0058 0058_enforce_housing_footprint_radius.sql Transactional rebuild enforcing garden_radius >0.001 AND <=16.0.
0059 0059_add_housing_placement_source_bindings.sql Source template/phase → area → allowed housing templates.
0060 0060_add_interaction_effects.sql Optional plot InteractionEffect(id,wi_id) dependency.

После 0057, до 0058, вручную выполнить preflight из Server/Sources/db/sqlite_migrations/README.md; любая row с NULL/non-numeric/NaN/non-finite/radius <=0.001 или >16 блокирует продолжение. 0058 уже содержит собственную BEGIN IMMEDIATE ... COMMIT; не оборачивать её в конфликтующую внешнюю transaction. До первого и после 0060: PRAGMA quick_check; должен дать ok, каждая row PRAGMA foreign_key_check; — finding.

SELECT id, typeof(garden_radius) AS value_type, garden_radius
FROM housing_sizes
WHERE garden_radius IS NULL
   OR typeof(garden_radius) NOT IN ('integer', 'real')
   OR garden_radius != garden_radius
   OR garden_radius > 1.7976931348623157e308
   OR garden_radius < -1.7976931348623157e308
   OR garden_radius <= 0.001
   OR garden_radius > 16.0
ORDER BY id;

Запрос должен вернуть 0 rows. Это ручной preflight, не automatic migration history/status.

8. Client SQLite manual release stream 0001..0012

Работа только offline с одной backed-up source compact.db, client/writers закрыты. kind=migration меняет DB; gate — read-only validation; packaging — filesystem step. Gate/export нельзя передавать migration runner или записывать как schema history.

Kind/policy Exact path Операция
0001 migration/required ../../migrate/skill_cast_client_visuals_migration_schema.sql Normalize skill cast visuals.
0002 migration/required ../../migrate/animation_ids_offline_migration.sql Normalize animation IDs.
0003 migration/required ../../migrate/animation_ids_case_alias_cleanup.sql Merge case-insensitive aliases.
0004 migration/conditional-destructive ../../migrate/skill_cast_client_visuals_drop_legacy_skill_columns.sql Только после reviewed backfill evidence.
0005 migration/required 0005_interactive_object_visual_catalog.sql Three-table object visual catalog.
0006 migration/required 0006_icon_system_schema.sql Icons + icon_id columns.
0007 migration/required 0007_icon_system_backfill.sql Deterministic legacy PNG paths/mappings.
0008 gate/required ../../migrate/icon_system_migration_validation.sql Все result sets должны дать 0 rows.
0009 packaging/required ../../migrate/icon_system_export_asset_manifest.ps1 Export physical Data/icons inventory; DB не меняет.
0010 gate/required ../../migrate/icon_system_asset_validation.sql DB/file cross-check; required findings 0.
0011 migration/conditional-destructive 0011_icon_system_drop_legacy_columns.sql Optional irreversible drop, только SQLite 3.35+, backup и evidence 0008/0010 на том же artifact.
0012 migration/required для нового status visual loader 0012_status_effect_visuals_schema.sql Schema-only status-effect presentation mapping.

Зафиксированное противоречие: текущий manifest.tsv заканчивается на 0011 и может не включать 0012, хотя файл 0012_status_effect_visuals_schema.sql существует и runtime loader его потребляет опционально. До исправления manifest оператор обязан вручную применить 0012 после 0011 (либо после осознанного пропуска conditional 0011, сохранив sequence record). Не скрывать этот out-of-manifest step; отдельно записать evidence. Это руководство не исправляет manifest, поскольку изменять разрешено только данный MD.

Physical delivery: единый migrated artifact → Data\compact.db. Packed delivery: тот же artifact сначала в Data\compact.db, затем существующий PakTool flow в Base.pak. Не мигрировать physical и packed copies отдельно.

9. Schema/content setup

9.1 Client visual tables — exact shape

CREATE TABLE IF NOT EXISTS interactive_object_visual_catalog_metadata (
  id INTEGER PRIMARY KEY NOT NULL, revision INTEGER NOT NULL,
  CHECK (id = 1), CHECK (revision > 0 AND revision <= 4294967295));
CREATE TABLE IF NOT EXISTS interactive_object_visual_assets (
  visual_asset_id INTEGER PRIMARY KEY NOT NULL,
  smc_path TEXT NOT NULL, idle_animation TEXT NOT NULL DEFAULT '',
  scale REAL NOT NULL DEFAULT 1.0, cast_shadow INTEGER NOT NULL DEFAULT 1,
  CHECK (visual_asset_id > 0 AND visual_asset_id <= 4294967295),
  CHECK (length(smc_path) BETWEEN 10 AND 512),
  CHECK (length(idle_animation) <= 128), CHECK (scale >= 0.01 AND scale <= 100.0),
  CHECK (cast_shadow IN (0,1)));
CREATE TABLE IF NOT EXISTS interactive_object_visual_required_assets (
  asset_id INTEGER PRIMARY KEY NOT NULL,
  CHECK (asset_id > 0 AND asset_id <= 4294967295),
  FOREIGN KEY(asset_id) REFERENCES interactive_object_visual_assets(visual_asset_id)
    ON DELETE RESTRICT ON UPDATE CASCADE);
CREATE TABLE IF NOT EXISTS status_effect_visuals (
  tag TEXT PRIMARY KEY, player_effect TEXT NULL, character_effect TEXT NULL,
  npc_effect TEXT NULL, party_only INTEGER NOT NULL DEFAULT 0);

Object metadata должна иметь ровно row id=1, positive revision; assets — positive IDs, client-local SMC path/animation/scale/shadow; required-assets — curated exact set реально используемых server IDs. Status visuals связывают semantic effect tag с optional player/character/NPC presentation names; party_only — integer flag.

Disabled/nonfatal: все три object visual tables отсутствуют, либо все существуют и counts ровно 0/0/0. Fatal: присутствует только часть schema; metadata/assets/manifest заполнены частично; metadata count ≠1; populated catalog с пустым manifest; unresolved required ID; malformed projection/path/value. Ready только для полностью валидного непустого catalog.

9.2 Server metadata, bindings и collision

0056 создаёт metadata (id=1, revision>0) и primary key binding (object_template_id,phase_id)->visual_asset_id; paths на сервере отсутствуют. 0057 требует explicit row для каждой reviewed phase в housing deployment:

9.3 Housing data chain

  1. housing_sizes: radius и view/butler sizing; после 0058 radius (0.001,16].
  2. housings: template/category/economy presentation metadata, limits и housing_size_id.
  3. housing_groups, housing_areas, housing_group_categories: logical grouping, activation, category/count policy.
  4. housing_economy_bindings: housing → root object template, stage count, decoration limit, tax period/currency, demolition delay.
  5. Stage/material/recovery bindings: stage → next phase; required items; recoverable object → item/count.
  6. Deployment v2: logical housing area → exact world/zone/area/layer polygon/exclusions/permissions.
  7. 0059: source object template+phase → deployed area → explicit allowed housing IDs.
  8. Visual mapping: housing_id → economy root object_template_id → construction/start phase_idinteractive_object_visual_bindings.visual_asset_id → client interactive_object_visual_assets.smc_path → packaged SMC.

housings.main_model_id не является rendering source для этой вертикали. Client не выбирает SMC по нему; authoritative network visual ID и exact catalog chain обязательны.

9.4 PLACEHOLDER SQL — не production rows

Ниже только форма. <PLACEHOLDER> необходимо заменить после content/map review; эти строки не являются реальными ID/данными и не должны исполняться как production content.

-- CLIENT PLACEHOLDER, NOT PRODUCTION
INSERT INTO interactive_object_visual_catalog_metadata(id,revision)
VALUES (1,<PLACEHOLDER_REVISION>);
INSERT INTO interactive_object_visual_assets
(visual_asset_id,smc_path,idle_animation,scale,cast_shadow)
VALUES (<PLACEHOLDER_VISUAL_ID>,'<PLACEHOLDER_SMC_PATH>','<PLACEHOLDER_IDLE>',1.0,1);
INSERT INTO interactive_object_visual_required_assets(asset_id)
VALUES (<PLACEHOLDER_VISUAL_ID>);

-- SERVER SQLITE PLACEHOLDER, NOT PRODUCTION
INSERT INTO interactive_object_visual_catalog_metadata(id,revision)
VALUES (1,<PLACEHOLDER_REVISION>);
INSERT INTO interactive_object_visual_bindings
(object_template_id,phase_id,visual_asset_id)
VALUES (<PLACEHOLDER_OBJECT_TEMPLATE_ID>,<PLACEHOLDER_PHASE_ID>,<PLACEHOLDER_VISUAL_ID>);
INSERT INTO interactive_object_housing_collision_bindings
(object_template_id,phase_id,shape_type,blocking_radius,half_extent_x,half_extent_z,blocks_housing)
VALUES (<PLACEHOLDER_OBJECT_TEMPLATE_ID>,<PLACEHOLDER_PHASE_ID>,<PLACEHOLDER_SHAPE>,
        <PLACEHOLDER_RADIUS>,<PLACEHOLDER_HALF_X>,<PLACEHOLDER_HALF_Z>,<PLACEHOLDER_BLOCKS>);

Client/server revision должны совпасть. Для v4 identity обе стороны FNV-1a-64 хешируют sorted unique positive used/required visual IDs и cardinality; paths в identity не входят.

10. Config reference

10.1 WorldInteractionRollout

Exact seven keys: interaction, object, loot, craft, skillPlot, housing, labor. Missing/unknown/numeric key, duplicate/zero ID или >4096 IDs делает всю policy invalid и выключает families 1–7. Enabled управляет OFFER; empty allowlist разрешает transport, но не content.

ContentIds meanings: interaction semantic; object template; loot monster/NPC template; craft recipe; skillPlot plot; housing template; labor contentless (array должна быть пустой).

"WorldInteractionRollout": {
  "Families": {
    "interaction": {"Enabled": true,  "ContentIds": [1,2,3,4,5,6,7]},
    "object":      {"Enabled": true,  "ContentIds": []},
    "loot":        {"Enabled": true,  "ContentIds": []},
    "craft":       {"Enabled": true,  "ContentIds": []},
    "skillPlot":   {"Enabled": true,  "ContentIds": []},
    "housing":     {"Enabled": false, "ContentIds": []},
    "labor":       {"Enabled": true,  "ContentIds": []}
  }
}

10.2 HousingDeployment Version 2

Root exact keys: Version, Enabled, Identity, AreaBindings. Identity keys/modes: Account=AuthenticatedSession; Family=Disabled или PersistedMembership; Guild=Disabled или AuthoritativeRuntime.

Binding exact keys: HousingAreaId, WorldId, ZoneId, AreaId, Layer, AllowedPermissions, Polygon, StaticCollisionExclusions. Polygon point: exact X,Z; 3..32 finite points, no repeated closing point, coordinates [-10000000,10000000]. Exclusions: 0..128 simple polygons, each 3..32 points. Permissions: unique nonempty subset Private/Public/Family/Guild, обязательно Private.

Family permission разрешать только с PersistedMembership и migration 0028; packet identity запрещён. Guild — только AuthoritativeRuntime с current CPC guild. Loader требует activated area, unique IDs, no overlap/touch land polygons в одном scope, максимум 4096 bindings. Enabled=true + empty bindings или rows при disabled — invalid.

"HousingDeployment": {
  "Version": 2,
  "Enabled": false,
  "Identity": {"Account":"AuthenticatedSession","Family":"Disabled","Guild":"Disabled"},
  "AreaBindings": [
    {
      "HousingAreaId": "<PLACEHOLDER_NOT_A_NUMBER>",
      "WorldId": "<PLACEHOLDER_NOT_A_NUMBER>",
      "ZoneId": "<PLACEHOLDER_NOT_A_NUMBER>",
      "AreaId": "<PLACEHOLDER_NOT_A_NUMBER>",
      "Layer": "<PLACEHOLDER_NOT_A_NUMBER>",
      "AllowedPermissions": ["Private"],
      "Polygon": [{"X":"<PLACEHOLDER>","Z":"<PLACEHOLDER>"}],
      "StaticCollisionExclusions": []
    }
  ]
}

Этот пример намеренно невалиден и не production: placeholders-strings нарушают numeric contract, polygon слишком короток. Он показывает только ключи и не может быть случайно принят loader-ом.

Static exclusions — операторское описание отсутствующей на сервере static brush/BSP geometry. Пустой array допустим только как зафиксированный результат map review, а не как утверждение автоматической full-world collision.

11. Dotenv и секреты

Shared ConfigManager автоматически ищет dotenv рядом с фактически запущенным executable; CWD и JSON directory не влияют. LC_ENV читается только из process environment до dotenv, case-insensitive: development, production, test; иное значение abort. Default: Debug ShareLib → development, non-Debug/Release → production.

Precedence, позднее значение выше:

  1. .env
  2. .env.local (пропускается в test)
  3. .env.<mode>
  4. .env.<mode>.local (включая .env.test.local)
  5. legacy explicit JSON EnvironmentFile или SecretsFile (не оба; required, relative к loaded JSON directory)
  6. process environment

Test exception: только .env.local пропускается; .env.test.local разрешён. Required empty/unresolved ${ENV:NAME} abort startup. Значения не логируются.

Имена secret variables, без значений:

Implementation находится в static ShareLib; существующие binaries её не получают от редактирования JSON/source. Нужны rebuild ShareLib и relink/rebuild всех consumers, минимум Connector и GameServer, а фактически всех использующих ConfigManager.

12. ECC/EntitiesMP и packaging

13. Build/deployment sequence

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

  1. Review endpoint ContractRevision=12 и declarations.
  2. Применить server SQLite 0001..0060 вручную/offline к staging copy; заполнить reviewed rows; сохранить backup/evidence.
  3. Применить PostgreSQL 0001..0046 в lc_game после специальных preconditions. Единственный source-verified CLI syntax приведён в §6.
  4. Обработать client stream 0001..0011 по manifest kind; отдельно вручную 0012; заполнить visual catalog/status visuals; пройти gates/export.
  5. Подготовить SMC/ECL/XML/localization и единый client artifact.
  6. Подготовить dotenv/config с secrets вне repository; baseline families оставить off/empty.
  7. Build order: server ShareLib до Connector/GameServer и других consumers; client EntitiesMP/ECC outputs до dependent client/link/package. Точная CLI build invocation/configuration из inspected source не установлена, поэтому команда не выдумывается.
  8. Deploy parser/binaries с families off; controlled restart; проверить startup diagnostics.
  9. Запустить отдельно разрешённые read-only audits, затем separately approved tests/runtime scenarios.
  10. Включать content staged по §15.

14. Startup/load order и fatality

Рекомендуемый dependency order, отражающий references: config/dotenv → static base tables → WI → doodad templates → loot/craft/plots/climate/farming/housing/visual/collision/source bindings → PostgreSQL connectivity/schema → runtime registries → area recovery → protocol backend/OFFER.

15. Staged rollout и rollback

Rollout

  1. Parser client/server deploy с families off.
  2. Backup, migrations, schema audits; никаких bulk imports.
  3. Конвертировать один production content set; проверить every reference/visual/collision/localization.
  4. Добавить малый exact allowlist: dependencies first (1; затем 2; затем 3/4; housing после 1+2/backend).
  5. Controlled restart — existing negotiated sessions не переоцениваются.
  6. Проверить RESULT, startup logs, client catalog revision/identity, owner-lane state и metrics.
  7. Для corpse требуется area unanimity; для housing — deployment Ready, v2+ catalog и semantics 8/9 только после 0059.
  8. Расширять малыми batches; никаких ranges/wildcards/arbitrary client IDs.

Rollback

content gate -> запрет новых mutations -> drain/recovery -> family gate -> reconnect -> binary rollback audit.

16. Admin, logs, limits и recovery

GM level 10 commands:

wi_diag metrics
wi_diag runtime <id>
wi_diag persistent <id>
wi_diag action <id>
wi_diag recovery <1..50>
wi_diag area <zone>:<area>
wi_diag area_retry <zone>:<area>

area_retry применять только после approved исправления data/config причины; он не repair/rewrite stored geometry. WI_SECURITY — parser/rate/security; WI_RECOVERY — timers/quarantine/area/housing recovery; WI_DIAG — GM audit. Logs не должны содержать token, secret, private payload или pointer.

Request Rate/burst per GameServer session
Family 1 action 12/s / 24
Family 3 take 8/s / 16
Family 3 roll 6/s / 12
Family 4 start 2/s / 4
Family 4 cancel/repeat 4/s / 8
Family 6 placement commit 1/s / 2
Family 6 management 3/s / 6

Buckets независимы, живут descriptor session и не сбрасываются renegotiation. Rate limit не заменяет authorization. Repeated logs bounded (первые 10, затем каждое сотое), counters сохраняются.

Housing/craft recovery pulses: startup/первый owner pulse и затем каждые 30 секунд; bounded pages. Не увеличивать budgets вслепую, не очищать lease/claim/timestamps/publication marker и не удалять journal. Area Failed не имеет automatic retry для non-transient geometry conflict.

17. Troubleshooting

Симптом/код Вероятная причина Действие
Missing all client visual tables Feature не установлена Допустимый disabled baseline; применить 0005 offline перед enable.
Одна/две visual tables или partial rows Повреждённый artifact Fatal: не запускать rollout; восстановить backup и пересобрать единый catalog.
Missing status_effect_visuals 0012 отсутствует в manifest/applied stream Вручную применить exact 0012 после 0011 до исправления manifest; записать evidence.
Missing env/unresolved placeholder Secret не provisioned или неверный executable root Проверить process env и precedence, не логировать значение; startup должен abort.
Missing ECL EntitiesMP output не generated/packaged Генерировать из .es только approved flow; не hand-edit/copy surrogate.
Missing SMC/model invisible Bad client asset path/package Проверить exact visual ID→SMC, case/path/package; server main_model_id не fallback.
Catalog revision mismatch Client/server metadata различаются Остановить rollout; доставить согласованные artifacts.
Catalog identity mismatch required set ≠ server used-binding set Сверить sorted positive IDs; extra client assets не включать в required identity.
ContentIds does not publish Empty/wrong family ID или dependency Проверить meaning family, loader snapshot, dependencies и restart.
SERVER_DISABLED Family/config/backend/deployment gate off Исправить readiness; не обходить OFFER вручную.
CAPABILITY_REQUIRED Request до RESULT, wrong version или v1 housing placement Negotiation/reconnect; placement только v2+ server catalog.
STALE_REVISION Changed object/plot/token snapshot Отозвать local capability, запросить authoritative snapshot; не retry старым token.
PARTIAL_SUCCESS loot Некоторые entry commits failed Применить per-entry results; не rollback committed entries.
PARTIAL_SUCCESS housing Durable commit возможен, publication/mirror pending Очистить ghost/token, запросить snapshot, расследовать recovery; не повторять mutation вслепую.
Area Failed Persisted geometry/bounds/exclusion/overlap/reference conflict wi_diag area; approved data/config resolution; затем area_retry. Не shrink/delete silently.
Recovery постоянно deferred DB latency, owner mismatch, pending outbox/page Read-only audit, inspect attempts/error; не править markers.
Poisoned craft operation Repeated non-continuation recovery error Проверить journal/outbox/quest/reservation exact links; не release hold вручную.
Manual SQLite duplicate column/table Script re-run/out-of-order/partial legacy install Остановиться; восстановить backup или провести approved forensic reconciliation. Не stamp.
0058 fails Invalid garden_radius rows Выполнить documented preflight; исправление — отдельная approved content operation.
SQLite locked/corrupt Consumers не остановлены/не staging/неверный SQLCipher client Stop all consumers, restore verified backup, повторить offline.
db_migrate не видит SQLite Это PostgreSQL-only tool SQLite применять вручную; не создавать фиктивную history/checksum.
Unknown handler/reference Incomplete content/schema Fail-closed; добавить reviewed concrete adapter/row, не fallback на first function.
Housing action 2 rejected Reserved AddDecoration unsupported Ожидаемо; нужен future protocol/catalog implementation, не client template ID.
Housing placement collides unexpectedly Missing/incorrect 0057/exclusions/NPC/terrain bounds Map/content review; client mesh не authority.
Legacy/new loot duplicates Ошибка area unanimity/gating Немедленно disable NPC ContentId; сохранить existing containers, не regenerate.
Negotiation changed but live client unchanged State process-local per connection Controlled reconnect/zone handoff.

18. Известные ограничения

19. Production readiness checklist

20. Приложение A — exact table inventory

Server static SQLite tables/altered tables

wi_groups, wi_group_wis, wi_details; doodad_almighties, doodad_func_groups, doodad_func_uses, doodad_func_timers, doodad_funcs, doodad_phase_funcs; item_grade_distributions, loot_packs, loots, loot_groups, loot_actability_groups, loot_pack_dropping_npcs, matcher_impl_sql_wheres, matcher_impl_operators, matchers, drop_rules, drop_rule_loot_packs, doodad_func_loot_items, doodad_func_loot_packs, gain_loot_pack_item_effects; altered crafts, craft_c_categories, craft_d_categories, craft_materials; craft_lines, craft_line_components, craft_packs, craft_pack_crafts, doodad_func_craft_packs; plots, plot_events, plot_conditions, plot_event_conditions, plot_aoe_conditions, plot_effects, plot_next_events; altered skills; climates, zone_climates, zone_climate_elems, zones, doodad_func_growths, doodad_func_climate_reacts, doodad_func_cutdownings; housing_sizes, housings, housing_groups, housing_areas, housing_group_categories; quest_world_interaction_objectives, recipe_unlock_sources, farming_placement_bindings, farming_action_bindings; housing_economy_bindings, housing_construction_stage_bindings, housing_construction_material_bindings, housing_recovery_item_bindings; interactive_object_visual_catalog_metadata, interactive_object_visual_bindings, interactive_object_housing_collision_bindings; housing_placement_source_bindings, housing_placement_source_templates; interaction_effects.

Client SQLite tables

Object visual: interactive_object_visual_catalog_metadata, interactive_object_visual_assets, interactive_object_visual_required_assets. Status: status_effect_visuals. Icon stream: icons plus icon_id additions to items, skills, buffs, t_action, t_affinity, t_affinity_work, t_missioncase; icon_asset_files — только temporary gate inventory, не persistent schema contract.

PostgreSQL feature tables/fields

Feature inventory 0024–0046: interactive_object_state; t_account_labor, t_character_labor, t_labor_reservation и altered t_expert; altered interactive_object_state farming fields; housing_plot_state; housing_decoration_state, housing_operation_journal, housing_family, housing_family_member; world_integration_action_journal, quest_world_interaction_progress, quest_world_interaction_credit, character_recipe_unlock; farming_placement_journal, farming_reward_outbox; housing_economy_reservation, housing_material_reservation_line, housing_economy_operation, housing_recovered_item_outbox, housing_economy_compensation_log; t_labor_special_effect_journal; housing_demolition_command; craft_operation_journal, craft_operation_material_intent, craft_operation_product_intent, craft_operation_inventory_result, craft_operation_appellation_result, craft_operation_publication_outbox, craft_operation_quest_mutation; altered t_characters, t_questdata, t_labor_reservation, journals, housing/object permission and plot bounds fields. Точные columns/constraints определяются SQL files; не реконструировать schema из summary.

21. Приложение B — migration-to-loader matrix

Migration range Primary loader/consumer Empty behavior Bad/partial behavior
Server SQLite 0001–0003 WorldInteractionManager WI content unavailable Invalid references reject snapshot/startup
0004–0009 DoodadTemplateManager, runtime manager No object templates Graph/type/reference error fail-closed
0010–0023 LootTableManager, object/effect adapters Corpse content not converted Invalid matcher/pack/item blocks candidate
0024–0031 Craft catalog/transaction adapters No authorized converted recipes Partial alterations/memberships fatal/load reject
0032–0039,0060 SkillPlotManager, runtime Linear skills/empty plots Referenced missing effect/edge rejects plot
0040–0046,0054 FarmingPolicyManager Farming bindings disabled Reward-bearing partial binding fail-closed
0047–0051 HousingTemplateManager Housing catalog unavailable Invalid size/group/category rejects readiness
0052–0053 Quest/unlock integration loaders No new objectives/unlocks Orphan/unknown source reject row/candidate
0055 Housing lifecycle/economy Backend not ready Missing stages/materials/economy blocks template
0056 Server object visual loader/protocol No visual publication Partial metadata/binding or mismatch blocks visuals
0057–0058 Housing placement collision/template loader Placement blocked/not ready Missing phase metadata or bad radius fatal gate
0059 Context action/Housing catalog bootstrap Semantic 9 unavailable Empty source allowlist/undeployed area rejects candidate
Client 0005 InteractiveObjectVisualCatalog::Load Missing-all or 0/0/0 nonfatal disabled Partial schema/rows fatal
Client 0012 Engine/Entities/StatusEffect.cpp Missing table: no DB mappings Malformed query/schema is deployment defect
PG 0024–0033 Object/labor/farming/housing repositories Feature must remain disabled Missing schema/constraint blocks startup/operation
PG 0034–0041 Craft/recovery/character owner Craft binary must not deploy Missing fences risk stale write; deployment prohibited
PG 0042–0046 Housing recovery/persistence Housing current binary must not deploy Invalid existing permission/bounds causes migration/load failure

22. Приоритет и устаревшие документы

Это руководство — новый консолидированный operational source. Прежние раздельные planning/progress/ADR/rollout/runbook documents считаются stale для повседневной эксплуатации и не должны использоваться изолированно. Исторические filenames могут сохраняться в repository для provenance, но их отдельные revision statements (например, старые 7/9/10) заменены текущим direct code fact ContractRevision=12.

При конфликте приоритет таков: фактические endpoint headers и runtime code → exact SQL migration files/README/manifest → shipped config schema → это руководство → старые документы. Любое последующее изменение кода/migration делает затронутую часть руководства устаревшей до синхронного обновления.