Skip to content

Full Item Sync (#13): purchases, Lost & Found, job payment and a shared inventory - #164

Open
OxoGhost01 wants to merge 6 commits into
AMacro:betafrom
OxoGhost01:feature/103-purchase-sync
Open

Full Item Sync (#13): purchases, Lost & Found, job payment and a shared inventory#164
OxoGhost01 wants to merge 6 commits into
AMacro:betafrom
OxoGhost01:feature/103-purchase-sync

Conversation

@OxoGhost01

Copy link
Copy Markdown

Full Item Sync (#13): purchases, Lost & Found, job payment and a shared inventory

Closes #102, #103, #104.

Summary

This implements the remaining sub-issues of #13 on top of the existing NetworkedItem / NetworkedItemManager groundwork.

The starting point turned out to be that item synchronisation was never actually running: snapshots were produced and sent, but the calls that hand received snapshots to the item manager were commented out on both the client and the server, so every item update was discarded on arrival. Enabling that is the first commit, and it surfaced a number of latent issues that the rest of the work builds on.

What is included

Shop purchases (#103)

Shop registers previously bypassed the register synchronisation entirely, so a client buying something spawned a local-only item and paid from a local wallet. Purchases now run through the same server-routed flow the service registers already used:

  • scanning an item is validated by the server, and the resulting basket is broadcast, so both players see the same basket and total
  • the purchase itself executes on the host, paid from the shared wallet, and the items it spawns replicate normally
  • shop stock levels are broadcast on change and on join, so shelves agree
  • purchased items are placed at the shop when any player is nearby, not only when the host is

Lost & Found (#104)

Summoning items (the shed button, fast travel) previously collected everything in the world, including other players' belongings. Items now record who last carried them, and a summon only collects the summoning player's own items.

Job payment

Completing a job prints physical banknotes at the validator. Because a client's job validation is executed on the host, those notes only ever existed on the host's machine. They are now spawned as ordinary networked world items so that they replicate, and because the wallet is shared and server-authoritative, banking money is routed through the server rather than credited locally, where it would simply be overwritten by the host's value.

One case is still open: a client who validates a job does not reliably see the notes unless the host is nearby. See Known limitations.

Shared inventory (#102)

See the design note below. Players carry the same set of items; the server owns the list and each player holds their own physical copy.

Design decision: one shared inventory

Multiplayer is co-operative today, so all players carry the same items. If anyone picks something up, everyone gets it; if anyone drops or uses it up, it leaves everyone's inventory.

What is deliberately not shared is presentation. Each player has their own physical copy of each item, so slot placement and which item is in hand are per-player and independent. Two players can hold their own copy of the same item at the same time.

This was chosen because a single shared pool matches how co-op is actually played: it avoids one player having to hand tools over for the other to work, and it avoids the awkward question of who "owns" a jointly earned item.

Per-player inventories are still the right model for a future competitive or role-separated mode, so that path has been kept rather than deleted: the per-player inventory serialisation is still written to the save, and the code that hands a player their own inventory is retained (commented, in NetworkedSaveGameManager.Server_GetPlayerInventory) so it can be switched back on when such a mode exists.

Notes for review

  • Items with their own authoritative synchronisation are deliberately excluded from the shared inventory: job papers (the job lives on that specific object, so a copy is a blank sheet), physical money (the wallet is already shared, so copying a banknote would let the same payment be banked twice) and licences.
  • Item state (battery charge, coal load, wick) travels with an item through the world and back, so picking something up does not reset it.
  • The shared inventory scan runs on a fixed interval rather than every network tick, and avoids per-tick allocations.
  • IdPool.ReleaseId previously accepted the unassigned id back and handed it out again, producing objects that could never be referenced over the network. This affected every IdMonoBehaviour type, not only items.

Known limitations

  • Player position on host restart. A returning player is placed where they left off within a session, but the per-player position only reaches disk when the game saves, which it often declines to do mid-session.
  • Client can't see the money after validating a job. The host has to be next to the client to get the money. (working on a fix)

Testing

Tested in two-player sessions (host + client) across repeated runs:

  • buying from a shop as the client and as the host, including basket, funds, stock and the receipt
  • taking, completing and validating jobs from both sides
  • dropping, picking up, holding and using up items in both directions
  • items with state (flashlight, lantern, shovel) surviving the round trip
  • disconnecting and rejoining, including inventory and position restoration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inventory Sync

1 participant