Skip to content

Repository files navigation

GameLovers Services

Unity VersionLicense: MITVersion

Quick Links: Installation | When to use | Quick Start | Services | Docs | Changelog | Migration Guide

Why Use This Package?

Building robust game architecture in Unity often leads to tightly coupled systems, scattered initialization logic, and memory management headaches. This Services package solves these pain points:

ProblemSolution
Scattered dependenciesLightweight service locator (MainInstaller) for centralized dependency management
Tightly coupled systemsMessage broker enables decoupled pub/sub communication
Manual update managementTick service centralizes Update/FixedUpdate/LateUpdate callbacks
Coroutines in pure C#Coroutine service runs Unity coroutines without MonoBehaviour
Memory churn from instantiationObject pooling with lifecycle hooks for efficient reuse
Inconsistent save/loadCross-platform data persistence with automatic serialization
Non-deterministic gameplayDeterministic RNG service with state save/restore
Version tracking complexityBuild version service with git commit/branch metadata

Built for production: Minimal per-frame allocations. Used in real games.


When to use

Use this package when you want a lightweight set of standalone services you can pick and choose from, without committing to a full DI framework.

Consider alternatives (e.g. VContainer, Zenject) when you need scoped lifetimes, factory bindings, or constructor injection across many types. In that case, use Installer directly (not MainInstaller) for multi-interface binding within your DI composition root.


System Requirements

Unity VersionStatus
6000.0+ (Unity 6)✅ Fully Tested
2022.3 LTS⚠️ Untested

Installation

Via Unity Package Manager (Recommended)

  1. Open Unity Package Manager (WindowPackage Manager)
  2. Click +Add package from git URL
  3. Enter: https://github.com/CoderGamester/Services.git

Via manifest.json

{
"dependencies": {
"com.gamelovers.services": "https://github.com/CoderGamester/Services.git"
}
}

Key Components

ComponentResponsibility
MainInstallerStatic service locator for global-scope single-interface bindings
InstallerInstance-based DI container (supports multi-interface binding)
IMessageBrokerServiceType-safe pub/sub messaging
ITickServiceCentralized Update/FixedUpdate/LateUpdate callbacks
ICoroutineServiceRun coroutines from pure C# classes
IPoolServiceObject pool registry and management
IDataService / IDataProviderCross-platform data persistence (read-write / read-only)
ITimeService / ITimeManipulatorUnified time access with offset/sync manipulation
IRngServiceDeterministic random number generation
ICommandService<TGameLogic>Typed command execution layer
VersionServicesRuntime access to build/git metadata
AssetResolverServiceAddressables-based typed asset loading by id + asset type
IAssetLoader / ISceneLoaderLow-level addressable load/unload/instantiate interfaces

Quick Start

usingUnityEngine;usingGameLovers.Services;publicclassGameBootstrap:MonoBehaviour{voidAwake(){varmessageBroker=newMessageBrokerService();vartickService=newTickService();vardataService=newDataService();MainInstaller.Bind<IMessageBrokerService>(messageBroker);MainInstaller.Bind<ITickService>(tickService);MainInstaller.Bind<IDataService>(dataService);}voidOnDestroy(){MainInstaller.CleanDispose<ITickService>();MainInstaller.Clean();}}// Resolve anywherevarbroker=MainInstaller.Resolve<IMessageBrokerService>();broker.Subscribe<PlayerDamagedMessage>(OnPlayerDamaged);publicstructPlayerDamagedMessage:IMessage{publicintPlayerId;publicfloatDamage;}

Services at a Glance

Full API reference and recipes live in docs/. Short examples below.

Service Locator (MainInstaller / Installer)

MainInstaller.Bind<IMessageBrokerService>(newMessageBrokerService());varbroker=MainInstaller.Resolve<IMessageBrokerService>();MainInstaller.TryResolve<IDataService>(outvards);MainInstaller.CleanDispose<ITickService>();MainInstaller.Clean();// Multi-interface binding — use Installer directlyvarinstaller=newInstaller();installer.Bind<TimeService,ITimeService,ITimeManipulator>(newTimeService());

