Files
Viano-Core/doc/clientless/population.md
T

200 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.