The bot will be able to:
- ✅ Log into OpenSimulator as an avatar
- ✅ Walk, turn, move around
- ✅ Know where it is and which objects surround it
- ✅ Listen and respond in chat
- ✅ Use LLM + local RAG
- ✅ Show explanatory subtitles (sources + reasoning)
opensim_ai_bot/
│
├─ lib/
│ └─ OpenMetaverse.dll
│
├─ bot/
│ ├─ client.py # connection + events
│ ├─ movement.py # walk, turn
│ ├─ perception.py # position, objects
│
├─ ai/
│ ├─ llm.py # LLM
│ ├─ rag.py # local RAG
│ └─ prompts.py
│
├─ knowledge/
│ ├─ docs/
│ │ ├─ opensim.txt
│ │ ├─ world.md
│ │ └─ objects.md
│
├─ subtitles/
│ └─ explain.py # explanatory subtitles
│
├─ main.py
└─ requirements.txt
import time
from OpenMetaverse import Vector3
class BotMovement:
def __init__(self, client):
self.client = client
def walk_forward(self, meters=2.0):
pos = self.client.Self.SimPosition
direction = self.client.Self.Movement.BodyRotation.GetForwardVector()
new_pos = Vector3(
pos.X + direction.X * meters,
pos.Y + direction.Y * meters,
pos.Z
)
self.client.Self.AutoPilot(new_pos)
time.sleep(2)
def turn_left(self):
self.client.Self.Movement.TurnLeft(True)
time.sleep(1)
self.client.Self.Movement.TurnLeft(False)
def turn_right(self):
self.client.Self.Movement.TurnRight(True)
time.sleep(1)
self.client.Self.Movement.TurnRight(False)class BotPerception:
def __init__(self, client):
self.client = client
def get_position(self):
pos = self.client.Self.SimPosition
return f"X={pos.X:.1f}, Y={pos.Y:.1f}, Z={pos.Z:.1f}"
def list_nearby_objects(self, radius=10):
objects = []
for obj in self.client.Network.CurrentSim.ObjectsPrimitives.Values:
if obj.Properties and obj.Properties.Name:
objects.append(obj.Properties.Name)
return objects[:10]Here I use abstraction, so you can swap it later.
class LLM:
def generate(self, prompt):
# Placeholder (later you connect a real model)
return f"(Response generated by the LLM)\n{prompt[:200]}"import os
class RAG:
def __init__(self, docs_path="knowledge/docs"):
self.docs = {}
self.load_docs(docs_path)
def load_docs(self, path):
for file in os.listdir(path):
if file.endswith(".txt") or file.endswith(".md"):
with open(os.path.join(path, file), "r", encoding="utf-8") as f:
self.docs[file] = f.read()
def retrieve(self, query):
for name, text in self.docs.items():
if query.lower() in text.lower():
return name, text[:500]
return None, "No relevant information."def explain(source, reason):
return f"""
📚 Source:
{source}
🧠 Explanation:
{reason}
"""import clr
import time
clr.AddReference("lib/OpenMetaverse")
from OpenMetaverse import GridClient
from bot.movement import BotMovement
from bot.perception import BotPerception
from ai.llm import LLM
from ai.rag import RAG
from subtitles.explain import explain
class OpenSimBot:
def __init__(self, first, last, password, uri):
self.client = GridClient()
self.first = first
self.last = last
self.password = password
self.uri = uri
self.movement = BotMovement(self.client)
self.perception = BotPerception(self.client)
self.llm = LLM()
self.rag = RAG()
self.client.Self.ChatFromSimulator += self.on_chat
def login(self):
params = self.client.Network.DefaultLoginParams(
self.first,
self.last,
self.password,
"AI Bot",
"Python"
)
params.URI = self.uri
print("🔌 Connecting...")
if not self.client.Network.Login(params):
raise SystemExit("❌ Login failed")
print("✅ Bot connected!")
def on_chat(self, sender, args):
msg = args.Message.lower()
name = args.FromName
print(f"💬 {name}: {msg}")
if "walk" in msg:
self.movement.walk_forward()
self.say("🚶 Walking")
elif "where are you" in msg:
pos = self.perception.get_position()
self.say(f"📍 I am at {pos}")
elif "what do you see" in msg:
objs = self.perception.list_nearby_objects()
self.say("👀 I see: " + ", ".join(objs))
else:
source, context = self.rag.retrieve(msg)
answer = self.llm.generate(context)
legend = explain(
source,
"I used internal world documentation to answer."
)
self.say(answer)
self.say(legend)
def say(self, text):
self.client.Self.Chat(
text,
0,
self.client.Self.ChatType.Normal
)
def run(self):
print("🤖 Bot active")
while True:
time.sleep(1)from bot.client import OpenSimBot
bot = OpenSimBot(
first="AI",
last="Bot",
password="password",
uri="http://127.0.0.1:9000"
)
bot.login()
bot.run()User:
where are you?
Bot:
📍 I am at X=128.0, Y=128.0, Z=22.0
User:
what is this object?
Bot:
(Response generated by the LLM)
This object is part of the system...
📚 Source:
objects.md
- ✅ Complete AI bot
- ✅ Real movement
- ✅ World perception
- ✅ Local RAG
- ✅ LLM ready
- ✅ Explanatory subtitles
- ✅ Professional structure
- FAISS / embeddings
- Per-user memory
- HUD with subtitles
- Menu-based commands
- Multilingual support
- XML / JSON logs
- Teacher / guide / safety mode