Teleportation Systems | Updated 2025

How to Build Teleporter Systems in LSL

Master teleportation scripting! Build single-destination teleporters, multi-destination networks, landmark systems, and stunning portal effects. Perfect for exploring your virtual world!

5 Teleporter Types
Network Systems
105 Min Tutorial

Teleportation Basics

Key LSL Functions for Teleporting:

Main Teleport Functions:

  • llTeleportAgent(key, string, vector, vector) - Requires PERMISSION_TELEPORT
  • llTeleportAgentHome(key) - Send avatar to home location
  • llMapDestination(string, vector, vector) - Opens map (no permission needed)

Coordinate System:

  • <X, Y, Z> - Regional coordinates (0-256 for X/Y)
  • Z = height above ground (usually 20-50 for safety)
  • llGetRegionName() - Current region name
Understanding Teleport Permissions
โš ๏ธ Permission Required

llTeleportAgent() needs explicit permission:

llRequestPermissions(avatar, PERMISSION_TELEPORT);

User must click "Yes" on permission dialog to allow teleporting.

โœ… No Permission Needed

llMapDestination() just opens map:

llMapDestination(region, pos, lookAt);

User must manually click "Teleport" on the map. Safe fallback option!

Type 1: Simple Touch Teleporter

Basic one-destination teleporter - touch to teleport to a fixed location.

// Simple Teleporter - Touch to teleport to fixed destination string DESTINATION_REGION = "Alife"; // Target region name vector DESTINATION_POS = <128, 128, 25>; // Landing coordinates vector LOOK_AT = <128, 128, 0>; // Camera direction after arrival default { state_entry() { // Visual indicator - floating text above teleporter llSetText("๐ŸŒ€ TELEPORTER\nTouch to visit " + DESTINATION_REGION, <0, 1, 1>, 1.0); // Glow effect to attract attention llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_GLOW, ALL_SIDES, 0.2]); } touch_start(integer num) { key avatar = llDetectedKey(0); string avatarName = llDetectedName(0); // Tell user what's happening llRegionSayTo(avatar, 0, "๐ŸŒ€ Preparing to teleport " + avatarName + " to " + DESTINATION_REGION + "..."); // Request teleport permission llRequestPermissions(avatar, PERMISSION_TELEPORT); } run_time_permissions(integer perm) { if (perm & PERMISSION_TELEPORT) { // Permission granted - teleport now! key avatar = llGetPermissionsKey(); llRegionSayTo(avatar, 0, "โœจ Teleporting..."); // Execute teleport llTeleportAgent(avatar, DESTINATION_REGION, DESTINATION_POS, LOOK_AT); // Log usage (optional) llOwnerSay("Teleported: " + llKey2Name(avatar)); } else { // Permission denied - offer map alternative key avatar = llGetPermissionsKey(); llRegionSayTo(avatar, 0, "โŒ Permission denied. Opening map instead..."); // Open map as fallback (no permission required) llMapDestination(DESTINATION_REGION, DESTINATION_POS, LOOK_AT); } } }
Setup Tips:
  1. Change DESTINATION_REGION to your target region name (case-sensitive!)
  2. Set DESTINATION_POS to safe landing coordinates (avoid spawning in walls)
  3. Test with llGetPos() to find exact coordinates at your destination
  4. Build teleporter on a platform or pedestal for visibility

Type 2: Multi-Destination Menu Teleporter

Choose from multiple destinations using a dialog menu.

