PlayerMockServiceBase
Shared behavior for PlayerMockService (server realm) and PlayerMockServiceClient (client realm): the place-wide discovery surface, and mock consumption -- the leak detection between sequential tests in the shared place.
Every mock a service observes -- alive at PlayerMockServiceBase.Init, or parented later -- is
marked as consumed in the service's realm, and the mark carries the consuming service's identity.
Observing a mock whose consumer has since been destroyed is an error: the mock outlived the
service that consumed it, which means it leaked from an earlier test. Because consumption replaces
asserting an empty place at Init, mocks may be created (and the local player designated) before
bags boot -- matching production, where Players.LocalPlayer exists before any service runs.
Only one server-realm service may be alive at a time, while multiple client-realm services (simulated clients) may coexist -- so the client service tolerates marks from live concurrent consumers and the server service treats them as an error. A mock never observed by any mock service carries no mark and is not protected; the batch runner's between-package sweep is the backstop there.
Functions
Init
Initializes the service and begins consuming every mock in the place. Deriving services must
define ServiceName, _consumedAttributeName, and _allowConcurrentConsumers as static fields.
GetPlayerMocks
Returns the mocks currently in the place. Mirrors Players:GetPlayers() -- the same answer from
any ServiceBag in either realm -- so infrastructure that sweeps existing players (e.g. a binder
unbinding on disable) can sweep the mocks the same way.
ObservePlayerMocks
Observes every mock in the place -- those already alive and those parented later, from any bag in
either realm -- emitting each mock once. Mirrors how Players.PlayerAdded +
Players:GetPlayers() are consumed, so a PlayerBinder can treat mocks like real joins.