Build fast, scalable mobile and WebGL games with a clean architecture, Addressables, and a lightweight service layer.
Target audience: Unity developers building mobile (iOS/Android) and WebGL games who want a solid starting point with best practices.
- Features
- Prerequisites
- Quick Start
- Project Architecture
- Folder Structure
- Packages and Dependencies
- Addressables Setup and Workflow
- Scenes and Game Flow
- Build and Deployment
- Performance & Optimization
- Troubleshooting
- API References
- Contributing
- License
- Contact
- SOLID-first architecture with manual dependency injection.
- Addressables-first asset pipeline for dynamic loading and small initial APK/WebGL payloads.
- Message-driven design with a simple message broker.
- State machineโdriven game flow.
- WebGL-ready with a working demo and production-friendly hooks for pause/quit.
- Built-in Compliance Screen prefab.
- Unity Editor: 6000.0.55f1
- API Compatibility Level: .NET Standard 2.1 (or .NET 4.x)
- Git LFS (Large File Storage)
- Clone
git clone https://github.com/CoderGamester/Core-Game.git
cd Core-Game
-
Open in Unity Hub (Unity 6000.0.55f1 recommended)
-
Generate Addressables settings
- Window > Asset Management > Addressables > Groups > Create/Generate Settings
- Configure UI (optional)
- Locate and open
UiConfigs.asset
(Project search or Tools > Select UiConfigs.asset if available)
- Open the "Boot" Scene and Play
- Open the scene named by
Constants.Scenes.BOOT
(boots into Main additively)
- Run the sample and inspect the flow
The entrypoint Main
(Assets/Src/Main.cs
) wires services and starts the game state machine.
Key responsibilities of Main
:
- Bind services via a lightweight
Installer
- Initialize Unity Services and internal versioning
- Start the
GameStateMachine
- Handle lifecycle events (pause, focus, quit) and persist data
Example (excerpt from Main.cs
):
var installer = new Installer();
installer.Bind<IMessageBrokerService>(new MessageBrokerService());
installer.Bind<ITimeService>(new TimeService());
installer.Bind<GameUiService, IGameUiServiceInit, IGameUiService>(new GameUiService(new UiAssetLoader()));
installer.Bind<IPoolService>(new PoolService());
installer.Bind<ITickService>(new TickService());
installer.Bind<ICoroutineService>(new CoroutineService());
installer.Bind<AssetResolverService, IAssetResolverService, IAssetAdderService>(new AssetResolverService());
installer.Bind<ConfigsProvider, IConfigsAdder, IConfigsProvider>(new ConfigsProvider());
installer.Bind<DataService, IDataService, IDataProvider>(new DataService());
var gameServices = new GameServicesLocator(installer);
installer.Bind<IGameServicesLocator>(gameServices);
_stateMachine = new GameStateMachine(installer);
Lifecycle hooks (excerpt):
private void OnApplicationPause(bool isPaused)
{
if (isPaused)
{
_dataService.SaveAllData();
_services.AnalyticsService.FlushEvents();
}
_services.MessageBrokerService.Publish(new ApplicationPausedMessage { IsPaused = isPaused });
}
State and logic boundaries are orchestrated by GameServicesLocator
, GameLogicLocator
, and GameStateMachine
instances.
Assets/
Addressables/
โ runtime-loadable assets (configs, scenes, prefabs, UI)Scenes/
โ scenes to be loaded (often additively) at runtimePrefabs/
โ UI and gameplay prefabs (e.g., Compliance Screen)
Libs/
โ third-party librariesResources/
โ avoid for game content; reserved for Unity defaults/pluginsSrc/
โ gameplay code and composition roots (e.g.,Main.cs
,BootSplashscreen.cs
)Cheats/
โ developer cheats and test toggles (e.g.,SROptions.Cheats.cs
)Commands/
โ commands to trigger game logic actions (e.g.,AcceptComplianceCommand.cs
,RestartGameCommand.cs
)Configs/
โ ScriptableObject config definitions (e.g.,DataConfigs.cs
,GameConfigs.cs
,SceneAssetConfigs.cs
)Data/
โ persistent data models (e.g.,AppData.cs
,PlayerData.cs
) saved viaIDataService
Editor/
โ editor-only tools (asset/sheet importers, utilities)Ids/
โ strongly-typed IDs and auto-generated Addressable IDs (AddressableId.cs
,GameId.cs
,SceneId.cs
)Logic/
โ domain game logic and facades (GameLogicLocator.cs
, plusClient/
andServer/
folders)Messages/
โ message types/events published viaIMessageBrokerService
(e.g.,ApplicationStateMessages.cs
)Presenters/
โ UI presenters (MVP) for all UI screens managed by the 'GameUiService' (e.g.,MainHudPresenter.cs
,MainMenuPresenter.cs
)Services/
โ game-specific services/adapters (GameServicesLocator.cs
, analytics helpers, UI service, world refs)StateMachines/
โ game flow states and orchestrator (e.g.,GameStateMachine.cs
,InitialLoadingState.cs
)Utils/
โ constants and small helpers (Constants.cs
)ViewControllers/
โ base/entity view controllers handled by the Presenters (ViewControllerBase.cs
,EntityViewController.cs
)Views/
โ view MonoBehaviours (e.g.,TimerView.cs
)
Packages/
โ Package Manager manifest and lockProjectSettings/
โ Unity project settings and versionWebGL_Build/
โ example built WebGL output and template files
Rationale: prioritize Addressables over Resources/
to reduce initial payloads and enable content updates.
Declared in Packages/manifest.json
(selected):
com.gamelovers.services
โ service locator and installer utilitiescom.gamelovers.statechart
โ state machinecom.gamelovers.uiservice
โ UI service scaffoldingcom.gamelovers.assetsimporter
โ Addressables import helperscom.gamelovers.configsprovider
โ static config providercom.gamelovers.dataextensions
โ extensions and data containerscom.gamelovers.googlesheetimporter
โ Google Sheets data importcom.cysharp.unitask
โ async/await for Unity without allocationscom.acegikmo.mathfs
โ math helpers- Unity packages: Addressables (2.6.0), Input System, UGUI, Cinemachine, Newtonsoft JSON, Analytics, Cloud Diagnostics, etc.
See also:
- Services
- Statechart Machine
- UI Service
- Assets Importer
- Configs Provider
- Data Extensions
- Google Sheet Importer
- UniTask
- Mathfs
- Open Addressables window
- Window > Asset Management > Addressables > Groups
- Create/Generate Settings (first time only)
- Organize groups (Configs, UI, Scenes, etc.) and assign labels as needed
- Build Addressables
- Build > New Build > Default Build Script
- Use generated IDs from
AddressableId
helpers
Example usage:
// Example from docs
AddressableId.Addressables_Configs_DataConfigs.GetConfig().Address;
Notes
- Prefer Addressables over
Resources/
for gameplay content - When changing serialized data, rebuild Addressables (and perform content update if using Remote)
Boot
scene containsBootSplashScreen
and is the initial sceneMain
scene hostsMain
(composition root) and gameplay entry- Boot loads Main additively, then merges scenes and destroys bootstrapper
- Build Settings
- Platform: WebGL
- Add Boot and Main scenes to Build Settings
- Build to:
WebGL_Build/
- Addressables
- Build Addressables before building player
- Hosting
- You can host the output (this repo ships a sample at
WebGL_Build/
) - Demo: https://codergamester.github.io/Core-Game/WebGL_Build/
Tips
- Enable compression and data caching in Player Settings as needed
- On WebGL,
OnApplicationQuit
is not called; this project publishes quit on pause for WebGL
- Build Settings
- Add Boot and Main scenes
- Android: IL2CPP, ARM64, Internet Access: Required if using remote Addressables
- iOS: IL2CPP, set bundle identifiers, enable required capabilities
- Addressables
- Choose Local or Remote profiles; rebuild Addressables for release
- Analytics/Diagnostics
- Configure Unity Services as needed (Analytics, Cloud Diagnostics)
- Prefer Addressables over
Resources/
- Pool frequently spawned objects (
IPoolService
) - Keep WebGL memory size appropriate for your content
- Use IL2CPP and code stripping on mobile release builds
- Defer heavy initialization with async (
UniTask
) during splash/boot
- Addressables not loading
- Ensure settings were created and groups built
- WebGL shows blank page
- Serve via HTTP(S); ensure compression/decompression settings are consistent
- Missing packages after opening project
- Open Package Manager to resolve; run
Reimport All
if needed
- Open Package Manager to resolve; run
- iOS tracking compile symbols
- iOS ATT calls are behind
UNITY_IOS
; ensure related package/capabilities only for iOS builds
- iOS ATT calls are behind
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m "Add some AmazingFeature"
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
- GitHub Issues: https://github.com/CoderGamester/Core-Game/issues
- LinkedIn: https://www.linkedin.com/in/miguel-tomas/
- Email: [email protected]
- Discord: gamester7178
- ALT+R (Windows) / โ+R (Mac) โ force compile project code
- ALT+1 (Windows) / โฅ+1 (Mac) โ open the "Boot" scene
- ALT+2 (Windows) / โฅ+2 (Mac) โ open the "Main" scene