// Multi-Destination Teleporter - Dialog menu with 4 destinations integer DIALOG_CHANNEL; key currentUser; // Destination data: [button_name, region_name, position] list DESTINATIONS = [ "Home", "Alife", <128, 128, 25>, "Shopping", "Marketplace", <100, 150, 22>, "Beach", "Paradise", <200, 180, 21>, "Events", "Concert Hall", <128, 64, 30> ]; string getDestinationRegion(string buttonName) { integer index = llListFindList(DESTINATIONS, [buttonName]); if (index != -1) return llList2String(DESTINATIONS, index + 1); return ""; } vector getDestinationPos(string buttonName) { integer index = llListFindList(DESTINATIONS, [buttonName]); if (index != -1) return llList2Vector(DESTINATIONS, index + 2); return ZERO_VECTOR; } default { state_entry() { // Use random dialog channel to avoid conflicts DIALOG_CHANNEL = -1 - (integer)("0x" + llGetSubString((string)llGetKey(), 0, 7)); llSetText("๐ŸŒ TELEPORT HUB\nTouch for destinations", <0.5, 1, 1>, 1.0); llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_GLOW, ALL_SIDES, 0.3]); } touch_start(integer num) { currentUser = llDetectedKey(0); // Build list of destination buttons list buttons = []; integer i; for (i = 0; i < llGetListLength(DESTINATIONS); i += 3) { buttons += llList2String(DESTINATIONS, i); } // Show dialog menu llDialog( currentUser, "๐ŸŒ€ Select your destination:\n\nChoose wisely!", buttons, DIALOG_CHANNEL ); // Listen for button click llListen(DIALOG_CHANNEL, "", currentUser, ""); // Auto-cleanup listener after 60 seconds llSetTimerEvent(60.0); } listen(integer channel, string name, key id, string message) { if (channel != DIALOG_CHANNEL) return; // Get selected destination data string destRegion = getDestinationRegion(message); vector destPos = getDestinationPos(message); if (destRegion != "") { llRegionSayTo(id, 0, "๐ŸŒ€ Teleporting to " + message + " (" + destRegion + ")..."); // Request permission and teleport currentUser = id; llRequestPermissions(id, PERMISSION_TELEPORT); } llSetTimerEvent(0.0); // Cancel cleanup timer } run_time_permissions(integer perm) { if (perm & PERMISSION_TELEPORT) { key avatar = llGetPermissionsKey(); // Find which destination was selected string destRegion = getDestinationRegion("Home"); // Default fallback vector destPos = getDestinationPos("Home"); // Teleport to selected destination llTeleportAgent(avatar, destRegion, destPos, ZERO_VECTOR); } } timer() { // Cleanup: Stop listening after timeout llSetTimerEvent(0.0); llListenRemove(0); // Remove all listeners } }
Adding More Destinations

Expand the DESTINATIONS list:

"Museum", "Art Gallery", <75, 200, 28>,

Each destination needs 3 entries: button label, region name, position vector.

Dialog Limits

LSL dialogs support up to 12 buttons.

For more destinations, create a paginated menu or use llTextBox() for text input selection.

Type 3: Landmark-Based Teleporter

Drop a landmark into the teleporter to set custom destinations!

// Landmark Teleporter - Drop landmarks to teleport to saved locations string destinationRegion = ""; vector destinationPos = ZERO_VECTOR; integer hasDestination = FALSE; default { state_entry() { // Allow inventory drops llAllowInventoryDrop(TRUE); llSetText("๐Ÿ“ LANDMARK TELEPORTER\nDrop landmark or touch to teleport", <1, 1, 0>, 1.0); // Check if we already have a landmark if (llGetInventoryNumber(INVENTORY_LANDMARK) > 0) { // Load first landmark string landmarkName = llGetInventoryName(INVENTORY_LANDMARK, 0); list data = llGetLandmarkDetails(landmarkName, [LANDMARK_REGION, LANDMARK_POSITION]); if (llGetListLength(data) == 2) { destinationRegion = llList2String(data, 0); destinationPos = llList2Vector(data, 1); hasDestination = TRUE; llSetText("๐Ÿ“ READY\nDestination: " + destinationRegion + "\nTouch to teleport", <0, 1, 0>, 1.0); } } } changed(integer change) { if (change & CHANGED_INVENTORY) { // New item added - check if it's a landmark if (llGetInventoryNumber(INVENTORY_LANDMARK) > 0) { string landmarkName = llGetInventoryName(INVENTORY_LANDMARK, 0); llSay(0, "๐Ÿ“ฅ Landmark received: " + landmarkName); llSay(0, "๐Ÿ” Analyzing destination..."); // Extract region and position from landmark list data = llGetLandmarkDetails(landmarkName, [LANDMARK_REGION, LANDMARK_POSITION]); if (llGetListLength(data) == 2) { destinationRegion = llList2String(data, 0); destinationPos = llList2Vector(data, 1); hasDestination = TRUE; llSay(0, "โœ… Destination set: " + destinationRegion + " at " + (string)destinationPos); llSetText("๐Ÿ“ READY\nDestination: " + destinationRegion + "\nTouch to teleport", <0, 1, 0>, 1.0); } else { llSay(0, "โŒ Invalid landmark data!"); } } } } touch_start(integer num) { key avatar = llDetectedKey(0); if (!hasDestination) { llRegionSayTo(avatar, 0, "โŒ No destination set! Drop a landmark into this teleporter first."); return; } llRegionSayTo(avatar, 0, "๐ŸŒ€ Teleporting to " + destinationRegion + "..."); llRequestPermissions(avatar, PERMISSION_TELEPORT); } run_time_permissions(integer perm) { if (perm & PERMISSION_TELEPORT) { key avatar = llGetPermissionsKey(); if (hasDestination) { llTeleportAgent(avatar, destinationRegion, destinationPos, ZERO_VECTOR); } } } }
How to Use Landmark Teleporters:
  1. Create a landmark: World โ†’ Landmark This Place (or Ctrl+Shift+L)
  2. Find landmark: Open Inventory โ†’ Search for landmark name
  3. Drop into teleporter: Drag landmark from inventory onto teleporter object
  4. Teleporter auto-configures to the landmark's destination!
  5. Touch teleporter to use the saved destination

