diff --git a/book.toml b/book.toml index 4e8865d84..10586853b 100644 --- a/book.toml +++ b/book.toml @@ -72,6 +72,7 @@ warning-policy = "ignore" # false-positives like hell with absolute links & late "/en/hosting/SS14-Admin/index.html" = "/en/server-hosting/setting-up-ss14-admin.html" "/en/hosting/robust-cdn/index.html" = "/en/server-hosting/setting-up-robust-cdn.html" "/en/hosting/oauth/index.html" = "/en/server-hosting/oauth.html" +"/en/hosting/port-forwarding/index.html" = "/en/server-hosting/port-forwarding.html" "/en/technical-docs/acronyms-and-nomenclature/index.html" = "/en/general-development/codebase-info/acronyms-and-nomenclature.html" "/en/getting-started/engine-changes/index.html" = "/en/general-developmnet/codebase-info/prs-with-engine-changes.html" "/en/getting-started/debugging-tools/index.html" = "/en/general-development/tips/debugging-tools.html" @@ -117,3 +118,4 @@ warning-policy = "ignore" # false-positives like hell with absolute links & late "/en/engine/lighting-fov/index.html" = "/en/robust-toolbox/rendering/lighting-and-fov.html" "/en/engine/sprites-icons/index.html" = "/en/robust-toolbox/rendering/sprites-and-icons.html" "/hosting/hub-rules/index.html" = "/en/community/space-wizards-hub-rules.html" +"/en/hosting/hub-rules/index.html" = "/en/community/space-wizards-hub-rules.html" diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 9b367a251..1252797aa 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -28,6 +28,7 @@ General Development - [Codebase Organization](en/general-development/codebase-info/codebase-organization.md) - [Acronyms & Nomenclature](en/general-development/codebase-info/acronyms-and-nomenclature.md) - [Tips](en/general-development/tips.md) + - [Beginner FAQ](en/general-development/tips/beginner-faq.md) - [Troubleshooting FAQ](en/general-development/tips/troubleshooting-faq.md) - [Debugging Tools](en/general-development/tips/debugging-tools.md) - [PRs With Engine Changes](en/general-development/tips/prs-with-engine-changes.md) @@ -117,12 +118,17 @@ Space Station 14 Design Proposals ================ + +---------------------- + - [Anomaly cores](en/proposals/anomaly-cores.md) - [PDA messaging](en/proposals/pda-messaging.md) - [Plant genetics](en/proposals/deltanedas-plant-genetics.md) +- [Security Genpop Rework](en/proposals/genpop_security.md) +- [Game Director](en/proposals/game-director.md) +- [Grid Inventory](en/proposals/grid-inventory.md) - [Exterminator](en/proposals/deltanedas-exterminator.md) ----------------------- Server Hosting ============== @@ -136,6 +142,8 @@ Server Hosting - [Setting up SS14.Changelog](en/server-hosting/setting-up-ss14-changelog.md) - [Setting up SS14.Watchdog](en/server-hosting/setting-up-ss14-watchdog.md) - [OAuth](en/server-hosting/oauth.md) +- [Maintenance]() + - [Debugging server lockups](en/server-hosting/maintenance/debugging-server-lockups.md) Other Projects ============== @@ -178,6 +186,9 @@ Maintainer Meetings ============== ---------------------- +- [2023-12-16](en/maintainer-meetings/maintainer-meeting-2023-12-16.md) +- [2023-11-25](en/maintainer-meetings/maintainer-meeting-2023-11-25.md) +- [2023-10-21](en/maintainer-meetings/maintainer-meeting-2023-10-21.md) - [2023-09-23](en/maintainer-meetings/maintainer-meeting-2023-09-23.md) - [2023-09-09](en/maintainer-meetings/maintainer-meeting-2023-09-09.md) - [2023-09-02](en/maintainer-meetings/maintainer-meeting-2023-09-02.md) diff --git a/src/en/assets/images/grid-inventory/grid-example.png b/src/en/assets/images/grid-inventory/grid-example.png new file mode 100644 index 000000000..5a0e5610b Binary files /dev/null and b/src/en/assets/images/grid-inventory/grid-example.png differ diff --git a/src/en/assets/images/grid-inventory/in-game.png b/src/en/assets/images/grid-inventory/in-game.png new file mode 100644 index 000000000..e53999761 Binary files /dev/null and b/src/en/assets/images/grid-inventory/in-game.png differ diff --git a/src/en/assets/images/grid-inventory/shape-examples.png b/src/en/assets/images/grid-inventory/shape-examples.png new file mode 100644 index 000000000..55f122536 Binary files /dev/null and b/src/en/assets/images/grid-inventory/shape-examples.png differ diff --git a/src/en/assets/images/hosting/scsi-while-true.png b/src/en/assets/images/hosting/scsi-while-true.png new file mode 100644 index 000000000..48e0e6ea3 Binary files /dev/null and b/src/en/assets/images/hosting/scsi-while-true.png differ diff --git a/src/en/assets/images/hosting/windbg-open.png b/src/en/assets/images/hosting/windbg-open.png new file mode 100644 index 000000000..071c6538e Binary files /dev/null and b/src/en/assets/images/hosting/windbg-open.png differ diff --git a/src/en/general-development/codebase-info/conventions.md b/src/en/general-development/codebase-info/conventions.md index 8dc514cc6..004bca8a5 100644 --- a/src/en/general-development/codebase-info/conventions.md +++ b/src/en/general-development/codebase-info/conventions.md @@ -133,10 +133,10 @@ This is so it is clear to others what it is. This is especially true if the same ## Prototypes ### Prototype data-fields -Don't cache prototypes, use prototypeManager to index them when they are needed. You can store them by their ID. When using data-fields that involve prototype ID strings, use custom type serializers. For example, a data-field for a list of prototype IDs should use something like: +Don't cache prototypes, use prototypeManager to index them when they are needed. You can store them by their ID. When using data-fields that involve prototype ID strings, use ProtoId. For example, a data-field for a list of prototype IDs should use something like: ```csharp= -[DataField("exampleTypes", customTypeSerializer: typeof(PrototypeIdListSerializer))] -public List ExampleTypes = new(); +[DataField] +public List> ExampleTypes = new(); ``` ### Enums vs Prototypes @@ -155,7 +155,7 @@ When specifying sound data fields, use `SoundSpecifier`. C# code example (click to expand) ```csharp= -[DataField("sound", required: true)] +[DataField(required: true)] public SoundSpecifier Sound { get; } = default!; ``` @@ -190,7 +190,7 @@ When specifying sprite or texture data fields, use `SpriteSpecifier`. C# code example (click to expand) ```csharp= -[DataField("icon")] +[DataField] public SpriteSpecifier Icon { get; } = SpriteSpecifier.Invalid; ``` @@ -200,10 +200,14 @@ public SpriteSpecifier Icon { get; } = SpriteSpecifier.Invalid; YAML prototype example (click to expand) ```yml= -# You can specify a specific texture file like this +# You can specify a specific texture file like this, /Textures/ is optional - type: MyComponent icon: /Textures/path/to/my/texture.png - + +# /Textures/ is optional and will be automatically inferred, however make sure that you don't start the path with a slash if you don't specify it +- type: MyComponent + icon: path/to/my/texture.png + # You can specify an rsi sprite like this - type: MyOtherComponent icon: diff --git a/src/en/general-development/setup/server-hosting-tutorial.md b/src/en/general-development/setup/server-hosting-tutorial.md index 386f7696d..345bc5898 100644 --- a/src/en/general-development/setup/server-hosting-tutorial.md +++ b/src/en/general-development/setup/server-hosting-tutorial.md @@ -1,40 +1,18 @@ # Server Hosting Tutorial -This is a tutorial/brain dump of how to set up an SS14 server. This guide will cover everything you need, from private servers to play with your friends, to production servers for proper server hosts. +Hosting a local sandbox server for playing around is easy, but setting up a large production server supporting hundreds of players is a bit harder. This guide is organized into "levels" corresponding to difficulty. -There are two methods you can use. A "bare" server that just runs the game server directly, or `SS14.Watchdog` which handles updates and runs the game server for you. We recommend the latter for more proper deployments and also if you want to be listed on the hub in the launcher. +## Level 0: Local Sandbox Server -If you have any questions, ask on Discord and/or ping PJB if you really don't get an answer. +1. Download and install the [.NET 8 Runtime](https://dotnet.microsoft.com/download) installed. You only need "x64" under "run console apps" not "hosting bundle" from the downloads page. +2. Download the latest version of the server from [our builds page](https://central.spacestation14.io/builds/wizards/builds.html), for your operating system. If you are running custom code, or a build is not available for your platform, see [Custom Code](#custom-code) below. +3. Extract that to a directory somewhere. +4. Run `Robust.Server.exe` (or `Robust.Server` [via terminal on macOS/Linux](#running-the-server-on-macos-or-linux)) -## Useful Links -All of the important links on this page in one convenient place. -* [Config Reference](../tips/config-file-reference.md) -* [.NET 7 Runtime](https://dotnet.microsoft.com/download) (Also included in full .NET 7 SDK) -* [ASP.NET Core 7 Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/7.0) (Also included in full .NET 7 SDK) -* [SS14.Watchdog](https://github.com/space-wizards/SS14.Watchdog/) -* [Official Builds](https://central.spacestation14.io/builds/wizards/builds.html) -* [Wizard's Den Infrastructure Reference](../../community/infrastructure-reference/wizards-den-infrastructure.md) (server specs) -* [Public Hub Server Rules](../../community/space-wizards-hub-rules.md) - -## Install Dependencies - -Regardless of the hosting method you choose, the server is not self-contained (and neither are client builds) and therefore needs a [.NET 7 Runtime](https://dotnet.microsoft.com/download) installed. You only need "x64" under "run console apps" not "hosting bundle" from the downloads page. - -For other services such as `SS14.Watchdog` you ALSO need the [ASP .NET Core 7 Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/7.0) (included in .NET 7 SDK). - -## Set Up Server -1. Download the latest version of the server from [our builds page](https://central.spacestation14.io/builds/wizards/builds.html), for your operating system. If you are running custom code, or a build is not available for your platform, see [Custom Code](#custom-code) below. -2. Extract that to a directory somewhere. -3. Run `Robust.Server.exe` (or `Robust.Server` [via terminal on macOS/Linux](#running-the-server-on-macos-or-linux)) -4. [Forward your network ports](#port-forwarding) -5. Give your friends and yourself your IP address and have them paste it into the "direct connect" dialog in the launcher. +## Level 1: Invite Your Friends -This will not, of course, handle automatic restarts (in case of a crash) or updates like the watchdog would. This also won't list your server publicly on the hub as advertising defaults to off. If you wish to have your server listed on the hub please read `Bare Server Configuration` below. - -```admonish info -Note that when you run a server like this, the build information that the launcher needs (so it has a version of the client to download) points to our central server. **We do not keep those builds around forever** so eventually people will no longer be able to connect to the server. Obviously this is not a problem if you want to set up a quick and dirty private server for your friends. Just make sure to download a new version of the server at least every week. -``` +You will need to do some extra steps if you want other people to be able to connect and play. ### Port Forwarding @@ -44,18 +22,12 @@ The server needs network ports to be forwarded so that people can connect. By de For more information about how to forward your ports, see: [Port Forwarding](../../server-hosting/port-forwarding.md) -#### Advanced Port Forwarding - -You can slap the HTTP status API behind a reverse proxy if you want. This is recommended for production servers since then you can do HTTPS (slap it behind nginx and turn on HTTPS). Note that if you do this you have to set the `status.connectaddress` config variable to specify the UDP address the main netcode should connect to. This has to look like this: `udp://server.spacestation14.io:1212` (for our server, obviously substitute with your params). - -### Custom Code -You need to [set up a development environment](./setting-up-a-development-environment.md) in order to produce a server build for custom code. After you do that, you need to generate the server build by running: - -`python Tools/package_server_build.py --hybrid-acz` -Check the `release/` folder for a packaged server for your custom codebase. +```admonish info +Note that when you run a server like this, the build information that the launcher needs (so it has a version of the client to download) points to our central server. **We do not keep those builds around forever** so eventually people will no longer be able to connect to the server. Obviously this is not a problem if you want to set up a quick and dirty private server for your friends. Just make sure to download a new version of the server at least every week. +``` -## Configure Your Server +### Configure Your Server You can configure settings in the server by editing the config file, `server_config.toml`. The config file is TOML which is basically INI ~~except better specified, somewhat more powerful, easier to misuse, and more annoyingly opinionated (comments NEED their own line)~~. @@ -94,6 +66,42 @@ mode = 1 See [Config File Reference](../tips/config-file-reference.md) for a somewhat more thorough guide on server configuration. +### Admin Privileges + +By default, no admin privileges are set. A privileged administrator can give out permissions to other admins with the `permissions` console command in-game, but that has a chicken-and-egg problem. To get initial `+HOST` administrator permissions to your server, you can use one of the following three methods: + +```admonish danger +`+HOST` privileges are **extremely dangerous** to give and should only be given to people who already have access to your computer or server. + +**Giving somebody `+HOST` allows them to completely take over your server and/or computer.** +``` + +* If you connect to the game server over localhost (IP `127.0.0.1` or `::1`), the game will automatically give you full host privileges. This can be disabled with the `console.loginlocal` CVar. +* If you set the `console.login_host_user` CVar to your user name, you will be given host when you connect. +* You can use `promotehost` command from the server console (e.g. `promotehost PJB`) to temporarily give a connected client host. + + +## Level 2: Server With Custom Code +You need to [set up a development environment](./setting-up-a-development-environment.md) in order to produce a server build for custom code. After you do that, you need to generate the server build by running: + +`dotnet build Content.Packaging --configuration Release` + +`dotnet run --project Content.Packaging server --hybrid-acz` + +```admonish info +Note that if you are running an older server before Content packaging was a thing, or need to use the legacy script (not supported anymore) then use this +`python Tools/package_server_build.py --hybrid-acz` +``` + +Check the `release/` folder for a packaged server for your custom codebase. + + +## Level 3: A "Production" Server + +This will not, of course, handle automatic restarts (in case of a crash) or updates like the watchdog would. This also won't list your server publicly on the hub as advertising defaults to off. If you wish to have your server listed on the hub please read `Bare Server Configuration` below. + +For other services such as `SS14.Watchdog` you ALSO need the [ASP .NET Core 8 Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) (included in .NET 8 SDK). + ### Setting Rules By default, the server ships with the rules that are used on Wizard's Den servers. To set custom rules for your own server: @@ -130,21 +138,7 @@ You will want to edit the server config file (`server_config.toml`) to add the f download_url = "" ``` -### Admin Privileges - -By default, no admin privileges are set. A privileged administrator can give out permissions to other admins with the `permissions` console command in-game, but that has a chicken-and-egg problem. To get initial `+HOST` administrator permissions to your server, you can use one of the following three methods: - -```admonish danger -`+HOST` privileges are **extremely dangerous** to give and should only be given to people who already have access to your computer or server. - -**Giving somebody `+HOST` allows them to completely take over your server and/or computer.** -``` - -* If you connect to the game server over localhost (IP `127.0.0.1` or `::1`), the game will automatically give you full host privileges. This can be disabled with the `console.loginlocal` CVar. -* If you set the `console.login_host_user` CVar to your user name, you will be given host when you connect. -* You can use `promotehost` command from the server console (e.g. `promotehost PJB`) to temporarily give a connected client host. - -## Performance Tweaks +### Performance Tweaks Here are some settings you probably want to enable on your server to improve performance: @@ -162,50 +156,14 @@ ROBUST_NUMERICS_AVX: true You can set environment variables from the watchdog, see below. -## Watchdog +## Level 4: Production Watchdog Server This is for people running their own codebase and server and/or those who want a more robust hosting solution. [`SS14.Watchdog`](https://github.com/space-wizards/SS14.Watchdog/) (codename Ian) is our server-hosting wrapper thing, similar to TGS for BYOND (but much simpler for the time being). It handles auto updates, monitoring, automatic restarts, and administration. We recommend you use this for proper deployments. ### Installation -1. Download or clone the latest `SS14.Watchdog` source code (linked above) -2. Run `dotnet publish -c Release -r linux-x64 --no-self-contained`, replacing `linux-x64` with an identifier for your platform -3. Copy the `SS14.Watchdog/bin/Release/net6.0/linux-x64/publish` directory (check this path for your platform as necessary) to where you want to store your SS14 server files. - -### Configuration -Configure the watchdog to add servers. Edit `appsettings.yml` inside the installed watchdog directory. - -1. Uncomment and set `BaseURL`. This is the address that your game servers will use to communicate with the watchdog. The default value is fine for small setups. For example: - ```yml - BaseUrl: https://builds.spacestation14.io/watchdog/ - ``` - -2. At the bottom of the config file, add a `Servers` YAML block, and then a `Instances` block inside of that. Inside the `Instances` block, add a block for each server that you plan to serve from this watchdog. For example: - - ```yml - - Servers: - Instances: - wizards_den: # ID of your server. - Name: "Wizard's Den" # Name of the server - Note that this is NOT the name of the server on the hub, that is set for each server under game.hostname in their respective config.toml files. - ApiToken: "foobar" # A secret password that you make up (API token) for the watchdog to control this server (e.g. update, restart) - ApiPort: 1212 # API port OF THE GAME SERVER. This has to match the 1212 HTTP status API (described below). Otherwise the watchdog can't contact the game server for stuff. - - # Auto update configuration. This can be left out if you do not need auto updates. Example is for our officially hosted builds. - # See below for alternatives. - UpdateType: "Manifest" - Updates: - ManifestUrl: "https://central.spacestation14.io/builds/wizards/manifest.json" - - # Any environment variables you may want to specify. - EnvironmentVariables: - Foo: bar - wizards_den_two: - # Name of the second server - Name: "Wizard's Den 2" - # etc... - ``` +[`Refeer to this`](https://docs.spacestation14.com/en/server-hosting/setting-up-ss14-watchdog.html) for intructions on building and configuring Watchdog. ### Server Instance Folder @@ -303,9 +261,14 @@ hash = "" Note that `SS14.Watchdog` specifies *most* of it for you if you have configured it with auto updates (depending on update provider). It notably cannot provide `engine_version` or `fork_id` version, so you're best off specifying the former in build.json (your build system should be non garbage for this) and the latter in a config file. -## Optional Infrastructure +## Level 5: Big Production Server Things that aren't necessary for small/private servers, but strongly recommended for forks or larger production servers. +### Advanced Port Forwarding + +You can slap the HTTP status API behind a reverse proxy if you want. This is recommended for production servers since then you can do HTTPS (slap it behind nginx and turn on HTTPS). Note that if you do this you have to set the `status.connectaddress` config variable to specify the UDP address the main netcode should connect to. This has to look like this: `udp://server.spacestation14.io:1212` (for our server, obviously substitute with your params). + + ### PostgreSQL Setup SS14 uses an SQL database to store server data like player slots. By default, an **SQLite** database is automatically used which is sufficient for local testing and small servers. If you want the ability to share the database between multiple servers or such however, the server also supports connecting to **PostgreSQL**. @@ -426,3 +389,13 @@ Type `./Robust.Server` then hit enter. If you see a bunch of stuff being printed ### Additional Troubleshooting [Troubleshooting](../tips/troubleshooting-faq.md#server) + +## Useful Links +All of the important links on this page in one convenient place. +* [Config Reference](../tips/config-file-reference.md) +* [.NET 8 Runtime](https://dotnet.microsoft.com/download) (Also included in full .NET 8 SDK) +* [ASP.NET Core 8 Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) (Also included in full .NET 8 SDK) +* [SS14.Watchdog](https://github.com/space-wizards/SS14.Watchdog/) +* [Official Builds](https://central.spacestation14.io/builds/wizards/builds.html) +* [Wizard's Den Infrastructure Reference](../../community/infrastructure-reference/wizards-den-infrastructure.md) (server specs) +* [Public Hub Server Rules](../../community/space-wizards-hub-rules.md) diff --git a/src/en/general-development/setup/setting-up-a-development-environment.md b/src/en/general-development/setup/setting-up-a-development-environment.md index 717ae7c75..d8e30432d 100644 --- a/src/en/general-development/setup/setting-up-a-development-environment.md +++ b/src/en/general-development/setup/setting-up-a-development-environment.md @@ -4,10 +4,10 @@ First you're gonna need some software: * [Git](https://git-scm.com/) or one of the [many](https://www.sourcetreeapp.com/) [third-party](http://www.syntevo.com/smartgit/) [UIs](https://tortoisegit.org/) that make it easier to use. Make sure to let it install to your PATH like [this](https://cdn.discordapp.com/attachments/560845886263918612/861267188971470898/unknown.png). * [Python 3.7 or higher](https://www.python.org/). Make sure to install it into your [PATH on Windows](https://cdn.discordapp.com/attachments/560845886263918612/1147634791148179457/image.png). You should get python from [python.org](https://www.python.org/). Versions installed from the windows store sometimes cause build issues. -* [.NET 7.0 SDK or greater](https://dotnet.microsoft.com/download). Visual Studio also installs this if you're on Windows. +* [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0). Visual Studio also installs this if you're on Windows. * ARM (M1) Mac users: You need to make sure to install x64 .NET, **not** ARM .NET. The engine does not currently run natively on Mac ARM so using x64 via Rosetta 2 emulation is recommended. * Preferably an IDE to make development not painful (all free options unless otherwise noted): - * For **Windows**, [Visual Studio 2022 **Community**](https://www.visualstudio.com/). For a minimal install (Jesus it's large) you're gonna want the .NET desktop development workload, the C# compiler, C# support, NuGet package manager, MSBuild and .NET 7 SDK or something along those lines. + * For **Windows**, [Visual Studio 2022 **Community**](https://www.visualstudio.com/). For a minimal install (Jesus it's large) you're gonna want the .NET desktop development workload, the C# compiler, C# support, NuGet package manager, MSBuild and .NET 8 SDK or something along those lines. * For **macOS**, [Visual Studio for Mac](https://docs.microsoft.com/en-us/visualstudio/mac/). * For **all platforms**, (NOT FREE) [Rider](https://www.jetbrains.com/rider/) is one of the best IDEs available, and many SS14 devs prefer it over Visual Studio. College/University students can get a free education license, even if they're not a computer science major. * For **all platforms**, [Visual Studio Code](https://code.visualstudio.com/) with the C# extension. Usually an inferior IDE experience than full blown IDEs like regular Visual Studio, but some experienced programmers enjoy the minimalism. diff --git a/src/en/general-development/tips/beginner-faq.md b/src/en/general-development/tips/beginner-faq.md new file mode 100644 index 000000000..404a58025 --- /dev/null +++ b/src/en/general-development/tips/beginner-faq.md @@ -0,0 +1,108 @@ +# Beginner FAQ + +## Contributing to Space Station 14 + +### I want to start contributing to Space Station 14 but I do not know where to start. + +Go to [Issues in Space Station 14](https://github.com/space-wizards/space-station-14/issues) +- Choose 1 or more of the following labels in [Labels](https://github.com/space-wizards/space-station-14/labels) +1. [Beginner Friendly](https://github.com/space-wizards/space-station-14/labels/Beginner%20Friendly) +2. [Difficulty: 1 - Easy](https://github.com/space-wizards/space-station-14/labels/Difficulty%3A%201-Easy) +3. [No C#](https://github.com/space-wizards/space-station-14/labels/No%20C%23) to work on issues that require no code. + +After you have chosen an issue to fix, follow the steps here to start making and testing code changes on your own copy of the Space Station 14 code: +- [Setting up a Development Environment](https://docs.spacestation14.com/en/general-development/setup/setting-up-a-development-environment.html) + - This will let you play a local copy of the game so you can see your changes in gameplay. +- [Git for the SS14 Developer](https://docs.spacestation14.com/en/general-development/setup/git-for-the-ss14-developer.html) + - This will let you work on code that you can transfer from your computer to your Github repository and eventually to Space Station 14. + + + +### How does code get transferred between my computer & the main Space-Station-14 repository? + +```admonish danger "Make a new branch so you are not working on the master branch!" +This is important to know so you do not accidentally delete all of your code changes when you update your copy of Space Station 14. +- [Git for the SS14 Developer](https://docs.spacestation14.com/en/general-development/setup/git-for-the-ss14-developer.html#3-setting-up-remotes) +``` + +**3 Code Locations to know:** +1) Your Computer code (Your copy) +2) Your Github Repository (Local Github) +3) Space Station 14 Github + + +**How the code is transferred.** +1. **Space Station 14 Github => Local Github**. You make a fork of the Space Station 14 repository so you have a Local Github copy of the code yourself. +2. **Local Github <==> Space Station 14 Github**. Do NOT make your own code changes on your master branch. +- Your master branch needs to be linked to the master branch of Space Station 14. +- Every time Space Station 14 Github updates its code, your master branch on your Local Github repository will need to update its code as well so it stays in sync. +3. **Local Github => Your copy**. Follow [Setting up a Development Environment](https://docs.spacestation14.com/en/general-development/setup/setting-up-a-development-environment.html) & [Git for the SS14 Developer](https://docs.spacestation14.com/en/general-development/setup/git-for-the-ss14-developer.html) +4. **Your copy**. Make a new branch from your code editor where you will make code changes. +5. **Your copy**. Test your changes in gameplay. +6. **Your copy => Local Github**. When your code is ready, make a commit to your Github repository from your non-master branch. +7. **Space Station 14 Github => Local Github**. Sync Fork + +![image](https://github.com/alwinnocom/docs/assets/63136288/0823b607-d87c-4495-97b8-32f06b343b4e) + +- For your code to work, it must fit into the code in Space Station 14 Github. +- You will have to keep your Local Github code up-to-date with the Space Station 14 Github. + +8. **Local Github => Your copy** Pull the updated code from your Local Github repository to your copy. + +![image](https://github.com/alwinnocom/docs/assets/63136288/725a5132-32d0-4e0c-9223-fb35186365da) + +You may need to merge changes if you are trying to change files that got changed from the update. +![image](https://github.com/alwinnocom/docs/assets/63136288/d6602410-3751-410d-9dd9-48f4b289706a) + + +9. **Your copy => Local Github**. Commit your changes. +10. **Local Github <==> Space Station 14 Github**. Make a pull request. +- If you make code changes from your master branch & make a pull request from your master branch, both your code changes and your pull request are at risk of self-destruction. + - The only way to keep your code up-to-date with the actual Space Station 14 code is to sync the code. + - This will require you to discard your commits. + - Once you discard your commits, your code changes will be deleted & your pull request will be closed. Which is not fun. +11. Wait for Code Reviewers to let you know if your code is good to go for merging. + + + +### I have an idea for a new feature or to fix an issue that I have not seen on Github. + +1. Try playing the game first so you know what features are already implemented. +- "Feature bloat" occurs if you make a feature that already exists. + - For example, allowing a specific action to toggle by pressing "4" when it already can be toggled by pressing "z". +2. Propose the Feature before you start making it. [Feature Proposals](https://docs.spacestation14.com/en/general-development/feature-proposals.html) +3. Open a New Issue on Space Station 14: [New Issue](https://github.com/space-wizards/space-station-14/issues/new/choose) + + + +## Coding Space Station 14 + +### I cannot play a local copy of the game because not all of the projects are loading. + +Have you completed step 2.3 of [Git for the SS14 Developer](https://docs.spacestation14.com/en/general-development/setup/git-for-the-ss14-developer.html#23-submodule-woes)? + +Make sure you use the command `cd` to navigate to your space-station-14 repository before running `RUN_THIS.py`. +![image](https://github.com/alwinnocom/docs/assets/63136288/1750eb6a-20e3-4d3c-9b4c-d7272787aaf2) + + + +## Researching Space Station 14 + +### I am looking for text that I saw in gameplay but I am not sure where to look. + +1. Lots of the in-game text can be found in XAML files & YML files. You can search through XAML files to find the parts of the user interface that you want to work on. +![image](https://github.com/alwinnocom/docs/assets/63136288/2a4aef1b-2839-455d-a867-b9c457f9d3a2) +2. If YML files are not showing up, you can find them on Github by going to the [Space Station 14 repository](https://github.com/space-wizards/space-station-14?search=1) & searching for .yml files. +3. Use your code editor to search for the exact text (for text that is not based on Project Fluent). For example, Visual Studio lets you use Ctrl + Shift + F to find certain text in all of the files. + +![image](https://github.com/alwinnocom/docs/assets/63136288/cffa2910-3c9f-4f77-87bc-7f8a43b6895f) + +4. Not all text shows up exactly as written because Space Station 14 uses Project Fluent to make text that automatically translates to different languages. +- [Project Fluent](https://docs.spacestation14.com/en/ss14-by-example/fluent-and-localization.html) + - This means that some text shows up as `Loc.GetString("id-that-references-fluent-file")` + +![image](https://github.com/alwinnocom/docs/assets/63136288/f5090633-19f5-4ec5-b843-15754cafff69) + +5. If you want to find where a method is referenced throughout the code, you can click on the method name on Github to find where the method is referenced. + +![image](https://github.com/alwinnocom/docs/assets/63136288/deefd271-cf47-451d-8309-0435770d6990) diff --git a/src/en/maintainer-meetings/maintainer-meeting-2023-10-21.md b/src/en/maintainer-meetings/maintainer-meeting-2023-10-21.md new file mode 100644 index 000000000..d8942c2da --- /dev/null +++ b/src/en/maintainer-meetings/maintainer-meeting-2023-10-21.md @@ -0,0 +1,108 @@ +# Maintainer Meeting (21 Oct 2023) + +**Time:** 21 Oct 2023 18:00 UTC + +**Attendees:** +- DrSmugleaf +- EmoGarbage +- ElectroSR +- KeronSHB +- PJB +- Visne +- Jezithyr +- Chief_Engineer +- notafet +- TheQuietOne +- faint + +## Audioparams refactor | Sloth +- Take a component with a default variation for example, you can't have any inheritors also use it so you have to manually set it every time which is a pita, or alternatively just do it in code and bulldoze the existing audioparams on the component. +- Ideally we'd be able to specify volume / pitch or whatever on the audio file but also have a global way of setting variation or the likes +- One possible solution is removing audioparams from soundspecifier and leaving volume / pitch on it maybe? + + +## Cinematic trailer | Jezithyr +- Thread number one (#progress-report-writing): https://discord.com/channels/310555209753690112/1036668046623903815/1044457700026761216 +- Thread number two (#maintainers-office): https://discord.com/channels/310555209753690112/1151546015330082867/1155994231417090069 +- Thread number three (#contributors): https://discord.com/channels/310555209753690112/1164636218051543060/1164641450563227719 +- Do we make a cinematic or gameplay trailer + - **Gameplay trailer**, cinematic trailer would be nice +- [GitHub issue for trailers](https://github.com/space-wizards/space-station-14/issues/20478) +- **Have somewhere for people to submit replays and timestamps** + + +## UIControllers and UI reloading | Jezithyr +- [UIController docs](https://docs.spacestation14.com/en/robust-toolbox/user-interface.html#ui-controllers) +- Right now UIControllers listen to an event on the system +- Full state reloading is a pain in the ass, slower and clunkier than just UI +- Do we move UI code to a separate assembly + - **Yes eventually** +- **Try making them EntitySystems** + + +## Medical and surgery | Jezithyr +- Wounds, damage is taken by DamageableComponent and handled by other components. +- New items/chemicals for medical should be frozen (any new ones would be removed once the refactor is done, specially around bleeding). + + +## Generic Entity\ monologue | DrSmugleaf +```cs +if (!Resolve(uid, ref comp)) + return; + +Entity ent; +var (uid, buckle, transform, physics) = ent; +if (!Resolve(ent, ref buckle, ref physics)) + return; + +Entity ent1; +Entity ent2 = (ent1, ent1.Comp); +``` + + +## Entity relations | DrSmugleaf +- Some components have EntityUid fields that may hold deleted entities or entities without the required component anymore +- Entity relations or having a way to register these fields with a delegate would fix this +- How to handle dangling entity references held in components +- idk + + +## Admin logs archival and current round replays | DrSmugleaf +- **Make archival part of SS14.Admin** +- **Partition by date** (for persistent forks otherwise we would do by round id) +- Sending replays through lidgren requires tcp window scaling +- Easy way is open a link on the browser and then open the replay on the launcher + + +## UI styling tweaks | EmoGarbage +- Hud redesign +- Some things are ugly, don't fit how the game looks +- Action bar being on the side is slightly annoying +- Having clothing right above the hands gets in the way of putting storage there +- The whole UI theme is very blue which doesn't fit the theme of the resto f the game +- The font is very generic +- **Just do it get an UI designer** + + +## Early Access Roadmap +- **nothing on this roadmap matters except early access trailer.** +- A trailer for Steam +- gamemodes/antags + - dynamic [c#16548](https://github.com/space-wizards/space-station-14/pull/16548) + - wizard +- The game runs like shit how do people play this + - "IDK but maybe when I fix the watchdog you can figure it out easier" | 09/09/2023 + - "I only played VRChat since last time and VRChat runs like shit so I don't know how people play this" | 23/09/2023 + - "" | 21/10/2023 + + +Crashes / Critical bugs: (when are we moving these to GitHub) +- Crashes the server reliably. +- Something that bricks your client often (needs a client restart). + - Example: Blackscreens the client until you reconnect. +- If something ruins the round and is disabled because of it. + - Example: Communal lung bug. + => till next time + like and subscribe + smash that button + ~~did you know only 6% of contribs join this meeting?~~ According to YouTube's statistics, diff --git a/src/en/maintainer-meetings/maintainer-meeting-2023-11-25.md b/src/en/maintainer-meetings/maintainer-meeting-2023-11-25.md new file mode 100644 index 000000000..5e877d779 --- /dev/null +++ b/src/en/maintainer-meetings/maintainer-meeting-2023-11-25.md @@ -0,0 +1,54 @@ +# Maintainer Meeting (25 Nov 2023) + +**Time:** 25 Nov 2023 18:00 UTC + +**Attendees:** +- DrSmugleaf +- PJB +- EmoGarbage +- Faint +- Lank +- Jezithyr +- Chief Engineer +- KeronshBB + +## Faster get/tryget methods for engine with arch | metalgearsloth +- Might not be safe with multiple threads from content +- Also check unsafe code in Arch +- **Arch should not cause unsafe-type bugs if incorrectly accessed through multithreaded code** + + +## Atmos method events | ElectroSR +- Remove them, they are private. +- **If downstreams need them, they can revert the change (or whatever subset they need for their features)** + + +## Early Access Roadmap +- **nothing on this roadmap matters except early access trailer.** +- A trailer for Steam + - ask enrico about the trailer +- gamemodes/antags + - dynamic [c#16548](https://github.com/space-wizards/space-station-14/pull/16548) + - wizard +- The game runs like shit how do people play this + - "IDK but maybe when I fix the watchdog you can figure it out easier" | 09/09/2023 + - "I only played VRChat since last time and VRChat runs like shit so I don't know how people play this" | 23/09/2023 + - "" | 21/10/2023 + + +Crashes / Critical bugs: (when are we moving these to GitHub) +- Crashes the server reliably. +- Something that bricks your client often (needs a client restart). + - Example: Blackscreens the client until you reconnect. +- If something ruins the round and is disabled because of it. + - Example: Communal lung bug. + => till next time + like and subscribe + smash that button + ~~did you know only 6% of contribs join this meeting?~~ According to YouTube's statistics, + +## PJB personal roadmap +- Audio rework DONE NO WAY +- Fix infra +- Watchdog rework: testmerges, **better way to get traces from game servers** +- Fix perf oh god diff --git a/src/en/maintainer-meetings/maintainer-meeting-2023-12-16.md b/src/en/maintainer-meetings/maintainer-meeting-2023-12-16.md new file mode 100644 index 000000000..a45d0db4b --- /dev/null +++ b/src/en/maintainer-meetings/maintainer-meeting-2023-12-16.md @@ -0,0 +1,110 @@ +# Maintainer Meeting (16 Dec 2023) + +**Time:** 16 Dec 2023 18:00 UTC + +**Attendees:** +- DrSmugleaf +- PJB +- EmoGarbage +- Faint +- Lank +- Visne +- ElectroSR +- notafet +- Julian +- Jezithyr +- chromiumboy + +## Dump the wiki | metalgearsloth +- Originally never intended long-term +- I don't want to be forced into maintaining this +- Just link people github if they want something out of game +- **Add banner** + +- **Possible solutions:** + 1. **Set up new site that is "the guide book, online". Current wiki keeps existing** + * Preferably with a banner or something "use guide book for up-to-date info" + 2. Set up new site, kill wiki + 3. Make a system to automatically integrate guidebook content into the wiki + +- **We're not stupid enough to delude ourselves into thinking anybody is going to step up to do (3) so lol** + +## P5S | ElectroSR +- [P5S thread](https://discord.com/channels/310555209753690112/1153246232064569394/1184947317829287947) +- [Engine PR](https://github.com/space-wizards/RobustToolbox/pull/4693) +- Electro is making another PR to use arrays instead of 100 dicts +- **Please god PJB finish the better profiler infrastructure** + - **Ability for maintainers to make profiles of game servers without bugging PJB** + - **Benchmarking server, automated benchmarks** + +## \ for the server OOC relay | PJB +- It's easier to setup +- Will it add significant overhead +- **Do it** + +## Better error monitoring system for game servers | PJB +- **Nobody checks grafana** +- **Checking Grafana sucks** +- **When PJB infrastructures it** + - Pain and suffering + +## Trailer 2 electric boogaloo | PJB +- **Ping maintainer and/or PM for feedback, send it in one message to Enrico and end the suffering.** +- how do we actually hold ourselves to it :godo: + +## Admin Affecting Issues | CE +- Erase verb is broken in its current state. It fails to delete some messages if the target is spamming. +- Skeleton still sometimes spawn in nullspace or whatever it's called requiring admin intervention to fix. +- Replays are completely broken. Before they broke the seek bar was glitched and would fast forward/backwards indefinitely after you used it. Seems to have been following the mouse well after the user stopped clicking. + - Send a message in contrib notifications or somewhere that old replays are (currently?) broken. + - **Have a separate download in the repo for old launcher that works with old replays.** + - Set up a steam beta for an old launcher for old replays? +- Adminhelp is often glitched and not showing specific players even if you can hear the ahelps being sent. You cannot right click player names in the ahelp menu. + - Broken right clicks: + - AHelp + - F7 players tab + - F7 objects tab +- There should be functionality for responding to ahelps through discord. + - **Wow we already addressed the ahelp thing halfway** +- Vehicles break after going over ice requiring admin intervention to fix. +- Restart votes seem to be abused to determine whether there are admins on. + - A fix to this could be allowing votes when admins are on but them having no effect. +- Add round numbers to ahelp (or to PDAs and call them shift numbers) + +## Do we record maintainer meetings | Petalmeat +- **Have to ask all maintainers and PMs if they are comfortable with it.** + +## Server hosting docs +- **Have a shorter docs page for people that want a server for only themselves or themselves+friends, link to it with a bot command.** + +## Early Access Roadmap +- **nothing on this roadmap matters except early access trailer.** +- A trailer for Steam + - ask enrico about the trailer +- gamemodes/antags + - dynamic [c#16548](https://github.com/space-wizards/space-station-14/pull/16548) + - wizard +- Steam account linking +- The game runs like shit how do people play this + - "IDK but maybe when I fix the watchdog you can figure it out easier" | 09/09/2023 + - "I only played VRChat since last time and VRChat runs like shit so I don't know how people play this" | 23/09/2023 + - "" | 21/10/2023 + - Miros runs fine | 16/12/2023 + - I am 5 parallel universes ahead of you + +Crashes / Critical bugs: (when are we moving these to GitHub) +- Crashes the server reliably. +- Something that bricks your client often (needs a client restart). + - Example: Blackscreens the client until you reconnect. +- If something ruins the round and is disabled because of it. + - Example: Communal lung bug. + => till next time + like and subscribe + smash that button + ~~did you know only 6% of contribs join this meeting?~~ According to YouTube's statistics, + +## PJB personal roadmap +- Audio rework DONE NO WAY +- Fix infra +- Watchdog rework: testmerges, **better way to get traces from game servers** +- Fix perf oh god diff --git a/src/en/meta/docs-example-page.md b/src/en/meta/docs-example-page.md index ec51edcd8..4cb4dfec4 100644 --- a/src/en/meta/docs-example-page.md +++ b/src/en/meta/docs-example-page.md @@ -32,7 +32,7 @@ All available admonishment types. To use an admonishment: `````` -```admonishment {type} "{text you want as title, or leave blank}" +```admonish {type} "{text you want as title, or leave blank}" description ``` `````` diff --git a/src/en/proposals/atmos.md b/src/en/proposals/atmos.md new file mode 100644 index 000000000..892fff984 --- /dev/null +++ b/src/en/proposals/atmos.md @@ -0,0 +1,113 @@ +# Roadmap For Atmospherics + +## Background + +Most atmos players currently agree that atmos is not very fun to play, for some of the following reasons: + +1. There is little content to play after round-start setup. Part of the problem is that things like distro and TEG are "set up and forget". + +2. Atmos can't actually rectify atmos problems in a reasonable amount of time. For example, if there actually is a plasma leak, scrubbers typically work too slowly resulting in the plasma inevitably being lit before it can be cleaned up. + +3. Atmos techs don't play with the rest of the station, preferring to isolate themselves to produce a funny green gas that is only particularly useful for shuttle bombing. Mechanics like this violate the [fundamental design principles](en/general-development/feature-proposals/ss14-fundamental-design-principles.md). While these mechanics shouldn't be removed per-se, more focus should be given to mechanics that increase interactions with the station, like making sure the air is breathable and well-heated. + +## Proposal + +Make atmos more fun and intuitive to play by adding more devices, engines, and processes inspired by SS13 and/or quasi-realism. + +**An atmos tech's primary job is to keep the station livable and breathable.** There are a lot of interesting real life challenges associated with making this happen, not in the least of which is that in space, every gas molecule wants desperately to escape into the cold of space. There is also the challenge of keeping the station appropriately temperature-regulated despite the cold outside and occasional plasma fires inside. There is the opportunity to create a lot of game play by recovering from a breach or a station fire. + +## Core Changes + +Using just the devices that already exist, there are some tweaks that can significantly improve gameplay in atmos by making it possible to effectively respond to events like fires or hull breaches. + +- **Globally increase MaxTransferRate** for devices that are not flow-based, e.g. pumps. + + - This solves problem (2). Among other things, it would make scrubbers and other devices actually useful for combating atmospheric problems. Currently players prefer to just space everything. Increasing this would provide a feasible alternative. + +### Device Design Principles + +Atmos devices should behave intuitively, as one might expect them to behave coming from real life experiences. This means that player should not need to care, or even be aware, about internal abstractions like the "pipe net". Devices should follow the basic principles that: + +1. Energy and matter should be neither created nor destroyed. +2. Gas flows from high pressure to low pressure unless forced by a pump. +3. Temperature transfers from hot to cold. Going the opposite direction requires energy input. + +These principles suggest changes to devices: + +- Instead of having hard transfer rate limits, **scale transfer based on pressure differences.** This means driving gas flow as a result of pressure differences created using pumps external to the device. + + - This addresses an important issue concerning atmos intuition and accessibility. Players should not have to understand the internal workings of the pipe net system (e.g. a pipe is one big node, gases move between them). In real life, a fan or pump creates a pressure difference, and pressure differences drive gas flow. If someone blows on one end of a straw, they can expect it to come out of the other end, not get stuck in the middle of a pipe net. + +- **Add soft clogging (aka pump efficiency curves).** Right now if you have two pumps in series, it is possible for the middle node to appear to be at 0 kPa because the second pump is faster. This leads to confusion and inaccessibility. When pumps get clogged, they also get "hard" clogged which means that they stop pumping altogether. + + - This lets us finally differentiate pressure and volume pumps. Pressure pumps are good at moving smaller quantities of gas across large pressure differentials, while volume pumps are better at moving more volume across smaller pressure differentials. + + - This also improves problem (2) by uncapping transfer rate. + +- **Make heaters and freezers binary.** Just like how central heating and air conditioning circulate air through heat/cold coils, gases should flow across heaters and freezers in order to exchange temperature. + + - Heaters and freezers are the only "true" unary devices. Even vents/scrubbers which appear unary actually operate on flow from the tile atmosphere into the pipe net. + +- **Make heaters and freezers thermodynamically sound.** Keeping a station properly heated or cooled is actually a substantial real-life problem. Because of the existence of generators like the TEG, keeping things thermodynamically balanced is also a great way to prevent infinite power hacks. + +## New Stuff + +This list isn't meant to be exhaustive. Some of the ideas discussed here aren't fully fleshed out. Some of these call for porting mechanics from SS13 with changes as needed/appropriate. + +- **A "substation" but for gas,** "gas manifold", distribution station, or whatever you want to call it. This would encourage distro to be at high pressure (for higher transfer rates) but then gas distribution stations scattered around the station would bring it down to a normal pressure that is released to vents. Adds antag complexity and gives atmos techs more control. + +- **Add gas condensation.** This would enable fractional distillation and permit conversion between gas and the equivalent reagent. + +- **Space heaters** to correct local temperature problems. + +- **Make station air flow-based.** Currently, air vents release air when the pressure is too low, and by default scrubbers only scrub waste gases. So if for some reason the station gets cold, there's no easy way to cycle the air out and heat it up. Of course, one could set all the scrubbers to siphon, heat their distro, and then set the air alarm to fill. But that would just be describing a bad way of doing what real life HVAC systems have always been doing: keep the air flowing. + + - This addresses problem (2) by making it possible to better regulate station temperature. + +- **Adding process-based alternatives to scrubbers and filters.** This calls for adding more gases and gas reactions. For example, with gas reaction-based scrubbing processes, scrubbers with limited uses, or physical processes. + + - This addresses problems (1) and (3) by adding more content that is directly related to the well-being of the station. + + - One of the most pressing challenges in the real world is "how does one separate different kinds of gas." Most current methods of gas extraction are based on chemistry (e.g. real life carbon dioxide scrubbers contain chemicals that react with CO2, pulling it out) or physical methods (e.g. fractional distillation, where one cools down air in different stages to get liquid nitrogen, oxygen, etc.) This creates a lot of opportunity for new game play mechanics and industrial processes. This would also give more opportunities to add gas-based reactions (i.e. more content). + + - This does not advocate for removal of scrubbers and filters, but rather makes it a mapper option, e.g. whether to use scrubbers at round-start or make atmos set up a system depending on the desired level of role-play. + + - When set up correctly, these should have much higher processing rates than scrubbers. This should give an incentive to set these up, e.g. on longer rounds, while still keeping scrubbers as an option. + + - This adds "optimization, tinkering, and creation of intricate builds." + +- **Various QoL improvements** such as the RPD. + +- **More engines**, but the specifics are left out of here to be their own design doc proposals. + +## Wishlist + +These proposals are for the long term future. Some of them require other proposals, e.g. to reduce the dependence on research/cargo, before they should be implemented. + +- **Phase out gas miners for all upstream maps.** It doesn't make sense that all stations have free and plentiful sources of gas, otherwise this might as well be on a planet. This is a game that is literally set in space. It would make sense to keep a few specialty miners, e.g. for plasma, if a station is set on a plasma mining planet. But in general, all other gases should be imported via gas canisters. Miners should still be kept available for any forks that choose to use them. + + - This solves problems (1) and (3). Maintaining a livable atmos would involve work during the round beyond setting up distro to pipe gas from miners. It would help increase interactions with other departments, such as cargo and salvage as atmos needs to order gas. + + - Ensuring a appropriate round-start supply of gas would make the game playable without a functional cargo department. + + - This would discourage fighting fires or atmos problems by wholesale spacing a section. There is currently very little downside to spacing a section to get rid of problems because of an unlimited gas supply. + + - There is [overwhelming consensus on mappers for this](https://discord.com/channels/310555209753690112/770682801607278632/1162179968915210280). + + - As an interim or for very low pop-count maps, keep miners but make them mine gas at low temperature that has to be heated up before use. This preserves a bit of an incentive for atmos players to not space a section at the first sign of trouble. + +- **Add maximum temperature and pressure limits for most devices** such as pipes and canisters. It does not make sense that one can contain the surface of the sun in their pipes. Adding limits would encourage designing processes and systems that work within reasonable constraints. + + - Some "sub-optimal" setups are really unintuitive and wouldn't work in real life due to temperature and pressure limits. + + - There are some concerns about being able to run burn chambers and the TEG. The screenshot below demonstrates a TEG that is capable of powering an entire large-sized station (256.8 kW current output, the peak output is quite a bit higher) with a maximum pressure excursion of 1600 kPa. It shows that pipes that burst at reasonable pressures are entirely consistent with having burn chambers. This just needs to be set up correctly. + + ![image](https://user-images.githubusercontent.com/3229565/274441724-712f4ebf-7440-4d81-879e-19aa29788822.png) + + - This addresses problem (1), the "set up and forget" issue by adding temperatures and pressures to monitor. It also allows the opportunity for sabatoge. + + - This prevents somebody from doing a fusion burn inside a pipe. + + - This would need a station map pipe monitor similar to the new power map. + +- **Breaking windows at high enough tile pressure differences.** To handle explosions and resulting space wind without leaning on the explosion system, and to encourage people to design burn chambers with more controlled burns instead of always putting their pedal to the metal. diff --git a/src/en/proposals/game-director.md b/src/en/proposals/game-director.md new file mode 100644 index 000000000..cb79334a8 --- /dev/null +++ b/src/en/proposals/game-director.md @@ -0,0 +1,210 @@ +# Game Director / Dynamic Event Scheduler + +**Authors:** tom-leys (RecallSingularity) + +## Abstract + +Triggers game events to attain a chaos goal. Goal varies during each round to create variety. +By measuring and varying chaos, the director keeps the challenge each round within a fun band. It reacts to player success +or failure by tailoring future events based on current chaos measured. + +The Game Director adds new game modes, initially CombatDynamic and CalmDynamic. They can only be triggered by an admin +running for instance `addgamerule CalmDynamic`. A later PR could put them into automatic rotation. + +## Background + +Events in SS14 trigger challenges or benefits for players. They might spawn spiders, dragons or zombies. Traitors +come on board, Nukies attack or vents spew grease. Pizza might be delivered or power is turned off to sections of the station. + +Historically events trigger in a few ways: + +- At round start (for instance a zombie or nukie round begins) +- Randomly, every 5 minutes or so (extended rounds) +- Randomly, at an increasing pace (survival rounds, now discontinued) +- Due to admin commands such as `addgamerule` +- Hand created by admins adding entities and using admin tools. + +In the absense of administrator intervention, extended rounds can become boring and monotonous. Zombie or Nukie rounds +are often boring for a period, intense for a period and if the station is saved boring again. + +Due to the random nature of the extended round system, events cannot be too dangerous or too beneficial to the players +or through RNG they are likely to trigger at the worst time. One station might be flooded with spiders, a dragon and space lube +under every vent while another only suffers a few rats and some flickering lights. + +The Game Director aims to provide an alternative to the extended mode that is flexible and drives a fun set of events +towards a larger set of Chaos Goals. A wide array of extreme events both positive and negative can then be added to the game +safe in the knowledge they will be run at suitable times rather than randomly. + +Discord Topic: https://discord.com/channels/310555209753690112/1110002801448329226 +GitHub PR: https://github.com/space-wizards/space-station-14/pull/16548 + +### Car Metaphor + +Imagine you are driving on the highway. You look at the metric of your speedometer to see how fast you are driving. The +speed limit specifies how fast you should go. You then pick either the apply gas, reduce gas or turn on radio events to +best match the car speed to the goal set by the speed limit. The director works in a similar way. + +## Basic method + +- **Chaos** - Metrics we are measuring and controlling with each event +- **Story** - Determines a series of Chaos Goals +- **Metrics** - Estimate the existing chaos on station +- **Events** - Have a predicted effect on chaos +- **Game Director** - Pick best Event to achieve story Metrics + +1. **Wait** until it is time for next event +2. Run **metrics** to measure current **Chaos** +3. Advance **StoryBeat** and **Story** (over time or based on Chaos) +4. Read **desired Chaos** from **current StoryBeat** +5. **Rank** valid events to achieve near desired chaos +6. Run **best event** + +## Chaos - Metrics of a station + +We want to measure how bad the Chaos is right now. If the station is doing well, the lights are on and the floor is clean, +we expect low chaos scores. If the lights are out, the place is spaced and enemies are roaming the station, we want high +chaos scores. + +To best tailor events to the exact situation on the station, chaos is measured by several metrics. +The solution to hunger is pizzas. The solution to enemies might be a squad of reinforcements. A station +that is too peaceful is ready for meteorites, spiders or other hazards. + +A wide range of challenges should be reflected by moderate chaos values for every metric to best challenge all departments +on the station. For instance many new anomolies will keep science busy and potentially annoy other players. But anomolies won't +tax security the same way traitors or spiders would. + +Obvious metrics, where a perfect station has chaos of 0 and it increases as things get messy: +- Hunger +- Thirst +- Anomaly +- Death +- Medical +- Security +- Power +- Atmos +- Mess + +Combat metrics: +- Friend - negative to represent how many friendlies are alive on the station +- Hostile - Score for all antags and monsters +- Combat - Friend + Hostile. <0 if crew is strong. 0 if balanced (fighting). >0 indicates crew is losing. + +## Story - Determines a series of Chaos Goals + +Stories are composed of StoryBeats and determine the Chaos Goals over a 15-30 minute period within a round. + +Beats generally last 5 minutes each, though they might end early if chaos hits certain thresholds. +These are called `endIfAnyWorse` and `endIfAllBetter`, useful if there is too much war, or perhaps too much peace. + +Once a story beat has ended, the director will move to the next beat in the story. Once a given story has finished, the +director will pick one of its stories at random to start. + +Player experience in SS14 should have both its highs and lows. A peaceful extended shift can become boring with no challenges +to overcome together. An overly intense battle might kill half the crew and leave the station in disorder that we cannot recover from. +What we want is a middle ground with some variation. + +The ideal story has a mix of both, with order followed by disorder and then a chance to recover and rebuild. We want variety with +pleasant cycles in intensity potentially building towards an overall climax as the round progresses. + +### Dynamic Game Modes: + +Each game mode preset specifies which stories will run and so determines the tone for the experience created by +the director. + +The number of stories and story beats is quite small right now, as we add more content to the game we will also expand +the range of stories followed by the director to increase the tonal variety between rounds. + +#### CombatDynamic +Contains combat stories and so will create a station with some fighting +- **RelaxedAttack** - Peace -> AttackMild -> EngineeringIssues +- **ScienceAttack** - Peace -> MadScience -> AttackMild -> Peace -> EngineeringIssues -> RepairStation +- **MajorCombat** - Peace -> AttackMild -> EngineeringIssues -> Attackers -> RestoreOrder -> RepairStation -> Peace + +#### CalmDynamic +More like an extended round, has a balance of minor chaos events +- **Relaxed** - Peace -> AttackMild -> EngineeringIssues +- **Science** - Peace -> MadScience -> Peace -> EngineeringIssues -> RepairStation + +### Story Beats +Some beats deliberately drive moderate or high chaos for a period of time. Others bring specific types of chaos to near +0 to encourage the director to pick helpful events until the station is moderate again. + +The hostile story beats tend to end if the station chaos rises too high. The recovery ones end if the chaos drops low +enough. By incorporating both into a story we can expect some hostile events, a period of chaos followed by positive +events and a period of recovery. + +- **Peace** - Minor Chaos across a wide range +- **PowerIssues** - Create high engineering chaos +- **MadScience** - Create high Science chaos +- **Attackers** - Drive high combat +- **AttackMild** - Drive medium combat +- **RestoreOrder** - Send help to quell disorder on the station +- **RepairStation** - Repair that station + +## Metrics - Estimate the existing chaos on station + +A number of systems called "Metrics" are used to summarize the chaos levels. Metrics each stand alone and so it will be +easy to add or remove them as the game matures. + +Metrics could subscribe to relevant events and dynamically adjust their scores as events occur on the station. Or they +can do a single pass through the component system when run. The single pass approach has been preferred in favor of its +stability and simplicity for now. + +#### Metrics at the moment +- **AnomalyMetric** - Are there many? Are they out of control? Writes to "Anomaly" +- **CombatMetric** - Who is on the station? How injured are our friends? Writes to "Hostiles", "Friendlies", "Death" and "Medical" +- **DoorMetric** - Uses doors as a proxy to surveying the ship for danger. Writes to "Security", "Atmos" and "Power" +- **FoodMetric** - How hungry are the friendly crew? Writes to "Hunger" and "Thirst" +- **PuddleMetric** - How messy is the station (partially as a proxy for safety). Writes to "Mess" + +I expect that as we describe a situation we want the Director to react to we will introduce further metrics to give us +richer insight into the station. We might want trust metrics based on how many traitors there are. Or staff / department +metrics based on staffing issues and role deaths. + +## Events - Have a predicted effect on chaos + +How do we describe what an event does? + +Events have a metric called "Chaos" which describes different types of negative effects they bring to the station. +Good events cause negative chaos. + +If our chaos estimates for each event are accurate, the game director can easily control chaos by picking the best events +for the current story beat. + +### Negative events increase chaos +SpiderSpawn: + - Hostiles: 40 - New hostiles are introduced + - Friends: 20 - Friends are likely to die + - Medical: 150 - Medical will have wounds to heal + +### Positive events reduce chaos +PizzaPartySmall: + - Hunger: -80 - The pizza party satisfies hunger + - Thirst: -40 - And also thirst + +## Game Director - Pick best Event to achieve story Metrics + +Each of the **story beats** from above has a matching chaos level, specifying factors that we care about at that point +in the story along with target values for those **Chaos factors**. + +Once we know what **Chaos metrics** we currently attempting to achieve, we have a chance to select the correct event. + +- The **Story Beat** has told us what chaos we want. +- The **Metrics** tell us what chaos the station currently has. +- Each **StationEvent** has a Chaos field predicting that event's impact + +So we iterate through all the possible events, choose the one which moves the station chaos nearest to our goal and set +that event into action. Simple! + +The whole process is richly logged into the admin log (under GameDirector) so the admins have insight into what the director +is attempting to achieve. + +# Conclusion + +The Game Director system will allow us to author specific experiences that are gated on how chaotic the station has become. + +The more events we introduce to the game with clear chaos outcomes, the better the system will be at guiding the station +through a specific narrative experience. + +The data driven nature of the metrics and story data means that a wide variety of narrative outcomes and station-specific +events can all be achieved through the same system. \ No newline at end of file diff --git a/src/en/proposals/genpop_security.md b/src/en/proposals/genpop_security.md new file mode 100644 index 000000000..5c6b02e89 --- /dev/null +++ b/src/en/proposals/genpop_security.md @@ -0,0 +1,55 @@ +# Genpop Security +By ike709 with heavy inspiration from [AndrewMontagne & OracleStation 13](https://github.com/OracleStation/OracleStation/pull/419) + +## Design Goal + +This is a proposal to redesign the flow of throwing criminals in the brig and their subsequent release. Right now prisoners who aren't permabrigged usually have nothing to do during their sentence except hurry up and wait, and security officers usually have no reason to interact with the prisoner until their time is up and they need to be escorted out of security. + +## Current Brig Experience + +The current experience for brigging criminals looks something like this (your mileage may vary by map): + +1. Criminal is arrested by security officer. +2. Criminal is brought to security and strip-searched. +3. Depending on the severity, the criminal is thrown into either an individual brig cell for a few minutes (which is the case for most criminals) or into the permabrig area which (depending on the map) usually allows permabrigged prisoners to interact and/or do things like gardening. +4. When a non-permabrigged prisoner's time is up, the cell door opens and they can collect their belongings, but they are still trapped in the security department due to airlock access until someone lets them out. + +## Turnstiles + +Turnstiles are a key feature in the new brig experience that I'm about to propose. Turnstiles are effectively one-way airlocks, allowing travel only in one direction while still allowing mappers or engineers to set normal airlock access requirements to move through them. Here's what they look like on Oracle, including the mapper overlay to show which direction players can move. + +![turnstile](https://i.imgur.com/QStUhoA.png) + +In this example a player with the relevant access requirements can only move from the north side to the south side of the turnstile. Even ignoring the rest of this design document, turnstiles would still be useful for things such as putting an exit in medbay or being able to leave the disposals room in maintenance. + +## Proposed Brig Experience - Genpop + +I propose that we completely nuke individual brig cells. All prisoners will now be thrown into a large secure area similar to the permabrig (called "genpop") where they can intermingle, kill eachother, or perform various other mapped-in activities like play arcade games or do basic botany. + +Here's an example from OracleStation. Note the turnstiles, the prisoner processing room in the lower part, and the actual genpop prisoner area in the upper part (ignore the armory in the bottom left): + +![genpop](https://user-images.githubusercontent.com/202160/35178888-91bb7eb6-fd87-11e7-9040-15a6ef93602c.png) + +I highly recommend taking a look at the [OracleStation pull request](https://github.com/OracleStation/OracleStation/pull/419) as it has gifs for most of the things I'm about to describe with words. + +This is what the new experience for brigging criminals would look like: + +1. Criminal is arrested by security officer. +2. Criminal is brought to security and strip-searched. +3. Criminal is given a prisoner ID with their name & the length of their sentence. This ID's access is required to pass through the "entrance" turnstile into genpop, to ensure the security officer processed them correctly. +4. Criminal is thrown into genpop with all the other prisoners via the "entrance" turnstile, regardless of their crime severity. Individual brig cells and a separate permabrig no longer exist. +5. The criminal's turnstile access is tied to their prisoner ID. Once their sentence has elapsed, they will now have access on their prisoner ID to pass through the "exit" turnstile from genpop back into the processing area. This means they can leave genpop with no intervention from security officers. +6. The criminal can retrieve their possessions from the locker in processing using their prisoner ID. +7. Using turnstiles, the criminal is able to exit genpop, processing, and the main security department entrance without needing a security officer to open doors for them. + +## Gameplay Implications + +Here's a non-exhaustive list of impacts these changes can have on gameplay, in no particular order: + +- Players no longer need help opening airlocks to exit security when their sentence elapses +- Players now have things to do while they are brigged, whether it's ~~killing~~ interacting with other prisoners or the items/machines mapped in genpop +- Players could escape early by stealing or trading eachother's prisoner IDs +- Wardens are now incentivized to actually keep an eye on the brig and its prisoners to prevent fights/prison breaks/shenanigans +- The brig effectively no longer has a prisoner capacity limit, as individual brig cells are no longer needed +- Security officers can pass through genpop turnstiles at will with their ID access, allowing them to enter/exit genpop without prisoners tailing them to escape + diff --git a/src/en/proposals/grid-inventory.md b/src/en/proposals/grid-inventory.md new file mode 100644 index 000000000..26b7a4015 --- /dev/null +++ b/src/en/proposals/grid-inventory.md @@ -0,0 +1,69 @@ +# Grid Inventory +**Authors:** EmoGarbage + +Credit to the SS13 server Fields of Fire, whose inventory overhaul served as inspiration for the UI. + +## Abstract + +Grid inventory is intended to be a replacement for the current inventory backend and UI. +It encompasses both an internal rewriting of storages, wherein they are classified by geometric shapes, as well as a redesign of the UI, aiming to translate the internal logistics of the system in an immediately understandable way. +Under the system, storages will consist of grids made up of tiles and items will be small items that can be moved around and fit into the grid. + +## Storage Pains + +Laying out what's wrong with the current storage system is important, because inventories--and for the purpose of this document, inventory refers to any given storage container, not the players' hands and clothing HUD--fail in subtle and unexpected ways. +The failures can be divided largely into two categories, mechanical and visual, and both show the unique ways in which a core system can underperform and in turn erode more central mechanics. + +In terms of the mechanical failings, those which call for the rewriting of the core of the system, the most evident is the inability to represent objects of unorthodox or strange shape. +Whether it be a numerical size or an enum, it is impossible to communicate the spacial properties of something like a broom or a life preserver. +Inventories cannot be long and thin or made up of many smaller sections. +There is a lot of genuine interest in nuance in the problem of storing an object: it exists as a microcosm of greater questions of the value of what you carry and if it can be stored in an efficient manner. +As the system exists currently, the "efficiency" of storage is not a concept that can be explored, which is a shame. + +On a more surface level, the presentation and interactions of a list inventory is also laden with issues. +By existing as an infinitely scalable list, containers are forced to express the sizes and capacity numerically, relying on exposing objectively meaningless numbers in order to communicate scale. +Furthermore, lists are bad at displaying images at a scale that is easily understood (due to their properties of being scalable) and thus rely on things like text, which simply saturates what should be a very simply HUD element with lots of text and numbers. +Lists are also frequently used to fill up large chunks of the screen, which genuinely looks terrible. + +Ideally, a perfect storage system should not only be able to handle weird sizes and shapes of containers and items alike, but also visually convey this in a way that is immediately able to be understood by a new player without being overly reliant on text and numbers. + +Thing goes in bag is simple: it should feel simple to do. +It should never feel sprawling or overwhelming or like you're scanning your screen for crap. + +## Grid Inventory + +Our solution? A to-scale HUD element that can represent uniquely shaped item's as well as display the size of things in an immersive and immediately understandable way. + +![](../assets/images/grid-inventory/in-game.png) + +### Items + +Items in grid inventory are a deviously simple. +They retain the ItemSize enum from the current system, but gain an additional `inventory shape`. +This is just the shape the item takes up in the grid and it additionally serves to codify the hidden weight mechanics of the current inventory in a more intelligent way. +Rather than tiny items having a weight value of 1, they simply take up a single square. +Items would have reasonable default sizes inferred from the current weight values of items with an optional specifier for other custom shapes. + +![](../assets/images/grid-inventory/shape-examples.png) + +Inside of the inventory, you'd be able to manually move around and rotate items, allowing gaps to be filled and space optimized with proper planning. +You'd also be able to intuit how much of the inventory an item fills from a simple glance, since the volume is of the container is represented visually. + +### Storage + +![](../assets/images/grid-inventory/grid-example.png) + +For the most part, storages exist as literal translations of the current values. +A 28 capacity simply becomes a 7x4 box. +In terms of balance, the numerical values of the different items and storages remains the exact same. +The only difference is having to place the items into the bag and organize them to potentially make room. + +Of course, putting an item in your bag will automatically try and orient it within the grid, not allowing it only if there's no room for it to fit. +This means there's an equal measure of convenience in terms of picking items quickly, only being a hindrance when trying to fit an unwieldy object. + +The hotkeys for quickly taking items in and out of bags will remain identical, simply remembering the order of inserted items and taking them out in the reverse order. + +### A Brief Aside About Slots + +For slot-based storage, like belts, the UI will remain the same, but simply with standardized item sizes. +A 7 slot belt is a container with 7 squares and every item takes up only a single square. This loses out on the benefits of the scaling, but it integrates well enough and conveys the same information as the previous system, so it's kinda moot. \ No newline at end of file diff --git a/src/en/robust-toolbox/ecs.md b/src/en/robust-toolbox/ecs.md index 9602539fb..abe8ef810 100644 --- a/src/en/robust-toolbox/ecs.md +++ b/src/en/robust-toolbox/ecs.md @@ -96,7 +96,7 @@ flowchart TD ```mermaid flowchart TD - subgraph Cofee Maker Machine + subgraph Coffee Maker Machine Damageable; PowerReceiver; SolutionContainer; diff --git a/src/en/server-hosting/maintenance/debugging-server-lockups.md b/src/en/server-hosting/maintenance/debugging-server-lockups.md new file mode 100644 index 000000000..b8cb3dd37 --- /dev/null +++ b/src/en/server-hosting/maintenance/debugging-server-lockups.md @@ -0,0 +1,234 @@ +# Debugging server lockups + +If `SS14.Watchdog` detects that your server has locked up, it will kill the server and restart it. If this happens for real on a live server, a chance of just looking at logs is out of the window. This guide will give a quick 101 for how to approach debugging this kind of issue. + +```admonish info +Just to be clear: you may get a similar error if the game server can't reach the watchdog due to misconfiguration, in which case the game server will reliably get killed after startup, on loop. This article is not about that, this is about a genuine, real-nasty crash bug. +``` + +## Background: Watchdog Pings + +The watchdog expects the game server to send it regular *ping* messages to indicate that the game server is still alive. The game server sends these pings at a regular interval of 15 seconds (currently unconfigurable, what was past me thinking), and the watchdog expects one at least every *`TimeoutSeconds`* in the instance configuration. If the game were to get stuck in an infinite loop of some kind, it would cease to send these pings and the watchdog would quickly kill it and restart it. + +## Alright, so what have we got? + +If you want to trigger this real easy, connect to your server and run something like this in `scsi`: + +![scsi prompt about to run 'while (true) { }'](../../assets/images/hosting/scsi-while-true.png) + +Expanding the log excerpt from above, we have something like this: + +``` +[WARN] net.ent: Got late MsgEntity! Diff: -12, msgT: 0, cT: 12, player: PJB +[WARN] eng: MainLoop: Cannot keep up! +[22:50:20 WRN SS14.Watchdog.Components.ServerManagement.ServerInstance] test: timed out, killing +[22:50:20 INF SS14.Watchdog.Components.ServerManagement.ServerInstance] test: making on-kill process dump of type Normal +[createdump] Gathering state for process 91738 Robust.Server +[createdump] Writing minidump to file /home/luna/ss14_watchdog_test/instances/test/dumps/dump_2023-10-24_22-50-20 +[createdump] Written 120233984 bytes (29354 pages) to core file +[createdump] Target process is alive +[createdump] Dump successfully written in 306ms +[22:50:20 INF SS14.Watchdog.Components.ServerManagement.ServerInstance] test: Process dump written to /home/luna/ss14_watchdog_test/instances/test/dumps/dump_2023-10-24_22-50-20 +[22:50:20 INF SS14.Watchdog.Components.ServerManagement.ServerInstance] test: killing process... +[22:50:21 INF SS14.Watchdog.Components.ServerManagement.ServerInstance] test shut down with status ProcessExitStatus { Reason = ExitCode, Status = 137, IsClean = False } +[22:50:21 WRN SS14.Watchdog.Components.ServerManagement.ServerInstance] test shut down before sending ping on attempt 1 +[22:50:21 INF SS14.Watchdog.Components.ServerManagement.ServerInstance] test: Restarting server after exit... +``` + +```admonish info +If you're even reading this page I hope you have enough experience hosting a server to know this, but just to be clear: those two `[WARN]` messages are **not it**. +``` + +The game server itself produced no meaningful logs (as it rarely does in a case like this), all we got to go by is the watchdog killing us. Luckily, the watchdog is configured by default to make a **core dump** of the game server process if it has to kill it, and listed the path dumped to in the log output. + +What is a core dump? It's a file that contains the memory of the process when it crashed. By default, this dump includes enough memory to get stack trace information using a debugger. If you want more, you can change the `TimeoutDumpType` property on the watchdog instance configuration to [one of these values](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/microsoft-diagnostics-netcore-client#dumptype-enum). Be warned that core dumps are quite big, and reporting more info can make them *outright huge*. + +```admonish danger +Core dumps can contain sensitive information from your server (such as database passwords) and should **not** be given to people you do not trust! +``` + +"Ok, so I have a file that weighs a couple hundred megabytes, what do I do with it? Do I drag it into Rider?" Oh you sweet summer child. + +You have two options that I know of to debug this: lldb and WinDBG. One of those is a command-line debugger. The other is a command-line Windows debugger that at least has the courtesy of having a basic UI. Hey, at least you don't need to use gdb! + +```admonish failure +Core dumps are fragile little beings, and by default do not include all the context needed to debug something on their own. In general, it is by far the easiest to debug them if you're debugging them on the system they happened on, and *none of the underlying files changed*, e.g. through game server update. + +With the necessary experience and or/infrastructure (symbol servers my beloved) it is possible to handle them much later or on another system, but that's far outside of the scope of this tutorial and even I don't have experience with that.[^2] +``` + +### Using lldb + +lldb is a decent[^1] debugger for Linux and macOS. Install it: + +```sh +# Or whatever package manager you use 🤗 +$ sudo apt install lldb +``` + +You will also need [SOS](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/sos-debugging-extension). This will extend lldb to make debugging a .NET trace possible: + +```sh +luna@Mimas:~/ss14_watchdog_test +$ dotnet tool install -g dotnet-sos +You can invoke the tool using the following command: dotnet-sos +Tool 'dotnet-sos' (version '7.0.447801') was successfully installed. +luna@Mimas:~/ss14_watchdog_test +$ dotnet sos install +Installing SOS to /home/luna/.dotnet/sos +Creating installation directory... +Copying files from /home/luna/.dotnet/tools/.store/dotnet-sos/7.0.447801/dotnet-sos/7.0.447801/tools/net6.0/any/linux-x64 +Copying files from /home/luna/.dotnet/tools/.store/dotnet-sos/7.0.447801/dotnet-sos/7.0.447801/tools/net6.0/any/lib +Creating new /home/luna/.lldbinit file - LLDB will load SOS automatically at startup +SOS install succeeded +``` + +Now you are ready to load the core dump into lldb: +``` +$ lldb -c instances/test/dumps/dump_2023-10-24_23-07-16 +Current symbol store settings: +-> Cache: /home/luna/.dotnet/symbolcache +-> Server: https://msdl.microsoft.com/download/symbols/ Timeout: 4 RetryCount: 0 +(lldb) target create --core "instances/test/dumps/dump_2023-10-24_23-07-16" +Core file '/home/luna/ss14_watchdog_test/instances/test/dumps/dump_2023-10-24_23-07-16' (x86_64) was loaded. +(lldb) +``` + +```admonish tip +You're going to want a [cheat sheet](https://github.com/carolanitz/DebuggingFun/blob/d0b21847d1ad1506bbaaded915c1625a21165b9c/lldb%20cheat%20sheet.pdf) for that `(lldb)` prompt. +``` + +At this point you have a native debugger open and you can well and truly debug everything. Hell, if the game server dies due to native crashes, this is also how you'd be debugging it. You can use regular `lldb` commands to do regular native debugging on native modules and whatever. Though it's still not for the heart and may require further setup, e.g. to get symbols for native libraries. + +For some meaningful info out of the *managed* stack trace, we can run the `clrstack` command from SOS: + +``` +(lldb) clrstack +OS Thread Id: 0x172fa (1) + Child SP IP Call Site +00007FFFD245BFB0 00007F15096C2F7B Submission#0+<>d__0.MoveNext() +00007FFFD245C000 00007F150962B9FE System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.__Canon, System.Private.CoreLib]](System.__Canon ByRef) +00007FFFD245C060 00007F150962B940 System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib]].Start[[System.__Canon, System.Private.CoreLib]](System.__Canon ByRef) +00007FFFD245C0A0 00007F15096C2E92 Submission#0.() +00007FFFD245C0E0 00007F15096C2CD3 Submission#0.(System.Object[]) +00007FFFD245C110 00007F150962B06C Microsoft.CodeAnalysis.Scripting.ScriptExecutionState+d__9`1[[System.__Canon, System.Private.CoreLib]].MoveNext() +00007FFFD245C1C0 00007F150962AD2B System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.CodeAnalysis.Scripting.ScriptExecutionState+d__9`1[[System.__Canon, System.Private.CoreLib]], Microsoft.CodeAnalysis.Scripting]](d__9`1 ByRef) +00007FFFD245C220 00007F150962AC50 System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib]].Start[[Microsoft.CodeAnalysis.Scripting.ScriptExecutionState+d__9`1[[System.__Canon, System.Private.CoreLib]], Microsoft.CodeAnalysis.Scripting]](d__9`1 ByRef) +00007FFFD245C260 00007F150962AB6F Microsoft.CodeAnalysis.Scripting.ScriptExecutionState.RunSubmissionsAsync[[System.__Canon, System.Private.CoreLib]](System.Collections.Immutable.ImmutableArray`1>, System.Func`2, System.Runtime.CompilerServices.StrongBox`1, System.Func`2, System.Threading.CancellationToken) +00007FFFD245C320 00007F150962A4CC Microsoft.CodeAnalysis.Scripting.Script`1+d__21[[System.__Canon, System.Private.CoreLib]].MoveNext() +00007FFFD245C500 00007F150962A21B System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.CodeAnalysis.Scripting.Script`1+d__21[[System.__Canon, System.Private.CoreLib]], Microsoft.CodeAnalysis.Scripting]](d__21 ByRef) +00007FFFD245C560 00007F150962A140 System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib]].Start[[Microsoft.CodeAnalysis.Scripting.Script`1+d__21[[System.__Canon, System.Private.CoreLib]], Microsoft.CodeAnalysis.Scripting]](d__21 ByRef) +00007FFFD245C5A0 00007F150962A03F Microsoft.CodeAnalysis.Scripting.Script`1[[System.__Canon, System.Private.CoreLib]].RunSubmissionsAsync(Microsoft.CodeAnalysis.Scripting.ScriptExecutionState, System.Collections.Immutable.ImmutableArray`1>, System.Func`2, System.Func`2, System.Threading.CancellationToken) +00007FFFD245C670 00007F15065AF51D Microsoft.CodeAnalysis.Scripting.Script`1[[System.__Canon, System.Private.CoreLib]].RunAsync(System.Object, System.Func`2, System.Threading.CancellationToken) +00007FFFD245C6D0 00007F15096C2BCA Microsoft.CodeAnalysis.Scripting.Script`1[[System.__Canon, System.Private.CoreLib]].CommonRunAsync(System.Object, System.Func`2, System.Threading.CancellationToken) +00007FFFD245C720 00007F15096A8336 Robust.Server.Scripting.ScriptHost+d__12.MoveNext() [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/Scripting/ScriptHost.cs @ 209] +00007FFFD245C800 00007F15096A79F3 System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Robust.Server.Scripting.ScriptHost+d__12, Robust.Server]](d__12 ByRef) +00007FFFD245C840 00007F15096A795C System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start[[Robust.Server.Scripting.ScriptHost+d__12, Robust.Server]](d__12 ByRef) +00007FFFD245C860 00007F15096A7913 Robust.Server.Scripting.ScriptHost.ReceiveScriptEval(Robust.Shared.Network.Messages.MsgScriptEval) +00007FFFD245C8F0 00007F150658947F Robust.Shared.Network.NetManager+<>c__DisplayClass106_0`1[[System.__Canon, System.Private.CoreLib]].b__0(Robust.Shared.Network.NetMessage) +00007FFFD245C960 00007F1506587964 Robust.Shared.Network.NetManager.DispatchNetMessage(Lidgren.Network.NetIncomingMessage) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Shared/Network/NetManager.cs @ 912] +00007FFFD245CA30 00007F15059608DF Robust.Shared.Network.NetManager.ProcessPackets() [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Shared/Network/NetManager.cs @ 492] +00007FFFD245CBE0 00007F15053F906A Robust.Server.BaseServer.Input(Robust.Shared.Timing.FrameEventArgs) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/BaseServer.cs @ 686] +00007FFFD245CD80 00007F1505963FA4 Robust.Shared.Timing.GameLoop.Run() [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Shared/Timing/GameLoop.cs @ 135] +00007FFFD245D760 00007F150525A0F5 Robust.Server.BaseServer.MainLoop() [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/BaseServer.cs @ 565] +00007FFFD245D7A0 00007F14F9729475 Robust.Server.Program.ParsedMain(Robust.Server.CommandLineArgs, Boolean, Robust.Server.ServerOptions) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/Program.cs @ 78] +00007FFFD245D8E0 00007F14F971B8D2 Robust.Server.Program.Start(System.String[], Robust.Server.ServerOptions, Boolean) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/Program.cs @ 46] +00007FFFD245D930 00007F14F9718901 Robust.Server.Program.Main(System.String[]) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/Program.cs @ 25] +``` + +Now this we can work with! At the bottom is the program main, at the top is *`Submission#0`* which is an internal detail of the C# Interactive that we ran `while (true) { }` in. While I can't show you the IL bytes or C# code in lldb (well I'm sure the former is possible with SOS), I can show you the assembly code which looks like a pretty simple infinite loop: + +``` +(lldb) disassemble -s 0x7f15096c2f72 -F intel + 0x7f15096c2f72: nop + 0x7f15096c2f73: nop + 0x7f15096c2f74: mov dword ptr [rbp - 0x1c], 0x1 +-> 0x7f15096c2f7b: nop + 0x7f15096c2f7c: jmp 0x7f15096c2f72 +``` + +I hope this helped getting started using a native debugger on stuff like this. + +### Using WinDBG + +WinDBG is the Windows debugger you pull out when all else has failed (which it has, here). [You can get WinDBG Preview from the Microsoft Store.](https://www.microsoft.com/store/productid/9PGJGD53TN86) + +You will also need [SOS](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/sos-debugging-extension). This will extend WinDBG to make debugging a .NET trace possible: + +``` +C:\Users\Luna +> dotnet tool install -g dotnet-sos +Skipping NuGet package signature verification. +You can invoke the tool using the following command: dotnet-sos +Tool 'dotnet-sos' (version '7.0.447801') was successfully installed. +C:\Users\Luna +> dotnet sos install +Installing SOS to C:\Users\Luna\.dotnet\sos +Creating installation directory... +Copying files from C:\Users\Luna\.dotnet\tools\.store\dotnet-sos\7.0.447801\dotnet-sos\7.0.447801\tools\net6.0\any\win-x64 +Copying files from C:\Users\Luna\.dotnet\tools\.store\dotnet-sos\7.0.447801\dotnet-sos\7.0.447801\tools\net6.0\any\lib +Execute '.load C:\Users\Luna\.dotnet\sos\sos.dll' to load SOS in your Windows debugger. +SOS install succeeded +``` + +You can load the created dump file into WinDBG by going File -> Start debugging -> Open dump file, then selecting the file. If the file doesn't have an extension, you need to change the filter on the open dialog to select it. + +![Showing the navigation in WinDBG to open dump file](../../assets/images/hosting/windbg-open.png) + +You will need to run the `.load` command mentioned in the above output to load SOS: + +``` +0:000> .load C:\Users\Luna\.dotnet\sos\sos.dll +``` + +```admonish tip +You probably still want a proper cheat sheet for WinDBG Preview. It has a bit of UI, but usage of the internal command line is still very necessary. Anyways I couldn't find anything like the well-formatted lldb one in 5 seconds of searching online, so find one yourself I guess. +``` + +I won't repeat myself from the lldb side: you have a full native debugger. This can do everything, if you know how to use it. + +You can use `!clrstack` to show the managed stack trace: + +``` +0:000> !clrstack +OS Thread Id: 0x9034 (0) + Child SP IP Call Site +000000F7BF57D0F0 00007ffab591c72a Submission#0+<>d__0.MoveNext() +000000F7BF57D150 00007ffaf84334b8 System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.__Canon, System.Private.CoreLib]](System.__Canon ByRef) +000000F7BF57D1B0 00007ffab591c642 Submission#0.() +000000F7BF57D220 00007ffab591c484 Submission#0.() +000000F7BF57D270 00007ffab4bb043c Microsoft.CodeAnalysis.Scripting.ScriptExecutionState+d__9`1[[System.__Canon, System.Private.CoreLib]].MoveNext() +000000F7BF57D330 00007ffab4bb0113 System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.CodeAnalysis.Scripting.ScriptExecutionState+d__9`1[[System.__Canon, System.Private.CoreLib]], Microsoft.CodeAnalysis.Scripting]](d__9`1 ByRef) +000000F7BF57D3A0 00007ffab4bb0040 System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib]].Start[[Microsoft.CodeAnalysis.Scripting.ScriptExecutionState+d__9`1[[System.__Canon, System.Private.CoreLib]], Microsoft.CodeAnalysis.Scripting]](d__9`1 ByRef) +000000F7BF57D3E0 00007ffab4baff72 Microsoft.CodeAnalysis.Scripting.ScriptExecutionState.RunSubmissionsAsync[[System.__Canon, System.Private.CoreLib]](System.Collections.Immutable.ImmutableArray`1>, System.Func`2, System.Runtime.CompilerServices.StrongBox`1, System.Func`2, System.Threading.CancellationToken) +000000F7BF57D490 00007ffab4baf932 Microsoft.CodeAnalysis.Scripting.Script`1+d__21[[System.__Canon, System.Private.CoreLib]].MoveNext() +000000F7BF57D680 00007ffab4baf6a3 System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.CodeAnalysis.Scripting.Script`1+d__21[[System.__Canon, System.Private.CoreLib]], Microsoft.CodeAnalysis.Scripting]](d__21 ByRef) +000000F7BF57D6F0 00007ffab4baf5d0 System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib]].Start[[Microsoft.CodeAnalysis.Scripting.Script`1+d__21[[System.__Canon, System.Private.CoreLib]], Microsoft.CodeAnalysis.Scripting]](d__21 ByRef) +000000F7BF57D730 00007ffab4baf4d0 Microsoft.CodeAnalysis.Scripting.Script`1[[System.__Canon, System.Private.CoreLib]].RunSubmissionsAsync(Microsoft.CodeAnalysis.Scripting.ScriptExecutionState, System.Collections.Immutable.ImmutableArray`1>, System.Func`2, System.Func`2, System.Threading.CancellationToken) +000000F7BF57D7F0 00007ffab30cd6b6 Microsoft.CodeAnalysis.Scripting.Script`1[[System.__Canon, System.Private.CoreLib]].RunAsync(System.Object, System.Func`2, System.Threading.CancellationToken) +000000F7BF57D860 00007ffab591c3ba Microsoft.CodeAnalysis.Scripting.Script`1[[System.__Canon, System.Private.CoreLib]].CommonRunAsync(System.Object, System.Func`2, System.Threading.CancellationToken) +000000F7BF57D8B0 00007ffab58f6f0d Robust.Server.Scripting.ScriptHost+d__12.MoveNext() [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/Scripting/ScriptHost.cs @ 209] +000000F7BF57D9C0 00007ffab58f6606 System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Robust.Server.Scripting.ScriptHost+d__12, Robust.Server]](d__12 ByRef) +000000F7BF57DA20 00007ffab58f657c System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start[[Robust.Server.Scripting.ScriptHost+d__12, Robust.Server]](d__12 ByRef) +000000F7BF57DA50 00007ffab58f653c Robust.Server.Scripting.ScriptHost.ReceiveScriptEval(Robust.Shared.Network.Messages.MsgScriptEval) +000000F7BF57DAE0 00007ffab30c3755 Robust.Shared.Network.NetManager.DispatchNetMessage(Lidgren.Network.NetIncomingMessage) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Shared/Network/NetManager.cs @ 810] +000000F7BF57DBA0 00007ffab265bfb7 Robust.Shared.Network.NetManager.ProcessPackets() [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Shared/Network/NetManager.cs @ 439] +000000F7BF57DD70 00007ffab265acea Robust.Server.BaseServer.Input(Robust.Shared.Timing.FrameEventArgs) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/BaseServer.cs @ 683] +000000F7BF57DE20 00007ffab2670b47 Robust.Shared.Timing.GameLoop.Run() [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Shared/Timing/GameLoop.cs @ 135] +000000F7BF57E5E0 00007ffab25d6685 Robust.Server.BaseServer.MainLoop() [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/BaseServer.cs @ 565] +000000F7BF57E610 00007ffaa93f24f0 Robust.Server.Program.ParsedMain(Robust.Server.CommandLineArgs, Boolean, Robust.Server.ServerOptions) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/Program.cs @ 78] +000000F7BF57E6A0 00007ffaa93f12ca Robust.Server.Program.Start(System.String[], Robust.Server.ServerOptions, Boolean) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/Program.cs @ 46] +000000F7BF57E700 00007ffaa93f06f2 Robust.Server.Program.Main(System.String[]) [/home/runner/work/space-station-14/space-station-14/RobustToolbox/Robust.Server/Program.cs @ 25] +``` + +Same as above, again. Wow! + +I hope this helped getting started using a native debugger on stuff like this. + +```admonish note +🤫 I actually used `dotnet dump collect` to get the Windows dump because I was too lazy to set up the watchdog twice just for this article. Works the same, mostly. Hell I'm pretty sure it uses the same underlying library to create the dump as the watchdog! +``` + +[^2]: I tried to open a Linux core dump in WinDBG, which is supported to some degree... but it cried about enough missing files and other pains I gave up. Try moving your watchdog `bin/` folder out of the way and debugging a core dump with lldb... Yeah you get wildly different results huh? + +[^1]: About as good as dev tooling on Linux gets, which is not very great. diff --git a/src/en/server-hosting/setting-up-ss14-watchdog.md b/src/en/server-hosting/setting-up-ss14-watchdog.md index 892218ea0..b686bbbbf 100644 --- a/src/en/server-hosting/setting-up-ss14-watchdog.md +++ b/src/en/server-hosting/setting-up-ss14-watchdog.md @@ -15,6 +15,10 @@ It is also worth going through the custom codebases section, especially if you i Some of it's sort of altered slightly. --> + + [`SS14.Watchdog`](https://github.com/space-wizards/SS14.Watchdog/) (codename Ian) is our server-hosting wrapper thing, similar to TGS for BYOND (but much simpler for the time being). It handles auto updates, monitoring, automatic restarts, and administration. We recommend you use this for proper deployments. ## Setup Process @@ -22,10 +26,12 @@ It is also worth going through the custom codebases section, especially if you i ### 1. Check Prerequisites You need to have: -+ .NET 6 SDK -+ ASP .NET Core 6 Runtime ++ .NET 8 SDK ++ ASP .NET Core 8 Runtime -Both of these can be found at the [.NET 6 download page](https://dotnet.microsoft.com/en-us/download/dotnet/6.0). +Both of these can be found at the [.NET 8 download page](https://dotnet.microsoft.com/en-us/download/dotnet/6.0). + +On Linux/MacOS use your favourite package manager (apt, dnf, pacman, brew etc) according to [Microsoft's installation instructions](https://learn.microsoft.com/en-us/dotnet/core/install/linux). ### 2. Build @@ -38,30 +44,14 @@ git clone --recursive https://github.com/space-wizards/SS14.Watchdog cd SS14.Watchdog # Build the Watchdog. -# The result is placed into: SS14.Watchdog/bin/Release/net6.0/linux-x64/publish +# The result is placed into: SS14.Watchdog/bin/Release/net8.0/linux-x64/publish dotnet publish -c Release -r linux-x64 --no-self-contained ``` -The contents of `SS14.Watchdog/bin/Release/net6.0/linux-x64/publish` can then be copied to some other place. - -### 3. Configure - -Before continuing, it is worth mentioning that the `SS14.Watchdog` executable assumes all configuration (such as `appsettings.yml`) and data is located in the current directory, not the directory the executable is in. - -As such, for simplicity in updating the Watchdog, you should arrange a directory as so: - -``` -bin/ : This is the /publish/ directory previously created. -instances/ : This directory contains one subdirectory for each instance you have defined, i.e.: -instances/ERZ2/ : Directory for game instance ID `ERZ2`. - See "Server Instance Folder" below for details on the insides of one of these. -appsettings.yml : The configuration for the Watchdog. - This should initially be copied from `bin/appsettings.yml`. -``` +The contents of `SS14.Watchdog/bin/Release/net8.0/linux-x64/publish` can then be copied to some other place. -The different aspects to the configuration are listed in the following sections. -### 4. Run +### 3. Run Assuming you've followed the structure laid out above, you simply need to have a terminal at the "main directory", and run `bin/SS14.Watchdog`. @@ -95,7 +85,7 @@ In particular, this can be used to expose the Watchdog outside of localhost with Urls: "http://*:5000" ``` -See the relevant documentation for more details: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-6.0#server-urls +See the relevant documentation for more details: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-8.0#server-urls Be sure to adjust BaseUrl accordingly! @@ -177,15 +167,13 @@ Secondly, you may want to simply force a server to be restarted. These tasks can be achieved with the following commands: -`curl -v -X POST -u myInstance:spooky http://localhost:5000/instances/myInstance/restart` - -`curl -v -X POST -u myInstance:spooky http://localhost:5000/instances/myInstance/update` +`curl -v -X POST -u myInstance:ApiToken http://localhost:5000/instances/myInstance/restart` -Here, `spooky` is the `ApiToken` of the instance `myInstance`. +`curl -v -X POST -u myInstance:ApiToken http://localhost:5000/instances/myInstance/update` ## Update Types -### For Vanilla Servers +### Manifest Update ```admonish info The server still won't automatically be notified of updates, so see above for instructions. @@ -203,36 +191,16 @@ Servers: ManifestUrl: "https://central.spacestation14.io/builds/wizards/manifest.json" ``` -### "Dummy" Update Provider - - - -The "Dummy" update provider will fake an update whenever it is queried, and otherwise simply assume that a server has already been extracted to `bin/`. - -As the Watchdog does not automatically periodically check for updates, the fake updates shouldn't get in the way. - -To configure this, use the following update configuration in your `appsettings.yml`, in the entry for your server instance: - -```yml -Servers: - Instances: - example: - # (skipped...) - UpdateType: "Dummy" -``` - You will have to manually move files around and extract the server binaries. Note that you should not move around or attempt to delete the files of a running server. - ### Jenkins Updates @@ -279,6 +246,29 @@ Servers: JobName: "Star" ``` +### "Dummy" Update Provider + + + +The "Dummy" update provider will fake an update whenever it is queried, and otherwise simply assume that a server has already been extracted to `bin/`. + +As the Watchdog does not automatically periodically check for updates, the fake updates shouldn't get in the way. + +To configure this, use the following update configuration in your `appsettings.yml`, in the entry for your server instance: + +```yml +Servers: + Instances: + example: + # (skipped...) + UpdateType: "Dummy" +``` + ### Custom Auto Updates Not supported, but it should be relatively trivial to edit the code for `SS14.Watchdog` to add support for whatever update mechanism you need. See `UpdateProvider.cs`. @@ -346,6 +336,35 @@ nowish = datetime.datetime.now().isoformat() print(json.dumps({"builds":{nowish: {"time": nowish, "client": {"url": "", "sha256": ""}, "server": {"linux-x64": {"url": "http://localhost:9283/SS14.Server_linux-x64.zip", "sha256": ""}}}}})) ``` +## Systemd service + +To allow the service to automatically start up with the server, you can make a service file. It will look something like this. + +Of course, change it to the actual directory of your watchdog. + +```/etc/systemd/system/SS14.Watchdog.service``` +```toml +[Unit] +Description=SS14 Watchdog +After=network.target + +[Service] +ExecStart=/path/to/SS14.Watchdog +WorkingDirectory=/path/to +Restart=always +# This is used for git method to not fail instantly. +Environment="DOTNET_CLI_HOME=/tmp" + +[Install] +WantedBy=default.target +``` +Now reload your systemd daemon and enable the service as you normally would. + +``` +systemctl daemon-reload +systemctl enable --now SS14.Watchdog +``` + ## General Troubleshooting ### Server keeps restarting every 30 seconds diff --git a/src/en/space-station-14/destructible.md b/src/en/space-station-14/destructible.md index e637a33a5..96efe3def 100644 --- a/src/en/space-station-14/destructible.md +++ b/src/en/space-station-14/destructible.md @@ -39,7 +39,7 @@ public partial class DamageTrigger : IThresholdTrigger /// /// The amount of damage at which this threshold will trigger. /// - [DataField("damage")] + [DataField] public int Damage { get; set; } public bool Reached(IDamageableComponent damageable, DestructibleSystem system) @@ -60,7 +60,7 @@ public partial class PlaySoundBehavior : IThresholdBehavior /// /// Sound played upon destruction. /// - [DataField("sound")] + [DataField] public string Sound { get; set; } = string.Empty; public void Execute(IEntity owner, DestructibleSystem system) diff --git a/src/en/space-station-14/mapping.md b/src/en/space-station-14/mapping.md index 0d399d114..50962d4bf 100644 --- a/src/en/space-station-14/mapping.md +++ b/src/en/space-station-14/mapping.md @@ -1,7 +1,7 @@ # Mapping ```admonish warning -Use a release build of the game. If anything goes wrong, a release build is less likely to crash and lose the work up to your last autosave. +Use a Tools build of the game. If anything goes wrong, a Tools or Release build is less likely to crash and lose the work up to your last autosave. ``` Please refer to the page contents menu on the right to get to the section that best suits your needs. @@ -35,13 +35,14 @@ To test the map: ## With Development Environment A [development environment](../general-development/setup/setting-up-a-development-environment.md) and [Git installation](../general-development/setup/git-for-the-ss14-developer.md) are strongly recommended, so that you can keep your local mapping server up to date and submit [pull requests](../general-development/codebase-info/pull-request-guidelines.md). -### Release Build -If you are using a development enviroment instead of just hosting a local server, make sure to use RELEASE instead of DEBUG mode. This is because DEBUG adds artificial lag (making mapping unpleasant) and crashes more (having more assertions enabled). +### Tools Build +If you are using a development enviroment instead of just hosting a local server, make sure to use Tools instead of Debug/DebugOpt mode. This is because Debug adds artificial lag (making mapping unpleasant) and crashes more (having more assertions enabled). +Additionally be careful to not use Release, which disables development environment tooling and configuration and causes the game to act like a standard server instead of a development environment. If you are launching via a console, you can just use: ``` -dotnet run --project Content.Server --configuration RELEASE -dotnet run --project Content.Client --configuration RELEASE +dotnet run --project Content.Server --configuration Tools +dotnet run --project Content.Client --configuration Tools ``` If you are using an IDE, there will be some other way of setting the configuration. For example, in VS there is simply a dropdown menu: @@ -298,4 +299,4 @@ All maps should also have a docking arm in addition to the arrivals and escape d * Protrude from the station with no immediate obstructions either side of it for at least 20 tiles either side. * This is to allow large ships for events to dock with ease. -* The docking arm should have at least a 2 tile wide docking airlock to allow structures to be dragged through it easily. \ No newline at end of file +* The docking arm should have at least a 2 tile wide docking airlock to allow structures to be dragged through it easily. diff --git a/src/en/ss14-by-example/adding-a-simple-bikehorn.md b/src/en/ss14-by-example/adding-a-simple-bikehorn.md index cfdb2a398..cca2e575a 100644 --- a/src/en/ss14-by-example/adding-a-simple-bikehorn.md +++ b/src/en/ss14-by-example/adding-a-simple-bikehorn.md @@ -194,7 +194,7 @@ namespace Content.Server.Sound [RegisterComponent] public sealed partial class PlaySoundOnUseComponent : Component { - [DataField("sound")] + [DataField] public string Sound = string.Empty; } } diff --git a/src/en/ss14-by-example/basic-networking-and-you.md b/src/en/ss14-by-example/basic-networking-and-you.md index ed5b0a497..430e84b91 100644 --- a/src/en/ss14-by-example/basic-networking-and-you.md +++ b/src/en/ss14-by-example/basic-networking-and-you.md @@ -34,13 +34,13 @@ An example of all of the networking code required for IDCardComponent now, from [Access(typeof(SharedIdCardSystem), typeof(SharedPDASystem), typeof(SharedAgentIdCardSystem))] public sealed partial class IdCardComponent : Component { - [DataField("fullName")] + [DataField] [AutoNetworkedField] [Access(typeof(SharedIdCardSystem), typeof(SharedPDASystem), typeof(SharedAgentIdCardSystem), Other = AccessPermissions.ReadWrite)] // FIXME Friends public string? FullName; - [DataField("jobTitle")] + [DataField] [AutoNetworkedField] public string? JobTitle; } @@ -323,4 +323,4 @@ This isn't going to be a super low-level overview of it or anything, but basical It's quite slow, but it's multithreaded and miles faster than the BYOND equivalent--fast enough to get us >250 players on 20 ticks-per-second, so it's good enough. -As for what this means to you and your code, note that in testing you won't receive states for entities that are too far away, and you may need to think about the special case of what happens when entities go in and out of range, though you don't usually need to worry about it. \ No newline at end of file +As for what this means to you and your code, note that in testing you won't receive states for entities that are too far away, and you may need to think about the special case of what happens when entities go in and out of range, though you don't usually need to worry about it. diff --git a/src/en/ss14-by-example/making-a-sprite-dynamic/porting-appearance-visualizers.md b/src/en/ss14-by-example/making-a-sprite-dynamic/porting-appearance-visualizers.md index 0b3fc8638..0adb3c8d8 100644 --- a/src/en/ss14-by-example/making-a-sprite-dynamic/porting-appearance-visualizers.md +++ b/src/en/ss14-by-example/making-a-sprite-dynamic/porting-appearance-visualizers.md @@ -12,10 +12,10 @@ Here's the full visualizer we're porting: [UsedImplicitly] public class ItemCabinetVisualizer : AppearanceVisualizer { - [DataField("openState", required: true)] + [DataField(required: true)] private string _openState = default!; - [DataField("closedState", required: true)] + [DataField(required: true)] private string _closedState = default!; public override void OnChangeData(AppearanceComponent component) @@ -45,10 +45,10 @@ Component: [RegisterComponent] public sealed class ItemCabinetVisualsComponent : Component { - [DataField("openState", required: true)] + [DataField(required: true)] private string _openState = default!; - [DataField("closedState", required: true)] + [DataField(required: true)] private string _closedState = default!; } ``` @@ -91,10 +91,10 @@ So it'll look like this now: [RegisterComponent] public sealed class ItemCabinetVisualsComponent : Component { - [DataField("openState", required: true)] + [DataField(required: true)] public string OpenState = default!; - [DataField("closedState", required: true)] + [DataField(required: true)] public string ClosedState = default!; } ```