# Architecture

## [Game](../api/Voile.Game.yml)

Entry point for your Voile game. It provides overridable methods for all stages of the lifetime, as well as exposes systems for rendering, input and resource management.

## Systems

Individual systems are the building blocks that you can use to construct your game. Default systems accessible in [Game](../api/Voile.Game.yml) class include [RenderSystem](../api/Voile.Rendering.RenderSystem.yml) and [InputSystem](../api/Voile.Input.InputSystem.yml).

They're convenient wrappers for various libraries and/or functionality providers (ex. particle systems, physics), requiring an initialization and shutdown stage to properly create and dispose their internal resources. As an example, an [FmodAudioSystem](../api/Voile.Audio.FmodAudioSystem.yml) requires to initialize [FMOD](https://www.fmod.com/) audio engine with certain parameters in `Start` method, and release native handles in `Dispose` method.

You can create custom systems by implementing [IStartableSystem](../api/Voile.IStartableSystem.yml), and/or [IUpdatableSystem](../api/Voile.IUpdatableSystem.yml). Custom systems can later be  instantiated and started in `Game`'s `Initialize` step, and disposed in `Shutdown`. For updatable systems, refer to system-specific documentation, as they may require a different or fixed timestep separate from rendering.

## Resources

Resources are non-source dependencies of your game. Textures, audio, config data (saved in TOML, JSON, YAML, etc.), and fonts are good example of resources that a game may use. For these typical resources, you can load them and manage their lifetime using the [ResourceManager](../api/Voile.Resources.ResourceManager.yml).

For advanced use, you can also create custom resources tailored for your needs by inheriting a base [Resource](../api/Voile.Resource.yml). Next step in implementing a resource requires you to create a class that implements [IResourceLoader](../api/Voile.Resources.IResourceLoader-1.yml) and register it in the [ResourceManager](../api/Voile.Resources.ResourceManager.yml) with `AddResourceLoaderAssociation<T>()`, in your `Game`'s `Initialize` step.

Each resource can be instantiated from a byte buffer, removing the need of using [ResourceManager](../api/Voile.Resources.ResourceManager.yml). This is not recommended and should only be used for corner cases where using ResourceManager is not optimal, such as loading resources from memory, network, and other places outside of the file system.
