200 lines
11 KiB
Markdown
200 lines
11 KiB
Markdown
# 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](area-catalog.md),
|
||
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:
|
||
|
||
```ini
|
||
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:
|
||
|
||
```text
|
||
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.
|