Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -68,6 +72,7 @@ flowchart TD
CoreServer
CoreClient
CoreShared
CoreCommon
end
style CoreModules stroke:#e91e63

Expand All @@ -86,6 +91,9 @@ flowchart TD
GoobShared --> GoobClient

GoobCommon --> CoreShared
CoreCommon --> GoobCommon
CoreCommon --> CoreShared

CoreShared --> GoobShared
CoreServer --> GoobServer
CoreClient --> GoobClient
Expand All @@ -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!
Loading