OpenSimulator Internals/Walkthroughs/Avatar Rez In Region
OpenSimulator Internals/Walkthroughs/Avatar Rez In Region
[edit]Overview
[edit]Traces what happens in code, connectors, and database from the moment a viewer completes login and connects to a region, through to the avatar standing in-world with appearance applied and scene state sent.
This covers the normal login case (not HG, not region transfer). See OpenSimulator Internals/Walkthroughs/Avatar Transfer Between Regions and OpenSimulator Internals/Walkthroughs/Avatar Goes HG for those paths.
1. Login Service Issues Seed Capability
[edit]OpenSim/Services/LLLoginService/LLLoginService.cs OpenSim/Server/Handlers/Login/LLLoginHandlers.cs
- Viewer POSTs login credentials to ROBUST LoginService (port 8002 by default) via XMLRPC.
- LLLoginService authenticates via AuthenticationService, loads UserAccount, fetches appearance via AvatarService.
- LoginService calls PresenceService.LoginAgent() -- writes presence row: UserID, RegionID, SessionID, SecureSessionID, Online=1.
- LoginService calls GridUserService.SetLastPosition() -- updates griduser: LastRegionID, LastPosition, Login timestamp.
- LoginService selects destination region via GridService -- reads from regions table.
- LoginService calls the destination region's NewUserConnection capability -- passes AgentCircuitData (agent UUID, session UUID, circuit code, appearance, teleport flags). This pre-populates AgentCircuitManager in the region before the viewer connects.
- LoginService returns login response to viewer: SimIP, SimPort, RegionX/Y, SeedCapability URL, circuit code, session UUIDs.
- DB writes
- presence -- INSERT or UPDATE: UserID, RegionID, SessionID, SecureSessionID, Online=1
- griduser -- UPDATE: LastRegionID, LastPosition, Login timestamp
2. Viewer Establishes UDP Circuit
[edit]OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
- Viewer sends UseCircuitCode packet to region UDP port.
- LLUDPServer.HandleUseCircuitCode() validates circuit code against AgentCircuitManager (pre-populated in step 1).
- On match: LLUDPClient created. LLClientView constructed and associated with the circuit.
- ScenePresence constructed:
- IsChildAgent = true initially (set in constructor)
- Constructor fetches UserAccount for god level and user flags
- Constructor calls RegisterToClientEvents() -- wires OnCompleteMovementToRegion → CompleteMovement, OnAgentUpdate → HandleAgentUpdate, OnRegionHandShakeReply → RegionHandShakeReply, and others
- Appearance set from AgentCircuitData appearance passed by LoginService
- AdjustKnownSeeds() called -- initialises known neighbour region cap seeds
- No DB writes at this step.
3. Viewer Sends CompleteMovementToRegion
[edit]OpenSim/Region/Framework/Scenes/ScenePresence.cs -- CompleteMovement()
The viewer fires CompleteMovementToRegion after receiving the circuit acknowledgement. This triggers ScenePresence.CompleteMovement() on the region side.
- For login (IsRealLogin true): does NOT wait for UpdateAgent -- skips WaitForUpdateAgent(). For teleports and crossings: waits up to 10 seconds for the source region's UpdateAgent call to arrive before proceeding.
- Checks flying state from AgentControlFlags.
- Calls MakeRootAgent() (see step 4).
- If not a cross-update: fetches group title via IGroupsModule.
- Rotates avatar to look direction.
- Initialises parcel tracking (m_currentParcelUUID, m_currentParcelHide).
- Sets m_inTransit = false.
- Sends RegionHandshake to viewer (ControllingClient.SendRegionHandshake()) if not a crossing.
- Calls ControllingClient.MoveAgentIntoRegion() -- sends the viewer its position and look.
- Validates baked texture cache via AvatarFactory. Queues appearance save if invalid.
- Sends initial avatar data to all presences (SendInitialAvatarDataToAllAgents()).
- Sends this avatar's appearance to self (SendAppearanceToAgent(this)).
- Sends current animation pack to self.
- Sends appearance and animations to all other presences (parcel visibility respected).
- Rezzes attachments: for real login, calls Scene.AttachmentsModule.RezAttachments(this).
- For login (not cross-update): calls IFriendsModule.SendFriendsOnlineIfNeeded().
- Hooks RegionHeartbeatEnd event for per-frame health regen and movement animation updates.
- No DB writes at this step (appearance save is queued async if needed).
4. MakeRootAgent()
[edit]OpenSim/Region/Framework/Scenes/ScenePresence.cs -- MakeRootAgent()
Called from CompleteMovement(). This is the critical path; delay here delays the crossing.
- Acquires m_completeMovementLock. Returns false immediately if already root agent (IsChildAgent == false).
- Handles pending sit: if ParentUUID is set, resolves the sit target prim and re-seats the avatar.
- Sets IsChildAgent = false.
- Updates RegionHandle to this region.
- Fires EventManager.TriggerSetRootAgentScene().
- Position adjustment (if not sitting):
- Checks and adjusts landing point (telehub, parcel landing point, ban lines) via CheckAndAdjustLandingPoint_OS() or _SL().
- Clamps position to region bounds.
- Raises position to ground height + avatar half-height.
- If ViaLogin or ViaLocation flags set: raycasts downward from PhysSearchHeight (300m) to find surface, adjusts Z to avoid being inside objects.
- Sets AbsolutePosition.
- Calls AddToPhysicalScene(isFlying) -- creates PhysicsActor, enters physics simulation.
- Calls m_scene.SwapRootAgentCount(false, IsNPC) -- increments root agent count.
- Resets MovementFlags to 0.
- Updates circuit child status: AuthenticateHandler.UpdateAgentChildStatus(circuitCode, false).
- Fires EventManager.TriggerOnMakeRootAgent(this) -- modules hook here.
- No DB writes at this step.
5. RegionHandshake / SendInitialData
[edit]OpenSim/Region/Framework/Scenes/ScenePresence.cs -- RegionHandShakeReply(), SendInitialData()
- Viewer sends RegionHandshakeReply in response to the handshake sent in step 3.
- RegionHandShakeReply() sets m_gotRegionHandShake = true and NeedInitialData = 2.
- On subsequent heartbeat frames, Update() checks NeedInitialData > 0 and calls SendInitialData().
- SendInitialData() waits for viewer caps seeds to be sent (ViewerFlags.SentSeeds), then waits a few more frames for the viewer to process them (NeedInitialData incremented to 6 before proceeding).
- When ready, fires async via Util.FireAndForget:
- Releases source region if callback URI present (v1 or v0.7 HG path).
- Closes old child agents via IEntityTransferModule.CloseOldChildAgents().
- Sends terrain layer data (Scene.SendLayerData()) if not a teleport.
- Sends parcel info (LandChannel.sendClientInitialLandInfo()).
- Sends full updates for all other root presences' avatars (SendOtherAgentsAvatarFullToMe()).
- Sends ObjectUpdate packets for all scene objects within draw distance -- either full updates or cache probes depending on viewer cache state.
- Creates child agents in neighbouring regions via IEntityTransferModule.EnableChildAgents(this).
- Enables child update processing (m_childUpdatesBusy = false).
- No DB writes at this step.
6. Attachments Rezzed
[edit]OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs -- RezAttachments()
Called from CompleteMovement() for real logins (IsRealLogin true). For teleports/crossings, attachments are carried in AgentData and scripts restarted via RestartAttachmentScripts() instead.
- For each attachment in appearance data: fetches inventory item from InventoryService.
- Fetches asset from AssetService.
- Rezzes SceneObjectGroup in world at attachment point.
- Note: method name typo IncomingAttechments() exists at Scene.cs line 2976 and AttachmentsModule.cs line 384 (Mantis pending).
- DB reads
- inventoryitems -- SELECT by item UUID for each attachment
7. Presence and GridUser Updated
[edit]OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs
After MakeRootAgent and CompleteMovement complete, the region confirms the avatar's position:
- PresenceService.ReportAgent() -- updates presence table, confirms RegionID.
- GridUserService.SetLastPosition() -- updates griduser with confirmed in-region position and look.
- DB writes
- presence -- UPDATE: RegionID confirmed for this session
- griduser -- UPDATE: LastPosition, LastLookAt, LastRegionID
Summary: DB Tables Touched
[edit]| Table | Operation | Step |
|---|---|---|
| presence | INSERT/UPDATE | LoginService (step 1) |
| griduser | UPDATE | LoginService (step 1), post-rez (step 7) |
| regions | SELECT | LoginService destination lookup (step 1) |
| avatarappearance | SELECT | LoginService via AvatarService (step 1) |
| avatarattachments | SELECT | LoginService via AvatarService (step 1) |
| inventoryitems | SELECT | AttachmentsModule.RezAttachments() (step 6) |
Note: avatarappearance and avatarattachments are read by LoginService, not by the region directly -- the appearance data travels to the region inside AgentCircuitData.
Key Flags
[edit]- TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID -- set for normal login. Controls landing point behavior, telehub routing, and whether WaitForUpdateAgent() is skipped.
- TeleportFlags.ViaHGLogin -- HG login path; triggers different appearance handling and skips baked texture validation.
- IsRealLogin() -- returns true only for ViaLogin without ViaHGLogin. Determines whether attachments are freshly rezzed vs carried from source region.
- m_gotCrossUpdate -- false for login, true for region crossings. Controls whether SendLayerData and child agent setup are deferred.
See Also
[edit]- OpenSimulator Internals/Walkthroughs
- OpenSimulator Internals/Code Map/ROBUST/LoginService
- OpenSimulator Internals/Code Map/ROBUST/PresenceService
- OpenSimulator Internals/Code Map/ROBUST/AvatarService
- OpenSimulator Internals/Code Map/Scene
- OpenSimulator Internals/Code Map/LLClientView
- OpenSimulator Internals/Connector Architecture/Presence Connector
- OpenSimulator Internals/Connector Architecture/Avatar Connector
- OpenSimulator Internals/Walkthroughs/Avatar Transfer Between Regions
- OpenSimulator Internals/Walkthroughs/Avatar Goes HG