Commit graph

2409 commits

Author SHA1 Message Date
Eduardo Dantas
1789d5f97f
docs(agents): route build validation workflow (#4089)
Keep Canary's active repository instructions concise while moving the complete local build-validation workflow into dedicated documentation.

Main changes:
- Reduce detailed build procedures in AGENTS.md and route them through docs/building/local-validation.md.
- Keep repository-wide build invariants in the always-loaded instruction layer.
- Require maintained build entry points to stay synchronized when C++ source or header files are added, removed, or renamed.
- Keep the relevant CMakeLists.txt, vcproj/canary.vcxproj, and test CMakeLists.txt registration requirements explicit.
- Clarify that local builds remain opt-in unless explicitly requested or authorized at the completion point of a larger task.

Local validation documentation:
- Add docs/building/local-validation.md.
- Document the supported Windows CMake and Visual Studio validation workflow.
- Document Visual Studio Developer Command Prompt and Developer PowerShell environment requirements.
- Document project-managed VCPKG_ROOT verification before configuring or building.
- Document the preferred windows-release preset workflow.
- Document how to inspect and reuse existing CMake preset caches.
- Document targeted recovery from incompatible or corrupted CMake/Ninja cache state.
- Avoid broad cache deletion or creating ad-hoc build directories as a recovery path.
- Document maintained Visual Studio solution and generated build entry-point checks.

MSVC Ninja dependency tracking:
- Document that Ninja requires matching raw cl.exe /showIncludes output to populate .ninja_deps correctly.
- Require configure and build steps to use a consistent environment and code page.
- Keep compiler launchers disabled for MSVC Ninja validation.
- Document diagnosis using rules.ninja, msvc_deps_prefix, raw /showIncludes output, and ninja -t deps.
- Clarify that ninja -t recompact cannot recreate missing dependency records.
- Document recovery for malformed or empty .ninja_deps without broad-cleaning build state.

Instruction budget:
- Keep detailed workflows out of the always-loaded AGENTS.md when they can be routed to versioned documentation.
- Preserve headroom for global and narrower scoped instructions.
- Prefer removing duplicated guidance before increasing instruction byte limits.

Validation:
- Audited the effective global and repository instruction chain at 18,449 bytes.
- Verified it remains below the 24 KiB maintenance target and default Codex instruction cap.
- Verified the routed local-validation documentation path exists.
- Reviewed the complete committed diff.
- Ran Git whitespace validation successfully.
- No build was run because this is a documentation-only change and no build was requested.

This keeps the active instruction layer smaller while preserving the full Canary build-validation, cache-recovery, and MSVC Ninja dependency-tracking workflow in a dedicated maintained document.
2026-08-15 00:56:10 -03:00
mimus-assa
6a1d6a0280
fix: Henricus stays silent in four Inquisition states and misleads in two more (#4084)
Bug Fixes:
- Improved Henricus’s mission-status responses for several quest progression states.
- Corrected outfit dialogue formatting for mission 5.
- Updated the final blessing message to display the accurately calculated price instead of a fixed amount.
2026-08-14 20:19:46 -03:00
mimus-assa
c379a4d6cf
fix: permanent The Inquisition questline rollback via holy water (#4083)
Bug Fixes:
- Holy water in the Eclipse Quest now works only with the correct cauldron items and quest progression.
- Prevented duplicate quest progress updates during the Shadow Nexus sequence.
2026-08-14 20:19:09 -03:00
mimus-assa
d0b2efb788
feat(npc): restore missing dialogue keywords for Thais NPCs (part 1/3) (#4082)
New Features:
- Expanded keyword-based NPC conversations across multiple characters.
- Added responses covering services, locations, lore, professions, notable characters, creatures, items, magic, and rumors.
- Improved interactions involving post offices, healing, equipment, and other in-game services.
- Added more consistent official-server dialogue for everyday questions and world-related topics.
2026-08-14 20:18:06 -03:00
Eduardo Dantas
475f3c1c14
fix(build): preserve msvc ninja dependency tracking (#4088)
Prevent compiler caching from breaking Ninja dependency tracking in MSVC builds.

Root cause:
- Ninja relies on the raw localized cl.exe /showIncludes output to populate .ninja_deps.
- Using ccache or sccache as a compiler launcher can hide or alter this output.
- This can leave Ninja with empty or incomplete dependency records.
- Header changes and generated CMake unity sources may then fail to trigger the expected incremental rebuilds.

Main changes:
- Detect MSVC builds using a Ninja generator through CANARY_MSVC_NINJA.
- Disable ccache automatically for MSVC Ninja builds.
- Disable sccache automatically for MSVC Ninja builds.
- Preserve ccache and sccache behavior for supported compiler and generator combinations.
- Reject preconfigured CMAKE_C_COMPILER_LAUNCHER or CMAKE_CXX_COMPILER_LAUNCHER values when using MSVC with Ninja.
- Fail configuration with a clear error when an external launcher would interfere with raw /showIncludes processing.
- Keep normal compiler-cache discovery and setup unchanged outside MSVC Ninja builds.

Build guidance:
- Document that MSVC Ninja builds must preserve raw cl.exe /showIncludes output.
- Document how to compare rules.ninja msvc_deps_prefix with direct cl.exe /showIncludes output when diagnosing dependency issues.
- Document recovery for malformed or empty .ninja_deps without broad cache deletion.
- Clarify that ninja -t recompact cannot recreate missing dependency records.
- Consolidate Canary-specific AGENTS.md guidance around build environments, dependency validation, callback lifetime safety, Lua userdata ownership, Docker quickstart behavior, and recurring defect prevention.

This preserves reliable incremental dependency tracking for MSVC Ninja builds while retaining compiler caching on build configurations where it is safe.
2026-08-14 18:19:56 -03:00
github-actions[bot]
84986e6ee2
chore: Update vcpkg baseline to 2026.07.29 (#4055)
## vcpkg Baseline Update

This PR updates the vcpkg baseline to the latest release.

**Release:** `2026.07.29`
**Previous:** `cd61e1e26a038e82d6550a3ebbe0fbbfe7da78e3`
**New:** `9e593bb18ea69cc5095e012465dcd675a822ed0d`

**Release notes:**
https://github.com/microsoft/vcpkg/releases/tag/2026.07.29

---
🤖 This PR is automatically updated when new vcpkg releases are published

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Eduardo Dantas <eduardo.dantas@hotmail.com.br>
2026-08-14 14:31:22 -03:00
Eduardo Dantas
ce1356b01e
ci(vcpkg): keep baseline updates synchronized and auto-mergeable (#4085)
Improve the vcpkg baseline update workflow so automated dependency PRs stay synchronized with main and can be handled by GitHub native auto-merge.

Main changes:
- Serialize scheduled and manual baseline updater runs with workflow concurrency.
- Fetch full history before updating the baseline branch.
- Synchronize the updater branch with the latest main before applying baseline changes.
- Rebase the existing updater branch on origin/main when it already exists.
- Create the updater branch from origin/main when it does not exist yet.
- Use force-with-lease for bot branch refreshes.
- Update vcpkg.json and vcpkg-configuration.json baseline fields together.
- Avoid creating empty commits when the branch already contains the target baseline.
- Look up existing baseline PRs by base and head branch.
- Queue GitHub native auto-merge after creating or updating the dependency PR.
- Validate PR numbers before attempting auto-merge.
- Report a warning when auto-merge cannot be queued, such as when repository auto-merge is disabled or branch protection still requires review.
- Update CI path filters so changes to update_vcpkg_baseline.yml trigger the relevant checks.

Safety:
- The updater does not approve reviews.
- The updater does not bypass branch protection.
- Native auto-merge remains controlled by the repository required reviews and status checks.
- If auto-merge cannot be enabled, the PR remains open for normal review.

Validation:
- actionlint passed for the workflow.
- YAML parsing passed.
- Extracted updater shell script passed bash -n.
- git diff --check passed.

This makes automated vcpkg baseline updates safer and less stale by keeping the update branch aligned with main, avoiding conflicting updater runs, and letting GitHub handle the final merge once required checks and reviews pass.
2026-08-14 12:56:43 -03:00
Eduardo Dantas
22a6904a3c
fix: guard scheduled callbacks against stale spawn lifetime (#4080)
fix(spawns): guard scheduled callbacks against stale lifetime

Prevent crashes caused by delayed monster, NPC, and loot-sale callbacks running after their original owner or referenced state has been destroyed, removed, or replaced.

Root cause:
- Non-blockable spawn countdowns captured raw spawn owners and references into the spawn map.
- SpawnsMonster::clear and SpawnsNpc::clear only canceled the recurring check event.
- Already scheduled countdown callbacks could still execute later and access invalid spawn containers or destroyed owner state.
- The delayed NPC gold-pouch sale path had the same lifetime shape by capturing a raw NPC pointer without a cancelable event handle.

Main changes:
- Make delayed monster and NPC spawn callbacks hold weak owners instead of raw this pointers.
- Re-resolve spawn blocks by stable ID when each delayed step executes.
- Invalidate pending spawn chains through generation checks when spawn events are stopped, removed, cleared, or logically replaced.
- Re-resolve NPC and player entities before executing delayed gold-pouch sales.
- Make stale delayed callbacks become safe no-ops before mutating game state.
- Remove movable SpawnMonster ownership behavior so pending scheduled callbacks cannot be detached from their original lifetime assumptions.
- Use bounded countdown arithmetic through subtractElapsedTime to prevent cooldown underflow when elapsed time exceeds the remaining duration.

Safety:
- Prevent stale callbacks from entering SpawnMonster::spawnMonster with destroyed spawnedMonsterMap state.
- Prevent delayed work from applying to removed or replaced spawn definitions.
- Prevent delayed NPC sale execution when the original NPC or player is no longer valid.
- Keep callback lifetime checks local to the delayed execution paths.
- Preserve normal spawn behavior for valid active spawn chains.

Documentation:
- Add AGENTS.md guidance for recurring defect prevention.
- Add deferred callback lifetime safety rules covering raw this captures, mutable container references, generation checks, ID reuse, cancellation domains, and bounded timer arithmetic.

Validation:
- Ran git diff --check origin/main...HEAD.
- Ran clang-format --dry-run --Werror on all changed files.
- Performed a static audit of direct and indirect dispatcher callbacks for borrowed references and raw destructible owners.
- No local build was run, following the repository build policy.

This makes scheduled spawn and delayed NPC callbacks resilient to owner destruction, spawn reloads, removed entries, and stale timer execution without changing normal spawn semantics.
2026-08-14 07:53:12 -03:00
Eduardo Dantas
ec41dfca1c
build: share content-addressed vcpkg dependencies across CMake and MSBuild (#4079)
Share content addressed vcpkg dependencies across CMake and MSBuild

This commit adds a schema v3 content addressed vcpkg dependency pool that can be shared safely across compatible Git worktrees and independent repositories.

The goal is to avoid duplicating expanded vcpkg dependency installations when different checkouts use the same dependency contract, while keeping build outputs isolated per worktree. The shared cache only reuses dependency roots when the full dependency fingerprint proves that the inputs are identical.

This avoids the unsafe model of sharing one mutable vcpkg installed directory across unrelated builds. Manifests registries overlays triplets features install options compiler identity SDK toolset vcpkg revision and cache implementation are all part of the validated contract.

The shared cache remains opt in. CI clean clones containers and normal local builds continue using local dependency roots unless CANARY_SHARED_CACHE_ROOT is explicitly configured.

Main behavior added

• Adds a schema v3 shared vcpkg dependency pool

• Shares vcpkg downloads across compatible repositories

• Shares ABI addressed vcpkg binary packages

• Shares expanded vcpkg installed roots only when the dependency fingerprint matches

• Shares vcpkg buildtrees and packages roots only when the dependency fingerprint matches

• Keeps CMake and Ninja build outputs local to each worktree

• Keeps MSBuild outputs local to each worktree

• Keeps objects PCH PDB files generated sources intermediate files and executables local

• Allows compatible CMake and MSBuild consumers to converge on the same dependency tree

• Gives incompatible configurations separate dependency pools

• Falls back to build local vcpkg roots when the shared cache is unavailable or cannot be verified

Fingerprint model

The dependency fingerprint is build system neutral. It covers the dependency inputs that decide whether an expanded vcpkg dependency tree can be reused safely.

The dependency fingerprint includes the manifest registry contents ordered overlays target triplet host triplet manifest features install options compiler identity toolset SDK vcpkg executable toolchain revision dependency tools and the normalized cache module implementation.

The consumer fingerprint is separate. It adds the build system specific consumer identity such as the CMake generator and tool path or the MSBuild configuration platform toolset and SDK. This lets CMake and MSBuild share the same dependency tree when their dependency inputs match while still validating their own consumer contract independently.

CMake integration

The CMake integration now includes the shared cache resolver before project initialization. The resolver selects fingerprinted vcpkg roots only after validating the full dependency contract.

CMake presets no longer hardcode VCPKG INSTALLED DIR paths. Instead the shared cache module can resolve the installed root when the shared cache is enabled and verified. When it is not enabled the build continues with local vcpkg storage.

CMake preset updates also add clean packages and clean buildtrees install options so transient vcpkg data does not remain in local preset directories unnecessarily.

CMake changes included

• Includes cmake SharedBuildCache cmake from the top level CMakeLists

• Removes hardcoded VCPKG INSTALLED DIR values from presets

• Lets the shared cache resolver choose the dependency root when safe

• Keeps local fallback behavior available

• Adds clean packages after build and clean buildtrees after build to vcpkg install options

• Requires fresh CMake configuration when dependency paths change

• Keeps build outputs inside the normal preset build directories

Visual Studio and MSBuild integration

This commit adds an opt in Visual Studio Solution bridge. The bridge generates an ignored machine local SharedVcpkgCache props file under vcproj and validates the complete contract before vcpkg restore.

The generated props file records the dependency fingerprint consumer fingerprint cache root expected manifest root triplets configuration toolset SDK install options and resolved installed root.

Before MSBuild restores dependencies or prepares the build, SharedVcpkgCache targets revalidate the generated contract. If the evaluated MSBuild values no longer match the generated contract, the build fails closed and asks the developer to regenerate the props file.

Visual Studio changes included

• Adds vcproj SharedVcpkgCache targets

• Adds support for generated vcproj .canary shared cache SharedVcpkgCache props

• Adds shared cache validation before vcpkg manifest install

• Validates manifest root target triplet host triplet link configuration toolset SDK and install options

• Pins the Visual Studio instance used by the vcpkg dependency contract

• Pins the CMake tool used to resolve the dependency contract

• Uses fingerprint specific installed buildtrees and packages roots

• Keeps local fallback through vcproj local .vcpkg buildtrees and .vcpkg packages when shared cache is inactive

• Keeps Solution build outputs local

• Adds generated shared cache files to gitignore while keeping the tracked target file

PowerShell tooling

Two PowerShell helpers were added for setup auditing cleanup and Solution contract generation. Both require PowerShell 7 2 and run with strict validation.

The main setup helper configures the shared cache root registers repository families manages relevant user environment values normalizes global sccache base directories configures vcpkg downloads and binary cache locations and can generate the Visual Studio Solution bridge file.

The Solution helper evaluates MSBuild properties resolves the shared dependency contract through the CMake resolver writes the generated props file and supports audit only and validate only modes.

Tooling added

• tools configure shared build cache ps1

• tools configure shared solution cache ps1

• Shared cache setup mode

• Audit only validation mode

• Safe repository registration

• Safe repository unregister support

• Global sccache path normalization

• Guarded transient vcpkg cleanup

• Guarded fingerprint specific cleanup

• Visual Studio Solution props generation

• Visual Studio Solution contract validation

• Visual Studio Solution contract auditing

Safety model

The shared cache fails closed whenever identity or filesystem safety cannot be proven. Mutable shared roots are only used on a verified local fixed filesystem and are isolated by fingerprint.

Safety rules included

• Requires a verified local fixed filesystem for mutable shared pools

• Rejects unsafe shared cache locations

• Keeps the shared cache outside every registered checkout

• Rejects ambiguous identity

• Rejects stale or mismatched generated contracts

• Rejects unsafe cleanup targets

• Uses operation locks around shared cache mutations

• Uses vcpkg locks around dependency roots

• Preserves existing authenticated VCPKG BINARY SOURCES values

• Does not print or persist authenticated binary source values

• Fails closed when repositories configure trees generated contracts paths identities or active processes cannot be validated

• Keeps opt out and unavailable cache paths build local

Docker and baseline updates

Container dependency installation now receives the full manifest dependency configuration instead of only vcpkg json. Docker builds copy vcpkg configuration json the local vcpkg registry and triplets into the manifest context before installing dependencies.

The vcpkg baseline update workflow now updates both vcpkg json and vcpkg configuration json atomically. It checks both the builtin baseline and the default registry baseline, updates both when needed, and reports the previous builtin and registry baseline values separately in the generated PR text.

Docker and workflow changes included

• Updates Dockerfile arm to copy vcpkg configuration json vcpkg registry and triplets

• Updates Dockerfile dev to copy vcpkg configuration json vcpkg registry and triplets

• Updates Dockerfile x86 to copy vcpkg configuration json vcpkg registry and triplets

• Preserves preprovisioned Docker manifest installs

• Updates the vcpkg baseline workflow to read both baseline declarations

• Updates the vcpkg baseline workflow to modify both files in the same PR

• Updates generated baseline PR comments to show previous builtin and registry baselines

Protobuf and generated source handling

The Visual Studio project also improves protobuf generation while adding the shared dependency bridge.

Protobuf changes included

• Uses a normalized absolute protobuf source root

• Uses the host triplet protoc path

• Adds incremental inputs and outputs for ProtoCompile

• Adds generated protobuf compile items only when protobuf generation is enabled

• Excludes generated protobuf compile items when protobuf support is disabled

Documentation and repository updates

• Adds shared build cache documentation

• Documents setup and migration flow

• Documents CMake integration

• Documents Visual Studio integration

• Documents cross repository and cross worktree compatibility

• Documents concurrency and locking behavior

• Documents fallback behavior

• Documents auditing recovery and cleanup procedures

• Updates README with shared build cache guidance

• Updates gitignore for generated local shared cache files

Validation performed

• cmake fresh preset windows release

• Full CMake Windows Release build

• No op CMake rebuild after the full build

• Full MSBuild Release x64 build

• Incremental MSBuild Release x64 rebuild with no compilation or link

• Full MSBuild Debug x64 build using its isolated dependency fingerprint

• Incremental MSBuild Debug x64 rebuild

• Verified that CMake Release and Solution Release resolve the same dependency fingerprint

• pwsh File tools configure shared build cache ps1 AuditOnly

• PowerShell parser validation for both helpers

• XML parsing

• JSON parsing

• cmake list presets

• actionlint

• git diff check

Overall this commit adds an opt in shared vcpkg dependency cache for Canary. It lets compatible CMake and MSBuild builds reuse expensive dependency artifacts across worktrees and repositories while keeping build outputs local and failing safely back to local roots whenever the shared dependency contract cannot be fully validated.
2026-08-13 18:50:05 -03:00
mimus-assa
1410bae1ab
feat: add missing NPC dialogue for Carlin (28 NPCs) (#4077)
New Features:
- Expanded NPC conversations with official dialogue covering identities, jobs, locations, characters, lore, quests, travel routes, items, and seasonal topics.
- Added responses across numerous NPCs, including ferry captains, guides, merchants, and quest-related characters.
- Added a map-related response that can provide a map part in exchange for a favour.
- Added distinctive responses to additional keywords, including “chchch” and “blood.”
- Added dialogue for seasonal topics such as presents, tokens, sleighs, and holiday exchanges.
2026-08-13 10:04:43 -03:00
mimus-assa
b96789ed59
fix: Gerimor cult list (Cults of Tibia Quest) (#4075)
Bug Fixes:
- Improved Gerimor’s mission dialogue when completion or final-boss requirements have not yet been met.
- Players can now view available cult-related topics and proceed to mission selection.
2026-08-13 10:03:07 -03:00
mimus-assa
2c8d34e291
fix: Barkless cult (Cults of Tibia Quest) (#4074)
Bug Fixes:
- Improved Tigo’s Barkless mission dialogue for players with incomplete mission progress.
- Ensured quest progression, trial-door access, and related mission states initialize correctly when beginning or resuming the interaction.
- Reset dialogue topics appropriately to provide a consistent conversation flow.
- Improved handling for players returning to the mission before completing its initial objectives.
2026-08-13 09:59:50 -03:00
Eduardo Dantas
7456d19c83
refactor(conditions): add typed damage condition factory (#4078)
Add a dedicated factory for damage conditions and use it when loading monster spells.

Main changes:
- Add Condition::createDamageCondition returning std::shared_ptr<ConditionDamage>.
- Keep the supported damage-condition mapping centralized in the typed factory.
- Make Condition::createCondition delegate supported damage-condition creation to createDamageCondition.
- Update Monsters::getDamageCondition to consume the typed factory result directly.
- Remove the need for std::dynamic_pointer_cast<ConditionDamage> in monster spell loading.
- Avoid duplicated condition-type checks and unsafe static casts in callers.

Behavior:
- Supported damage conditions keep their existing behavior and object-pool allocation.
- Non-damage and unsupported condition types return nullptr.
- Monster spell validation from #4072 is preserved.
- Invalid monster spell conditions continue to be rejected instead of producing unsafe condition objects.

Tests:
- Add condition_factory_test.cpp.
- Cover every supported damage condition type.
- Cover non-damage condition rejection.
- Cover unsupported condition rejection.
- Cover ConditionId and sub-ID propagation.
- Cover compatibility with the generic Condition::createCondition factory.

Validation:
- Ran clang-format --dry-run --Werror.
- Ran git diff --check.
- Verified monster spell loading no longer uses dynamic_pointer_cast<ConditionDamage>.
- Local build was not run; added unit tests are registered in the existing CMake test target and will run in CI.

This keeps damage-condition creation centralized, removes RTTI from monster spell loading, and makes the condition factory contract clearer and safer.
2026-08-13 08:57:04 -03:00
Leilani A.
11f9a2aee2
fix(monsters): reject invalid damage conditions during spell loading (#4072)
Prevent server crashes when loading monster spells that reference unsupported or non-damage condition types.

Main changes:
- Update Monsters::getDamageCondition to create the base condition first.
- Replace the unsafe static_self_cast path with dynamic_pointer_cast<ConditionDamage>.
- Return nullptr when the created condition is not a valid damage condition.
- Update Monsters::deserializeSpell to validate the returned damage condition before adding it to combat.
- Log an error with the condition id and monster description when the condition is invalid.
- Reject the invalid spell instead of continuing with a null or invalid condition pointer.

Crash fixed:
- Avoid access violations caused by monster attacks using condition types that cannot be converted to ConditionDamage.
- Prevent invalid condition setup from reaching Protocol or game startup paths through malformed monster spell definitions.

Tests:
- Add monster_spell_test.cpp.
- Cover unsupported damage condition rejection with CONDITION_AGONY.
- Cover non-damage condition rejection with CONDITION_HASTE.
- Verify invalid spells are rejected and spellBlock.spell remains empty.

This makes monster spell loading safer by rejecting invalid condition types during deserialization instead of allowing unsafe casts to crash the server.
2026-08-12 16:20:06 -03:00
Eduardo Dantas
d9fba17031
fix(network): retry rejected protocol cleanup (#4073)
fix(network): make protocol cleanup reliable under dispatcher saturation

Resolves #3585.

Make Connection::close cleanup reliable when dispatcher immediate queues are saturated.

Before this change, Connection::close ignored the boolean returned by Dispatcher::addEvent and submitted Protocol::release with a 30-second expiration. Under sustained dispatcher backlog, the cleanup callback could be rejected at admission or expire before execution. That could leave ProtocolGame attached to its player longer than intended, pushing the eventual cleanup into the regular ping-timeout path and making the delay appear in Game::checkCreatures telemetry.

Main changes:
- Remove the expiration from Protocol::release dispatch.
- Try ProtocolInput first for protocol cleanup.
- Fall back to WorldCommit when ProtocolInput rejects admission.
- Retain the closing connection and retry after 50 ms when both dispatcher lanes reject admission.
- Keep at most one retry timer per closing connection.
- Treat dispatcher shutdown as terminal and avoid rearming the I/O retry in that case.
- Rate-limit the dispatcher saturation warning globally to once every 5 seconds.
- Keep all protocol and player ownership mutation on the dispatcher thread.

Behavior:
- Closing connections now retain ownership until a non-expiring protocol-release callback is accepted by a dispatcher lane.
- Saturation is reported without flooding logs.
- Normal disconnected-player reconnect window remains unchanged.
- Existing 60-second forced logout behavior remains unchanged.

Tests:
- Add unit coverage for boolean fallback-lane admission.
- Add unit coverage for terminal dispatcher shutdown classification.
- Run git diff --check.
- Verify the changed C++ ranges against the repository clang-format configuration.
- Local build and executable unit tests were not run; GitHub Actions provides executable validation for this PR.

Documentation:
- Update performance and lifetime documentation with reliable network-close cleanup requirements.

This prevents protocol cleanup from being silently dropped or expired during dispatcher backlog while preserving dispatcher ownership and existing disconnect behavior.
2026-08-12 16:03:36 -03:00
Eduardo Dantas
b0092a9b87
feat(pvp): add Expert PvP world type and combat rules (#4033)
Add Expert PvP world type and combat rules

This commit adds Expert Open PvP support to Canary as an explicit world type through worldType = expert-pvp.

The implementation introduces a dedicated ExpertPvp component for Expert specific combat, relation, field, movement, collision, and marking rules. Existing combat, spell, tile, player, game, and protocol code remain as thin integration points, while the Expert PvP decisions live under src creatures players components pvp.

This keeps the new behavior isolated from the existing world types and avoids spreading Expert PvP specific rules across unrelated systems.

The existing PvP world type handling was also clarified. retro-pvp is now the explicit Retro Open PvP value, while pvp remains supported as a compatibility alias for retro-pvp. no-pvp and pvp-enforced remain outside the Expert PvP decision path.

Main world type changes

• Adds worldType expert-pvp

• Makes retro-pvp the explicit Retro Open PvP config value

• Keeps pvp as a compatibility alias for retro-pvp

• Changes the default config value from pvp to retro-pvp

• Removes the old toggleServerIsRetroPVP config option

• Updates Lua helpers so IsRetroPVP reads the world type string

• Adds IsExpertPVP for Lua scripts

• Keeps no-pvp and pvp-enforced behavior outside the Expert PvP component

The ExpertPvp component centralizes relation classification and decision making for the new world type. It evaluates PvP mode, actor and target relation, combat action type, field ownership, side effects, player collision, and viewer specific situation marks.

The component covers relations such as self, access players, party allies, guild allies, war enemies, direct attackers, protected ally attackers, direct targets, skulled targets, neutral players, monsters, player summons, and NPCs.

Main Expert PvP rules included

• Dove mode behavior

• White Hand behavior

• Yellow Hand behavior

• Red Fist behavior

• Direct combat decisions

• Rune target decisions

• Area spell decisions

• Summon combat decisions

• Field step decisions

• Field damage decisions

• Player walkthrough decisions

• Pathfinding probe decisions

• Viewer specific field visual decisions

• Viewer relative creature situation marks

Combat integration now asks ExpertPvp before allowing Expert PvP relevant actions. This applies to direct attacks, runes, aggressive area spells, mana and health combat, conditions, dispels, default combat actions, and field damage.

When Expert PvP handles an action, it can allow or block the action and apply the correct side effects. These side effects include fight state, PZ lock behavior, skull actions, square feedback, and unjustified kill tracking where applicable.

Secure mode behavior is handled through the Expert PvP relation rules instead of the older broad secure mode check. This allows secure mode retaliation without applying unjustified protection zone locks in cases where the Expert PvP relation allows the response.

Magic Wall and Wild Growth now carry Expert PvP cast time context. When Expert PvP is enabled, these fields are created as safe field variants and receive owner context so the server can evaluate relation dependent behavior later.

Magic Wall and Wild Growth changes

• Stores the field owner context when the rune is cast

• Stores the owner PvP mode at cast time

• Tracks owner targets and attackers at cast time

• Uses safe visual field items as the base item in Expert PvP

• Resolves viewer specific appearance through protocol serialization

• Evaluates collision and pathfinding from the field context

• Evaluates field stepping side effects through ExpertPvp

• Prevents Expert PvP owned safe fields from being removed like regular no-pvp safe fields

• Keeps normal no-pvp behavior for non Expert PvP worlds

Tile and pathfinding logic now consult ExpertPvp for Expert owned fields. This allows Magic Wall and Wild Growth to appear or behave differently depending on the viewer and the PvP relation, while still using the existing movement and tile query paths as the final authority.

Player walkthrough and body blocking were updated so Expert PvP can decide whether a player can walk through another player outside legacy safe zones. Party, guild, war, attacker, protected ally, and target relations are used to keep collision behavior aligned with Expert PvP hand modes.

PvP situation tracking was added so player relations can affect persistent creature marks. The server can now send viewer relative creature marks for the current client profile and refresh visible marks when relevant state changes.

Situation mark updates happen when needed for events such as party changes, guild changes, attacked player tracking, player removal, and visible relation changes.

Protocol changes

• Adds ExpertPvpModeByte as a protocol feature flag

• Enables Expert PvP mode byte support for the Tibia 11.00 profile

• Keeps Tibia 11.00 on the verified four byte Set Tactics layout

• Keeps current 15.25 on its verified three byte tactics layout

• Defaults unsupported profiles safely to Dove mode

• Avoids appending speculative PvP mode bytes to the current 15.25 profile

• Sends Expert PvP controls only when the protocol profile supports them

• Sends viewer relative creature marks only through supported packet layouts

The current 15.25 profile keeps its verified tactics payload layout and does not receive a speculative extra PvP byte. This prevents client desync or crash risk. Unsupported profiles are forced safely to Dove when Expert PvP is enabled but the protocol cannot represent the mode.

Player state now includes a dedicated PvP component. The selected Expert PvP mode is stored on the player and persisted to the database.

Persistence and database changes

• Adds PlayerPvp component

• Adds player getPvpMode and setPvpMode support

• Saves expert_pvp_mode during player save

• Loads expert_pvp_mode during player load

• Adds players.expert_pvp_mode to schema.sql

• Bumps database version to 59

• Adds migration 59 for the players.expert_pvp_mode column

• Skips the migration safely if the column already exists

Lua API support was expanded so scripts can inspect PvP state and attach field context where needed.

Lua API changes

• Adds Player getPvpMode

• Adds Player hasAttacked

• Adds Item setExpertPvpFieldContext

• Updates generated Lua API documentation

• Updates Magic Wall and Wild Growth scripts to attach Expert PvP field context

The PR also updates blessing and death loss behavior to use the new Retro PvP world type detection instead of the removed toggleServerIsRetroPVP config. This keeps existing Retro PvP behavior while moving the decision to the explicit world type model.

Additional behavior covered

• Party relation handling

• Guild relation handling

• War enemy relation handling

• Skull relation handling

• Aggressor relation handling

• Protected ally relation handling

• Field ownership behavior

• Viewer specific field visuals

• Body blocking and player collision

• Situation marks and persistent creature marks

• Defensive PZ lock behavior

• Secure mode retaliation behavior

• Blessing cost and Twist of Fate behavior under Retro PvP detection

Out of scope

• Frag sharing

• player_kills.weight schema changes

• Debug commands

• Unrelated PvP features

• Broad behavior changes to existing world types

Documentation and tests

• Adds Expert PvP implementation roadmap documentation

• Adds Expert PvP porting plan documentation

• Links the new documentation from the systems overview

• Documents the behavioral contract

• Documents the implementation roadmap

• Documents the in game regression matrix

• Adds Expert PvP unit coverage

• Adds protocol profile coverage for Expert PvP mode support

• Adds regression scenarios for all world types

Validation performed

• Built canary target

• Built canary_ut target

• Built canary_it target

• Expert PvP and protocol profile tests passed with 49 of 49 tests

• Full unit binary passed with 311 of 311 tests

• Integration binary passed with 40 of 40 tests

• Manual scenarios were exercised during implementation

• Tested secure mode retaliation

• Tested defensive PZ lock behavior

• Tested Magic Wall and Wild Growth cast time relations

• Tested viewer specific visuals and collision

• Tested situation marks

Test configuration

• Platform Windows x64

• Compiler Microsoft Visual C plus plus 19.44

• Protocol coverage Tibia 11.00 and current 15.25 profiles

Known validation note

Two isolated CTest invocations terminated during global teardown after their test bodies passed. The same behavior reproduces on the main baseline. Running the unit suite in one process passes all 311 tests.

Overall this commit adds Expert Open PvP as a gated world type with dedicated relation based combat and field rules. It keeps existing world types protected from Expert PvP behavior, persists the selected PvP mode, supports protocol safe PvP mode handling, updates Lua APIs and documentation, and adds regression coverage for the new rules.
2026-08-10 18:42:55 -03:00
mimus-assa
157e6f9e21
fix: Simon the Beggar's shovel has no price (#4066)
Bug Fixes
- Fixed Simon the Beggar’s shovel shop so shovels can be purchased at the correct price.
- Shovel buying, selling, and item-check interactions remain available.
2026-08-06 13:29:12 -03:00
mimus-assa
34e0f81d21
fix: NPCs sell spells under names that no spell registers (#4065)
Bug Fixes:
- Corrected spell names shown and taught by NPCs across the game world.
- Standardized rune names for Paralyze, Convince Creature, Explosion, Light Magic Missile, Poison Field, Fire Field and Energy Field.
- Corrected the Invisibility spell name and capitalization.
- Existing prices, requirements, vocation restrictions and dialogue remain unchanged.
2026-08-06 13:28:37 -03:00
mimus-assa
b045dfab02
fix: storage keys that do not exist, silently dropping quest progress (#4064)
Bug Fixes:
- Improved quest, mission, outfit, cooldown, and progress tracking for more reliable activity completion.
- Fixed Giant Smith Hammer quest completion and NPC mission checks.
- Corrected ritual task and fame-point progress tracking.
- Fixed Dream Courts encounter cooldowns, transformations, teleport access, and quest progression.
- Improved mission-state tracking and corrected several quest progression issues.
2026-08-06 13:27:35 -03:00
mimus-assa
3fab22d340
fix: The Way of the Monk quest (#4063)
Bug Fixes:
- Corrected shrine progress tracking for The Way of the Monk quest to prevent resets.
- Updated the Empathy and Power shrine locations to their correct floors.
2026-08-06 13:20:39 -03:00
mimus-assa
159cab3b48
fix: Augustin throws "message type invalid" on every sale (#4062)
Bug Fixes:
- Updated Augustin’s sale confirmation message to display using the appropriate trade notification style.
2026-08-06 13:19:35 -03:00
mimus-assa
41b9262dc0
fix: Brengus sells the tribal mask instead of buying it (#4061)
Bug Fixes:
- Updated Brengus’s shop pricing for tribal masks.
- Tribal masks are now sold to players for 100 gold instead of being bought for 250 gold.
2026-08-06 13:19:06 -03:00
Eduardo Dantas
20fbb53ecb
fix(protocol): align effect sources and virtue state (#4056)
New Features:
- Combat visual effects now identify their source, improving clarity between self, player, creature, and global effects.
- Graphical effect source information is supported for compatible client profiles while preserving legacy behavior.
- Virtue and serenity data are now displayed conditionally based on vocation support.

Bug Fixes:
- Corrected virtue restoration and mapping when loading saved player data.
2026-08-06 13:18:30 -03:00
Eduardo Dantas
44a2e1227f
fix(monster): refresh renamed creatures (#4054)
Bug Fixes:
- Fixed monster name change updates so clients reliably refresh the displayed monster for all visible spectators.
- Improved /setmonstername behavior with stricter name parsing/validation, accurate counting of renamed monsters, and clearer player feedback (including cases where no monsters are found or all already match).
2026-08-06 13:17:32 -03:00
mimus-assa
d3cb205564
fix: Storkus outfit and dialogue (Inquisition mission 3 / Vampire Hunter) (#4053)
New Features:
- Updated Storkus’s appearance.
- Improved quest dialogue to accurately reflect vampire dust progress and remaining requirements.
- Added a refreshed greeting message.

Bug Fixes:
- Corrected quest progression handling to prevent inaccurate progress updates and dialogue responses.
2026-08-06 13:16:59 -03:00
Luciano
c50b849a06
fix(docker): fix MyAAC frontend build and optimize image (#4048)
Performance:
- Reduced the Docker image size by separating build-time tools from the runtime environment.
- Removed unnecessary development dependencies from the final image.

Reliability:
- Preserved the existing container startup behavior and application deployment flow.
- Ensured the application files have the correct runtime ownership and permissions.
2026-08-06 13:16:15 -03:00
mimus-assa
8c06104604
fix: Prey Wildcard store offers should be 1x10 and 5x50 coins (#4045)
Bug Fixes:
- Adjusted the quantities included with the “Prey Wildcard” offers to reflect the correct amounts.
2026-08-06 13:15:34 -03:00
mimus-assa
38d5ca1bac
fix: djinn NPCs should accept a normal greeting once the player is recognized (#4044)
Bug Fixes:
- Improved Djinn War NPC greeting interactions by considering quest progress when handling greeting messages.
- Players with the appropriate quest state can now proceed through relevant NPC conversations without being incorrectly dismissed.
- Updated greeting behavior across multiple Djinn War NPCs for more consistent quest interactions.
2026-08-06 13:15:02 -03:00
mimus-assa
92476e96e1
fix: Barbarian Test Quest (#4025)
Bug Fixes:
- Improved Barbarian Test dialogue routing so responses and progression steps track the player’s current quest status more consistently.
- Prevented quest progress from being reset when players revisit the honey/mead introduction.
- Refined mead quest progression rules, including stricter checks for eligible quest stages and updated success/pass conditions to reduce unintended resets and edge cases.
2026-08-06 13:14:22 -03:00
Luan Santos
4f01de4063
build: pin vcpkg registry and developer tools (#4052)
Pin vcpkg registry and native developer toolchain

This commit moves Canary patched protobuf port from the old overlay port model into a versioned local vcpkg registry and pins the native developer toolchain used by local builds and CI.

The goal is to make dependency resolution more reproducible without changing the CMake target structure or the existing CI build flow. The project still builds through the same CMake presets and vcpkg manifest model, but protobuf is now resolved from a controlled repository local registry instead of an unversioned overlay port path.

The vcpkg configuration now uses a pinned builtin registry baseline and a filesystem registry for the local protobuf package. The protobuf package is provided through the new vcpkg registry directory with its portfile metadata wrappers version database and Canary specific patches.

This keeps the patched protobuf dependency versioned inside the repository and makes future dependency updates easier to review because the registry baseline package version port version and patch set are all explicit.

The new local protobuf registry defines protobuf version 6.33.4 with port version 1 and keeps the required dependencies declared through the package metadata, including abseil host protobuf utf8 range vcpkg cmake and vcpkg cmake config. It also preserves optional zlib support through the protobuf zlib feature.

The developer toolchain is now pinned through mise. The repository adds a mise configuration that pins CMake Ninja sccache and Python, sets the default CMake generator to Ninja, and defines standard tasks for bootstrapping configuring building testing installing and checking cache stats.

Pinned tool versions

• mise minimum version 2026.5.15

• CMake 4.3.4

• Ninja 1.13.2

• sccache 0.14.0

• Python 3.14.6

A new bootstrap script installs the pinned vcpkg checkout into the configured VCPKG ROOT path, defaulting to the repository local tools directory. The script clones microsoft vcpkg when needed, fetches and checks out the builtin baseline from the vcpkg manifest, bootstraps vcpkg with metrics disabled, and prints the selected vcpkg root.

Main changes included in this commit

• Moves the patched protobuf port from overlay ports to a local vcpkg registry

• Adds a repository local vcpkg registry directory

• Adds protobuf package metadata under the local registry

• Adds protobuf version database entries for the local registry

• Pins the default builtin vcpkg registry baseline

• Configures protobuf to resolve from the filesystem registry

• Keeps overlay triplets unchanged

• Keeps CMake target structure unchanged

• Keeps the existing CI build flow conceptually unchanged

• Adds protobuf patches inside the versioned registry port

• Adds wrappers and package configuration files needed by the patched protobuf port

• Adds a mise based native developer toolchain definition

• Pins CMake Ninja Python and sccache for local development

• Sets VCPKG ROOT to the repository local tools vcpkg path by default

• Sets Ninja as the default CMake generator for the pinned workflow

• Adds mise tasks for bootstrap configure build test install and cache stats

• Adds a Python bootstrap script for the pinned vcpkg checkout

• Updates CI build workflows to install pinned build tools through mise

• Updates Linux macOS and Windows reusable build workflows to use the repository local vcpkg directory for CMake builds

• Updates CI path filters so changes to mise vcpkg configuration and the local registry trigger the correct jobs

• Updates cmake format checks to use pinned Python setup and hashed Python requirements

• Adds hashed requirements for cmakelang PyYAML and six

• Updates README test instructions to use the pinned mise workflow

• Updates development documentation to describe the unified local setup and build workflow

Workflow behavior after this change

Local developers can install the pinned tools and bootstrap vcpkg from the repository root before configuring or building Canary. The standard path is now based on mise install followed by the repository tasks for bootstrap configure build and test.

CI now sets up pinned build tools through mise before running native build steps. Linux and macOS workflows no longer rely on system installed Ninja from apt or brew for the build tool version. They install only the remaining platform dependencies and use the pinned toolchain for CMake Ninja and Python.

Windows CMake builds also use the pinned tool setup and place vcpkg under the repository local tools directory. Solution builds keep their existing repository vcpkg location behavior where needed.

CMake formatting now installs its Python dependencies through a hashed requirements file before running cmakelang format. This makes the formatting tool dependencies more deterministic and avoids installing unpinned formatter dependencies directly in the workflow.

Validation

• macOS release preset configures successfully with the local registry

• macOS release preset builds successfully with the local registry

• Manual testing was otherwise not reported

Overall this commit makes Canary native build dependency resolution more reproducible by versioning the patched protobuf port in a local vcpkg registry and pinning the developer toolchain through mise, while keeping the existing CMake presets target structure and CI build flow intact.
2026-08-05 09:07:02 -03:00
mimus-assa
30e022c1da
fix: !autoloot all was unreachable, "all" left commented out in validValues (#4067) 2026-08-05 08:25:51 -03:00
mimus-assa
d42e8e9165
fix: Zoltan Myra addon reward for male summoners (#4060)
This commit fixes the Mage and Summoner outfit quest flow in Zoltan so male characters can receive the missing second addon reward from the Myra branch.

Before this change, the Myra keyword only handled the female reward path. Female characters with AddonHatCloak set to 10 could receive the summoner addon 138,2 and the mage addon 141,2. Male characters with the same quest progress had no equivalent branch, so they could fall through to the completed state reply or the default unknown reply without ever receiving the male summoner addon.

As a result, addon 133,2 was unobtainable for male players through this quest flow. The female summoner addon was already granted elsewhere as well, but the male summoner counterpart was not granted by Zoltan, by an item, or by another script.

This commit adds the mirrored male branch for the Myra reward. When a male character has AddonHatCloak equal to 10 and does not already have the male summoner second addon, Zoltan now grants the expected male outfit addons and completes the quest state in the same way as the female branch.

The female branch is intentionally left unchanged, so existing behavior for female characters is preserved.

Main changes included in this commit

• Adds a male reward branch to the myra keyword flow in Zoltan

• Grants addon 133,2 for the male summoner outfit

• Grants addon 130,2 for the male mage outfit

• Keeps the same dialogue used by the existing female reward branch

• Sends the same blue magic effect after granting the reward

• Updates AddonHatCloak storage from 10 to 11 after the reward

• Resets MissionHatCloak storage to 0 after the reward

• Preserves the existing female reward branch for addons 138,2 and 141,2

• Keeps the completed state response for AddonHatCloak equal to 11

• Hoists the AddonHatCloak storage read into a local variable

• Avoids reading the same quest storage multiple times inside the same myra branch

Root cause

The Myra keyword in data otservbr global npc zoltan lua only checked PLAYERSEX FEMALE for the reward path. There was no PLAYERSEX MALE equivalent for the same AddonHatCloak progress state.

Because of that, male characters who had completed the required quest progress could not receive the male summoner second addon from Zoltan. The server never reached a reward branch for addon 133,2.

Runtime behavior after this change

A male character with AddonHatCloak equal to 10 can now speak with Zoltan using the myra keyword and receive the correct Mage and Summoner addon rewards.

After the reward is granted, the quest progress is advanced to AddonHatCloak 11 and MissionHatCloak is reset to 0, matching the existing female flow.

This is a non breaking quest script bug fix. It only adds the missing male reward path and does not change the female reward behavior.
2026-08-04 15:10:27 -03:00
LeoTK
593de82e9c
fix: allow spell casting while paralyzed (#4058)
Resolve #3986
2026-08-03 18:07:14 -03:00
Eduardo Dantas
f7ae4d17ed
fix(protocol): decode 15.25 stand and chase modes (#4051)
Fix current client tactics payload decoding for protocol 15 25

This commit fixes the tactics packet layout used by the current protocol profile.

The official 15 25 client no longer sends the old fight chase secure layout for SetTactics. Instead the current client sends three bytes after opcode 0xA0 using the layout chase secure PvP. Canary was still decoding those bytes as fight chase secure, which caused the server to read the Secure byte as the chase state.

Because of that incorrect decoding, when the official client sent Stand and Secure enabled, the server interpreted the packet as chase enabled. Selecting an attack target then made the character keep moving because the server was following the wrongly decoded chase state. OTC did not show the same behavior because it was not using that current official payload layout.

This commit updates both read and write paths for the current tactics payload. The server now parses 0xA0 as chase secure PvP for the current protocol profile and serializes 0xA7 using the same three field layout.

The wire change is gated to the current protocol profile only. Tibia 11 00 and 8 60 keep their existing tactics layouts and are not affected by this protocol fix.

The earlier speculative movement and path cancellation workaround was removed because the dispatcher and movement scheduling were not the source of the bug. The issue was caused by a protocol payload mismatch between Canary and the official 15 25 client.

Main changes included in this commit

• Parses current 15 25 SetTactics opcode 0xA0 as chase secure PvP

• Serializes current tactics opcode 0xA7 using the same chase secure PvP layout

• Gates the tactics wire change to the current protocol profile

• Preserves the existing Tibia 11 00 tactics layout

• Preserves the existing 8 60 tactics layout

• Removes speculative movement workaround changes

• Removes speculative path cancellation workaround changes

• Keeps the fix focused on the actual protocol payload mismatch

Root cause

The official 15 25 client sends three bytes after SetTactics opcode 0xA0. Two independent TibiaAPI recordings showed the current layout as A0 01 01 00. The extracted 15 25 client schema also defines two boolean fields followed by the PvP enum.

Canary was still interpreting those three bytes as fight chase secure. With Stand and Secure enabled, the packet A0 00 01 00 incorrectly set chase to true on the server because the Secure byte was being read as the chase byte.

After selecting an attack target, the server then correctly followed that incorrectly decoded chase state. This made the official client continue moving when it should not have.

Validation performed

• Confirmed the three field 0xA0 layout in two independent 15 25 TibiaAPI recordings

• Confirmed the matching three field 0xA0 and 0xA7 schema in extracted 15 25 client binaries

• Confirmed the matching three field 0xA0 and 0xA7 schema in extracted 15 30 client binaries

• Added profile assertions covering current protocol behavior

• Added profile assertions covering Tibia 11 00 behavior

• Ran git diff check

A build was not rerun after replacing the original movement workaround with the protocol level fix.

Fixes issue 4050.

Overall this commit fixes the official current client tactics behavior by aligning Canary with the real 15 25 tactics packet layout, while keeping older protocol profiles on their existing wire format.
2026-07-29 18:16:39 -03:00
mimus-assa
7644bcbcbb
fix: Mortimer (Explorer Society) hands out the wrong pick and never advances the mission storages (#4047) 2026-07-25 11:21:18 -03:00
mimus-assa
8f72a201bb
fix: familiar spells unlearnable — NPCs sell a spell name that does not exist (#4046) 2026-07-25 11:20:51 -03:00
André Morais
7323503b3d
fix: increase the god maximum speed (#4049) 2026-07-22 12:04:53 -03:00
Eduardo Dantas
71a0f92b4d
fix: dispatcher backlog warnings (#4036)
Fixes #4035

Fixes noisy dispatcher warnings introduced by the lane-aware scheduler.
Queue-age diagnostics were emitted as warnings for background and idle
work, while the adaptive warning could be triggered by the histogram p99
samples even when no player-visible queue remained backlogged.

This made expected adaptive throttling on slower hosts look like a
server fault.
2026-07-19 14:22:28 -03:00
Eduardo Dantas
691614c1a3
fix(ci): serialize windows vcpkg cache writers (#4041) 2026-07-18 10:07:48 -03:00
Eduardo Dantas
e0ac98e399
fix(network): avoid deprecated enum arithmetic (#4039)
Refactor
• Standardized protocol size-related constants with explicit 32-bit
integer types for clearer, safer handling of message limits.

Bug Fixes
• Improved message body access by resetting the internal read/write
cursor before returning the body buffer, enhancing consistency during
protocol message parsing.
2026-07-16 11:14:17 -03:00
Eduardo Dantas
a879c9312e
fix(audit): repair invalid item ranges and reduce storage false positives (#4034) 2026-07-13 22:02:47 -03:00
Eduardo Dantas
de9d7880d9
feat(audit): add profile-aware content reference validation (#4031)
Add a deterministic profile-aware gameplay content auditor

This commit adds a deterministic profile-aware static auditor for Canary gameplay content.

The auditor models the repository using the same mutually exclusive datapack profiles used at runtime. The canary profile is built from data, plus the data canary. The otservbr global profile is built from data plus data otservbr global. This keeps definitions from alternative datapacks isolated and prevents one profile from incorrectly satisfying or conflicting with another profile.

This is a tooling-only change. It does not modify server runtime behavior.

The new auditor is available as a Python CLI through python m tools.canary_audit. It extracts typed gameplay definitions, references, registrations, and unresolved expressions from Lua, XML, and appearance data. The covered areas include items, monsters, NPCs storages actions, movement, events, weapons, and spells.

The tool also extracts authoritative item IDs from the data appearances.dat file. This extraction follows the runtime requirements for protobuf ID fields, flags, and the uint16 item ID domain, instead of treating every numeric field as an item definition.

Lua analysis is intentionally conservative. The scanner ignores comments and string contents, tracks lexical scope and constructor ownership, and leaves dynamic expressions unresolved instead of guessing. This makes unresolved dynamic coverage visible without fabricating false missing references.

XML validation was added for item overrides, creature references, storage ranges, overlapping ranges, and out-of-range values. The XML parser disables external entities and fails closed if the parser cannot enforce that safety setting.

The auditor generates deterministic schema-validated artifacts for CI and local review.

Generated artifacts

• project-index.json

• symbol-registry.json

• reference-report.json

• summary.md

Semantic fingerprints are stable and narrowly scoped. Finding fingerprints includes occurrence multiplicity, so a waiver for one known legacy occurrence cannot hide a newly duplicated occurrence later.

Baseline waivers are supported for existing known issues. The current shared items.xml contains four reversed item ranges. These produce eight profile-specific error findings and are recorded with individual fingerprints and engineering reasons. The waivers keep the initial CI gate usable while ensuring that any new error-level finding still blocks CI.

Main changes included in this commit

• Adds the tools.canary_audit Python CLI

• Adds profile-aware scanning for the canary datapack profile

• Adds profile-aware scanning for the otservbr global datapack profile

• Keeps gameplay profiles isolated during extraction and rule evaluation

• Adds typed definitions for items, monsters, NPCs, storages, actions, movement, events, weapons, and spells

• Adds typed references for gameplay content relationships

• Adds typed registrations for action IDs, unique IDs, movement, events, weapons, spells, and related content

• Tracks unresolved dynamic Lua expressions instead of guessing their values

• Extracts authoritative item IDs from data items appearances.dat

• Parses protobuf fields for ID and flags according to runtime requirements

• Enforces the uint16 item ID domain

• Adds conservative Lua analysis that ignores comments and string contents

• Tracks lexical scope during Lua extraction

• Tracks constructor ownership during Lua extraction

• Adds XML validation for item overrides

• Adds XML validation for creature references

• Adds XML validation for storage ranges

• Adds XML validation for overlapping ranges

• Adds XML validation for out-of-range values

• Adds deterministic JSON and Markdown audit artifacts

• Adds schema validation for generated artifacts

• Adds stable semantic fingerprints

• Adds narrowly scoped baseline waivers

• Adds occurrence multiplicity to fingerprints

• Adds a read-only GitHub Actions workflow for audit validation

• Adds CI schema validation

• Adds CI test execution

• Adds CI scans for both supported profiles

• Publishes the audit summary in CI

• Uploads generated audit artifacts in CI

• Adds repository documentation for architecture commands extension points, exit codes, and coverage boundaries

Correctness and safety improvements

• Keeps canary and otservbr global datapack definitions isolated

• Prevents alternative datapack content from satisfying the wrong profile

• Prevents alternative datapack content from conflicting with the wrong profile

• Uses full protobuf field parsing for appearance data

• Avoids treating unrelated numeric fields as item definitions

• Disables XML external entities

• Fails closed when XML entity hardening cannot be enforced

• Confines discovery paths to the repository

• Confines output paths to the repository

• Rejects symlink escapes

• Writes output artifacts atomically per file

• Applies limits to Lua tokens

• Applies per-file fact limits

• Applies total fact limits

• Applies diagnostic limits

• Applies finding limits

• Uses indexed interval lookups for range validation

• Uses bounded finding evidence

• Uses heap-based overlap sweeps

• Uses precomputed Lua delimiter pairs to avoid quadratic behavior

Coverage boundaries

Binary OTBM maps are not parsed by this auditor.

Action ID and unique ID selectors are indexed as registrations, but the auditor does not claim that matching map selectors exist.

Dynamic Lua expressions remain visible as unresolved coverage. They are not fabricated as missing references.

Validation performed

• python m unittest discover s tools canary_audit tests t . p test_*.py v

• python m tools.canary_audit validate-schemas

• python m tools.canary_audit scan profile all output-dir artifacts canary-audit

• python m tools.canary_audit validate input-dir artifacts canary-audit

Validation results

• 60 unit and integration tests passed

• Full two-profile scan completed with exit code 0

• 39311 facts were produced

• 2194 findings were produced

• 8 legacy errors were waived with exact fingerprints

• 0 operational diagnostics

• 0 new blocking findings

• Generated JSON artifacts passed schema validation

No C++ build was run because this change only adds Python tooling documentation, configuration schemas, and CI support.

Overall, this commit adds a deterministic profile-aware gameplay content auditor that can be run locally and in CI. It improves repository visibility for unresolved references, duplicate definitions, duplicate registrations, invalid ranges, and profile-specific content issues while keeping runtime behavior unchanged.
2026-07-13 20:47:00 -03:00
Eduardo Dantas
9365c1c4aa
perf: add fair dispatcher scheduling and parallel monster AI (#4030)
Add lane aware dispatcher scheduling and parallel monster compute

This commit replaces fixed dispatcher draining with bounded lane aware scheduling and adds a dedicated compute path for expensive monster decisions.

The goal is to keep player visible movement and actions responsive during monster heavy workloads while still using additional CPU cores for expensive AI preparation. Worker threads are allowed to compute suggestions only. They do not mutate world state and they do not commit gameplay changes.

The dispatcher remains the only authority for map movement target changes combat Lua RNG cooldowns conditions effects and network visible state. This keeps the gameplay contract safe while moving expensive immutable preparation work away from the main execution path.

Before this change player input movement commits monster movement AI continuations maintenance and generic work competed in broad dispatcher queues. Under large monster workloads this could delay player visible work and could repeatedly submit movement or AI tasks that were already stale or guaranteed to be rejected.

This commit introduces explicit dispatcher lanes and execution modes for protocol input player movement player actions world commits worker completions visible monster work background monster work deferred gameplay maintenance and generic parallel work.

Fixed draining is replaced with weighted deficit round robin scheduling and producer round robin where ordering permits it. This gives player visible work explicit priority while still allowing background work to make bounded progress.

Dispatcher fairness and backpressure changes

• Adds explicit dispatcher lanes for player visible work monster work deferred work maintenance worker completions and generic work

• Adds execution modes for protocol input player movement actions world commits visible monster work background monster work and worker completions

• Adds monotonic ready time metadata to preserve scheduling age accurately

• Adds producer tokens generations and estimated task cost

• Replaces fixed queue draining with weighted deficit round robin

• Adds producer round robin where task ordering allows it

• Adds bounded admission for dispatcher work

• Adds explicit rejection telemetry for tasks that cannot be admitted

• Adds queue age telemetry scheduled lateness telemetry barrier timing and internal work measurements

• Applies runtime and task budgets to creature movement barrier batches deferred gameplay and worker completions

• Adapts background budgets across normal constrained and emergency states

• Uses player visible p99 and oldest ready age to reduce background pressure automatically

• Coalesces repeated movement refresh and post think work while preserving the oldest ready timestamp

This commit also adds a dedicated bounded monster compute service. The compute service has visible and background queues with visible work receiving stronger service weighting. On hosts with up to two CPUs the service can fall back to inline execution instead of creating extra worker pressure.

The compute service prepares expensive monster decisions such as pathfinding target candidate ranking and geometric combat eligibility. These results are returned as immutable suggestions. Every completion is re resolved by entity ID generation epoch position and navigation revision before the dispatcher can apply anything.

Parallel monster compute changes

• Adds a bounded monster compute service

• Adds visible and background compute queues

• Uses three to one service weighting for visible compute work

• Uses hardware aware worker defaults

• Uses inline execution on hosts with up to two CPUs

• Publishes immutable navigation snapshots by sixteen by sixteen sector

• Tracks topology and occupancy revisions separately

• Offloads bounded monster follow pathfinding

• Offloads target candidate ranking

• Offloads geometric combat eligibility checks

• Re resolves every completion before applying it

• Validates entity ID generation epoch position and revision on completion

• Keeps every movement step validated and committed through existing movement and query APIs

• Reserves completion capacity so accepted requests cannot silently lose their completion token

Visible monster work is now protected from stale background work. Monster movement and AI work are separated into visible and background lanes. When a player becomes relevant pending monster movement post think and compute work can be promoted to visible priority.

Visibility hysteresis is used to avoid rapid priority oscillation. Stale background entries are prevented from consuming or cancelling promoted visible work.

Visible work protection changes

• Separates visible monster movement and background monster movement

• Separates visible monster AI and background monster AI

• Promotes pending movement work when a player becomes relevant

• Promotes pending post think work when a player becomes relevant

• Promotes pending compute work when a player becomes relevant

• Uses visibility hysteresis to avoid priority flicker

• Keeps player NPC bed push teleport floor change summon and autowalk semantics on their existing authoritative paths

• Prevents stale background queue entries from consuming promoted visible work

• Prevents stale background queue entries from cancelling promoted visible work

Delayed monster ticks no longer catch up by replaying movement or attack bursts. Missed ticks are consumed once and are not replayed as bursts. This keeps monster movement and combat cadence more stable under backlog.

The change also hardens stress and lifetime behavior. Benchmark only flags were added for forced monster activity and hostile monster friendly fire. These remain disabled by default and must not be used as production behavior.

Stress and safety hardening

• Adds benchmark only forced monster activity configuration

• Adds benchmark only hostile monster friendly fire configuration

• Keeps both benchmark flags disabled by default

• Defers dispatcher budget reads until configuration is loaded

• Stabilizes zone weak caches with owner based ordering

• Synchronizes access to zone weak caches

• Handles ownerless Soul War corpses created by benchmark monster versus monster kills

• Fixes nil player quest loot chance handling

• Improves rejected and failed scheduled action handling

• Improves protocol and maintenance timer reliability when scheduling fails

• Stops the monster compute service before the shared thread pool during shutdown

Configuration added or updated

• creatureWalkTasksPerPass default 128 reloads on config reload

• walkParallelTasksPerPass default 8 reloads on config reload

• creatureAsyncTasksPerBucket default 16 reloads on config reload

• deferredGameplayTasksPerPass default 16 reloads on config reload

• workerCompletionsPerPass default 64 reloads on config reload

• dispatcherSliceDurationMs default 2 reloads on config reload

• dispatcherSloMs default 50 reloads on config reload

• dispatcherEmergencyMs default 100 reloads on config reload

• monsterComputeThreads default 0 uses hardware aware selection and requires restart

• monsterComputeQueueCapacity default 2048 requires restart

Safety contracts

• Workers receive values or immutable snapshots only

• Workers return suggestions only

• Workers never call the dispatcher directly

• Lua stays on the dispatcher

• RNG stays on the dispatcher

• Damage stays on the dispatcher

• Effects stay on the dispatcher

• Conditions stay on the dispatcher

• Cooldowns stay on the dispatcher

• Map mutation stays on the dispatcher

• Client fanout stays on the dispatcher

• Every queue is bounded

• Every accepted request and completion token is bounded

• Stale topology results are discarded

• Occupancy staleness is treated only as a hint

• Monster delayed ticks are consumed once and are never replayed as attack or movement bursts

Documentation and project updates

• Documents the dispatcher fairness architecture

• Documents the parallel monster AI contracts

• Documents rollout gates and remaining risks

• Documents profiling evidence and production versus stress test assumptions

• Adds performance and lifetime roadmap documentation

• Updates CMake entries for new source files

• Updates Visual Studio project entries for new source files

Validation performed

• Visual Studio x64 Release build

• CMake windows release enabled tests unit target passed with 264 of 264 tests

• Dispatcher policy tests

• Weighted deficit round robin tests

• Adaptive budget tests

• Admission tests

• Coalescing tests

• Shutdown tests

• Navigation snapshot tests

• Monster pathfinding tests

• Target ranking tests

• Combat intention tests

• Relevance tests

• Compute saturation tests

• Weak cache regression tests

• Local gameplay smoke tests for player walk, monster follow combat target changes and visibility promotion

• Benchmark only all monsters active stress runs

• Benchmark only friendly fire stress runs

• Visual Studio profiling with bounded queues

Test configuration

• Server Canary 3 6 1

• Client protocol 15 25

• Operating system Windows x64

• Compiler Microsoft Visual Studio MSVC

• Compute service using 4 workers

• Compute capacity using 2048 tokens

Rollout gates are still required

• Linux build and runtime validation

• Production like hunt benchmark with player visible p99 at or below 50 milliseconds

• Stale path rate below 20 percent

• Compute saturation below 1 percent

• Reload and shutdown stress with pending requests and completions

• At least 72 hours in the Canary before production promotion

The all monsters active benchmark validates overload bounds and fairness. It is intentionally harsher than a production hunt and should not be treated as a production acceptance result on its own.

Overall, this commit introduces bounded lane-aware dispatcher scheduling and a dedicated safe compute path for monster AI preparation. It improves fairness under monster-heavy workloads, protects player visible latency, reduces stale work, and uses extra CPU cores without allowing worker threads to mutate authoritative game state.
2026-07-12 19:23:14 -03:00
Eduardo Dantas
e8237cef7b
ci(release): link exact client release (#4019)
Validate the matching client release before publishing Canary

This commit updates the Canary release workflow so every Canary release links to and validates the exact client release that matches the configured Canary client version.

The release process now resolves the matching client release from CLIENT VERSION and the derived client display value. For example, a Canary build targeting client version 1513 resolves to a client release tag that starts with 15 13. This avoids publishing Canary release notes that point users to a generic latest client package that may not match the server protocol version.

A new client release validation step was added before the Canary publish job. The workflow queries the client releases, finds the most recently published non-draft and non-pre-release tag matching the expected client display prefix, and exposes that resolved tag for the publish step.

The publish job now depends on this validation step. Canary is only published after the matching client release is found and its required download assets are confirmed. This makes the release flow safer because broken or missing client downloads are caught before the Canary release is published.

The workflow now validates that the matching client release includes the required package assets.

Required client assets

• client client tag zip

• client 11 zip

• 8 6 extended zip

The generated Canary release notes now link to the exact resolved client release tag rather than the latest client release. This makes the download target deterministic and keeps Canary release notes aligned with the client package expected by the configured CLIENT VERSION.

Client packaging remains outside the Canary release workflow. The Canary workflow only validates and links to the matching client release. It does not generate the modern client zip, the client 11 zip, the extended 8 60 zip, or the legacy dat and spr packages.

The related client packaging automation now lives in client PR 19. That workflow is responsible for producing and updating the modern client package and the full 11 and 8 60 client packages using assets exported from the current client tag.

Main changes included in this commit

• Adds a validate client release job to the Canary release workflow

• Resolves the expected client release prefix from CLIENT VERSION and client display

• Finds the matching client release before publishing Canary

• Ignores draft and prerelease client releases during matching

• Uses the most recently published matching client release tag

• Validates that the required client package assets exist

• Blocks Canary publishing when the matching client release is missing

• Blocks Canary publishing when required client assets are missing

• Passes the resolved client release tag to the publish job

• Updates Canary release notes to link to the exact client release tag

• Replaces the previous latest client release link with a deterministic version matched link

• Keeps client packaging out of the Canary release workflow

• Keeps legacy dat and spr generation out of the Canary release workflow

• Points maintainers to the dedicated client packaging workflow

Release workflow behavior

The release workflow first prepares and validates the Canary release metadata. It then runs the new client release validation job alongside the normal checks and build jobs.

The client release validation job queries the client release list, filters for published releases matching the expected client display prefix, selects the newest matching release, and verifies that the required assets are present.

If validation succeeds, the resolved client tag is passed to the publish job. The publish job uses that tag when generating the release notes link.

If validation fails, the Canary release is not published. This prevents a Canary release from pointing to missing or incompatible client packages.

Validation performed

• git diff check

Overall, this commit makes the Canary release process stricter and more deterministic. Canary releases now validate and link to the exact client release expected by the configured client version, while leaving all client packaging responsibilities in the dedicated client workflow.
2026-07-07 19:26:37 -03:00
Eduardo Dantas
bc826add94
perf: improve lifetime scheduling and monster AI hot paths (#4023)
Optimize monster hot paths and deferred gameplay scheduling

This commit implements the next slice of the performance and lifetime roadmap for the Canary creature and monster hot paths.

The focus is to reduce dispatcher pressure, async task fanout, spectator churn, pathfinding churn, and target list lifetime risk under monster-heavy workloads while keeping player visible gameplay behavior intact.

The change keeps combat and condition handling on the serial dispatcher path, but moves delayed monster post think work into a budgeted DeferredGameplay lane. This allows monster follow-up work to make progress without competing directly with the most sensitive gameplay operations on the main dispatcher.

Creature async work is now sliced through bounded buckets. This limits how much async creature work can be emitted at once and helps avoid large bursts of scheduled tasks. The deferred async flag clearing behavior is preserved, so creatures are not incorrectly considered ready for another async pass before the deferred work has actually completed.

Monster movement AI refreshes are now coalesced. Instead of scheduling repeated movement refreshes for the same monster in a burst, the system can merge pending refresh intents and execute them more controllably. This reduces redundant dispatcher work and helps monster-heavy scenarios avoid excessive task fanout.

Target lifetime handling was also improved. Monster target tracking now keeps player count bookkeeping balanced even when weak target references expire. This reduces the risk of monsters staying active because an expired player target was removed from the target list without updating the related active player count.

Pathfinding and tile lookup hot paths now reuse scoped floor cursors. This avoids repeated cursor setup work during repeated spectator and pathfinding operations while keeping the safe lifetime boundaries documented. The reuse is scoped so temporary lookup state does not escape beyond the valid operation window.

Benchmark-only monster stress options were added to make heavy monster workloads easier to test. These settings are intended for profiling and stress validation only, not normal production gameplay. A startup warning appears when stress settings are enabled, so operators do not accidentally run production servers with benchmark behavior active.

The change also preserves current client protocol compatibility details unrelated to the monster performance work, but necessary to keep behavior stable. The current 15 13 screenshot event payload encoding and level percent protocol gates remain preserved.

Main changes included in this commit

• Adds benchmark-only monster stress configuration flags

• Adds a startup warning when benchmark monster stress flags are enabled

• Allows stress scenarios such as keeping monsters active for benchmark purposes

• Allows monster versus monster target selection only through the benchmark stress configuration

• Slices creature async work through bounded buckets

• Preserves deferred async flag clearing behavior

• Routes delayed monster post think work through the budgeted DeferredGameplay lane

• Keeps combat and condition execution serial on the dispatcher

• Coalesces monster movement AI refreshes to reduce redundant scheduling

• Improves monster target tracking and target list lifetime safety

• Keeps target player count bookkeeping balanced when weak target references expire

• Improves monster idle behavior under expired target cleanup cases

• Reuses scoped floor cursors for pathfinding and tile lookup hot paths

• Documents the safe lifetime boundaries for cursor reuse

• Reduces spectator and pathfinding churn in monster-heavy workloads

• Preserves the current 15 13 screenshot event payload encoding

• Preserves level percent protocol gates

• Fixes the special Starving Wolf trap interaction

• Adds dispatcher queue latency logging to help monitor responsiveness

• Documents performance and lifetime roadmap evidence

• Documents validation assumptions for production-like scenarios and stress test scenarios

Runtime behavior

Monster AI and creature scheduling should now produce less dispatcher pressure during dense monster activity. Delayed monster post-think work is handled through the deferred gameplay lane with a budget, rather than being allowed to fan out into unbounded dispatcher pressure.

Player visible gameplay contracts remain intact. Combat and conditions continue to run through the serial dispatcher path, so the change does not intentionally reorder sensitive gameplay effects.

Movement and auto-walk behavior should be more predictable under load because repeated monster movement AI refreshes can be coalesced rather than stacking redundant work. Monsters should still move and react, but the refresh work is scheduled with less unnecessary churn.

Target tracking is safer when targets disappear. If a player target expires through a weak reference cleanup path, the monster target side bookkeeping is also updated, so idle and active state decisions are not based on stale player counts.

Stress testing behavior

The new monster stress flags are benchmark-only controls. They make it easier to reproduce monster-heavy workloads for profiling and validation, but they are not intended as normal server behavior.

When these flags are enabled, the server emits a startup warning to make the configuration's non-production nature clear.

Validation performed

• Static validation with git diff check HEAD 5 HEAD

• Reviewed production-like behavior assumptions for dispatcher and monster scheduling

• Reviewed stress test behavior assumptions for monster heavy workloads

• Follow up commits addressed validated comments around target count cleanup

• Follow-up commits addressed trap handling comments

• Follow-up commits addressed async scheduling comments

• Follow up commits addressed documentation comments

Overall, this commit improves the performance and lifetime safety of the Canary monster and creature hot paths. It reduces unnecessary async fanout dispatcher pressure, movement refresh churn, and pathfinding lookup overhead while preserving the serial gameplay contracts that matter for players.
2026-07-07 19:23:39 -03:00
Eduardo Dantas
f01b4f9060
docs(lua-api): sync screenshot signature (#4027) 2026-07-07 14:17:19 -03:00
Eduardo Dantas
ab863b04d2
feat: update current client 15.25 compatibility (#4020)
Update current client protocol compatibility to 15.25 byte contract

This commit updates the current client runtime profile to match the Tibia 15.25 byte contract and keeps the changes behind explicit runtime protocol feature flags.

The goal is to make the current client able to log in and keep running without message boundary debug errors while preserving the existing multiprotocol structure. This is a compatibility update focused on sending and consuming the bytes expected by the current client. It does not implement the full gameplay systems behind the new official windows dialogs rewards shops progression or balance features.

The current profile now enables versioned payload flags for the confirmed 15.25 differences. These flags gate the new packet shapes so the modern client can receive the expected payloads while older profiles do not automatically inherit incompatible message layouts.

The update also adds minimal byte compatible shims for new current client module windows and side dialogs. Taskboard and Soul Seals now have official client packet shims that respond with structurally valid empty windows where the gameplay system is not fully implemented yet. This keeps the client protocol stable without pretending that the complete feature set exists server side.

Several current client payloads were aligned with the 15.25 format. This includes resource balances graphical effects vocation specific data skill wheel weapon proficiency game events quest related payloads store summary parsing and related request parsers.

Main changes included in this commit

• Updates the current client runtime profile to the 15.25 byte contract

• Adds runtime feature flags for confirmed current client payload differences

• Gates 15.25 specific packet layouts behind explicit ProtocolFeature flags

• Adds support for official skill wheel payload differences

• Adds support for official weapon proficiency payload differences

• Adds support for graphical effect source byte differences

• Adds support for official vocation specific player data

• Adds support for official Taskboard packet family handling

• Adds support for official Soul Seals packet family handling

• Adds minimal byte compatible Taskboard shims for the current client

• Adds minimal byte compatible Soul Seals shims for the current client

• Adds explicit parsers for several previously unhandled current client opcodes

• Aligns resource balance request parsing with the current client payload

• Aligns graphical effect payloads with the current client format

• Aligns vocation specific data payloads with the current client format

• Aligns skill wheel payloads including quest bonus and gem list layout

• Aligns weapon proficiency payloads including detail list support

• Aligns game event payloads and related request handling

• Expands GameStore parsing for offer descriptions and events

• Adds stricter packet parsing and trailing byte handling where needed

• Improves protocol aware login logging with richer asset signature details

• Adds a god level protocol probe command for live protocol and message testing

• Documents the 15.25 compatibility scope and versioned payload flags

Protocol profile changes

The current profile mask now includes the new protocol feature flags required by the 15.25 byte contract. These flags allow the server to describe exactly which current client payloads are active instead of tying every behavior only to a raw client version number.

This keeps the compatibility layer safer for multiprotocol support because older profiles can continue using their own packet shapes while the current profile enables the official 15.25 payload differences.

Module shim changes

Taskboard support was added as a minimal official client shim. The server consumes the expected current client packet shape and returns structurally valid empty Taskboard windows. This keeps the client UI protocol satisfied while leaving the full Taskboard gameplay implementation for future work.

Soul Seals support was also added as a minimal official client shim. The server reads the expected request data validates the packet shape and responds with a structurally valid empty placeholder response. This prevents message boundary issues for the current client without implementing the complete Soul Seals system yet.

Payload compatibility changes

The current client expects several packet layouts that differ from older protocol profiles. This commit updates the server to match those confirmed layouts for the active current profile.

The affected areas include skill wheel payloads weapon proficiency details vocation specific player data resource balance requests graphical effects game events store parsing quest related payloads and related packet parsers.

These changes are focused on byte compatibility. They make the packet boundaries and payload shapes stable so the current client can operate without protocol debug breaks.

Bug fixes and robustness improvements

This commit also includes several protocol adjacent fixes found during the compatibility work. Packet parsing was made stricter in selected paths. Quest tracker validation and logging were updated. Store parser state handling was improved by avoiding shared global mutation for the default entries per page value.

The update also fixes precision and argument handling issues in related current client payload paths including level percent casting and forge skill stat argument placement.

Protocol probe tooling

A god only protocol probe command was added for live protocol testing. This gives maintainers a way to test selected protocol and message flows in game while keeping the command restricted to god group access.

The probe tool includes built in probes and file driven local probes, making it useful for reproducing current client packet behavior without exposing the tool to normal players.

Documentation changes

The systems documentation was updated with the 15.25 compatibility scope and multiprotocol feature notes. The documentation explains that this PR is a byte compatibility update and not a full gameplay implementation for every new current client window or system.

It also documents the versioned payload flags so future protocol updates can continue using explicit feature gated packet differences instead of mixing incompatible layouts into shared paths.

Validation performed

• Tested current client login locally

• Tested key current client UI surfaces locally while fixing reported client debug cases

• Confirmed fixes for skill wheel payload boundaries

• Confirmed fixes for character stats payload boundaries

• Confirmed fixes for store summary payload boundaries

• Confirmed fixes for defense stats payload boundaries

• Confirmed fixes for game event payload boundaries

• Confirmed fixes for graphical effect payload boundaries

• Confirmed fixes for related current client request parsers

• Full compile and build validation was not run

Known scope limitation

This commit intentionally does not implement the full gameplay systems behind the new current client windows dialogs rewards shops progression systems or balance features.

The purpose is to stabilize the message shape first. Full gameplay behavior can be implemented later on top of the now compatible packet structure.

Overall this commit brings the current client protocol path in line with the Tibia 15.25 byte contract. It adds explicit feature gated compatibility for confirmed payload differences introduces minimal shims for new official client windows improves parser coverage and documents the compatibility boundary while preserving the existing multiprotocol architecture.
2026-07-06 20:42:40 -03:00
Eduardo Dantas
3d14df709a
fix(recompile): back up the active runtime executable (#4026)
Fix recompile executable backup path resolution

This commit updates recompile.sh so the backup and restore flow resolves the Canary executable path from the active CMake output configuration instead of assuming a single hardcoded runtime path.

The previous follow up from PR 3985 fixed the default linux release case by recognizing that the executable is written to the repository root as canary instead of build canary. However that approach still only covered one output layout. It did not correctly handle Debug builds where the executable is named canary debug and it also did not handle builds using TOGGLE BIN FOLDER where the executable is written under the preset bin directory.

This change makes the recompile backup path follow the effective build mode and configured output layout. The executable name is now resolved from the effective CMake build type. Debug builds back up and restore canary debug while release like builds use canary.

The executable directory is also resolved from TOGGLE BIN FOLDER. When TOGGLE BIN FOLDER is disabled the runtime executable is expected in the repository root. When TOGGLE BIN FOLDER is enabled the executable is expected under the build preset bin output path.

The script now reads explicit CMake D overrides first and falls back to the existing CMakeCache txt when available. This means rerunning recompile.sh keeps using the same output contract that CMake already configured instead of guessing a new path.

Main changes included in this commit

• Resolves the Canary executable name from the effective CMake build type

• Uses canary debug for Debug builds

• Uses canary for release like builds

• Resolves the executable directory from TOGGLE BIN FOLDER

• Supports the repository root executable output layout

• Supports build preset bin executable output layout

• Reads explicit CMake D overrides before cache values

• Falls back to CMakeCache txt when available

• Keeps backup and restore handling aligned with the active CMake output path

• Reduces the chance of backing up or replacing the wrong executable

• Improves failure handling by restoring the saved executable from the resolved runtime path when configure or build fails

• Keeps the change focused on recompile.sh path resolution and backup safety

Validated path resolution cases

• linux release resolves to canary

• linux debug resolves to canary debug

• linux release with TOGGLE BIN FOLDER enabled resolves to build linux release bin canary

• linux release with TOGGLE BIN FOLDER enabled and CMAKE BUILD TYPE set to Debug resolves to build linux release bin canary debug

Validation performed

• bash n recompile.sh

• Exercised the path resolution helpers without running main

• git diff check

No compile or full build was run.

Overall this commit makes recompile.sh match the executable path that CMake actually configured. This fixes the incomplete hardcoded backup path handling from the previous change and makes recompilation safer across release debug root output and bin folder output layouts.
2026-07-06 20:31:54 -03:00
Eduardo Dantas
749af99147
fix(protocol): align 15.13 game event payload (#4022)
New Features:
• Added richer screenshot/game-event payload support, including optional
skill id/level, achievement name, race id, and bestiary step.
• Extended protocol feature flags to enable higher-precision player
level percentage transmission when supported by the connection.

Bug Fixes:
• Preserved legacy message formats for older clients and non-applicable
screenshot types to avoid protocol mismatches.
• Updated Lua achievement and screenshot calls to forward the new
optional context fields.
2026-07-03 18:36:57 -03:00
Eduardo Dantas
60f9c62aff
fix(release): preserve main client metadata (#4021) 2026-07-02 23:11:35 -03:00