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 viaIDataServiceEditor/โ 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
AddressableIdhelpers
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)
Bootscene containsBootSplashScreenand is the initial sceneMainscene 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,
OnApplicationQuitis 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 Allif 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: game.gamester@gmail.com
- 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