Generated reference. This page mirrors
Code/Housing/README.md, this module's source-of-truth documentation (Standards/02_DOCUMENTATION_STANDARDS.md §1). Edit it there, not here -- this file is regenerated on every docs build and any local edit is silently overwritten.
Housing¶
Purpose. Property groups: buying a fixed set of World ownables (Door, WorldContainer)
as one unit, at one price, with one Ownership record for the whole group. The "master/slave
door linking → property groups" follow-on
ROADMAP.md Milestone 7
already named and deferred, finally scoped by
ADR-0013. See
29_HOUSING.md.
Responsibilities.
- HousingListingDefinition — content, not code (ADR-0004's precedent): a display name, the
group's own fixed GroupOwnableId, the fixed set of member OwnableIds
(MemberOwnableIds), and GroupPrice. See that file's header comment for why
GroupOwnableId is author-assigned data, not runtime-generated.
- IHousingListingRegistry / HousingListingRegistry — every loaded, validated listing,
mirroring IItemRegistry/IJobRegistry minus inheritance resolution.
- IHousingService / HousingStore — PurchaseGroupAsync: the atomic (by ordering, not by a
real transaction, same as PropertyStore.PurchaseAsync) validate, assign-ownership,
link-members, debit-money, publish-event sequence. Holds no persisted state of its own —
see HousingStore.cs's header comment.
- HousingConfiguration — the operator-tunable kiosk interaction range, following
Code/World/DoorConfiguration.cs's precedent.
- HousingListingComponent — the placed-in-map kiosk: [Property] ListingAssetId,
[Sync(FromHost)] IsOwned/OwnerName, and [Rpc.Host] RequestPurchaseGroup(), following
DoorComponent's exact shape (one component instance per entity, acting on itself).
Not responsible for.
- Who owns a group, or access resolution — Ownership's job, entirely untouched by this
module (ADR-0013 point 3: IOwnershipService gains zero new surface).
- A door's or container's own lock/seal state — World's job; this module only ever calls
IPropertyService.SetGroupAsync/IWorldContainerService.SetGroupAsync to link a member in,
never touches IsLocked/IsSealed itself.
- Moving money — Economy's job, same as PropertyStore.
- Reselling a group, or changing its membership after purchase. ADR-0013's own deliberately
deferred open question — membership is fixed at purchase time from the listing; there is no
"add/remove a member" API anywhere in this module.
- A member id that resolves to neither a registered Door nor a registered
WorldContainer. Logged as an operator-visible anomaly during PurchaseGroupAsync, never
a reason to fail an otherwise-legitimate purchase — see HousingStore.LinkMembersAsync's own
comment.
Dependencies. Core (IServiceRegistry, IServiceResolver, IEventBus, IGameLog,
IConfigurationInspector), Character (Character), Economy (IEconomyService), Ownership
(IOwnershipService, OwnableId, OwnerRef), World (IPropertyService,
IWorldContainerService, Door, WorldContainer), Movement (IPawnLocator, for
HousingListingComponent's distance check), the S&box engine (Component, GameResource,
Rpc, Sync, ResourceLibrary).
Public API.
- IHousingService — PurchaseGroupAsync(Character buyer, HousingListingDefinition listing).
- IHousingListingRegistry — Find(string assetId), Get(string assetId), All.
- HousingListingComponent.
Events published.
- HousingGroupPurchasing — cancellable, published once eligibility (unowned, affordable) is
confirmed but before ownership is assigned or money moves. Mirrors
Applejack.World.DoorPurchasing exactly.
- HousingGroupPurchased(HousingListingDefinition, OwnableId GroupId, Character Buyer) —
published once ownership has been assigned. Mirrors Applejack.World.DoorPurchased.
Persistence. None owned by this module. The group's Ownership record lives under
ownership/{groupId} (Ownership module, no different from any other OwnableId); each
member's GroupId link lives on that member's own doors/{id}/containers/{id} document
(World module). See HousingStore.cs's header comment for why this is deliberate, not a gap.
Future improvements.
- Reselling a group as a unit, and what happens to member access grants on resale — ADR-0013's
own deliberately deferred open question.
- A Manage level or a real "remove a member's access" flow, once Ownership grows either
(see Code/Ownerships/README.md's own "Future improvements").