Alife Virtual School - Class 14: Money Handling in LSL
Money Handling in LSL — Free class in Alife Virtual School
Turn Your Creations into a Business: An Intermediate Guide to LSL Money Scripts
Welcome, creators, to Class 14 of the Alife Virtual School! You’ve learned to build, to texture, and to write basic scripts. Now, it’s time to take the next big step: learning how to make your virtual creations come alive with commerce. In a bustling world like Alife Virtual, with over 1,148,000 members, the ability to buy and sell is what transforms a hobby into a thriving in-world business. Whether you dream of opening a popular nightclub with a tip jar for your DJ, selling your custom-designed outfits from a vending machine, or generating passive income by renting out homes on your land, it all starts with mastering money handling in LSL.
This skill is the bridge between being a builder and being an entrepreneur. It allows you to create interactive, self-sufficient systems that can operate 24/7, earning you Lindens while you’re offline or exploring other parts of our world. And here in Alife Virtual, we empower you to do just that. With features like free mesh and texture uploads, you can stock your vendors without worrying about fees, and you have the perfect place to set up shop on your very own FREE private island—a massive 65,536 sqm space with 10,000 prims that’s yours forever, with no monthly tier fees.
In this comprehensive tutorial, we will demystify LSL's money functions. We'll go step-by-step through the essential tools you need to securely handle transactions, provide customer feedback, and build three of the most common commercial objects: a tip jar, a vending machine, and a rental box. Let’s get ready to script your success!
What You Will Learn
- How to securely detect and receive payments using the
money()event. - How to request permission to directly debit a user's account for services like rentals using
llRequestPermissions()andPERMISSION_DEBIT. - How to give money back to a user, for refunds or change, with
llGiveMoney(). - How to provide clear confirmation messages to your customers using
llSay(). - How to combine these functions to build a functional tip jar.
- How to create a vending machine that delivers an inventory item upon payment.
- The foundational logic for building a time-based rental system.
Prerequisites
This is an intermediate class. To get the most out of it, you should be comfortable with the following:
- Basic LSL Knowledge: You should understand variables, states, events (especially
touch_start), and basic flow control (if/elsestatements). If you're new to scripting, consider starting with our beginner LSL classes first. - Alife Virtual Account: You need an account to practice in-world. If you don't have one, you can register for free and get your free full-body mesh avatar.
- Firestorm Viewer: Alife Virtual uses the popular Firestorm Viewer, the same one used for Second Life. This means the interface and your skills are directly transferable. Our world is accessible on any desktop computer—no VR headset required!
- In-World Building Tools: You should know how to create a prim, open its edit window, and create/add a new script to its contents tab.
Part 1: The Core of LSL Money Handling - The `money` Event
The absolute heart of any LSL transaction script is the money() event. This event is triggered automatically inside your script whenever an avatar pays the object that contains the script. You don't need to call it; you just need to tell the script what to do when it happens.
The event itself provides two crucial pieces of information:
key id: The unique UUID (Universally Unique Identifier) of the person who paid the object.integer amount: The amount of Lindens they paid.
Let's see this in its simplest form. We'll build a basic Tip Jar that thanks the user for their donation.
Step-by-Step: Building a Simple Tip Jar
- Create Your Tip Jar Object: In-world, create a simple prim (e.g., a cylinder or a box) that will serve as your tip jar. Name it "Tip Jar".
- Create the Script: Inside the object's Contents tab, create a new script. Name it "TipJar_Script".
-
Write the Code: Double-click the script to open the LSL editor and replace the default code with this:
default { state_entry() { // Set the hover text above the object to invite people to pay. // The last parameter, 1.0, makes the text white. <1.0, 1.0, 1.0> would also work. llSetText("Tip Jar\nRight-click and Pay to tip!", <1.0, 1.0, 1.0>, 1.0); } money(key id, integer amount) { // The money event has been triggered! // 'id' now holds the key of the tipper. // 'amount' holds how much they tipped. // First, let's get the name of the person who paid us. // We use the 'id' key to look up their name. llKey2Name(id, (string name) => { // This is an anonymous function that runs once the name is found. // It's a modern, efficient way to handle asynchronous lookups. // Now, we'll say thank you in local chat. llSay(0, "Thank you, " + name + ", for the generous tip of L$" + (string)amount + "!"); // You could also send a private message with llInstantMessage(id, "Thank you!"); }); } } - Save and Test: Save the script. Now, right-click your "Tip Jar" object, select "Pay," and enter any amount. You should see your thank you message appear in local chat!
Pro Tip: UsingllKey2Namewith an anonymous function(string name) => { ... }is the modern, non-blocking way to get a user's name. Older tutorials might use a separatedataserver()event, but this new syntax is cleaner and prevents your script from lagging while it waits for the name from the server.
Congratulations! You've just handled your first transaction. This simple script is the foundation for almost every commercial object in Alife Virtual.
Part 2: Taking It Further - The Vending Machine
A tip jar is great, but what if you want to give something in return for a payment? This is where vending machines come in. The logic is simple: check if the user paid the correct amount, and if so, give them an item from the object's inventory.
This is where one of Alife Virtual's best perks for creators comes into play: free mesh, texture, and animation uploads. Unlike Second Life, where every upload costs Lindens, here you can create and upload the assets for your products without any cost, making it much easier to experiment and stock your vendors.
Step-by-Step: Building a "Free Drink" Vending Machine
- Prepare Your Object and Item:
- Create a box prim and name it "Drink Vending Machine".
- Create another, smaller object to be the "product." This could be a simple sphere you name "Cool Drink".
- Important: Make sure the "Cool Drink" object has its permissions set to Copy/Transfer for the next owner. You can do this by right-clicking the object, going to the "General" tab in the edit window, and checking the boxes under "Next owner can:".
- Drag the "Cool Drink" object from your inventory into the Contents tab of the "Drink Vending Machine".
- Create the Vending Script: Inside the vending machine, create a new script named "Vendor_Script".
-
Write the Code: Paste the following code into your new script.
// ----- CONFIGURATION ----- integer gPrice = 10; // The price of our item in L$ string gItemName = "Cool Drink"; // The EXACT name of the item in inventory // ------------------------- default { state_entry() { // Set the hover text to show the price. llSetText("Get a " + gItemName + "!\nOnly L$" + (string)gPrice, <1.0, 1.0, 1.0>, 1.0); } money(key id, integer amount) { // Check if the amount paid is EXACTLY the price. if (amount == gPrice) { // Payment is correct. Give the item. llGiveInventory(id, gItemName); // Thank the customer. llInstantMessage(id, "Thank you for your purchase! Enjoy your " + gItemName + "."); } else { // Payment is incorrect (too much or too little). llInstantMessage(id, "Sorry, the price is exactly L$" + (string)gPrice + ". Refunding your payment."); // Refund the incorrect amount using llGiveMoney. llGiveMoney(id, amount); } } } - Save and Test:
- Save the script.
- First, try paying the wrong amount (e.g., L$5 or L$15). The script should send you an instant message and refund your money.
- Now, pay the correct amount (L$10). The script should thank you and you'll receive a folder in your inventory containing the "Cool Drink" object.
You've now created an automated retail system! You can expand this by adding more items and more complex logic, but the core principle remains the same: `money()` -> check amount -> `llGiveInventory()`. To see our full list of free classes that can help you expand your skills, be sure to browse the Alife Virtual School catalog.
Part 3: Advanced Transactions - The Rental System
Rental systems introduce a new level of complexity: time and permissions. Instead of a one-time transaction, you're managing access over a period. This is perfect for renting out skyboxes, homes, or shop space on your free 65,536 sqm private island. With 10,000 prims at your disposal at no monthly cost (compared to over $300/month for a similar island in Second Life), creating a rental empire is a very real possibility in Alife Virtual.
For rentals, we introduce a new function: llRequestPermissions(). We use this to ask the user for PERMISSION_DEBIT, which allows our script to automatically take money from their account at a later time (e.g., when rent is due). This is far more user-friendly than requiring them to manually pay every week.
Warning: PERMISSION_DEBIT is a powerful permission. Always be transparent with users about why you are requesting it and how much you will be debiting. Abusing this permission is a violation of the terms of service.
Step-by-Step: Foundational Rental Box Logic
A full rental script is too long for this tutorial, but we will build the essential permission and payment core. This script will ask for debit permission when touched and thank the user when they accept and pay the initial fee.
- Create the Rental Box: Create a prim, name it "Rental Box", and place it near the property you intend to rent.
- Create the Script: Create a new script inside the box named "Rental_Core_Script".
-
Write the Code: This code handles the permission request and the initial payment.
// ----- CONFIGURATION ----- integer gPricePerWeek = 100; // Rent amount // ------------------------- key gTenant; // Variable to store the tenant's key default { state_entry() { llSetText("Available for Rent\nL$" + (string)gPricePerWeek + "/week\nClick to rent!", <0.0, 1.0, 0.0>, 1.0); } touch_start(integer total_number) { // When touched, request debit permissions from the person who touched it. key toucher = llDetectedKey(0); if (toucher != gTenant) // Don't ask for permission if it's already rented to them { llRequestPermissions(toucher, PERMISSION_DEBIT); } } run_time_permissions(integer perm) { // This event triggers after the user responds to the permission dialog. if (perm & PERMISSION_DEBIT) { // User granted permission! Now they need to pay the first week. // We get the key of the avatar who granted the permission. key payer = llGetPermissionsKey(); gTenant = payer; // Assign them as the tenant llSetText("Tenant: " + llGetDisplayName(gTenant) + "\nThank you! Please pay L$" + (string)gPricePerWeek + " to begin your rental.", <1.0, 0.5, 0.0>, 1.0); } else { // User denied permission. llOwnerSay("User denied debit permissions."); } } money(key id, integer amount) { // Check if the payment is from our designated tenant and for the correct amount. if (id == gTenant && amount == gPricePerWeek) { // Payment successful! llSay(0, "Payment received! This property is now rented to " + llGetDisplayName(id) + "."); llSetText("Rented to:\n" + llGetDisplayName(id), <1.0, 0.0, 0.0>, 1.0); // --- ADVANCED LOGIC GOES HERE --- // In a full script, you would now: // 1. Start a timer (llSetTimerEvent) to check when the next payment is due. // 2. When the timer goes off, use llDebit(gTenant, gPricePerWeek). // 3. Add logic to evict the tenant if the debit fails. // ---------------------------------- } } } - Understand the Flow:
- A user clicks the box (
touch_start). - The script asks for debit permission (
llRequestPermissions). - The user clicks "Yes" in the dialog, which triggers the
run_time_permissionsevent. - The script updates its text, telling the user to pay the first week's rent.
- The user pays the box, which triggers the
moneyevent. - The script confirms the payment and the rental begins.
- A user clicks the box (
This forms the secure "handshake" for a rental agreement. From here, you would add timers and debit calls to fully automate the process, creating a source of truly passive income in Alife Virtual.
Common Mistakes and How to Avoid Them
- Not Handling Incorrect Payments: Forgetting the
elseblock in the vendor script is a common error. If you don't refund incorrect payments, you will have very unhappy customers. Always usellGiveMoney()to return any amount that isn't what you expected. - Forgetting
llRequestPermissions: CallingllDebit()without first gettingPERMISSION_DEBITwill do nothing. The permission must be explicitly granted by the user first. - Hardcoding Item Names and Prices: It's tempting to write
if (amount == 10)directly in your code. By defining prices and names as variables at the top of the script (likegPrice), you can easily change them later without hunting through your code. - No User Feedback: Don't leave your customers guessing! Use
llSay(),llOwnerSay(), orllInstantMessage()to tell users what's happening, whether a payment was successful, incorrect, or if permissions were granted.
Advanced Tips and Tricks
- Easy Payments with `llSetPayPrice`: You can make payments easier by setting a default price. Add
llSetPayPrice(gPrice, [gPrice, 0, 0, 0]);to yourstate_entry. Now, when a user clicks "Pay," the correct amount is already filled in! - Offer Multiple Options with `llDialog`: Instead of one price, you can use a
touch_startevent to triggerllDialogwith a menu of items. The user's selection can then set the expected price before they pay. - Transaction Logging: For business owners, keeping records is crucial. You can use
llOwnerSay()to send a message only to yourself with transaction details, or even write logs to a notecard for permanent storage. - Group-Owned Objects: You can set an object for sale and deed it to a group. If you do this, any money paid to the object will go to the group's funds, which can then be distributed among group members. This is great for collaborative business ventures.
Practice Exercise
It's time to put your new knowledge to the test! Your assignment is to build upon our first example.
- Create a "Personalized Tip Jar".
- Modify the script so that it only thanks the user if they tip exactly L$50.
- If they tip any other amount, the script should say, "Thank you for the tip!" but also send them a private instant message (IM) saying, "Tip L$50 for a special thank you!"
- If they tip exactly L$50, the script should shout (using
llShout) a big "THANK YOU!" that can be heard from further away.
This exercise will test your ability to use if/else if/else logic with the money() event and to use different communication functions based on the amount paid.
Frequently Asked Questions (FAQ)
- 1. What's the difference between paying an object and using
llGiveMoney()? - Paying an object (Right-Click > Pay) triggers the
money()event in that object's scripts.llGiveMoney(target_key, amount)is a script function that directly transfers money from the object's owner to the specified user key. You use "Pay" to receive money andllGiveMoneyto send it (like for refunds). - 2. Can a script steal money from me?
- A script cannot take money from you without your explicit permission. It can only receive money you voluntarily pay to it, or if you grant it
PERMISSION_DEBIT. Always be careful what permissions you grant, just as you would in the real world. - 3. How can I make my vending machine give out a folder of items instead of just one?
- The
llGiveInventory()function is smart! If you put all your items (the object, a notecard landmark, clothes, etc.) into a new folder within your main object's inventory, you can simply usellGiveInventory(id, "Name of Your Folder"). The user will receive the entire folder. This is the standard way to package products. - 4. Are there transaction fees in Alife Virtual?
- No. When a user pays your object L$100, you receive L$100. Alife Virtual does not take a cut of peer-to-peer or object-to-peer transactions, giving you more profit from your sales.
Summary and Next Steps
Today, you've unlocked one of the most powerful capabilities in LSL. You've learned how the money() event is the gateway to all commerce, how to manage payments with `if` statements, how to deliver goods with llGiveInventory, and how to handle refunds with llGiveMoney. You even took a peek into the advanced world of debit permissions for rental systems.
You now have the foundational skills to create a wide range of commercial products and start building your own business right here in Alife Virtual. Your next steps could be to explore more advanced topics like database integration for tracking sales across multiple vendors or creating more complex user interfaces with `llDialog`.
The best way to learn is by doing. You have the knowledge, and Alife Virtual provides the perfect, cost-free environment to practice.
Ready to Build Your Empire? Claim Your Free Island Today!
There's no better place to practice your new LSL money-handling skills than on your own land. As a member of Alife Virtual, you are entitled to a FREE 65,536 sqm private island with 10,000 prims—forever. There are no setup costs and no monthly fees. It’s the ultimate sandbox for your creativity.
Register your free Alife Virtual account now and then claim your free island to start building your first shop, rental property, or anything else you can imagine!
🎓 Ready to Practice In-World?
Get your FREE island and practice everything you just learned — no credit card, no monthly fees.
Claim Your Free Island Now →No credit card required · Takes 2 minutes · Your island is FREE forever