diff --git a/src/en/general-development/codebase-info/goob-reforged/reforged-modules.md b/src/en/general-development/codebase-info/goob-reforged/reforged-modules.md index 7734318..e6fd084 100644 --- a/src/en/general-development/codebase-info/goob-reforged/reforged-modules.md +++ b/src/en/general-development/codebase-info/goob-reforged/reforged-modules.md @@ -18,16 +18,18 @@ Goob Reforged repository has a script to automatically create a module and conne ## Terminology -- **Core Module**: Modules belonging to the base space-station-14 repository. These include `Content.Client`, `Content.Server`, `Content.Shared`, and their dependencies like `Content.Shared.Database`. +- **Core Module**: Modules belonging to the base space-station-14 repository. These include `Content.Client`, `Content.Server`, `Content.Shared`, their dependencies like `Content.Shared.Database`, and `Content.Common`. -- **Custom Module**: Modules that are part of the Client or Server process but don't belong to Core Modules. For example, in Goobstation's case, these are prefixed with `Content.Goobstation.`. +- **Custom Module**: Modules that are part of the Client or Server process but don't belong to Core Modules. They are located in the `/Modules/` folder and have an infix. - **Engine Module**: Modules that are part of RobustToolbox (the game engine). These are prefixed with `Robust.`. -- **.Common**: A module type intended to be shared between Custom and Core modules. These hold interfaces, components, and other types that both module types need to share. +- **.Common**: A module type intended to be shared between Custom and Core modules. These hold interfaces, components, and other types that both module types need to share. `Content.Common` is located on top of all other `.Common` modules. - **Infix**: The module identifier, which is the middle part of a module name. For example, "Goobstation" in `Content.Goobstation.Common`. +- **Postfix**: The special module identifier, which specifies its special role, for example `.Database`. Read [Special module projects](#special-module-projects) for more details. + ## How ### Module manager @@ -49,6 +51,8 @@ flowchart TD style CoreClient stroke:#6b9bb3 CoreShared[Content.Shared] style CoreShared stroke:#6b9bb3 + CoreCommon[Content.Common] + style CoreShared stroke:#6b9bb3 GoobServer[Content.Goobstation.Server] style GoobServer stroke:#3498db @@ -68,6 +72,7 @@ flowchart TD CoreServer CoreClient CoreShared + CoreCommon end style CoreModules stroke:#e91e63 @@ -86,6 +91,9 @@ flowchart TD GoobShared --> GoobClient GoobCommon --> CoreShared + CoreCommon --> GoobCommon + CoreCommon --> CoreShared + CoreShared --> GoobShared CoreServer --> GoobServer CoreClient --> GoobClient @@ -111,6 +119,91 @@ In order to fix this, each Core project should have a special .csproj `Target` t Unfortunately, the method of Module Compilation described above doesn't solve the issue entirely. When no changes are made to any files in the core module, the .csproj `Target` doesn't trigger, and modules are ignored even if they have some changes. -This problem is solved by adding the `Content.Modules.Server` and `Content.Modules.Client` projects. They reference all modules at once as a direct Project reference, so when a change is made to any module, it gets recompiled correctly. +Because of that, when you make changes to modules and not to the core projects, you have to compile the whole solution so the changes are applied correctly. This is done automatically if you launch from an IDE. + +## Module organization + +Modules are highly recommended to be independent of other modules. This means that each module references only the core and nothing else. + +Here's a chart to represent this structure: + +```mermaid +flowchart TD + Core[Core] + style Core stroke:#6b9bb3 + Goobstation[Goobstation] + style Goobstation stroke:#6b9bb3 + Lavaland[Lavaland] + style Lavaland stroke:#6b9bb3 + Utils[Utils] + style Utils stroke:#6b9bb3 + Modules[".Modules projects (end)"] + style Utils stroke:#6b9bb3 + + subgraph CustomModules["Custom Modules"] + Goobstation + Lavaland + Utils + end + style CustomModules stroke:#e91e63 + + Core --> Goobstation + Core --> Lavaland + Core --> Utils + + Goobstation --> Modules + Lavaland --> Modules + Utils --> Modules +``` + +The only exception for that convention are **library modules** that provide some general tools or API for other modules to use. + +Those may be required if there are multiple modules that use same features. + +For example, lets assume that both `Lavaland` and `Goobstation` modules need to use code from `Utils`. + +Then it's okay to change the project structure like this: + +```mermaid +flowchart TD + Core[Core] + style Core stroke:#6b9bb3 + Goobstation[Goobstation] + style Goobstation stroke:#6b9bb3 + Lavaland[Lavaland] + style Lavaland stroke:#6b9bb3 + Utils[Utils] + style Utils stroke:#6b9bb3 + Modules[".Modules projects (end)"] + style Utils stroke:#6b9bb3 + + subgraph CustomModules["Custom Modules"] + Goobstation + Lavaland + Utils + end + style CustomModules stroke:#e91e63 + + Core --> Utils + + Utils --> Goobstation + Utils --> Lavaland + + Goobstation --> Modules + Lavaland --> Modules +``` + +## Special module projects + +In `Goobstation` module folder, you can find some projects with weird Postfixes, such as `Content.Goobstation.Client.UIKit`, `Content.Goobstation.Server.Database`. Those are projects that have a unique role in code. Each of them has to be explained separately. + +- `.Server.Database` - a project that specifies a single Database model. At the moment Goob Reforged uses the core model and the Goob model for proper modularity. +- `.Client.UIKit` - a project that references `Robust.Client` and `Content.Shared`, and which is referenced directly by `Content.Client`. Contains custom UI elements that have to be usable in `Content.Client`, without making changes to it directly. + +### Content.Common + +`Common` modules sometimes need to use some of the game's code, for example to inherit an interface for a type or to use a general data structure. + +Those are usually located at `Content.Shared`, and are inaccessible for Common modules. That's why `Content.Common` exists - it allows to use the code ported from `Content.Shared` in all `Content.*.Common` custom modules. -That's why you should **always use `Content.Modules` projects for development!** +The files from `Content.Shared` are moved into `Content.Common` without changing the namespace. This is needed so no `using`s in the code of Core modules have to be changed. And even though it shows as a `Content.Shared.*` namespace, it's actually also available from `Content.*.Common` custom modules!