-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4cec66c
commit 014650f
Showing
6 changed files
with
527 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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` |
Oops, something went wrong.