homunculus

Quick Start

Getting started with Homunculus

This library is a work in progress!

It is not intended for use yet, large changes are due to happen. This library is primarily intended for chat functionality in Second Life. Other features may not work as intended or may be incomplete. Use at your own risk.

Introduction

Homunculus Bot is a minimal Node.js package that allows basic interactions with the virtual world Second Life, utilizing the official Second Life UDP protocol.

Homunculus Bot is not affiliated with or sponsored by Linden Research, Linden Lab or Second Life.

Installation

From a new empty project folder
npm init -y
npm install @gwigz/homunculus-core @gwigz/homunculus-bot
npm install --save-dev @types/node
bun init -y
bun add @gwigz/homunculus-core @gwigz/homunculus-bot
bun add --dev @types/node

Authentication

It's recommended that you create an .env file in the root of your project, see the example file.

Basic Usage

This is a simple example of how to connect to Second Life and listen for nearby chat messages.

index.ts
import {  } from "@gwigz/homunculus-core"
import {  } from "@gwigz/homunculus-bot"

const  = new ()

const  = new (, {
  : "!",
  : .,
})

// register a command that responds to `!ping`
.({
  : "ping",
  : (, , ) => {
    // return a message (to local chat)
    return `Pong ${.}!`
  },
})

// by default, we connect using the SL_USERNAME, SL_PASSWORD, and SL_START
// environment variables -- alternatively, you can just pass those values in
.()

To run the script, you can use the following command:

npx dotenv-cli npx tsx index.ts
bun run index.ts

Chat Commands

Register commands that respond to local chat messages. Currently, commands only work from local chat, restriction options will be added in future updates.

Responses can be guarded using message.source, which is the UUID which sent the message.

.({
  : "ping",
  (, , {  }) {
    // only respond to messages from a specific avatar
    if ( !== "a2e76fcd-9360-4f6d-a924-000000000003") {
      return
    }

    // return a message (to local chat)
    return "Hi Philip!"
  },
})

API Handlers

Unfinished feature

This feature is not tested yet, and may not work as intended.

LSL/SLua handlers are registered using the registerApiHandler method.

const  = new (, {
  : "!",
  : "#api",
  : ",",
  : 81513312, // channel returned strings are sent to
})

// handles i.e. `llOwnerSay("#api,status")`
.({
  : "status",
  (, , ) {
    // optionally respond over `apiChannel`
    return "OK!"
  },
})

This registers a function that responds to llOwnerSay messages. These currently work on both rezzed objects and attachments, restriction options are planned for future updates.

Parameter Validation

We also support Zod validation for API handlers. Here's an example of handling JSON parameters.

import {  } from "zod/v4"

// handles i.e. `llOwnerSay("#api,sound," + json)`
.({
  : "sound",
  async (, { ,  }) {
    await ..(, )
  },
  : .({
    : .().(),
    : .().(0).(1).(1),
  }),
  : "json",
})

This provides a type-safe way to handle parameters, and also provides default values — for example, here the gain parameter is set to 1 by default.

Resources