11 KiB
AdventureBot profiles, daily plans and population
The generator owns its characters explicitly in vcore_adventure_generated_bot.
Lua stays in the character database and is loaded through the existing sandbox
as generated:<guid>. Hand-written named profiles retain precedence. Neither
names nor account prefixes establish ownership.
Profile version 2
identity records name, level, numeric native class and specialization index,
role (tank, healer, damage), seed, racial home zone/capital, favorite
adventure zone/region and RP origin/vocation/background. Race/class combinations
remain native and names use cultural grammars with native validation.
Generation supports levels 1–85, limited by the configured native maximum. Death knights require at least 55. Primary profession rights are already in the profile at low levels, but training waits for native level eligibility. Talents begin at 10. Warriors/paladins may use protection, death knights blood; priests, shamans and druids can receive healing specifications. Role metadata and native specialization/equipment are provided, not complete tank/healer combat AI. Existing class rotation limitations still apply.
Personality includes aggression, adventurousness, wanderlust, home attachment, sociability, group loyalty, tavern/wilderness/city affinities and danger tolerance. Activities and regional preferences are weighted. Low aggression reduces only proactive attacks, never existing self-defence. Group support and the absolute no-flee rule for grouped bots remain intact.
movement.ground_mounts contains weighted native creature display IDs for the
existing ground adapter; flight_mounts and companions contain weighted spell
IDs. Corresponding counts are emitted for inspection; parsed dictionary sizes
are authoritative. Ground mounts begin at 20, flight at 60; native geography,
spell/collision restrictions and flight licenses still apply. Companion choice
is rerolled at the beginning of a walk, not during an active scene. Generation
checks available native spell/model data. inventory.keep_items protects tools
and other explicitly permitted backpack items.
Older generated profiles are upgraded on their next load, preserving their name/background, personality and professions. The baseline native level becomes the fixed profile level during this one-time upgrade. Hand-written profiles are not rewritten. Existing stored day plans are retained.
Geography and daily plans
The live access and flight rules now use the editable area catalog, including inherited faction restrictions and minimum levels. The older leveling table below remains an import source, rather than the runtime authority.
Apply sql/custom/world/2026_10_29_00_adventure_population.sql. Its editable
vcore_adventure_zone catalog describes outdoor leveling bands and capital
accessibility for Cataclysm. Reapplying preserves operator edits. Unknown outdoor
bands receive a low planning weight. Regions more than five levels above the bot
are excluded; lower-level home visits remain possible, while adventure favors
level-appropriate regions. Favorite adventure regions exclude capitals.
Racial home/capital preferences are strong during town activities. Curiosity flattens preference weights and increases location/region variety. These remain weights among legal targets, not exclusive destinations. Existing native travel and MMAP validation still determines whether a planned destination is reachable; existing failure recovery can select an alternative if a route fails.
The existing vcore_adventure_day world table persists exactly 24 hourly slots
per character/date. Every slot contains both intent and destination before
execution. An intent spans one or more complete civil hours; destination changes
inside it are also preplanned. Consecutive equal intent/destination slots share
the end of their complete block, including instance timing. Travel consumes this
budget. Group preparation still uses its leader's meeting location and subsequent
goal. Runtime group adoption does not overwrite members' personal plans.
Dates and hour boundaries use the server process's local timezone, including
native mktime DST handling. Same-day relog/restart restores all 24 slots. An
incomplete or outdated day is atomically replaced and old dates removed. The
controller refreshes the day even while combat/recovery temporarily owns visible
behavior. On the DST fall-back day a repeated civil hour uses the same slot; a
skipped spring hour has no extra synthetic activity.
Loader configuration
Apply sql/custom/characters/2026_10_29_00_adventure_population.sql as well.
Defaults are deliberately disabled and have four zero online targets:
Clientless.Adventure.Loader.Enabled = 0
Clientless.Adventure.Loader.Alliance.Persistent = 0
Clientless.Adventure.Loader.Alliance.Temporary = 0
Clientless.Adventure.Loader.Horde.Persistent = 0
Clientless.Adventure.Loader.Horde.Temporary = 0
Clientless.Adventure.Loader.IntervalMs = 2000
Clientless.Adventure.Loader.MinLevel = 1
Clientless.Adventure.Loader.MaxLevel = 85
Clientless.Adventure.Loader.RotationPercent = 15
Clientless.Adventure.Loader.RotationMinAgeHours = 24
Clientless.Adventure.Manager.IntervalSeconds = 300
Each target is clamped to 0–5000. Zero suppresses new automated logins for that pool; changing a target does not forcibly evict already connected bots. Persistent and temporary Alliance/Horde inventories never substitute for one another. Loading/Removing sessions reserve capacity. A failed saved bot is retried with backoff instead of generating unbounded replacements.
Loading starts during normal world updates, with at least a ten-second initial delay. It is not part of mandatory server initialization. One login/generation operation is initiated per interval with round-robin pool selection. Snapshot, account registration, creation preflight and atomic save use polled asynchronous database callbacks; the loader never waits on a future. Native character setup, training/equipping and native deletion still execute on the world thread, one operation at a time. Existing native login/profile/catalog routines contain synchronous reads; this is not a claim of a completely asynchronous game core. Saved generated instance visitors also use these quotas. The former synchronous WorldScript startup loop no longer starts them independently. Legacy manually created visitors retain asynchronous, delayed and paced recovery; no generator schema is required for that legacy path. This prevents saved visits from bypassing a zero/disabled generated population.
Failures suspend/retry the loader and never request server shutdown. Large populations need separate latency/memory/CPU load acceptance.
When saved inventory is insufficient, new normal accounts with random unknown
credentials are registered using native SRP6 and prepared account inserts.
vcore_adventure_bot_account records ownership and faction. Native account
expansion/security/session checks and per-realm character limits are enforced.
Accounts are retained when bots rotate. External/player accounts are not
converted or deleted.
Temporary rotation and maintenance
Rotation is considered once per offline temporary candidate per process, before
login, with configurable chance/minimum age. It remains in the same faction and
temporary pool. First create and atomically save a replacement on an available
owned account (a new account can provide spare capacity). Then journal the pair
in vcore_adventure_rotation and mark the old bot replacing. Only a ready saved
replacement permits native permanent deletion. Persistent, connected and
non-owned characters cannot pass the deletion checks. Failed creation retains
the original. The journal resumes cleanup after a restart.
Cleanup verifies native character removal, then commits deletion of the old
world day plan before deleting profile, supply/instance state and the journal.
A failed world cleanup retains the journal for retry. Retired characters from
older manual retire operations are retained; retirement is not implicitly
converted to deletion.
The manager acts on versioned generated profiles only. At login and on staggered periodic checks it restores fixed level/XP, native class abilities, profession ranks, available talents, riding and profile equipment. Wrong class is reported, not converted. Dead/combat/dungeon/transit/casting states defer mutation. A full backpack is cleaned through native item destruction; equipped slots are untouched. One stack of each currently appropriate supply, bags, fishing poles and explicit profile tools/leash survive. Full inventories containing only permitted items are retained. Missing/invalid gear is repaired through the native equip checks, not rerolled unconditionally every interval. Ordinary player characters and hand-written Arthoran profiles are outside this maintenance ownership boundary.
Console diagnostics:
clientless population status
clientless population reload
clientless generate profile <guid>
clientless adventure plan <guid>
After editing the configuration, use the native reload config before
clientless population reload (or restart). Reload is refused while a population
operation is pending. Disabling the loader does not disable profile maintenance
for already online generated bots. No forced logout occurs on disable.
Technical verification and remaining acceptance
Production-code tests cover daily persistence with the real TINYINT hour shape, four pool quotas/retries, replacement ownership and cleanup failures, weighted Lua dictionaries/companions, full-inventory protection, shared birth/maintenance gear eligibility, native malformed item-spell cooldown safety and asynchronous prepared-statement contracts. Existing clientless regressions are retained.
On the test server, both factions received persistent bots at levels 1 and 85. All four pool targets were independently reached. A level-60 protection warrior was generated with its tank profile, native protection tree and weapon/shield. An administrative level1 -> level5 change was corrected to profile level1 on relogin; the saved day hash did not change. An expired test day was replaced by 24 current-date slots, and same-day plans survived a complete server restart. A dedicated temporary test character37 was replaced by38; native character, profile, day and supply/instance state were removed, with no remaining journal. Existing characters29–32 were retained. Inventory ownership hashes for human21 and Arthoran26 remained unchanged.
Two native defects exposed during these tests were fixed: the account insertion statement needed asynchronous registration, and an item sentinel spell ID could reach an asserting equip-cooldown lookup. The generator now rejects missing item spell data and native equip cooldowns skip missing spells. Unowned characters retain their prior native behavior for valid item data.
The test also encountered existing route failures involving unavailable map719 terrain and NPC/graph destinations. Those use existing fallback behavior; the MMAP/obstacle/TravelGraph overhaul remains deferred. Neutral-tagged markers in opposing faction capitals are now excluded explicitly from destination selection. A large population (for example 1,000 concurrent bots), travel quality, class-role combat behavior and visual gameplay have not been accepted by these technical checks. The loader is restored to disabled/zero targets after testing.