Type 4: Teleporter with Portal Effects

Create stunning visual effects with swirling particles and glowing animations!

// Portal Teleporter - With particle effects and animations string DESTINATION_REGION = "Alife"; vector DESTINATION_POS = <128, 128, 25>; startPortalEffect() { // Swirling blue particle vortex llParticleSystem([ PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_INTERP_COLOR_MASK, PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE, PSYS_SRC_BURST_RADIUS, 0.5, PSYS_SRC_ANGLE_BEGIN, 0, PSYS_SRC_ANGLE_END, PI, PSYS_PART_START_COLOR, <0.2, 0.5, 1.0>, // Blue PSYS_PART_END_COLOR, <0.8, 0.9, 1.0>, // Light blue PSYS_PART_START_ALPHA, 1.0, PSYS_PART_END_ALPHA, 0.0, PSYS_PART_START_SCALE, <0.5, 0.5, 0.0>, PSYS_PART_END_SCALE, <2.0, 2.0, 0.0>, PSYS_PART_MAX_AGE, 2.0, PSYS_SRC_MAX_AGE, 0.0, PSYS_SRC_BURST_RATE, 0.1, PSYS_SRC_BURST_PART_COUNT, 5, PSYS_SRC_ACCEL, <0, 0, -1.0>, // Pull upward PSYS_SRC_OMEGA, <0, 0, 3.0> // Spin effect ]); } default { state_entry() { // Portal visual setup llSetText("๐ŸŒ€ PORTAL\n" + DESTINATION_REGION, <0.2, 0.8, 1.0>, 1.0); llSetColor(<0.1, 0.3, 0.8>, ALL_SIDES); llSetLinkPrimitiveParamsFast(LINK_THIS, [ PRIM_GLOW, ALL_SIDES, 0.5, PRIM_FULLBRIGHT, ALL_SIDES, TRUE ]); // Start portal effects startPortalEffect(); // Rotating animation llTargetOmega(<0, 0, 1>, 1.0, 1.0); // Spin on Z-axis } touch_start(integer num) { key avatar = llDetectedKey(0); // Flash effect when activated llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_GLOW, ALL_SIDES, 1.0]); llRegionSayTo(avatar, 0, "โšก Portal activated! Preparing teleport..."); // Sound effect llPlaySound("teleport_whoosh_uuid", 1.0); // Request permission llRequestPermissions(avatar, PERMISSION_TELEPORT); // Reset glow after 1 second llSetTimerEvent(1.0); } run_time_permissions(integer perm) { if (perm & PERMISSION_TELEPORT) { key avatar = llGetPermissionsKey(); // Teleport with dramatic effect llRegionSayTo(avatar, 0, "โœจ Entering portal vortex..."); llTeleportAgent(avatar, DESTINATION_REGION, DESTINATION_POS, ZERO_VECTOR); } } timer() { // Reset glow to normal llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_GLOW, ALL_SIDES, 0.5]); llSetTimerEvent(0.0); } }
Custom Portal Colors

