Help with framework

I want my game to be modular and scalable. So recently I’ve been learning how to make better code and frameworks (Knit) and using external tools like Visual Studio Code

I’m using Knit framework by @sleitnick I’m pinging you so hopefully you will see this and can give an answer please


In Knit there is 1 script and 1 local script for bootstrapper and everything else is modules.

There’s 3 “types” of modules (I think):

  • Services/Controllers,
  • Modules (I think this is for things like libraries and classes),
  • and Components (wrapping Instances)

What I need help is knowing how and when to use these different things.

“Services are high level singletons that provide a service to the game”

How do I know if I should be making a Service? When I think of Service I think of something that handles a lot of things (e.g. DataStoreService handles all datastore stuff.) Let’s say I want to display the players name above their head, is that a Service? If not what is it a Module? It’s for sure not a Script or a Local Script because there are only 2 of those for bootstrapping. Should I be making Services like “DisplayNameAbovePlayersHeadService” ?

I’m also confused where actual game logic goes, as in you make all these fancy classes with methods, but then where do you call those methods? (I think the answer to this is in the KnitStart method of a Service/Controller and any other module which needs to access the public methods)

Does everything in one service go under one class in one file or can you have multiple classes and multiple files?

How do I know if I should be making a regular class or a Service/Controller. If it’s just a regular class how does it get called (it doesn’t get called on runtime by Knit)


I know each developer can structure things at their discretion as long as it’s organized and efficient.

I’m looking for guidance/insight on how to do to make an efficient codebase architecture/usage of frameworks. (in this case Knit)

It really boils down to, what question or set of questions can I can ask myself to figure out what type of script is right for a specific task?

2 Likes

Correct. However, any script can tie into Knit if desired.


A service (or client controller) should serve a single purpose and be the single point of truth for that purpose. For instance, you might have a MoneyService which manages money, or a VehicleService which deals with vehicles in the game. These services might use modules to help them out, but are mostly self-contained.

Technically, two services could talk to each other. It’s not bad for a service to talk to another, but this is called “coupling” and should be reduced when possible (but will definitely happen, and that’s ok). However, it is bad practice if two services talk to each other. This is called a circular dependency. While it is technically allowed, it is not encouraged.


This is up to you. For me, game logic usually begins at the event level (e.g. user input) and is then processed by a service/controller, or by a component/module that then will talk to a service/controller. You could even have a standalone script that then accesses Knit (Knit doesn’t force you to only live within the service/controller/module/component hierarchy).


One service/controller/class/etc. per file is good practice. Split things up into multiple ModuleScripts. You can put multiple in a file if you want, but I would discourage it. It’s much easier to navigate your codebase if things are split up IMO.


This boils down to when you should use a singleton and when you should not. (Some people would argue you should never use singletons, but I obviously thing that’s a bit ridiculous). I find it useful to use services/controllers when I want them to be the single source of truth of a particular set of information, or when there’s no purpose in having a bunch of them. But at the end of the day, just do whatever works best for your game.


At the end of the day, Knit is designed to assist you in giving a bit of structure when you want it, and stay out of the way when you don’t want it. It gives you a lot of freedom to do whatever you want. This was a purposeful move away from AeroGameFramework’s strict structure, which pigeon-holes developers into patterns that might not really work in all scenarios.

12 Likes

Thank you, I’ve been watching all your videos trying to see how you do it. And writing/rewriting my code.

So just another example so that I know I have it clear. Tell me if I have right.

So in Jailbreak there are vehicles, the vehicles will spawn when a player is nearby. So they might have a VehicleController which listens for a player to be near a vehicle which then fires a “SpawnCar” function in VehicleService. VehicleService might use any number of Modules to spawn the car. Then the garage might be a component (or module) which talks to VehicleService.

So that would be basically any game mechanic (you did say they are the backbone of the game.)

I’m still a little confused on how to tell what should be a singleton and what should not (like a class).
image
Now I have this, I have PlayerDataService which creates player data objects when a profileadded event fires. PlayerDataService accesses ProfileCacher which accesses ProfileService. I want each PlayerData object to have it’s own methods (so it’s a class), but PlayerDataService already returns the PlayerDataService table. So maybe I should make a Module called PlayerData which returns PlayerData objects. Then what would PlayerDataService’s role be? Is PlayerDataService even a singleton?


So basically I have to relax and stop overthinking it. I realize I’m overthinking things, I know some people just make a script and when it works they move on, but I’ve always been one to think “well am I doing efficiently?”, “I want my game to be scalable”, “should I rewrite it?”. I’m trying to be more open when structuring the game and structuring scripts and figure things out as I go.

Is there anything I ask myself or think to figure out what role a particular script will play (is it a singleton, is it a class, is it even a regular script, should it be part of the framework or should it be detached but still access services)

Anyway thank you for all the help, sorry this got long I got carried away

p.s.

Did you mean two Modules?

3 Likes