Message Broker

// static method subscriptions are NOT supportedbroker.Subscribe<EnemyDefeatedMessage>(OnEnemyDefeated);broker.Publish(newEnemyDefeatedMessage{EnemyId=42});broker.PublishSafe(newEnemyDefeatedMessage{EnemyId=42});// safe during publishbroker.Unsubscribe<EnemyDefeatedMessage>(this);broker.UnsubscribeAll(this);

Tick Service

vartick=newTickService();tick.SubscribeOnUpdate(OnUpdate);tick.SubscribeOnUpdate(OnThrottled,deltaTime:0.1f);// rate-limitedtick.SubscribeOnFixedUpdate(OnFixed);tick.SubscribeOnLateUpdate(OnLate);tick.UnsubscribeAll(this);tick.Dispose();// destroys host GameObject

Coroutine Service

varcs=newCoroutineService();IAsyncCoroutinehandle=cs.StartAsyncCoroutine(MyRoutine());handle.OnComplete(()=>Debug.Log("Done!"));cs.StartDelayCall(()=>Debug.Log("2 s later"),delay:2f);cs.Dispose();

Pool Service

varpool=newPoolService();pool.AddPool(newGameObjectPool<Bullet>(50,prefab));varbullet=pool.Spawn<Bullet>();pool.Despawn(bullet);

Data Service

vards=newDataService();PlayerDataplayer=ds.LoadData<PlayerData>();// loads from PlayerPrefs or creates freshplayer.Level=10;ds.SaveData<PlayerData>();

RNG Service

RngDatarngData=RngService.CreateRngData(seed:42);varrng=newRngService(rngData);introll=rng.Range(1,7);// 1–6intsaved=rng.Counter;rng.Restore(saved);// replay from saved point

Time Service

vartime=newTimeService();DateTimeutc=time.DateTimeUtcNow;floatunity=time.UnityTimeNow;longunixMs=time.UnixTimeNow;time.AddTime(3600f);// fast-forward 1 hour (ITimeManipulator)

Command Service

publicstructLevelUpCommand:IGameCommand<GameLogic>{publicvoidExecute(GameLogicgl,IMessageBrokerServicemb){gl.PlayerLevel++;mb.Publish(newPlayerLevelledUpMessage{Level=gl.PlayerLevel});}}ICommandService<GameLogic>cmd=newCommandService<GameLogic>(gameLogic,messageBroker);cmd.ExecuteCommand(newLevelUpCommand());

Version Services

// No setup call needed — version metadata auto-loads at SubsystemRegistration,// with a lazy-load fallback on first property access.stringbranch=VersionServices.Branch;stringcommit=VersionServices.Commit;stringext=VersionServices.VersionExternal;// always safe, no load needed// Optional explicit pre-warm (idempotent — no-ops if already loaded):// VersionServices.LoadVersionData(); // sync, recommended default// await VersionServices.LoadVersionDataAsync(); // async — only useful for large VersionData blobs

Asset Loading

// Low-levelvarloader=newAddressablesAssetLoader();vartexture=awaitloader.LoadAssetAsync<Texture2D>("Textures/hero");// High-level: typed by idvarresolver=newAssetResolverService();resolver.AddConfigs(spriteConfigs);// AssetConfigsScriptableObject<SpriteId, Sprite>varsprite=awaitresolver.RequestAsset<SpriteId,Sprite>(SpriteId.Hero,true,false);awaitresolver.LoadSceneAsync<SceneId>(SceneId.MainMenu,LoadSceneMode.Single,true);

Editor Tools

The package ships a set of editor utilities that work in both Edit and Play mode.

Services Explorer

Open via Tools > GameLovers > Services Explorer.

A dockable UIToolkit window with one tab per service. During Play mode each tab live-refreshes at 250 ms intervals. In Edit mode a snapshot banner is shown and data is read on demand.

