Skip to content

Commit

Permalink
port the rest of content docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mirrorcult committed Sep 12, 2023
1 parent 4cec66c commit 014650f
Show file tree
Hide file tree
Showing 6 changed files with 527 additions and 5 deletions.
6 changes: 5 additions & 1 deletion book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,8 @@ warning-policy = "ignore" # false-positives like hell with absolute links & late
"/en/technical-docs/codebase-organization/index.html" = "/en/general-development/codebase-info/codebase-organization.html"
"/en/content/mapping/index.html" = "/en/space-station-14/mapping.html"
"/en/content/mapping-sins/index.html" = "/en/space-station-14/mapping/mapping-sins.html"
"/en/content/mapping-checklist/index.html" = "/en/space-station-14/mapping/mapping-checklist.html"
"/en/content/mapping-checklist/index.html" = "/en/space-station-14/mapping/mapping-checklist.html"
"/en/content/dungeons/index.html" = "/en/space-station-14/dungeons.html"
"/en/content/node-networks/index.html" = "/en/space-station-14/node-networks.html"
"/en/content/NPCs/index.html" = "/en/space-station-14/npcs.html"
"/en/content/cartridge-loader/index.html" = "/en/space-station-14/cartridge-loaders.html"
190 changes: 190 additions & 0 deletions src/en/assets/yml/dungeon_template.yml

Large diffs are not rendered by default.

57 changes: 56 additions & 1 deletion src/en/space-station-14/cartridge-loaders.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,58 @@
# Cartridge Loaders