Change particle colors for themed portals:

  • Fire portal: <1, 0.3, 0> to <1, 1, 0>
  • Toxic portal: <0, 1, 0> green particles
  • Dark portal: <0.5, 0, 0.5> purple/black
Portal Sound Effects

Add ambient sound loop:

llLoopSound("portal_hum_uuid", 0.5);

Creates atmospheric portal ambiance!

Type 5: Network Hub System

Advanced multi-pad teleporter network - like a train station for your virtual world!

// Teleport Network Hub - Multiple pads with synchronized network integer NETWORK_CHANNEL = -847362; // Shared channel for all pads string PAD_ID = "PAD_A"; // Unique ID for THIS pad (change per pad) // This pad's location for return trips string THIS_REGION; vector THIS_POSITION; // Network destinations (shared by all pads) list NETWORK_PADS = [ "PAD_A", "Welcome Hub", <128, 128, 25>, "PAD_B", "Shopping District", <100, 200, 22>, "PAD_C", "Residential Area", <200, 100, 28>, "PAD_D", "Event Center", <150, 150, 30> ]; string getPadRegion(string padID) { integer index = llListFindList(NETWORK_PADS, [padID]); if (index != -1) return llList2String(NETWORK_PADS, index + 1); return ""; } vector getPadPosition(string padID) { integer index = llListFindList(NETWORK_PADS, [padID]); if (index != -1) return llList2Vector(NETWORK_PADS, index + 2); return ZERO_VECTOR; } default { state_entry() { // Register this pad's location THIS_REGION = llGetRegionName(); THIS_POSITION = llGetPos(); // Visual setup string padName = getPadRegion(PAD_ID); llSetText("๐Ÿš‰ TELEPORT PAD\n" + padName + "\nTouch for network", <0, 1, 1>, 1.0); // Glowing platform llSetColor(<0, 0.5, 1>, ALL_SIDES); llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_GLOW, ALL_SIDES, 0.3]); // Listen for network updates llListen(NETWORK_CHANNEL, "", "", ""); } touch_start(integer num) { key avatar = llDetectedKey(0); // Build destination menu (exclude current pad) list buttons = []; integer i; for (i = 0; i < llGetListLength(NETWORK_PADS); i += 3) { string padID = llList2String(NETWORK_PADS, i); if (padID != PAD_ID) // Don't show current pad { string buttonLabel = llList2String(NETWORK_PADS, i + 1); buttons += buttonLabel; } } // Show network map dialog llDialog( avatar, "๐Ÿš‰ TELEPORT NETWORK\n\nSelect destination pad:", buttons, NETWORK_CHANNEL ); } listen(integer channel, string name, key id, string message) { // Find which pad was selected integer i; for (i = 0; i < llGetListLength(NETWORK_PADS); i += 3) { if (llList2String(NETWORK_PADS, i + 1) == message) { string targetPad = llList2String(NETWORK_PADS, i); string targetRegion = llList2String(NETWORK_PADS, i + 1); vector targetPos = llList2Vector(NETWORK_PADS, i + 2); llRegionSayTo(id, 0, "๐Ÿš‰ Teleporting to " + message + "..."); // Activate platform effect llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_GLOW, ALL_SIDES, 1.0]); llSetTimerEvent(1.0); // Reset glow // Request teleport llRequestPermissions(id, PERMISSION_TELEPORT); return; } } } run_time_permissions(integer perm) { if (perm & PERMISSION_TELEPORT) { // Find destination from recent dialog selection // (In full implementation, store selected destination) string targetRegion = getPadRegion("PAD_B"); // Example vector targetPos = getPadPosition("PAD_B"); llTeleportAgent(llGetPermissionsKey(), targetRegion, targetPos, ZERO_VECTOR); } } timer() { llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_GLOW, ALL_SIDES, 0.3]); llSetTimerEvent(0.0); } }
Building a Network:
  1. Copy this script into each teleport pad
  2. Change PAD_ID for each pad ("PAD_A", "PAD_B", etc.)
  3. Update NETWORK_PADS list with all pad locations
  4. All pads share the same NETWORK_CHANNEL for communication
  5. Users can travel between any pads in the network!

๐ŸŒ€ Build Your Teleportation Network!

Connect your virtual world with these powerful teleporter scripts.