2 Commits
2 changed files with 29 additions and 3 deletions
+5 -3
View File
@@ -196,7 +196,6 @@ function AzerothAIEmitSnapshots()
local guids={} local guids={}
for _,player in pairs(players) do for _,player in pairs(players) do
if is_playerbot(player) then if is_playerbot(player) then
emit("player.snapshot",player_payload(player))
guids[#guids+1]=player:GetGUIDLow() guids[#guids+1]=player:GetGUIDLow()
emitted=emitted+1 emitted=emitted+1
end end
@@ -207,9 +206,9 @@ function AzerothAIEmitSnapshots()
for _,p in pairs(players) do if is_playerbot(p) then ordered[#ordered+1]=p end end for _,p in pairs(players) do if is_playerbot(p) then ordered[#ordered+1]=p end end
table.sort(ordered,function(a,b) return (socialLast[a:GetGUIDLow()] or 0)<(socialLast[b:GetGUIDLow()] or 0) end) table.sort(ordered,function(a,b) return (socialLast[a:GetGUIDLow()] or 0)<(socialLast[b:GetGUIDLow()] or 0) end)
for _,p in ipairs(ordered) do for _,p in ipairs(ordered) do
if not p:IsDead() and not p:IsInCombat() and os.time()-(socialLast[p:GetGUIDLow()] or 0)>600 then if not p:IsDead() and not p:IsInCombat() and not p:IsMoving() and os.time()-(socialLast[p:GetGUIDLow()] or 0)>600 then
for _,q in pairs(p:GetPlayersInRange(25) or {}) do for _,q in pairs(p:GetPlayersInRange(25) or {}) do
if q:GetGUIDLow()~=p:GetGUIDLow() and is_playerbot(q) and not q:IsDead() and not q:IsInCombat() and p:GetTeam()==q:GetTeam() and p:GetPhaseMask()==q:GetPhaseMask() and os.time()-(socialLast[q:GetGUIDLow()] or 0)>600 then if q:GetGUIDLow()~=p:GetGUIDLow() and is_playerbot(q) and not q:IsDead() and not q:IsInCombat() and not q:IsMoving() and p:GetDistance(q)<=15 and p:GetTeam()==q:GetTeam() and p:GetPhaseMask()==q:GetPhaseMask() and os.time()-(socialLast[q:GetGUIDLow()] or 0)>600 then
roster.socialA=p:GetName();roster.socialB=q:GetName();roster.zoneName=area_name(p:GetZoneId()) roster.socialA=p:GetName();roster.socialB=q:GetName();roster.zoneName=area_name(p:GetZoneId())
socialLast[p:GetGUIDLow()]=os.time();socialLast[q:GetGUIDLow()]=os.time() socialLast[p:GetGUIDLow()]=os.time();socialLast[q:GetGUIDLow()]=os.time()
break break
@@ -219,6 +218,9 @@ function AzerothAIEmitSnapshots()
if roster.socialA then break end if roster.socialA then break end
end end
emit("player.snapshot",roster) emit("player.snapshot",roster)
for _,player in pairs(players) do
if is_playerbot(player) then emit("player.snapshot",player_payload(player)) end
end
return emitted return emitted
end end
+24
View File
@@ -0,0 +1,24 @@
# Autonomous conversations
The live bridge proposes nearby, same-faction stationary bot pairs within 15 yards. Delivery allows up to 25 yards. Both
must be alive, out of combat and in the same phase. Opportunities ride the fresh
roster snapshot transport. The database admits at most one exchange per two-minute
clock bucket and enforces ten minutes between social requests involving a bot.
Human requests take queue priority. Ordinary bot chatter does not trigger replies.
An exchange consists of a model-generated opening and one model-generated reply.
Each delivery rechecks distance, faction, phase, life and combat state in the game.
Expired requests and pairs that have moved apart are cancelled. No characters are
teleported or held in place for conversations.
Only a confirmed reply creates reciprocal observation memories and neutral
acquaintance records. This does not invent friendship or change affinity based
solely on speaking. Replay IDs prevent duplicate memories. Each resident retains
at most 100 memories and 100 relationship records on this path. Completed and
failed conversation requests are pruned after 24 hours; character memorials and
other game/event history have separate retention policies.
Memories and relationships are stored in `realm_state.payload` in the application's
D1 SQLite database under `.wrangler/state/v3/d1` in the Ubuntu deployment. This
uses the VM's disk, backed by the host PC's storage. The per-resident memory limit
is not a total disk quota: additional identities and other logs can still grow.