{{#template ../templates/porting.md}}
Cartridge loaders are things like PDAs and PCs.

Cartridges will be interchangeably referred to as program or cartridge depending on if they are installed onto the cartridge loader or just inserted into it.

## Concepts
### Insertion
The `CartridgeLoaderSystem` will send a `CartridgeAddedEvent` event to the cartridge entity when it gets inserted or installed onto the loader.
### Installation
Cartridge prototypes can be specified on the `CartridgeLoaderComponent` that should be installed on map init and inserted cartridges can be installed onto the loader by players.
Cartridge loaders have a maximum amount of programs they can have installed.
The installation limit is ignored when installing cartridges specified in the loaders prototype.
### Activation
A cartridge/program will be saved as active on the cartridge loader component and the `CartridgeActivatedEvent` will be raised at it when the player opens the program throught the ui.
### Deactivation
When the player exits a program or changes to another program the `CartridgeDeactivatedEvent` will be raised at the currently active program and the saved active program will be changed/cleared.
This doesn't happen when the players closes the loaders UI. Opening the UI agian will just display currently active program ui.
### Event relay
The `CartridgeLoaderSystem` will relay specific events to the currently active program and all programs that are running in the background. This includes device networking events.

#### Currently relayed events:
- `DeviceNetworkPacketEvent` using the `CartridgeDeviceNetPacketEvent`
- `AfterInteractEvent` using the `CartridgeAfterInteractEvent`
- Any subclass of `CartridgeMessageEvent` which gets wrapped using `CartridgeUiMessage`, a subclass of `BoundUserInterfaceMessage` for sending messages from the cartridges ui

All relayed events contain the cartridge loaders entity uid as the property: `LoaderUid`.
### Background programs
A program can register and deregister itself as active in the background and it will receive mostly the same events as the active program.
The `CartridgeUiMessage` event won't be relayed to background programs.

Something like a messaging program would run in the background for example.
### Program UI fragments
Cartridge UIs are subclasses of the abstract `CartridgeUi` class which defines methods for getting the root control of that piece of UI and methods for setting it up and updating it. The root control returned gets attached to a control in the catridge loaders UI using that controls `AddChild` method. Those pieces of UI are called UI fagments.

Cartridge prototypes specify the UI fragment to use in the`CartridgeUiComponent`'s `Ui` field.
Example:
```yaml
- type: CartridgeUi
ui: !type:NotekeeperUi
```
### Homescreen Items
```admonish danger
Homescreen items are not yet implemented
```

Cartridges can add something to homescreen of a CartridgeLoader. The specific variant of cartridge loader isn't required to show these. (PDAs will but PCs might not)

Homescreen Items are just text that will be displayed on the homescreen like:
```
- Alerts: 0
- New Messages: 14
- Latest news:
John Genero caused an uproar when he slipped the clown that
was leaving banana peels everywhere
```
The items are sorted by a priorty property and there are a limited number of items that can be displayed.
If an Item is added when the items are already full the lowest priority one gets removed.
59 changes: 58 additions & 1 deletion src/en/space-station-14/dungeons.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,60 @@
# Dungeons

{{#template ../templates/porting.md}}
Dungeons are procedurally generated structures constructed from templates.

## Quickstart

To generate a dungeon:
1. Have a map, either space or planet (via the `planet` command) ready
2. Have a preset in mind, then run the dungeon command. This has autocompletion to help. `dungen <MapId> <preset> <position X> <position Y> [Optional seed]`. This will then run a job to generate the dungeon.

You should note that at the moment planets keep any visited areas loaded so if you load the dungeon on an area that's been visited before it will mix with the biome entities. To prevent this load it somewhere else (the easiest way to determine is zoom out and see what loaded tiles).

## How it works
DungeonPresetPrototype

V

DungeonRoomPackPrototype

V

DungeonRoomPrototype

### Dungeon templates
Dungeon rooms specify what map to use and the tile offset into the map. This keeps the map count down, makes loading faster, and allows all rooms to be visible at once.

When making a new template you should make sure to save it as a map and that the map has the gridcomponent.

### Dungeon preset
The dungeon preset has a list of areas that can be occupied via room packs. It also has a whitelist of rooms to use.
The dungeon preset is fixed and has no RNG involved.

### Dungeon room pack
These comprise a list of rooms inside of a fixed bounds. This bounds is matched to the room pack areas specified in preset.
These are randomly selected to be used for the preset as long as the areas match.

Note that the rooms inside of a pack should not touch each other; the generator will form connections between them.

### Dungeon rooms
These specify a bounds for the area they match inside of a room pack.
As outlined above they also specify the map and what part of the map their contents comes from.

### Additional notes
Presets, room packs, and rooms can be used inside of any valid rotation.

Generation is only deterministic to the degree that the same configuration on the same commit will give the same dungeon between runs. If new prototypes are added then this will adjust the room selection.

## Making new content
Adjusting the prototypes requires simple yaml changes. You should make a map ingame and check the coordinates are correct and to see what your layout would look like.

Making new rooms requires a saved map file and prototypes created specifying the offset into the map to be used. Look at the existing DungeonRoomPrototypes to see what the yaml looks like.

There is a template that can be used below. **Note that there is no limit to size or rooms.**

[dungeon_template.yml](../assets/yml/dungeon_template.yml)

## Mapping suggestions

* At the time of writing there is no automatic cabling so if you wish for the dungeon to be powered it's recommended you attach wires at the middle points on each edge for your rooms (still inside of the bounds).

74 changes: 73 additions & 1 deletion src/en/space-station-14/node-networks.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,75 @@
# Node Networks

{{#template ../templates/porting.md}}
This is not my system, it's a documentation of someone else's.
<!--And this isn't my write-up, I just ported it from HackMD-->

`Node`s, `NodeContainer`s and `INodeGroup`s are the trinity of pieces that make up the 'connectivity layer' in SS14. This is used for pipes and wires (power).

The table of contents of this should provide a high-level overview of the system.

## `NodeContainer` : The component in entities that interact with the node system

`NodeContainer` is the component that whatever device you're building will be interacting with to access the node system.

`Content.Server.GameObjects.Components.Atmos.Piping.Pumps.BasePumpComponent` should be considered the "reference code" for a component that needs to use Nodes in a way that isn't *too* complex, but requires thought due to it not being as "universally connected" as a WireNet device.

## `Node` subclasses : Defines connectivity between itself and other nodes

A `Node` is a specific connection point on an entity.

A `Node` instance is a specific connection point, and the behaviour of that instance defines how that connection point connects to other nodes.

For example, each side of a pump is a separate `PipeNode` that only connects in that direction, but both sides of a pipe are a single `PipeNode` that connects in both directions.

But `AdjacentNode` doesn't have any way to define such a direction, and just connects to all adjacent nodes of the same type.

All `Node`s have a property called `NodeGroupID`, exposed in the prototype as `nodeGroupID`, that determines compatibility between `Node`s and the type of `INodeGroup` that it uses.

Implementing `GetReachableNodes` controls the discovery of `Node`s, while calling `RefreshNodeGroup` is a way to manually force a refresh of this node.

Note that `AdjacentNode`'s code doesn't actually check `NodeGroupID` - this check is performed by the `Node` base class in `GetReachableCompatibleNodes`. This implies `GetReachableNodes` in general does not need to perform this check, so only perform the necessary checks, such as with `PipeNode` which can only ever connect to other `PipeNode`s because.

I am unsure if having an asymmetric connection will cause problems in practice, so try not to create a situation where this can occur. (i.e. something that acts like `PipeNode` next to `AdjacentNode` - `AdjacentNode` will connect to `PipeNode` but not vice versa)

To actually use the `Node` for anything useful, the `Node` needs to either be fed information about it's parent network via the `INodeGroup`, which has overridable functions for when nodes are added and removed, or whatever is accessing it needs to use it's `NodeGroup` property, which has no update callbacks and always has a type of `INodeGroup`.

Though this should be clear already: `Node`s within an entity do not automatically connect to each other unless this is forced to occur via their connection behaviour (directly or indirectly, like via a player connecting a pump to itself).

Finally, again, if you just need "connect to adjacent entities of the same group" behaviour, use `AdjacentNode` as shown below:

```yml
- type: NodeContainer
nodes:
- !type:AdjacentNode
nodeGroupID: Apc
- !type:AdjacentNode
nodeGroupID: WireNet
```
## `INodeGroup` : Represents a connected group of `Node`s, and contains group behaviour

`INodeGroup` instances represent a connected group of `Node`s.

This implies that any `Node` in the group is connected to any other `Node`. (Not necessarily directly, but not going through any "explicit separators" such as pumps in the PipeNet system.)

The `INodeGroup` implementation is chosen via the `Node`'s `NodeGroupID`. See `NodeGroupFactory.cs` (described below) for more details.

Note that all `INodeGroup` implementations at present extend `BaseNodeGroup`.

## `NodeGroupFactory.cs` : Creates `INodeGroup`s for `Node`s and houses the `NodeGroupID` enum

`NodeGroupFactory.cs` contains the network types in the `NodeGroupID` enum.

`NodeGroupID`s are mapped to `INodeGroup` implementations via the NodeGroup reflection attribute (such as `[NodeGroup(NodeGroupID.Pipe)]` in `IPipeNet.cs`).

Multiple `NodeGroupID`s may be mapped to one `NodeGroup` implementation.

`NodeGroupFactory` (accessed via IoC as INodeGroupFactory) has one member of importance, `MakeNodeGroup`. (There is also `Initialize`, which is called from the server EntryPoint, and is used to scan for classes using reflection.)

`MakeNodeGroup` creates a new `INodeGroup` from a `Node`, getting the type from `Node.NodeGroupID`.

## Appendix: Some Power Group IDs:

+ `Apc`: APC Extension Cables -> `ApcNetNodeGroup`
+ `MVPower`: MV Wire -> `PowerNetNodeGroup`
+ `HVPower`: HV Wire -> `PowerNetNodeGroup`
Loading

0 comments on commit 014650f

Please sign in to comment.