TabWhat it showsPrimary CTA / Actions
OverviewPer-service card grid with bound/ready status and direct jump-linksOpen (jumps to tab), per-service primary CTA
VersioningVersionExternal, VersionInternal, Branch, Commit, BuildNumber; version-data.txt previewReveal version-data.txt
InstallerAll MainInstaller bindings (interface → concrete type)Clean All; Clean, CleanDispose per binding
Message BrokerAll IMessage subscriptions with expandable subscriber listsUnsubscribe All; Unsubscribe per type, Publish default(T) test
TickUpdate / FixedUpdate / LateUpdate subscriber lists with throttle settingsUnsubscribe All; Clear per list
CoroutineActive IAsyncCoroutine handles (start time, running, completed)Stop All Coroutines; Stop individual
PoolAll registered pools: spawned count, sample entityClear All Pools; DespawnAll, Dispose, RemovePool, Ping sample
DataAll loaded data types with indented JSON previewSave All Data; Save, Load, Delete PlayerPrefs key
TimeLive DateTimeUtcNow, UnityTimeNow, UnityScaleTimeNow, UnixTimeNowReset Time; AddTime slider, SetInitialTime picker
RNGSeed, Counter, peek-next N valuesRestore(count)
Asset ResolverAssetMap tree: asset type → id type → (id → ref, loaded status)Unload All (behind destructive toggle); Unload per asset
Assets ImporterDiscovered IAssetConfigsImporter list with per-importer path and statusImport All; Set Path, Import, Select per importer
Addressable IdsGenerator settings (ScriptFilename, Namespace, AddressableLabel) with output statusGenerate Addressable Ids; Open Addressables Groups

Custom Inspectors

  • AssetConfigsScriptableObject — diagnostics panel (duplicate keys, empty GUIDs) + default fields + "Regenerate Addressable Ids" button.
  • AddressablesIdGeneratorSettings — settings are now configured in the Services Explorer Addressable Ids tab (Tools > GameLovers > Addressable Ids > Open in Explorer).
  • AssetReferenceScene (property drawer) — resolved scene path label + "Open in Addressables Groups" button.

Scaffolders

Assets > Create > GameLovers Services > …

EntryGenerates
Messagestruct : IMessage
Commandstruct : IGameCommand<TGameLogic>
ServiceIMyService + MyService : IMyService, IDisposable
Pool Entityclass implementing IPoolEntitySpawn + IPoolEntityDespawn

File names and namespaces are set interactively in the Project window, identical to Unity's built-in "Create > C# Script" flow.


Samples

Importable samples live under Samples~/ and are exposed via the Unity Package Manager:

SampleAddressables required?Focus
Services PlaygroundNoAll foundation services (MainInstaller, MessageBroker, Tick, Coroutine, Pool, Data, Time, Rng, Commands, Versioning) wired into a single scene. Doubles as the manual end-to-end protocol for the Services Explorer window
Asset ResolverYes (~2 minutes setup)Typed asset loading via AssetResolverService + AssetConfigsScriptableObject<TId, TAsset>, plus the Addressable Ids generator and Assets Importer pipeline

Each sample ships as a complete, runnable Unity scene with a programmatically-built UI — no per-import wiring step (the Asset Resolver sample requires marking your sprites Addressable; see its README). For the index, AI-assistant common-mistakes section, and full list of sample-only types (which are NOT part of the package public API), see Samples~/README.md.

To import a sample: Window > Package Manager > GameLovers Services > Samples > Import.


Contributing

Contributions are welcome! See GitHub Issues to report bugs or request features. For development setup, architecture details, namespace conventions, and coding standards, see AGENTS.md.


Related docs

DocumentPurpose
docs/README.mdFull per-service API reference
AGENTS.mdContributor/agent guide (architecture, gotchas, workflows)
CHANGELOG.mdVersion history
MIGRATION.mdv1.x → v2.0.0 migration guide

Support

License

MIT — see LICENSE.md.

About

This package contains a set of services to ease the development of a basic game architecture

Topics

Resources

Stars

6 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages