Skip to content

Adding Custom Shells

0r_houses - Custom Shell Integration Guide#

This guide explains step-by-step how to integrate your custom shell (player-specific interior objects) systems into the 0r_houses system. Whether you are using K4MB1 Shells, loaf_housing, or your own custom shell scripts, you can use this infrastructure to add shell houses into 0r_houses.


Step 1: Defining a New House Theme#

First, open the config/house_themes.lua file. We will add a new "Shell" theme to the section where we define normal house themes.

It is extremely important to add the IsShell = true value to tell the script that this is a Shell. You can also define custom variables like ShellModel which you will send to your custom shell creation code.

lua
Config.HouseThemes["MyCustomTheme"] = {
    Name = 'MyCustomTheme', -- Unique Theme Name
    Label = 'Ultra Luxury Shell House', -- Name Displayed in Menus
    IsShell = true, -- YOU MUST ABSOLUTELY SET THIS TO TRUE
    ShellModel = 'shell_luxury_01', -- Object name or hash you will use in your shell code
    Garage = false,
    EmptyIpl = false,
    ManageMenuItem = 'bkr_prop_clubhouse_laptop_01a',
    MapHasTintColor = false,
    OnlyIPL = false,
    Image = 'newloft.png', -- Name of the image file in the web/assets/ folder
    
    -- Note: Since shells spawn at dynamic coordinates,
    -- we will calculate stash and wardrobe values dynamically inside client_editable.lua.
    -- You can write empty values or offsets (differences) here for a start.
    stashes = {
        [1] = {
            name = 'Bedroom Stash',
            offset = vector3(-1.5, 2.0, 0.5), -- Distance to the center of the shell for calculation
            stashWeight = 50,
            Lock = true,
        }
    },
    wardrobes = {
        vector3(-2.5, 1.5, 0.5) -- Distance to the center of the shell for calculation
    }
}

Step 2: Spawning the Shell (When the Player Enters)#

The moment the player enters the house, the Config.CreateCustomShell function at the bottom of the config/client_editable.lua file is automatically triggered.

This function has two main tasks:

  1. Placing (spawning) the shell object into the world.
  2. Returning the coordinate of the point where the player will stand inside (as vector3 or vector4) so the player can teleport into the shell.

In the example below, a hypothetical shell script is used for the spawn process:

lua
Config.CreateCustomShell = function(houseId, houseData, themeData)
    -- 1. Let's get our shell model
    local modelStr = themeData.ShellModel
    
    -- 2. Send a request to your shell script and spawn the shell.
    -- This is just an example, use your own script's export!
    -- Example: local spawnCoord = {x = 100.0, y = 100.0, z = -50.0}
    local shellObj, shellCenterCoord = exports['my_shell_script']:CreateShell(modelStr)
    
    -- If it doesn't spawn, we cancel the process by returning nil
    if not shellCenterCoord then return nil end
    
    -- 3. Let's dynamically update the house coordinates when the player falls inside.
    -- Let's adjust the Stash placement relative to the center of the shell
    if themeData.stashes and themeData.stashes[1] then
        houseData.coords.stashes = {
            [1] = {
                name = themeData.stashes[1].name,
                -- We add the offset amount from the theme config to the shell center coordinate
                coord = vec3(
                    shellCenterCoord.x + themeData.stashes[1].offset.x, 
                    shellCenterCoord.y + themeData.stashes[1].offset.y, 
                    shellCenterCoord.z + themeData.stashes[1].offset.z
                ),
                stashWeight = themeData.stashes[1].stashWeight,
                Lock = themeData.stashes[1].Lock
            }
        }
    end
    
    -- Let's adjust the Wardrobe placement
    if themeData.wardrobes and themeData.wardrobes[1] then
        houseData.coords.wardrobes = {
            vec3(
                shellCenterCoord.x + themeData.wardrobes[1].x, 
                shellCenterCoord.y + themeData.wardrobes[1].y, 
                shellCenterCoord.z + themeData.wardrobes[1].z
            )
        }
    end
    
    -- 4. We are returning the actual point where the player will be teleported!
    -- The player will enter the game at the shell center coordinate.
    return vec4(shellCenterCoord.x, shellCenterCoord.y, shellCenterCoord.z, 0.0) 
end

Step 3: Deleting the Shell (When the Player Exits)#

When the player leaves the house, the Config.DeleteCustomShell function in config/client_editable.lua is triggered to avoid exhausting the game and to increase performance.

Here, you need to delete the shell object you created in the previous step:

lua
Config.DeleteCustomShell = function(houseId, houseData, themeData)
    -- Remove the shell from the world via your shell script's export.
    -- Example:
    exports['my_shell_script']:RemoveShell()
    
    -- Note: If you created the object yourself with CreateObject, 
    -- you can keep that object in a variable (e.g. ActiveShells[houseId] = obj)
    -- and delete it with the DeleteEntity(obj) function.
end

Summary:#

  1. Create your theme as IsShell = true in house_themes.lua.
  2. Call your shell script via Config.CreateCustomShell in client_editable.lua, update the coordinates of house items (stash/wardrobe) relative to the shell, and return the entry point.
  3. Clean up the shell when leaving the house via Config.DeleteCustomShell in client_editable.lua.