Getting a service
Last updated
Was this helpful?
Last updated
Was this helpful?
In Knight, services can be accessed in a few different ways depending on how your configuration is set up. A key setting that impacts how you fetch services is the CYCLIC_INDEXING_ENABLED
flag, which controls whether cyclic dependencies between services are allowed. By default, this setting is enabled.
Services in Knight can be accessed using either the Knight.Import
method or the newer, more memory-efficient Knight.GetService
method (introduced in version 0.0.7). These methods allow you to retrieve and interact with other services in your game.
However, if you have CYCLIC_INDEXING_ENABLED
set to true
(the default setting), you can also access other services directly by indexing the Knight.Services
table within a service. This allows services to reference one another cyclically.
When CYCLIC_INDEXING_ENABLED
is true
, you can access another service directly from within your current service without worrying about manual importing or memory overhead from excessive service loading. This is useful for cases where services need to call each other's functions during their execution.
Here’s an example of how you can use cyclic indexing to call a function from another service:
In this example:
Service.Services.OtherService
refers to another service called OtherService
Running on the same context level (Server or Client), to reference a shared Service/Object use Service.Shared...
CallFunction()
is a method defined within the OtherService
service.
With CYCLIC_INDEXING_ENABLED
set to true
, Knight's internal service loader allows services to reference one another via the Services
table. This is beneficial when services are interdependent, such as when one service needs to trigger an event or call a function in another service.
While cyclic indexing can be convenient, it's important to note that in complex projects, heavy reliance on cyclic dependencies can increase the difficulty of managing your services. This is especially true if the dependency chain grows large. To avoid memory issues and potential bugs, Knight introduced GetService
as an alternative.
On large experiences such as the Rosource Project, the Emergency Response Series, etc we average around ~3GB Client Memory with Cyclic enabled. Please note this specifically with the large-coldebase with all gameplay features.
If you prefer to avoid cyclic dependencies altogether, you can disable cyclic indexing by setting CYCLIC_INDEXING_ENABLED
to false
in your KNIGHT_CONFIG.lua
file. When cyclic indexing is disabled, services must be explicitly retrieved using either Knight.Import
or Knight.GetService
, and attempts to access services via cyclic indexing will fail.
Here’s how you disable cyclic indexing:
With cyclic indexing disabled, you would need to retrieve services like this:
Use Cyclic Indexing Sparingly: While convenient, cyclic indexing can lead to tightly coupled services. For better maintainability, consider using GetService
or Import
to explicitly manage dependencies.
Optimize for Memory Usage: In large games with many services, consider disabling cyclic indexing and using GetService
for a more memory-efficient approach.
Keep Dependencies Clear: Regardless of whether cyclic indexing is enabled or disabled, ensure that your services have well-defined responsibilities to avoid confusion and unintended dependencies.
Article & Art by vq9o