Skip to main content

Player Housing

The housing system lets players purchase, decorate, and share personal houses. It supports grid-based furniture placement, visitor management, and persistent house layouts saved to the server. Housing is one of the most requested features in the monster capture genre.

Architecture Overview

ClassFileResponsibility
HousingServiceHousing/HousingService.csHouse purchase, furniture CRUD, visitor management, save/load
HouseDataHousing/HousingService.csSerializable house state (grid, furniture, ownership)
FurniturePlacementCore/OnlineTypes.csPer-furniture position and rotation on the grid

Access via:

var housing = NakamaManager.Instance.Housing;

Housing is initialized automatically during connection when OnlineConfig.EnableHousing is true.

Configuration

Config FieldDefaultDescription
EnableHousingtrueToggle the housing system
MaxFurniturePerHouse50Maximum furniture items per house
HouseGridSize16 x 16Grid dimensions in tiles
AllowHouseVisitorstrueDefault visitor access setting

Purchasing a House

Players can purchase a house from a template:

HouseData house = await housing.PurchaseHouseAsync("template_small_cottage");

// house.Id -- unique house instance ID
// house.OwnerId -- the player's user ID
// house.TemplateId -- "template_small_cottage"
// house.GridWidth, house.GridHeight -- from config (16x16)
// house.Furniture -- empty list
// house.AllowVisitors -- from config default

House Ownership

bool hasHouse = housing.HasHouse;
HouseData myHouse = housing.MyHouse;

Furniture Placement

Furniture is placed on a grid with position and rotation.

Placing Furniture

bool placed = await housing.PlaceFurnitureAsync(
furnitureId: "sofa_red",
gridX: 5,
gridY: 3,
rotation: 0); // 0, 90, 180, 270

Placement fails if:

  • The player does not own a house (MyHouse == null).
  • The furniture count has reached MaxFurniturePerHouse (default: 50).

Removing Furniture

bool removed = await housing.RemoveFurnitureAsync(
furnitureId: "sofa_red",
gridX: 5,
gridY: 3);

Removal matches on both furnitureId AND grid position, so multiple instances of the same furniture at different positions are handled correctly.

Furniture Data Model

[Serializable]
public class FurniturePlacement
{
public string FurnitureId; // References a furniture ScriptableObject
public int GridX; // Grid column
public int GridY; // Grid row
public int Rotation; // 0, 90, 180, or 270 degrees
public string CustomData; // Optional custom metadata
}

Furniture Events

housing.OnFurniturePlaced += (FurniturePlacement placement) =>
{
Debug.Log($"Placed {placement.FurnitureId} at ({placement.GridX}, {placement.GridY})");
};

housing.OnFurnitureRemoved += (string furnitureId) =>
{
Debug.Log($"Removed {furnitureId}");
};

Visitor Management

Toggling Visitor Access

// Allow visitors
await housing.SetVisitorsAllowedAsync(true);

// Set to private
await housing.SetVisitorsAllowedAsync(false);

The AllowVisitors flag on HouseData is updated immediately.

Visiting Another Player's House

HouseData theirHouse = await housing.VisitHouseAsync(ownerUserId);

bool isVisiting = housing.IsVisiting;
string visitingId = housing.VisitingHouseId;

// Leave when done
await housing.LeaveHouseAsync();

Visitor Events

housing.OnVisitorEntered += (string visitorUserId, string visitorName) =>
{
Debug.Log($"{visitorName} entered your house!");
};

housing.OnVisitorLeft += (string visitorUserId) =>
{
Debug.Log($"Visitor left.");
};

Saving and Loading

House state is persisted to the server:

// Save current house layout
await housing.SaveHouseAsync();

The OnHouseLoaded event fires when house data is loaded (either after purchase or when loaded from the server on connect):

housing.OnHouseLoaded += (HouseData house) =>
{
// Rebuild the house visual from house.Furniture list
foreach (var f in house.Furniture)
{
SpawnFurnitureVisual(f.FurnitureId, f.GridX, f.GridY, f.Rotation);
}
};

HouseData Model

The full HouseData class:

FieldTypeDescription
IdstringUnique house instance ID
OwnerIdstringOwner's Nakama user ID
OwnerNamestringOwner's display name
TemplateIdstringHouse template reference
GridWidthintGrid width in tiles
GridHeightintGrid height in tiles
FurnitureList<FurniturePlacement>All placed furniture items
AllowVisitorsboolWhether visitors can enter
CreatedAtlongCreation timestamp (Unix ms)

Housing as Social Space

Houses serve as social hubs where players can:

  • Decorate and express -- place furniture from in-game shops or rewards.
  • Invite friends -- share your house with the friends list.
  • Host gatherings -- visitors can interact and chat inside the house.
  • Showcase collections -- display trophies, rare items, or monster statues.

The visitor enter/exit events integrate with the social notification system so house owners are notified when players visit.