Это практическое руководство описывает подготовку статического контента, клиентского представления, server-authoritative runtime и диагностику World Interaction System (WI).
Документ не является разрешением применять SQL, запускать миграции, сервер, клиент, сборку или генераторы. Все SQL-блоки ниже предназначены для reviewed candidate-копий баз. PostgreSQL fresh migrations psql/0020..0026 являются неприменёнными source migrations и не должны выполняться без отдельного DBA/release review и явного разрешения.
| Возможность | Статус |
|---|---|
Item → skill → InteractionEffect → Collect |
Runnable только в isolated cloned projection: real target-once item 6363 с временным exact a_num_0/use_skill_id=84, затем обязательный restore 1161/predecessor binding |
| NPC action → Collect | Runtime-open в том же Collect subset |
Doodad discovery и exact deterministic DoodadFuncLootItem |
Runtime-open |
| Один area-owned Timer/Growth scheduler | Runtime-open |
Exact item_spawn_doodads placement |
Runtime-open |
| Isolated synchronous skill plots with supported concrete effects | Runtime-open bounded subset; InteractionEffect plots rejected |
Immediate craft с crafts.delay = 0 |
Runtime-open |
Doodad Craft Pack/Start → существующий Craft.xml |
Runtime-open для discovery/context; phase не меняется |
| Ordinary corpse Inspect/TakeAll/TakeItem | Runtime-open, но только memory-only |
| Blueprint preview/placement/build contribution/completion | Код существует, но production rollout заблокирован geometry/model/projection/PG/release packages |
| Seed InsideGarden и garden harvest | Код существует, но зависит от полностью готового housing runtime |
| Authored ore/tree spawn и Gather | Код существует, но rollout заблокирован spawn/model/map package |
Delayed craft (delay != 0) |
Fail closed; delayed Labor/job path отсутствует |
| Durable corpse loot | Fail closed: нет stable persisted NPC generation |
| Decoration placement, common farms, authoritative ClimateReact | Fail closed |
Текущий release verdict — NO-GO. Нет canonical non-zero projection, final SQLite/client/map artifacts, approved PostgreSQL subset, canary isolation и достаточной telemetry.
| Что нужно получить | Основные authoring rows | Где показывается | Runtime/PG boundary | Статус/раздел |
|---|---|---|---|---|
| Использовать предмет и получить другой предмет | items.a_num_0 = items.use_skill_id → skills.a_index → skill_effects.effect_id → effects.actual_id → interaction_effects.wi_id; skill_products, source/skill_reagents |
inventory item/skill presentation | 0020 + 0021 при labor |
Isolated runnable fixture 6363→84; требуется self-target через portrait и exact restore, §7 |
| Действие у NPC | t_npc.npc_interaction_set_id → npc_interaction_sets.id → npc_interactions exact direct skill_id XOR global skill_constant_key; direct продолжает effect/WI chain, service constant идёт в typed service dispatch |
interactActions.xml |
direct Collect writer; services отдельным handler slice | Runtime-open, §7 |
| Поставить seed/workbench | items.use_skill_id + item_spawn_doodads.item_id/doodad_id → Start phase |
item-use placement UX, world model | 0020..0023, placement context из 0026 |
Runtime-open, §8 |
| Harvest/Gather с ростом/respawn | doodad_funcs → DoodadFuncLootItem; doodad_phase_funcs → Growth/Timer |
doodad action + countdown | inventory/labor + object phase/revision | Runtime-open narrow subset, §8/§11.3 |
| Крафт у NPC | crafts.craft_npc, craft_materials, single craft_products |
existing Craft.xml |
immediate existing Craft path; delay=0 |
Runtime-open, §9 |
| Крафт у doodad | DoodadFuncCraftPack или DoodadFuncCraftStart → recipe membership |
action icon slot opens Craft.xml |
object generation/revision/context revalidated | Runtime-open context, §9 |
| Loot обычного трупа | loot_pack_dropping_npcs → pack/group/entries |
interactActions.xml + lootWindow.xml |
area memory + normal character inventory save; per-action DB commit и durable corpse tables отсутствуют | Runtime-open memory-only, §10 |
| Blueprint/build/garden | item_housings, housing graph/polygon, build skill reagents; seed InsideGarden |
preview/world/build action | fresh 0020..0026 |
Код есть, rollout blocked, §11 |
| Статический ore/tree | lc_doodad_spawns → exact doodad graph |
world model/action/countdown | 0020..0023; gather serialization in CArea, без claim table |
Код есть, package blocked, §11.3 |
| Skill plot | skills.plot_id → plots → events/conditions/effects/edges |
обычное skill presentation | synchronous bounded executor | Не является WI interaction chain; template-only, §11.4 |
| Decorations/common farms/climate | соответствующие 0006 tables недостаточны |
нет positive runtime | handler/package отсутствуют | Fail closed, §11.5 |
Правило выбора: сначала выберите одну строку таблицы, затем добавляйте только её closure. Наличие соседних tables не включает соседний сценарий.
Сервер авторитетен для:
Клиентские craft_id, slot, transform и выбранная action — только запрос. Локальная SQLite, UI, model/icon mapping и preview не дают gameplay authority.
Item Collect:
actual inventory slot → item use binding → skill/effect/WI Collect
→ exact reagent/product/labor plan → revalidate → one durable commit → publish result
NPC action:
runtime NPC → prototype/set/action → server-resolved skill target
→ supported Collect plan → revalidate NPC/range/resources → commit
Doodad:
object+generation → current phase+revision → exact func_skill_id/action
→ permission/range/runtime subset → area claim → inventory/phase transaction without Labor
→ successful completion → memory Labor deduction → publish
Craft:
client-local recipe presentation → craft_id + NPC/doodad context
→ server preloaded recipe/context/material/NAS/labor/proficiency validation
→ immediate mutation/result; delay != 0 rejected
Corpse:
NPC death → server loot route/roll → memory-only area corpse
→ eligible participant Inspect → activation/id/revision TakeAll
→ server partial reward plan/claim → shared inventory commit
Housing:
actual blueprint slot + proposed transform → server binding/geometry/owner-limit preview
→ second full validation + footprint claim → plot/carrier/building commit
→ exact build-step actions/reagents/labor/revisions → terminal completion
Canonical DDL sources:
sqlite/0001_wi_skill_item_bridge.sql — foundation, item/skill/effect/WI/NPC.sqlite/0002_doodads_and_placement.sql — doodad templates, phases/functions, placement.sqlite/0003_loot.sql — global skill constants/default corpse action types, loot packs/routes и doodad loot payloads.sqlite/0004_craft.sql — craft extension, packs and workbench payloads.sqlite/0005_skill_plots.sql — skill plot graph.sqlite/0006_housing_farming_and_layout.sql — housing/farm/climate/map adapter tables.Existing LC tables remain authoritative identities: items.a_index, skills.a_index, effects.id, skill_effects.id, crafts.id, t_npc.a_index.
items, skills, icons, craft/category/material/product tables supply presentation.sqlite/client_0001_model_resources.sql adds exact model ID → LC resource mapping.SkillManager также требует final post-animation-migration shape skill_cast_client_visuals: для каждого client-loaded skill (skills.a_base_class >= 0) должны существовать ровно две строки weapon_index=0 и 1; loader читает ready_ani_id, still_ani_id, fire_ani_id и visual columns. Одних legacy skills.a_cd_* недостаточно.lc_gamePostgreSQL stores mutable durable state, not the static catalog:
| Source | Purpose |
|---|---|
0020 |
operation identity and inventory reservations; NAS mutates directly in the cohesive commit |
0021 |
account/character Labor и account-leading character index |
0022 |
durable account-to-static-account-buff assignments; requires 0021 first |
0023 |
doodad instances and deadlines |
0024 |
housing plots/buildings |
0025 |
construction, ACL, decoration state |
0026 |
doodad placement contexts |
Во всех WI PostgreSQL tables account_id — integer t_characters.a_user_index, а не text a_portal_index.
Fresh chain не содержит delayed Craft, durable corpse, audit/gathering-claim или Labor cleanup migrations; rollback выполняется DB recreation/snapshot.
Server:
Server/Sources/GameServer/App/Features/WorldInteraction/WorldInteraction.* — authoritative action plans, revalidation and dispatch;.../WorldInteraction/Content/Loaders/* — explicit static SQLite gates/load order;.../WorldInteraction/Content/Validation/* — graph/reference/runtime-shape validation;.../WorldInteraction/Content/Models/* — immutable content values;.../WorldInteraction/Runtime/Models/* — area/character-owned runtime state;Server/Sources/GameServer/Craft.* — existing recipe cache/context/execution;Server/Sources/GameServer/Area.* — doodad/housing/corpse ownership, scheduler and publication;Server/Sources/GameServer/DBManager*, DBProcess*, EventProcessWithThread.* — cohesive durable commit and main-thread completion;Server/Sources/GameServer/Battle_NPCDropItem.cpp — corpse producer and legacy fallback boundary.Client:
Client/Sources/Engine/App/Core/Managers/SkillManager.* — local skills, placement bindings and lc_model_resources preload;Client/Sources/Engine/Contents/function/InteractionCandidateArbiter.*, NpcActionUI.* + xml/interactActions.xml — единый owner/priority/cache для NPC/doodad/corpse и shared action window;Client/Sources/Engine/Contents/function/CorpseLootUI.* + xml/lootWindow.xml — corpse snapshot/TakeAll;Client/Sources/Engine/Custom/Craft.* + xml/Craft.xml — existing local craft catalog and exact context serialization;Client/Sources/Engine/Interface/IconTextureManager.* — icons.id → Data/icons/<filename>;Client/Sources/EntitiesMP/*.es — entity behavior source. Generated .h/.cpp нельзя редактировать или подключать напрямую; взаимодействие идёт через virtual functions.| Данные | Server static SQLite | Client compact SQLite | Зачем |
|---|---|---|---|
LC items/skills identities и gameplay fields |
Да | Да, те же IDs и только нужные client columns | Server проверяет gameplay, client разрешает name/icon/tooltip и item-use UX. В baseline/client schema есть items.a_num_0, но нет WI-only items.use_skill_id/use_skill_as_reagent и skill extension tuple из 0001; эти columns принадлежат server projection |
effects, concrete effect rows, skill_effects, interaction_effects, wi_*, reagents/products/requirements |
Да | Только если уже нужны существующему client skill path; не authority | Server строит и исполняет chain |
| NPC set/action binding | Да | Не требуется для authority | Action list приходит с server; client получает только action/skill/availability |
Doodad templates/phases/functions и item_spawn_doodads |
Да | item_spawn_doodads нужен placement UX; craft-action slots нужны doodad Craft UI |
Server владеет graph; client лишь routing/presentation |
crafts, craft_materials, craft_products, categories и Pack/Start membership |
Да | Да, exact matching recipe IDs/rows | Server валидирует cache; Craft.xml читает local catalog и не получает его по сети |
| Loot packs/routes | Да | Нет | Roll и eligibility только server-side; item presentation уже есть локально |
| Housing graph/polygons/spawns | Да | Только item bindings, необходимые UX, плюс matching released map | Geometry/ownership только server-side |
icons и localized item/skill texts |
Не нужны gameplay handler-у | Да | Локальные names/icons/tooltips |
lc_model_resources |
Нет | Да | Разрешает server-sent model ID в .smc/.mdl resource |
Нельзя «применить demo SQL один раз в какую-то SQLite». Для recipe/doodad UX выпускаются две reviewed проекции: server-authoritative и client-presentation. Их shared IDs должны совпасть, а допустимые различия перечисляются в projection manifest.
items.fixed_grade, items.max_enchantable_grade, items.gradable; runtime не имеет aliases, fallback или dual-read старых имён.Server/wearables.sql — fresh server baseline: он сразу материализует конечную schema. Его нельзя применять как upgrade к уже развёрнутой DB.Data\compact.db и не выполняет migrations. Единственный разрешённый переход существующего unpacked client source artifact — при остановленных consumers применить Client/Sources/migrate/item_grade_profile_offline_source_migration.sql ровно один раз к predecessor-shaped source DB, проверить конечные columns/constraints/rows отдельной release procedure и только затем упаковать новый immutable compact.db. Скрипт не применяется к уже canonical DB, runtime DB или server DB.export json/items.json — immutable LC predecessor evidence, не active generator/import input. Его profile keys намеренно остаются predecessor-shaped и не копируются в SQL authoring. WI System/aa_sqlite_database_info/items.json — отдельный AA reference export; его fixed_grade/max_enchantable_grade/gradable не разрешают AA→LC identity mapping без reviewed manifest.Server load order:
LC item/skill prototypes
→ generic effects and concrete effect payloads
→ WI foundation
→ optional loot
→ optional doodads and craft payload types
→ effect/doodad closure
→ optional climates
→ optional farms
→ optional authored spawns
→ optional housing
→ optional skill plots (or prove no plot links)
→ NPC action bindings
→ atomic immutable snapshot publication
→ existing Craft cache
Правила gates:
lc_doodad_spawns становится authoritative empty catalog и может retire durable static spawns при reconciliation.Canonical packaging caveat: sqlite/0006_housing_farming_and_layout.sql физически создаёт housing, climate, farm и lc_doodad_spawns gates одним script. Поэтому «установить только housing из 0006» без изменения reviewed migration stream нельзя, а полное применение 0006 одновременно объявляет остальные complete schemas installed (даже если rows empty). Release owner обязан либо дать accepted content/disposition для каждого gate из 0006, либо отдельно одобрить split schema migration. Ручное вырезание CREATE TABLE blocks не является projection.
Canonical DDL также содержит forward FK references: 0001.skills.plot_id→plots(0005), 0001.interaction_effects.doodad_id→doodad_almighties(0002), 0002.doodad_almighties.climate_id→climates(0006). DDL source order сохранён, но content DML нельзя считать независимо deployable только по номеру script: candidate schema preflight обязан доказать фактическое parent-table closure и PRAGMA foreign_key_check на offline copy. Такая executable проверка в рамках этого аудита не запускалась.
skills.target_selection_id=0/NULL означает Unspecified для generic staging legacy skills и не блокирует snapshot. Явное 1..4 обязательно только для skills, enrolled через реальный WI binding (item/effect/NPC/doodad/craft/housing/plot). Не обновляйте все 1618 legacy rows. Аналогично DDL default doodad_almighties.model_kind_id=0 loader отвергает: у каждой doodad row требуется exact 1..7.
| Meaning | Client enum | Server enum | Value |
|---|---|---|---|
| Once-use item type | CItemData::ITEM_ONCEUSE |
ITYPE_ONCE |
2 |
| Target once-use subtype | CItemData::ITEM_SUB_TARGET |
IONCE_TARGET |
10 |
Client CNetworkLibrary::UseSlotItem() входит в target branch только для exact 2/10, берёт skill из items.a_num_0, требует active eTARGET, использует этот skill для delay/range и отправляет MSG_ITEM_TARGET. Server do_ItemTarget() независимо повторяет exact 2/10 check и передаёт тот же getItemNum0() в ResolveItemInteractionSkill(). Для WI binding server затем требует exact equality items.a_num_0 = items.use_skill_id; одного use_skill_id недостаточно.
| Meaning | Value |
|---|---|
| Self | 0 |
| Friendly / Party / Raid / Hostile / AnyUnit | 13 / 14 / 15 / 16 / 17 |
| Position | 18 |
| Doodad | 20 |
| Pet | 22 |
| SourcePosition / Others / FriendlyOthers | 26 / 28 / 29 |
| CursorPosition / GeneralUnit / MySlave | 30 / 31 / 38 |
| Corpse | 39 |
| Selection Unspecified (legacy staging only) | 0 |
| Selection Source | 1 |
| Selection Target | 2 |
| Selection Line | 3 |
| Selection Location | 4 |
| Relation Any | 0 |
| Meaning | Value |
|---|---|
| Start phase | 1 |
| Normal phase | 2 |
| End phase | 3 |
| Public permission | 0 |
| Owner permission | 1 |
| Account permission | 6 |
| Invalid placement area | 0 |
| InsideGarden | 1 |
| OutsideGarden | 2 |
doodad_almighties.model_kind_id также является loader enum, а не permissive zero default:
| Meaning | Value |
|---|---|
| Default | 1 |
| Plant | 2 |
| Flower | 3 |
| Grass | 4 |
| BigTree | 5 |
| MediumTree | 6 |
| SmallTree | 7 |
Loader принимает полный enum range, но положительный runtime уже: для action permission реализованы только Public=0, Owner=1, Account=6; остальные значения загружаются, но action discovery возвращает unavailable. Для placement поддержаны только exact InsideGarden=1 и OutsideGarden=2; Invalid=0 не является permissive default.
WI groups имеют фиксированную runtime identity и не относятся к demo range:
wi_groups.id |
Exact name | Handler |
|---|---|---|
| 1 | Craft |
craft metadata |
| 2 | Collect |
implemented Collect paths |
| 3 | Building |
reserved building identity |
| Откуда → куда | Exact columns | Что это означает |
|---|---|---|
| item → skill | target-use dispatch: items.a_num_0; WI authority: items.use_skill_id = skills.a_index; direct path требует a_num_0=use_skill_id; items.use_skill_as_reagent |
Какое умение client выбирает для target packet и какое server повторно разрешает из фактического item slot; при use_skill_as_reagent=1 direct Collect дополнительно списывает ровно один source item |
| skill → generic effect | skill_effects.skill_id = skills.a_index, skill_effects.effect_id = effects.id, skill_effects.enable=1 |
Какие enabled effects принадлежат skill |
| generic effect → interaction payload | effects.actual_type='InteractionEffect', effects.actual_id = interaction_effects.id |
Exact case-sensitive family и concrete payload identity; actual_id не является wi_id; interaction_effects.source_direction current loader читает как boolean 0/1 |
| interaction payload → WI | interaction_effects.wi_id = wi_details.wi_id = wi_group_wis.wi_id; wi_group_wis.wi_group_id = wi_groups.id |
Выбирает handler group и metadata wi_details.lp/apply_expert/distance_sqrt |
| skill economy | skill_reagents.skill_id/item_id/amount/enable, skill_products.skill_id/item_id/amount/enable |
Server-authored inputs/outputs direct Collect/build paths; строки одного item агрегируются |
| skill requirements/tools | unit_reqs.owner_type='Skill', unit_reqs.owner_id=skills.a_index; skills.or_unit_reqs, mainhand_tool_id, offhand_tool_id |
Metadata загружается, но current Collect/doodad placement/harvest/build runtime требует отсутствие requirements/tools и or_unit_reqs=0; это не способ включить проверку requirement |
| NPC → action skill | t_npc.npc_interaction_set_id = npc_interaction_sets.id; npc_interactions.npc_interaction_set_id, exact one-of skill_id/skill_constant_key |
Server публикует positive npc_interactions.id как action ID и resolved positive skill ID как presentation key; source kind/key остаётся typed server dispatch metadata |
| placement item → doodad | item_spawn_doodads.item_id = items.a_index, .doodad_id = doodad_almighties.id; item одновременно обязан иметь items.use_skill_id |
Размещаемый template выбирается binding-ом, а допустимость placement — skill metadata фактического item |
| doodad → phase | doodad_func_groups.doodad_almighty_id = doodad_almighties.id, .doodad_func_group_kind_id |
Ровно одна Start phase (1); model берётся из phase .model, иначе template .model |
| phase → manual action | doodad_funcs.doodad_func_group_id, .actual_func_type/.actual_func_id, .func_skill_id, .perm_id, .next_phase |
func_skill_id — единственный discovery key; polymorphic payload выбирается exact type+ID; SQL FK на payload намеренно нет |
| phase → automatic function | doodad_phase_funcs.doodad_func_group_id, .actual_func_type/.actual_func_id |
Timer/Growth создают один durable deadline; это не clickable action |
| loot action → WI/item | doodad_func_loot_items.id = doodad_funcs.actual_func_id, .wi_id, .item_id, .count_min/.count_max/.percent/.remain_time/.group_id |
Current positive handler требует fixed count, 10000, 0, 0, Collect WI и different action next_phase |
| craft recipe → WI/skill/context | crafts.id, .skill_id, .wi_id, .craft_npc, .req_doodad_id; pack/start membership tables |
Recipe economy связывается с Craft WI; NPC, direct doodad binding и Pack/Start — разные context routes |
| blueprint → design/build | item_housings.item_id/design_id/completion; housing_build_steps.housing_id/step/model_id/skill_id/num_actions |
completion=0 — blueprint; build step должен иметь exact skill_reagents and contiguous step from 1 |
| housing area → geometry | housing_areas.housing_group_id; lc_housing_area_polygons.housing_area_id/world_id/zone_id/area_id/layer_id/is_exclusion; vertices |
Server-authoritative inclusion/exclusion scope и ordered 1-based X/Z polygon |
| skill → skill plot | skills.plot_id = plots.id; event/condition/effect/edge tables use their exact parent IDs |
Отдельный synchronous skill executor. plot_effects.actual_id ссылается на concrete effect payload, не на effects.id; InteractionEffect для plot запрещён |
Диапазон 900000+ ниже остаётся только для WI-owned identities и map/model scope placeholders. Все внешние item/NPC/skill references являются реальными LC prototypes из export json и статически сверены с Server/wearables.sql; это доказывает baseline identity выбранных LC rows, но не превращает соседние AA graph IDs в production mapping.
Для item/NPC/skill rows ключом является соответственно items.a_index, t_npc.a_index, skills.a_index. Имена взяты из localized_texts.json (tbl_name, tbl_column_name='name', idx=<ID>). Icon metadata взята из items.json/skills.json → icon_id → icons.json(id,filename); filenames ниже не выдуманы.
| ID | Имя ru_ru (en_us) |
Source evidence | Назначение в guide | Риск/ограничение |
|---|---|---|---|---|
6363 |
Свиток немоты (Silent Scroll of Keron Mage Collective) | items.json:a_index=6363, enabled exact type/subtype 2/10, a_num_0=1161, a_num_1=1, SMC Data\Item\Common\ITEM_treasure02.smc; smc_id.model_name='ITEM_treasure02', mesh Data\Item\Common\ITEM_treasure02.bm, texture Data\Item\Common\Texture\ITEM_treasure.tex; localized_texts.json:items/name+description/6363; icon 2657 → legacy/items/tex_0010_r10_c01.png; exact row также присутствует в Server/wearables.sql |
isolated direct Collect source item | Наименьший найденный exported consumer closure: только item presentation/model rows и original skill binding; zero exact item-key rows в quest/exchange/equipment/collection/luckydraw/craft/NPC-drop tables и zero semantic source literal. Existing skill 1161 имеет canonical a_targetType=2 (TargetOne), unsupported для WI Collect. Поэтому client clone временно меняет только реально существующий dispatch field a_num_0:1161→84, а server clone — a_num_0:1161→84 плюс WI-only use_skill_id=84/use_skill_as_reagent=1; full per-schema predecessor snapshot/drift/affected-row/restore обязателен. Existing name/description намеренно остаются combat-scroll и не являются production Collect UX |
117 |
Плод древня (Treant Fruit) | items.json:a_index=117; localized_texts.json:items/name/117; icon 264 → legacy/items/tex_0001_r00_c07.png |
direct Collect product | Existing economy item: enabled collection requirements и legacy NPC drop slots; prototype/consumer rows не менять и не удалять |
114 |
Волчий клык (Wolf Fang) | items.json:a_index=114; localized_texts.json:items/name/114; icon 261 → legacy/items/tex_0001_r00_c04.png |
NPC Collect reagent | Existing economy item: enabled collection requirements и legacy NPC drop slots; demo расходует реальные stacks только в isolated clone |
115 |
Волчий коготь (Wolf Claw) | items.json:a_index=115; localized_texts.json:items/name/115; icon 262 → legacy/items/tex_0001_r00_c05.png |
NPC Collect product | Existing economy item: enabled collection requirements и legacy NPC drop slots; demo создаёт additional supply только в isolated clone |
876 |
Семечко (Seed) | items.json:a_index=876; localized_texts.json:items/name/876; icon 802 → legacy/items/tex_0003_r02_c12.png |
seed/placement item | Existing enabled seed identity. Exact-key export audit нашёл presentation/model closure, но отсутствие явной relation не доказывает отсутствие player-held/live use; новый item-use binding поэтому всё равно cloned-isolation-only |
11378 |
Чертеж оружия титана (Drawing of the titan weapon) | items.json:a_index=11378, enabled type/subtype 2/6, a_num_0=837; localized_texts.json:items/name/11378; icon 3906 → legacy/items/tex_0016_r02_c00.png; t_quest.json:a_index=837,a_start_type=1,a_start_data=11378 |
housing blueprint identity вместо fake 900009 |
Не housing prototype и не production-safe: это production quest-start drawing. Допустим только как identity-shape fixture на клонированной DB, отдельном character/zone и с exact snapshot/restore use_skill_*; quest row и item prototype не изменять/не удалять |
11539 |
ТЕСТОВЫЙ МАТЕРИАЛ СИНТЕЗА (Carp) | items.json:a_index=11539, enabled type/subtype 2/7; localized_texts.json:items/name/11539; icon 4449 → legacy/items/tex_0018_r06_c12.png; t_synthesis_items.json:id=1,item_id=11539,grade=1,synthesis_exp_add=30000,is_pickup=1 |
workbench placement identity вместо fake 900011 |
Явный test material и не equipment/quest/craft material/product, но имеет существующий synthesis consumer. Только cloned DB/character/zone; exact snapshot/restore use_skill_*, synthesis row не менять/не удалять |
118 |
Сырая древесина (Raw Wood) | items.json:a_index=118; localized_texts.json:items/name/118; icon 265 → legacy/items/tex_0001_r00_c08.png |
harvest reward и housing construction material | Existing economy item: enabled collection requirements и legacy NPC drop slots; demo создаёт/расходует additional supply только в isolated clone |
110 |
Олений рог (Deer Horn) | items.json:a_index=110; localized_texts.json:items/name/110; icon 257 → legacy/items/tex_0001_r00_c00.png |
craft material | Existing economy item: enabled collection requirements, legacy NPC drops и baseline craft_materials.id=3,craft_id=6,amount=1; demo не должен менять эти consumers |
111 |
Оленья шкура (Deer Hide) | canonical LC profile fixed_grade=1, max_enchantable_grade=-1, gradable=0; a_flag=27, stack cap a_weight=9999; immutable predecessor export json/items.json подтверждает identity/value lineage, но не является generator input; localized_texts.json:items/name/111; icon 258 → legacy/items/tex_0001_r00_c01.png |
craft result и corpse drop | Existing economy item: enabled collection requirements и legacy NPC drop slots; demo creates an additional craft/corpse supply route only in isolated clone. Initial grade равен 1, поэтому explicit corpse loot обязан иметь grade_id=1 |
1690 |
ТЕСТ (Werewolf) | t_npc.json:a_index=1690, enabled level 13, Default.xml, no NPC skills; localized_texts.json:npcs/name/1690; model Data\\Item\\qqqq\\test.smc; zero t_npc_regen*.json rows keyed to NPC 1690 |
NPC interaction и corpse route | Явный test NPC с legacy drop slots, но не world-reachable из export. Требуется approved isolated runtime/admin spawn fixture; snapshot/restore exact npc_interaction_set_id; prototype/drop rows не менять/не удалять |
1683 |
Мастерская (Workshop) | t_npc.json:a_index=1683, enabled, Default.xml; crafts.json:craft_npc=1683 recipes 1..6; eleven enabled t_item_exchange.a_npc_index=1683; t_npc_regen.json:a_index=3677507 in zone 0, layer 0, (584,109.37000274658203,767.3499755859375); client UIQuestNew.cpp special-cases NPC 1683 for event-exchange caption |
immediate NPC craft context | Reachable shared workshop/event-exchange NPC. Все шесть baseline recipes имеют delay=1000 и остаются отдельным legacy content; guide prototype не меняет, demo recipe разрешён только в cloned isolated projection/zone, не на live spawn |
491 |
Восход (Sunrise) → временно Осмотреть труп / Inspect corpse | skills.json:a_index=491: a_base_class=999, show=0, a_targetType=2, icon 5127; localized_texts.json:skills/name+description+tooltip/491; two empty-effect/NULL-animation visual rows weapon_index=0/1; icons.json:5127 → legacy/skills/tex_0001_r03_c02.png; exact identity также есть в Server/wearables.sql |
corpse Inspect, action 930005 |
Export/source consumer audit ниже даёт zero gameplay consumers. Только disposable cloned client/server artifacts: server metadata временно 39/2/0, client target/name/description/tooltip временно corpse-specific; icon 5127 сохраняется. Exact predecessor restore обязателен |
492 |
Недавний восход (Ready for Sunrise) → временно Забрать добычу / Take loot | skills.json:a_index=492: a_base_class=999, show=0, a_targetType=0, predecessor icon 5127; localized_texts.json:skills/name+description+tooltip/492; two empty-effect/NULL-animation visual rows weapon_index=0/1; exact identity также есть в Server/wearables.sql. Для demo client skill reference меняется на existing icon 5126 → legacy/skills/tex_0001_r03_c01.png; global icons row не меняется |
corpse Take, action 930006 |
Export/source consumer audit ниже даёт zero gameplay consumers. Только disposable clone: server metadata временно 39/2/0, client target/icon/localization временно corpse-specific; exact predecessor a_targetType=0, icon_id=5127 и все тексты восстанавливаются |
504 |
Зелье ускорения ([Cash] Haste Potion) → временно Store / Магазин | a_base_class=999, show=0, a_targetType=0, predecessor icon 4905; exact name/description/tooltip и две empty-effect/NULL-animation visual rows 0/1 |
global npc_store |
Reviewed zero gameplay-binding closure; cloned target/icon/text repurpose with exact restore |
505 |
Атака и защита (Power Potion) → временно Storage / Склад | То же prototype/visual closure; predecessor icon 4905 |
global npc_storage |
Reviewed zero gameplay-binding closure; cloned target/icon/text repurpose with exact restore |
506 |
Зелье силы ([Cash] Strength Potion) → временно Auction / Аукцион | То же prototype/visual closure; predecessor icon 5114 |
global npc_auction |
Reviewed zero gameplay-binding closure; cloned target/icon/text repurpose with exact restore |
507 |
Зелье ловкости ([Cash] Dex Potion) → временно Create guild / Создать гильдию | То же prototype/visual closure; predecessor icon 5115 |
global npc_guild_create |
Reviewed zero gameplay-binding closure; cloned target/icon/text repurpose with exact restore |
В LC export нет real housing blueprint/completion relation: world_building_templates, world_building_stages, world_building_stage_materials, world_build_category_rules, world_building_cultivation_areas и world_housing_cultivation_rules пусты. Поэтому 11378 выбран не как доказанный housing item, а как ближайший real drawing-shaped prototype по явному запросу real ID. Все drawings 11378..11391 запускают enabled quests 837..850 через a_start_type=1/a_start_data=<item>; 11378 не имеет меньшего production risk и потому строго isolated-test-only. Семантически близкий completion material 11435 отвергнут: enabled exchange 276 создаёт его из 11434, а exchange 278 расходует его у reachable NPC 1683.
Для workbench exact-key audit 11539 нашёл только presentation/model closure и t_synthesis_items.id=1; zero rows в craft_materials, craft_products, quest item fields, item_weapons/item_armors/item_accessories/holdables/wearables, NPC drops и semantic source literals. Поэтому он меньше production tools closure, но не consumer-free. Sibling 11540 отвергнут из-за того же synthesis route с большим synthesis_exp_add=600000; 11608 отвергнут как localized closed-testing title item (type/subtype=2/11, a_num_0=205), а не disposable placement material. Production tools {193..196,252..265} отвергнуты: каждый имеет item_weapons.item_id equipment binding и обслуживает legacy production path.
Low-level set 110/111/114/115/117/118 также не consumer-free: export содержит enabled t_item_collection requirements и legacy t_npc.a_item_* drop slots для этих IDs; 110 дополнительно уже расходуется craft_materials.id=3 в baseline recipe 6. Demo не UPDATE/DELETE эти relations, но новые reward/consumption routes меняют economy, поэтому весь set разрешён только в disposable cloned candidate с отдельными inventories. Для 876 exact item-key relations вне presentation/model closure не найдены, однако это не доказывает отсутствие существующих stacks или runtime/event issuance.
Target-once audit нашёл enabled exact 2/10 prototypes {2382,2848,5068,6360..6366,11319}. 2382 имеет affinity/luckydraw consumers, 2848 — luckydraw, 6361/6362/6365/6366 — collection/luckydraw, 11319 — luckydraw; 5068 и skill 996 имеют пустые en_us/ru_ru names. У 6360/6363/6364 exported gameplay consumer rows не найдены; выбран 6363 с полной localization/icon/model closure и exact baseline SQL row. Это не доказывает отсутствие уже выданных stacks или внешнего event issuance, поэтому fixture всё равно запрещён вне disposable clone.
Original associated skill 1161 также полностью существует в baseline export: a_base_class=999, show=0, canonical a_targetType=2 (TargetOne), legacy a_appRange/a_fireRange/a_fireRange2=5, icon 4905, localized name Немота (Silence), description/tooltip и ровно две NULL-animation visual rows weapon_index=0/1. Он unsuitable для Collect именно из-за unsupported legacy TargetOne; guide его row не UPDATE/DELETE. Temporary skill 84 имеет a_targetType=0 (Self), тот же existing icon 4905, localization и две visual rows; §7 изменяет только его reviewed WI extension tuple и связывает его с patched 6363.a_num_0/use_skill_id.
Server/wearables.sql подтверждает существование перечисленных item/skill/NPC identities, но не является доказательством полного byte-for-byte равенства export rows. В частности, для items 114 и 117 поле a_flag различается (export json: 0; SQL literal: 4294967323). Guide это поле не меняет и не использует; source owner обязан разрешить расхождение отдельно, а predecessor manifest всегда снимается с фактической candidate DB. Ни одно утверждение ниже не полагается на assumed full-row equality.
Skills 84..93 — baseline intersection, а не новые test skills. В skills.json у них a_base_class=999, show=0, a_targetType=0, icon 4905; skill_cast_client_visuals.json уже содержит для каждого exact rows weapon_index=0/1 с NULL animation IDs; icons.json:id=4905 задаёт legacy/skills/tex_0000_r00_c00.png. Имена существующие и намеренно не переименовываются этим demo:
| ID | Русское имя | Demo role | Риск |
|---|---|---|---|
84 |
Незначительное мгновенное восстановление здоровья | isolated direct item Collect | Existing hidden technical skill; item 6363 временно переключается с original skill 1161 на 84, только с exact restore |
85 |
Среднее мгновенное восстановление здоровья | NPC Collect | То же |
86 |
Значительное мгновенное восстановление здоровья | doodad harvest | Target metadata будет временно изменена на Doodad |
87 |
Малое мгновенное восстановление маны | seed placement | Existing item-skill identity |
88 |
Незначительное мгновенное восстановление маны | immediate NPC craft metadata | Existing item-skill identity |
89 |
Среднее мгновенное восстановление маны | workbench action/craft metadata | Target metadata будет временно изменена на Doodad |
90 |
Значительное мгновенное восстановление маны | housing blueprint placement | Housing остаётся blocked |
91 |
Малое мгновенное восстановление здоровья и маны | housing build contribution | Target metadata будет временно изменена на Doodad; housing blocked |
92 |
Незначительное мгновенное восстановление здоровья | workbench placement | Real item 11539; весь branch isolated-test-only из-за synthesis consumer |
93 |
Среднее мгновенное восстановление здоровья и маны | isolated structural plot | Template-only |
Эти skill names не соответствуют будущему production UX. Поэтому set 84..93 допускается только для disposable isolated technical candidate с exact predecessor tuple; canonical production projection должна выбрать owner-approved dedicated skills/localization. WI-PROTOTYPE-02 consumer audit не нашёл gameplay closure: zero skill_effects.skill_id, zero skill_tree.col_0..7, zero NPC a_skill0..3, zero quest skill reward, zero craft/AI/item binding и zero semantic hardcoded skill-ID comparison в GameServer/client Engine/EntitiesMP *.es. Две visual rows на каждый skill (weapon_index=0/1) и localization являются presentation closure. Совпадающие literals 84..93 в source относятся к item IDs, chances, localization keys и unrelated enums, а quest a_start_data/condition literals — к NPC/item semantics по их type fields. Поэтому IDs приняты без замены, но только для cloned isolated candidate: отсутствие exported consumers не является разрешением превращать hidden legacy identities в production content.
Corpse action skills намеренно выбраны вне 84..93: все десять уже заняты другими guide scenarios и имеют несовместимую metadata, поэтому их cumulative closure не равна zero. Для real technical skills 491/492 повторный exact audit нашёл zero skill_effects.skill_id, zero skill_tree.col_0..7, zero parsed NPC a_skill0..3, zero base_skill_id, quest/craft/tagged/WI skill relation и zero semantic skill-ID comparison/Create в GameServer, client Engine и primary *.es. Numeric source literals 491/492 относятся к NPC prototype checks, localization/UI coordinates; единственный semantic m_skillProtoList.Create(493,1) доказывает, почему соседний 493 отвергнут. Raw items.a_num_0 collisions не являются skill links: для 491 это ровно disabled armor 10559/10560, для 492 — ровно disabled armor 8434/10591/10592/10598/10695/10696/10702; все имеют a_type_idx=1, тогда как item-use skill paths отсутствуют. Export visual closure — exact two rows weapon_index=0/1, empty effects and NULL animation IDs for each skill. Это evidence только для isolated clone, не production ownership.
Global NPC service manifest §7.4 добавляет real NPC prototypes {20,33,89,149,899} и использует отдельные reviewed real skills {504,505,506,507}. Skills 84..93 уже заняты cumulative guide roles и для services не переиспользуются. Для 504..507 export/source audit подтвердил a_base_class=999, show=0, a_targetType=0, zero skill_effects, zero skill-tree/parsed NPC/base-skill/WI/craft bindings, zero enabled once-use items.a_num_0 binding и zero semantic hardcoded skill-ID use; existing non-once item numeric collisions не являются skill links. Client closure содержит exact две empty-effect/NULL-animation visual rows weapon_index=0/1; predecessor icons равны 504/505→4905, 506→5114, 507→5115. NPC evidence: shoppers 20/33 имеют t_shop spawn rows; keeper 149, guild NPC 89 и auction candidate 899 имеют exact t_npc_regen rows. Их prototypes, flags, shop/regen rows, global icons 5123..5126 и visual rows не вставляются и не удаляются; меняются только guarded skill presentation/target/localization fields и nullable NPC set binding с exact restore. Inserted WI-owned set/action IDs {907010..907014,907110..907114} проходят collision preflight и не являются LC prototype IDs.
| ID | Placeholder purpose | Конкретный blocker |
|---|---|---|
900200 |
LC zone (t_zonedata.a_zone_index) |
Нет approved configured local zone/map package |
900201 |
LC area index | Зависит от выбранной zone и её a_areacount |
900202 |
LC layer | Зависит от выбранной zone и её a_ylayer |
Внешних item/NPC/skill prototype placeholders больше нет. 900200..900202 — только unresolved map scope, а не item/NPC IDs. Используемые model IDs {950001,950002,950003,950010,950020,950030,950031}, polygon coordinates и model paths остаются именованными demo placeholders до accepted content packages. Guide больше не вставляет synthetic icon IDs: реальные prototype icons перечислены выше. PostgreSQL character 900500 — отдельный diagnostic placeholder, а не static content ID.
Дополнительные demo identities: 912011 — CraftStart payload, 914011 — его doodad action, 920012 — Start→recipe membership, 915100 — authored static spawn, 970001 — plot, 970002 — root event, 970003 — только reserved optional plot_effects.id (сам structural demo его не вставляет). Все они проходят тот же collision review.
Имена non-ID placeholders для manifest: DEMO_ZONE_ID=900200, DEMO_AREA_ID=900201, DEMO_LAYER_ID=900202; DEMO_HOUSING_POLYGON_V1..V4=(100,100),(140,100),(140,140),(100,140); DEMO_STATIC_SPAWN_X/Y/Z/ROTATION=(120,0,120,0); DEMO_TEST_CHARACTER_ID=900500; DEMO_MODEL_PATH_* — строки §12.1. Эти labels не являются SQL variables: при замене значение меняется согласованно во всех authoring, diagnostics и cleanup predicates.
Перед authoring проверьте collisions и prerequisites. В examples используются только explicit column lists, без wildcard selects:
-- Server projection after 0001: capture all three mutable C0 fields.
SELECT a_index, a_type_idx, a_subtype_idx, a_num_0, a_num_1,
a_enable, a_job_flag, a_flag, a_wearing,
use_skill_id, use_skill_as_reagent, icon_id
FROM items
WHERE a_index IN (110,111,114,115,117,118,876,6363,11378,11539)
ORDER BY a_index;
-- Client compact projection: WI-only use_skill columns are absent by design.
SELECT a_index, a_type_idx, a_subtype_idx, a_num_0, a_num_1,
a_enable, a_job_flag, a_flag, a_wearing, icon_id
FROM items
WHERE a_index IN (110,111,114,115,117,118,876,6363,11378,11539)
ORDER BY a_index;
-- Server projection skill tuple after 0001.
SELECT a_index, a_base_class, icon_id,
show,
plot_id, consume_lp, actability_group_id, category_id, timing_id,
a_targetType, target_selection_id, target_relation_id,
min_range, max_range, casting_time, cooldown_time, channeling_time,
channeling_tick, channeling_mana, target_dead, target_alive,
check_terrain, target_water, target_only_water, target_my_npc,
or_unit_reqs, mainhand_tool_id, offhand_tool_id
FROM skills
WHERE a_index BETWEEN 84 AND 93 OR a_index IN (491,492,504,505,506,507)
ORDER BY a_index;
-- Client projection contains canonical a_targetType, but not the 0001 tuple.
SELECT a_index, a_base_class, show, a_targetType, icon_id
FROM skills
WHERE a_index BETWEEN 84 AND 93 OR a_index IN (491,492,504,505,506,507)
ORDER BY a_index;
SELECT a_index, a_enable, npc_interaction_set_id
FROM t_npc
WHERE a_index IN (1683,1690)
ORDER BY a_index;
-- Original item-associated skill: immutable evidence only, never updated by this demo.
SELECT a_index, a_base_class, show, a_targetType,
a_appRange, a_fireRange, a_fireRange2, icon_id
FROM skills
WHERE a_index=1161;
SELECT skill_id, weapon_index, ready_ani_id, still_ani_id, fire_ani_id
FROM skill_cast_client_visuals
WHERE skill_id IN (84,491,492,1161)
ORDER BY skill_id, weapon_index;
-- Corpse skills: raw numeric item collisions must remain disabled armor data,
-- not item-use skill bindings. Exact rows/counts are immutable audit evidence.
SELECT a_index, a_type_idx, a_subtype_idx, a_enable, a_num_0
FROM items
WHERE a_num_0 IN (491,492)
ORDER BY a_num_0, a_index;
SELECT tbl_name, tbl_column_name, idx, en_us, ru_ru
FROM localized_texts
WHERE tbl_name='skills' AND idx IN (491,492)
AND tbl_column_name IN ('name','description','tooltip')
ORDER BY idx, tbl_column_name;
-- Existing consumers of the two isolated-only replacement items must remain exact.
SELECT a_index, a_enable, a_start_type, a_start_data
FROM t_quest
WHERE a_index=837 AND a_enable=1 AND a_start_type=1 AND a_start_data=11378;
SELECT id, type, item_id, grade, synthesis_exp_add, is_pickup
FROM t_synthesis_items
WHERE id=1 AND type=1 AND item_id=11539 AND grade=1
AND synthesis_exp_add=30000 AND is_pickup=1;
SELECT a_zone_index, a_areacount, a_ylayer
FROM t_zonedata
WHERE a_zone_index = 900200;
Результаты server item, client item, skill и NPC prototype queries должны быть сохранены verbatim в immutable predecessor manifest до первого UPDATE. Для 6363 обе schema-specific manifest rows обязательно сохраняют actual a_num_0=1161; server row дополнительно сохраняет actual use_skill_id/use_skill_as_reagent, которых в client schema нет. Cleanup принимает только exact values через bound :prev_*, и их нельзя заменять assumed defaults. Каждый prototype UPDATE обязан иметь полный predecessor predicate по изменяемому tuple, немедленный changes()/driver affected-row check и затронуть ровно одну row; skill template выполняется отдельно для каждого ID 84..93, также с expected affected rows 1. Иное число означает drift и требует ROLLBACK, а не продолжения INSERTs. Если real row отсутствует либо tuple отличается от evidence выше, остановитесь и выпустите новый reviewed manifest. Для 11378 manifest дополнительно pin-ит unchanged quest relation t_quest(837).a_start_type=1,a_start_data=11378; для 11539 — unchanged synthesis relation t_synthesis_items(1).item_id=11539,grade=1,synthesis_exp_add=30000,is_pickup=1. Skills 491/492 имеют отдельный corpse manifest: server сохраняет exact previous a_targetType/target_selection_id/target_relation_id; client сохраняет previous a_targetType/icon_id и exact en_us/ru_ru каждой name/description/tooltip row. Для 84..93 должны сохраняться a_base_class=999, show=0, icon_id=4905; для 491/492 — a_base_class=999, show=0, predecessor icon_id=5127. Для каждой row в final client DB обязательны обе существующие skill_cast_client_visuals rows weapon_index=0/1, которые guide не INSERT/UPDATE/DELETE. Global icons rows никогда не UPDATE/DELETE. Между export и Server/wearables.sql доказано совпадение identities и используемой presentation/target metadata, но не полное равенство всех нетронутых полей; AA→LC identity mapping допускается только из отдельного reviewed manifest, а не из равенства integer ID.
Service predecessor manifest отдельно сохраняет server target/range tuple и client a_targetType/icon_id плюс exact 12 localization rows для 504..507. Exact predecessor icons: 504=4905, 505=4905, 506=5114, 507=5115; guessed restore запрещён.
Заменить и записать в manifest нужно всё следующее:
{110,111,114,115,117,118,876,6363,11378,11539}, NPC {20,33,89,149,899,1683,1690}, skills {84..93,491,492,504..507}; для direct Collect отдельно pin original 6363.a_num_0=1161, для service clone pin 504..507 target/icon/localization и все пять NPC set predecessors, для corpse pin exact metadata/icon/localization predecessors 491/492; external prototype placeholders отсутствуют; заменить только map scope 900200/900201/900202 из approved package;{902001,902002,902003,902004}; foundation row IDs {902101..902104,902201..902204,903001,903002,904001,904002,905001,905002,906001,906002,906101,907001,907101,907010..907014,907110..907114}; doodad {910000..910003,911001..911003,911010,911020,912001..912003,912010,912011,913001,913002,914001,914010,914011,915001,915002,915100}; craft {920001,920002,920010..920012,920100,921001,921002,922001,922002}; loot {930001..930006}; housing {940001..940003,940010,940020,940030,940031,940040,940050,940060,940101}; plot {970001,970002} plus reserved optional plot_effects.id=970003;{950001,950002,950003,950010,950020,950030,950031}, each final resource path/kind/animation/scale/offset/shadow and transitive asset hashes; промежуточные IDs диапазона не резервируются этим guide;missing_icon.png, every item/skill name/description/tooltip language row; synthetic icon rows не создаются;920100 (должна отсутствовать до §9), titles/category names, materials/results/grades/rate/NAS/labor/delay/actability and whether Pack or Start is selected;900500, its actual account_id, approved PG migration subset and canary scope; эти values не вставляются вручную в runtime tables;actual_type, concrete payload table/ID and selectors, если no-op template превращается в реальное умение;Ни один numeric/path/coordinate placeholder не имеет default production meaning.
Writes перечисляет только tables данного guide, не owner-created LC prototype/localization rows. Cleanup означает exact IDs/predicates §15 плюс восстановление изменённых prototype columns из manifest.
| Demo | Класс | Writes (insert/update) | Reverse cleanup | Обязательные prerequisites/blockers |
|---|---|---|---|---|
| Foundation item/NPC Collect | NPC subset runtime-supported; direct 6363→84 runnable only in isolated cloned projection |
wi_groups, wi_details, wi_group_wis, skills, items.a_num_0/use_skill_*, skill_products, skill_reagents, interaction_effects, effects, skill_effects, npc_interaction_sets, npc_interactions, t_npc |
NPC binding/actions → skill/effect payload → products/reagents → WI mappings/details → exact item/skill prototype restore | Complete 0001 + forward parent closure; matching client/server cloned item row; self-target through player portrait; exact predecessor/restore; 0020/0021; never live/shared item stacks |
| Seed/workbench doodads | Runtime-supported placement/harvest subset; InsideGarden seed blocked without housing | doodad_groups, doodad_almighties, doodad_func_groups, Growth/Timer/LootItem payloads, doodad_phase_funcs, doodad_funcs, items, item_spawn_doodads |
item bindings/actions/functions → payloads → phases/templates/group → item restore | Complete 0002/0003; Foundation WI 902003; exact model and map/placement package; 0020..0023/0026 |
| Immediate craft + Pack | Runtime-supported immediate subset, template до matching server/client projection | craft_c_categories, skills, crafts, craft_materials, craft_products, craft_packs, craft_pack_crafts, doodad_func_craft_packs, doodad_funcs |
action → membership/payload → product/material → recipe/pack/category → skill restore | Complete 0004 and doodad phase 911010; Craft WI 902004; matching client catalog; delay=0 |
| CraftStart alternative | Runtime-supported alternative delta | doodad_func_craft_starts, doodad_func_craft_start_crafts, doodad_funcs |
action → membership → payload | Base craft recipe 920002; choose intentionally instead of Pack duplicate UX; matching client rows |
| Corpse loot | Runtime-supported memory-only subset | server skills 491/492, foundation skill_constants, corpse_action_types, corpse_loot_skill_overrides, loot_packs, loot_groups, loots, loot_pack_dropping_npcs; client skills/localized_texts плюс compact mirrored skill_constants, corpse_action_types |
route → loot → synthetic group → pack; global actions/constants → exact server/client skill/localization/registry restore | Complete server 0001+0003 и client client_0002; exact matching constants/actions, enabled NPC/item and valid item grade; two local visual rows and shipped icons; durable corpse PostgreSQL schema отсутствует |
| Housing/build/garden | Template-only, rollout blocked | housing sizes/taxation/design/build/group/area/polygon/item binding; skill_reagents; items |
item binding/geometry/area/group/build/reagent → design/taxation/sizes → item/skill restore | Complete 0006 all gates, §11 blockers, accepted geometry/model/map, fresh 0020..0026 |
| Authored static Gather | Loader/runtime shape, package blocked | lc_doodad_spawns |
exact spawn row only | §8 graph; accepted map transform/model package; reconciliation approval |
| Isolated skill plot | Structural template-only/no-op | plots, plot_events, skills |
unlink skill → optional exact child → event → plot → remaining skill tuple restore | Complete 0005; separate skill 93; no InteractionEffect; concrete gameplay payload intentionally absent |
| Client models/icons | Models template-only; prototype icons reused as-is | lc_model_resources; no icon/prototype-icon writes |
exact model rows only | Final client schema, exact sparse model set/assets, existing icon PNGs/localization and two skill_cast_client_visuals rows per loaded skill |
Класс примера: NPC Collect — runtime-open template после canonical projection, PostgreSQL 0020/0021, isolated canary и client/server prototype closure. Direct item Collect теперь использует real enabled target-once item 6363: его exact LC type/subtype 2/10 уже входит в client ITEM_ONCEUSE/ITEM_SUB_TARGET и server ITYPE_ONCE/IONCE_TARGET dispatch. Original a_num_0=1161 указывает на combat skill с canonical a_targetType=2 (TargetOne), который WI Collect не принимает. Поэтому runnable isolated fixture образует один compatibility set из двух отдельно транзакционных cloned artifacts: client меняет только свой реально существующий dispatch field a_num_0 на 84; server меняет a_num_0 и WI-only binding use_skill_id/use_skill_as_reagent на 84/1. Cross-database atomic transaction здесь не предполагается: traffic открывается только после успешной подготовки обоих artifacts, а teardown восстанавливает оба predecessor artifacts. Это не production repurpose предмета.
Скрипт предполагает, что 0001 и требуемая forward-FK parent schema closure из §4 уже находятся в отдельной offline candidate-копии, а перечисленные LC prototypes существуют. Это не разрешение устанавливать пустые optional packages в release artifact.
До блока existing rows wi_groups.id IN (1,2,3) должны быть либо отсутствующими, либо иметь exact pairs 1/Craft, 2/Collect, 3/Building. INSERT OR IGNORE ниже нужен только для shared fixed identities и не разрешает silently принимать другое name. Все остальные inserted primary/unique IDs, включая wi_id=902001..902004, должны отсутствовать по exact table/key collision review.
Skill prototype updates выполняются одним parameterized template по одной row. Desired values, отличающиеся между IDs:
| Skill | a_targetType |
target_selection_id |
consume_lp |
max_range |
Роль |
|---|---|---|---|---|---|
84 |
0 |
1 |
0 |
0.0 |
direct Collect |
85 |
0 |
1 |
0 |
0.0 |
NPC Collect (target остаётся source character) |
86 |
20 |
2 |
0 |
8.0 |
doodad harvest |
87 |
0 |
1 |
0 |
8.0 |
seed placement |
88 |
0 |
1 |
5 |
0.0 |
immediate NPC craft metadata |
89 |
20 |
2 |
5 |
8.0 |
workbench action/craft metadata |
90 |
0 |
1 |
0 |
8.0 |
housing blueprint placement |
91 |
20 |
2 |
1 |
8.0 |
housing contribution |
92 |
0 |
1 |
0 |
8.0 |
workbench placement |
Для всех девяти server rows desired plot_id=NULL, actability_group_id=category_id=timing_id=0, target_relation_id=0, min_range=0.0, все timing/water/dead/my-NPC/requirement flags — 0, кроме target_alive=1; tool IDs — NULL. Каждому вызову server template передаются exact :prev_* из одной immutable manifest row и desired :demo_* из таблицы выше; сразу после каждого вызова driver/SELECT changes() обязан подтвердить ровно 1. Client baseline не содержит этот WI extension tuple; там сохраняется/проверяется только существующий skills.a_targetType (для C0 skill 84 он уже canonical 0) и presentation/visual closure.
PRAGMA foreign_keys = ON;
BEGIN IMMEDIATE;
INSERT OR IGNORE INTO wi_groups (id, name) VALUES
(1, 'Craft'),
(2, 'Collect'),
(3, 'Building');
INSERT INTO wi_details (id, wi_id, lp, apply_expert, distance_sqrt) VALUES
(902101, 902001, 1, 0, 0.0),
(902102, 902002, 1, 0, 0.0),
(902103, 902003, 1, 0, 0.0),
(902104, 902004, 1, 0, 0.0);
INSERT INTO wi_group_wis (id, wi_group_id, wi_id) VALUES
(902201, 2, 902001),
(902202, 2, 902002),
(902203, 2, 902003),
(902204, 1, 902004);
-- Execute exactly once for each skill 84..92 with the reviewed bindings above.
UPDATE skills SET
plot_id=:demo_plot_id,
consume_lp=:demo_consume_lp,
actability_group_id=:demo_actability_group_id,
category_id=:demo_category_id,
timing_id=:demo_timing_id,
a_targetType=:demo_a_targetType,
target_selection_id=:demo_target_selection_id,
target_relation_id=:demo_target_relation_id,
min_range=:demo_min_range,
max_range=:demo_max_range,
casting_time=:demo_casting_time,
cooldown_time=:demo_cooldown_time,
channeling_time=:demo_channeling_time,
channeling_tick=:demo_channeling_tick,
channeling_mana=:demo_channeling_mana,
target_dead=:demo_target_dead,
target_alive=:demo_target_alive,
check_terrain=:demo_check_terrain,
target_water=:demo_target_water,
target_only_water=:demo_target_only_water,
target_my_npc=:demo_target_my_npc,
or_unit_reqs=:demo_or_unit_reqs,
mainhand_tool_id=:demo_mainhand_tool_id,
offhand_tool_id=:demo_offhand_tool_id
WHERE a_index=:skill_id
AND a_base_class=999 AND show=0 AND icon_id=4905
AND plot_id IS :prev_plot_id AND consume_lp IS :prev_consume_lp
AND actability_group_id IS :prev_actability_group_id AND category_id IS :prev_category_id
AND timing_id IS :prev_timing_id AND a_targetType IS :prev_a_targetType
AND target_selection_id IS :prev_target_selection_id AND target_relation_id IS :prev_target_relation_id
AND min_range IS :prev_min_range AND max_range IS :prev_max_range
AND casting_time IS :prev_casting_time AND cooldown_time IS :prev_cooldown_time
AND channeling_time IS :prev_channeling_time AND channeling_tick IS :prev_channeling_tick
AND channeling_mana IS :prev_channeling_mana AND target_dead IS :prev_target_dead
AND target_alive IS :prev_target_alive AND check_terrain IS :prev_check_terrain
AND target_water IS :prev_target_water AND target_only_water IS :prev_target_only_water
AND target_my_npc IS :prev_target_my_npc AND or_unit_reqs IS :prev_or_unit_reqs
AND mainhand_tool_id IS :prev_mainhand_tool_id AND offhand_tool_id IS :prev_offhand_tool_id;
SELECT changes() AS affected_server_skill_update; -- require exactly 1 before the next statement
-- Server half of isolated-only runnable 6363→84 fixture.
UPDATE items
SET a_num_0 = 84,
use_skill_id = 84,
use_skill_as_reagent = 1
WHERE a_index = 6363
AND a_type_idx=2 AND a_subtype_idx=10 AND a_num_0=:prev_item_6363_num0
AND :prev_item_6363_num0=1161
AND a_num_1=1 AND a_enable=1 AND a_job_flag=511
AND a_flag=16778257 AND a_wearing=-1 AND icon_id=2657
AND use_skill_id IS :prev_item_6363_use_skill
AND use_skill_as_reagent IS :prev_item_6363_use_reagent;
SELECT changes() AS affected_server_item_6363_update; -- require exactly 1
INSERT INTO skill_products (id, skill_id, item_id, amount, enable) VALUES
(906001, 84, 117, 1, 1),
(906002, 85, 115, 1, 1);
-- NPC action has no source item, therefore it needs an explicit reagent.
INSERT INTO skill_reagents (id, skill_id, item_id, amount, enable) VALUES
(906101, 85, 114, 2, 1);
INSERT INTO interaction_effects (id, wi_id, doodad_id, source_direction) VALUES
(903001, 902001, NULL, 0),
(903002, 902002, NULL, 0);
INSERT INTO effects (id, actual_type, actual_id, description) VALUES
(904001, 'InteractionEffect', 903001, 'WI demo: item Collect'),
(904002, 'InteractionEffect', 903002, 'WI demo: NPC Collect');
INSERT INTO skill_effects (
id, skill_id, effect_id, always_hit, application_method, chance,
consume_item_count, consume_item_id, consume_source_item,
start_level, end_level, friendly, non_friendly,
source_buff_tag, source_nobuff_tag, target_buff_tag, target_nobuff_tag, target_npc_tag,
weight, front, back, interaction_success_hit, enable
) VALUES
(905001, 84, 904001, 1, 1, 100, 0, 0, 0, 1, 55, 1, 1, '', '', '', '', '', 1, 0, 0, 1, 1),
(905002, 85, 904002, 1, 1, 100, 0, 0, 0, 1, 55, 1, 1, '', '', '', '', '', 1, 0, 0, 1, 1);
INSERT INTO npc_interaction_sets (id, name)
VALUES (907001, 'WI demo NPC Collect');
INSERT INTO npc_interactions (id, npc_interaction_set_id, skill_id)
VALUES (907101, 907001, 85);
UPDATE t_npc
SET npc_interaction_set_id = 907001
WHERE a_index = 1690
AND a_enable=1
AND npc_interaction_set_id IS :prev_npc_1690_interaction_set;
SELECT changes() AS affected_server_npc_1690_update; -- require exactly 1
COMMIT;
Client compact DB не получает 0001 и не имеет items.use_skill_id/use_skill_as_reagent. Для C0 его complete symmetric half — только следующий a_num_0 override; добавлять отсутствующие WI-only columns в client schema запрещено:
BEGIN IMMEDIATE;
UPDATE items
SET a_num_0 = 84
WHERE a_index = 6363
AND a_type_idx=2 AND a_subtype_idx=10
AND a_num_0=:prev_client_item_6363_num0
AND :prev_client_item_6363_num0=1161
AND a_num_1=1 AND a_enable=1 AND a_job_flag=511
AND a_flag=16778257 AND a_wearing=-1 AND icon_id=2657;
SELECT changes() AS affected_client_item_6363_update; -- require exactly 1
-- Immutable prerequisites, not writes: skill 84 has a_targetType=0,
-- icon_id=4905 and exact visual rows weapon_index 0/1.
COMMIT;
Для cumulative client projection с doodad/build actions из таблицы §7.1 отдельно mirror-ится только реально существующий canonical skills.a_targetType. Baseline skills 84..93 имеют a_targetType=0, поэтому client UPDATE нужен только для desired Doodad skills {86,89,91} и выполняется по одной row:
BEGIN IMMEDIATE;
-- Execute once for skill_id 86, 89 and 91 only; :demo_a_targetType=20.
UPDATE skills
SET a_targetType=:demo_a_targetType
WHERE a_index=:skill_id
AND a_base_class=999 AND show=0 AND icon_id=4905
AND a_targetType IS :prev_client_a_targetType
AND :prev_client_a_targetType=0;
SELECT changes() AS affected_client_skill_target_update; -- require exactly 1 each
COMMIT;
Остальной WI skill extension tuple существует и изменяется только на server. Skill 84 для C0 уже имеет одинаковый canonical Self=0 в baseline client/server prototypes; client preflight проверяет его, но не делает no-op UPDATE.
Все соответствующие server/client transactions выполняются offline. Tool обязан не делать COMMIT, если любой affected-row result не равен 1; если один artifact уже записан, compatibility set не публикуется и восстанавливается из immutable predecessor.
Direct Collect допускается только если:
a_num_0) exact-но совпадает с WI item binding;2/Collect;apply_expert = 0;Для exact 6363 type/subtype уже правильные и не меняются. Runnable test sequence: на isolated character получить отдельный test stack 6363, левой кнопкой выбрать собственный portrait (CSimplePlayerInfoUI::OnLButtonDown() вызывает SetTargetMe()), затем использовать item. Client читает patched a_num_0=84, проходит delay/range с self distance 0, отправляет свой MSG_CHAR_PC/index; server повторно разрешает inventory slot, exact 2/10, equality a_num_0=use_skill_id=84, target Self/Source и authoritative Collect plan. Выбор чужого target корректно даст TargetMismatch. Forged packet не является тестом.
Override 6363.a_num_0 1161→84 допустим только в disposable cloned client/server compatibility set и должен затронуть ровно одну row в каждой отдельной projection transaction. Server дополнительно и тем же guarded способом меняет use_skill_id/use_skill_as_reagent; client этих columns не имеет. a_type_idx, a_subtype_idx, a_num_1, icon/localization, original skill 1161 и все presentation rows не меняются. После C0 остановите consumers и выполните conditional restore §15; при любом drift — ROLLBACK/whole-artifact restore. Existing combat description предмета вводит в заблуждение и делает fixture непригодным для player-facing/live canary, но не блокирует isolated execution.
NPC action дополнительно требует текущий runtime NPC, тот же area/layer, distance не больше 8 м, exact NPC prototype → set → action binding. UI получает actionId, skillId, availability; name/icon берутся из client local skill data.
1690 не имеет keyed row ни в t_npc_regen.json, ни в regen combo/cube/raid exports. Поэтому §7 NPC action и §10 corpse route не появятся от одних static rows. Обязательный prerequisite — уже существующий, отдельно reviewed admin/runtime spawn fixture, который создаёт t_npc.a_index=1690 только в закрытой cloned test zone/area и допускает его controlled death; guide не добавляет guessed regen SQL или spawn command. После teardown восстанавливается весь cloned zone artifact/runtime state. Использовать production monster вместо 1690 ради reachability запрещено: corpse mapping тогда изменит loot path всех его live instances.
a_targetType=0 (Self), target_selection_id=1 (Source), target_relation_id=0 (Any). NPC является interaction context, но target supported Collect всё равно source character. Не меняйте его на NPC/GeneralUnit ради подписи окна.a_targetType=20 (Doodad), target_selection_id=2 (Target), target_relation_id=0; placement item — Self/Source/Any. У skill нет второго target-type source: используется только skills.a_targetType. В plots.target_type_id остаются authored AA values 0..26, которые loader конвертирует в canonical 0,13..38.skills.a_targetType должно входить в один reviewed client/server content artifact set; legacy 0..12 нельзя переосмысливать по совпадающим AA numbers.plot_id IS NULL, tool IDs NULL, or_unit_reqs=0, нет enabled unit_reqs с owner_type='Skill', а casting_time/cooldown_time/channeling_time=0. Loader может принять больше metadata, но handler закроется как unsupported.skill_reagents/skill_products — gameplay rows. use_skill_as_reagent=1 добавляет один actual source item к reagents; не дублируйте тот же расход случайно в skill_reagents, если нужны не две единицы.skills.consume_lp * wi_details.lp; wi_details.distance_sqrt сейчас лишь загружается и не заменяет target/doodad/NPC range checks.GetSkillData(skillId).GetName() и CUIIcon::setSkill(skillId). Поэтому в client DB нужны loader-visible skills.a_index с a_base_class >= 0, skills.icon_id, две skill_cast_client_visuals rows и localized_texts rows для tbl_name='skills', tbl_column_name IN ('name','description','tooltip'), idx=skill_id, column текущего языка. Отдельной skills.a_enable в canonical client schema нет.interactActions.xml имеет exact hierarchy Window interactActions → UIText txt_active_npc + UIArray array_interact_actions (row=1,col=5,show_row=1) → template UIArrayItem → frame UIImage → UIIcon icon_interact + UIText hotkey_text_slot. Runtime capacity равна 5: те же slots обслуживают hit-test/click, Shift+1..5, tooltip/hover и disabled/pending state; name/status columns и scrollbar отсутствуют.localized_texts(tbl_name='items', tbl_column_name='name'|'description', idx=item_id); у items отдельной tooltip localization в этом path нет.Это disposable cloned prototype, совместимый с cumulative guide: skills 84..93 остаются закреплены только за ролями §6.1 и не переиспользуются. Services временно repurpose reviewed real skills 504..507 в остановленных cloned server/client SQLite artifacts и затем exact-но восстанавливают их target/icon/localization predecessors.
| Constant | Skill | Client icon | Временное имя en_us / ru_ru |
NPC binding |
|---|---|---|---|---|
npc_store |
504 |
5123 → legacy/skills/tex_0001_r02_c14.png |
Store / Магазин |
20 и 33, два разных sets |
npc_storage |
505 |
5124 → legacy/skills/tex_0001_r02_c15.png |
Storage / Склад |
149 |
npc_auction |
506 |
5125 → legacy/skills/tex_0001_r03_c00.png |
Auction / Аукцион |
reviewed candidate 899 |
npc_guild_create |
507 |
5126 → legacy/skills/tex_0001_r03_c01.png |
Create guild / Создать гильдию |
89 |
Все server skills получают exact GeneralUnit(31)/Target(2)/Any(0) и range 0..8m. Client получает a_targetType=31, distinct existing icon references и service localization; существующие две visual rows weapon_index=0/1 с empty effects и NULL animation IDs не изменяются. icons, prototypes и skill_cast_client_visuals не INSERT/DELETE; icon/visual rows вообще не UPDATE.
NPC evidence. 20 (Merchant Geres) и 33 (Weapon Trader Baran) enabled, имеют a_flag=33554705 с NPC_SHOPPER и реальные t_shop rows zone 0, layer 0: (629.75,109.958,743.75) и (618.75,109.964,743.0). Area.cpp создаёт runtime NPC из t_shop, отдельный regen им не нужен. 149 (Storekeeper Bianca) имеет NPC_KEEPER в a_flag=33816848 и regen 3663343, zone 0, layer 0, (593,109.966,739.75). 89 (Royal Guard Captain) имеет NPC_GUILD в a_flag=34144528 и regen 3663187, zone 0, layer 0, (538,109.971,729.5). 899 (Trading Agent Siban) имеет regen 3663842, zone 0, layer 0, (495,109.977,892.5). Auction не имеет отдельного authoritative a_flag readiness gate: exported a_flag1=1 — legacy NPC1_TRADEAGENT interaction marker, но service authorization опирается на authored typed binding и live SubHelper. Поэтому marker не является authority и случайный NPC по нему не назначается.
Complete constants schema также требует уже authored exact corpse pair §10. До write сохраните оба predecessor result sets verbatim во внешний immutable manifest. Collision/consumer queries ниже должны вернуть zero rows; role/spawn queries — exact evidence rows. Package-specific consumers (doodad_funcs, crafts, housing_build_steps) также должны быть zero, если соответствующие optional tables установлены.
PRAGMA foreign_keys = ON;
SELECT constant_key,skill_id,enabled FROM skill_constants
WHERE constant_key IN ('corpse_inspect','corpse_take')
ORDER BY constant_key COLLATE BINARY; -- exact enabled prerequisite from §10
SELECT constant_key,skill_id,enabled FROM skill_constants
WHERE constant_key IN ('npc_store','npc_storage','npc_auction','npc_guild_create')
OR skill_id IN (504,505,506,507); -- zero rows
SELECT id,name FROM npc_interaction_sets
WHERE id IN (907010,907011,907012,907013,907014); -- zero rows
SELECT id,npc_interaction_set_id,skill_id,skill_constant_key FROM npc_interactions
WHERE id IN (907110,907111,907112,907113,907114)
OR skill_id IN (504,505,506,507)
OR skill_constant_key IN ('npc_store','npc_storage','npc_auction','npc_guild_create'); -- zero rows
SELECT id,skill_id,effect_id,enable FROM skill_effects
WHERE skill_id IN (504,505,506,507); -- zero rows
SELECT id,skill_id,item_id,amount,enable FROM skill_reagents
WHERE skill_id IN (504,505,506,507); -- zero rows
SELECT id,skill_id,item_id,amount,enable FROM skill_products
WHERE skill_id IN (504,505,506,507); -- zero rows
SELECT id,owner_id,owner_type,kind_id,enable FROM unit_reqs
WHERE owner_type='Skill' AND owner_id IN (504,505,506,507); -- zero rows
SELECT a_index,plot_id FROM skills
WHERE a_index IN (504,505,506,507) AND plot_id IS NOT NULL; -- zero rows
SELECT a_index,a_type_idx,a_subtype_idx,a_num_0,use_skill_id FROM items
WHERE use_skill_id IN (504,505,506,507)
OR (a_enable=1 AND a_type_idx=2
AND a_num_0 IN (504,505,506,507)); -- zero rows
SELECT num_row,job,subjob,col_0,col_1,col_2,col_3,col_4,col_5,col_6,col_7
FROM skill_tree
WHERE 504 IN (col_0,col_1,col_2,col_3,col_4,col_5,col_6,col_7)
OR 505 IN (col_0,col_1,col_2,col_3,col_4,col_5,col_6,col_7)
OR 506 IN (col_0,col_1,col_2,col_3,col_4,col_5,col_6,col_7)
OR 507 IN (col_0,col_1,col_2,col_3,col_4,col_5,col_6,col_7); -- zero rows
-- Exact predecessor snapshots: require 4 and 5 rows respectively.
SELECT a_index,a_base_class,show,icon_id,plot_id,consume_lp,
actability_group_id,category_id,timing_id,a_targetType,
target_selection_id,target_relation_id,min_range,max_range,
casting_time,cooldown_time,channeling_time,channeling_tick,channeling_mana,
target_dead,target_alive,check_terrain,target_water,target_only_water,
target_my_npc,or_unit_reqs,mainhand_tool_id,offhand_tool_id
FROM skills WHERE a_index IN (504,505,506,507) ORDER BY a_index;
SELECT a_index,a_enable,a_flag,a_flag1,npc_interaction_set_id
FROM t_npc WHERE a_index IN (20,33,89,149,899) ORDER BY a_index;
SELECT a_index,a_enable,a_flag,a_flag1,(a_flag&1) AS shopper,
(a_flag&262144) AS keeper,(a_flag&524288) AS guild
FROM t_npc WHERE a_index IN (20,33,89,149,899) ORDER BY a_index;
SELECT a_keeper_idx,a_zone_num,a_pos_x,a_pos_h,a_pos_z,a_y_layer
FROM t_shop WHERE a_keeper_idx IN (20,33) ORDER BY a_keeper_idx;
SELECT a_index,a_zone_num,a_npc_idx,a_pos_x,a_pos_h,a_pos_z,a_y_layer
FROM t_npc_regen WHERE a_index IN (3663343,3663842,3663187)
ORDER BY a_index;
Если consumer найден, его нельзя удалять ради demo. Каждый changes() ниже обязан быть 1, иначе ROLLBACK; ID-specific :prev_skill_<id>_* берутся только из соответствующей captured predecessor row.
PRAGMA foreign_keys = ON;
BEGIN IMMEDIATE;
UPDATE skills
SET a_targetType=31,target_selection_id=2,target_relation_id=0,
min_range=0.0,max_range=8.0
WHERE a_index=504
AND a_base_class=999 AND show=0 AND icon_id=4905
AND a_targetType IS :prev_skill_504_a_targetType
AND target_selection_id IS :prev_skill_504_target_selection_id
AND target_relation_id IS :prev_skill_504_target_relation_id
AND min_range IS :prev_skill_504_min_range AND max_range IS :prev_skill_504_max_range;
SELECT changes() AS affected_server_service_skill_504; -- 1
UPDATE skills
SET a_targetType=31,target_selection_id=2,target_relation_id=0,
min_range=0.0,max_range=8.0
WHERE a_index=505 AND a_base_class=999 AND show=0 AND icon_id=4905
AND a_targetType IS :prev_skill_505_a_targetType
AND target_selection_id IS :prev_skill_505_target_selection_id
AND target_relation_id IS :prev_skill_505_target_relation_id
AND min_range IS :prev_skill_505_min_range AND max_range IS :prev_skill_505_max_range;
SELECT changes() AS affected_server_service_skill_505; -- 1
UPDATE skills
SET a_targetType=31,target_selection_id=2,target_relation_id=0,
min_range=0.0,max_range=8.0
WHERE a_index=506 AND a_base_class=999 AND show=0 AND icon_id=5114
AND a_targetType IS :prev_skill_506_a_targetType
AND target_selection_id IS :prev_skill_506_target_selection_id
AND target_relation_id IS :prev_skill_506_target_relation_id
AND min_range IS :prev_skill_506_min_range AND max_range IS :prev_skill_506_max_range;
SELECT changes() AS affected_server_service_skill_506; -- 1
UPDATE skills
SET a_targetType=31,target_selection_id=2,target_relation_id=0,
min_range=0.0,max_range=8.0
WHERE a_index=507 AND a_base_class=999 AND show=0 AND icon_id=5115
AND a_targetType IS :prev_skill_507_a_targetType
AND target_selection_id IS :prev_skill_507_target_selection_id
AND target_relation_id IS :prev_skill_507_target_relation_id
AND min_range IS :prev_skill_507_min_range AND max_range IS :prev_skill_507_max_range;
SELECT changes() AS affected_server_service_skill_507; -- 1
INSERT INTO skill_constants (constant_key,skill_id,enabled) VALUES
('npc_store',504,1),('npc_storage',505,1),
('npc_auction',506,1),('npc_guild_create',507,1);
INSERT INTO npc_interaction_sets (id,name) VALUES
(907010,'WI demo Store: Merchant Geres'),
(907011,'WI demo Sto