From 53ec2d43b5879ea9dab10dbfc289ef00a17da7ac Mon Sep 17 00:00:00 2001 From: Albert Snow Date: Mon, 16 Oct 2023 19:36:46 -0500 Subject: [PATCH 01/14] Update setting-up-a-development-environment.md (#81) --- .../setup/setting-up-a-development-environment.md | 5 +++++ 1 file changed, 5 insertions(+) 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 b618c8bb4..0ea9a92f9 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 @@ -132,3 +132,8 @@ Unhandled exception. Robust.Shared.IoC.Exceptions.ImplementationConstructorExcep ``` Uninstall .NET Core SDK x86. Install .NET Core SDK x64. + + +## The client and server aren't available in Visual Studio to configure in Multiple startup projects + +This may be because you opened the project as a folder rather than a solution. Make sure you open it as a solution and click the space station 14 .sln file. From b4c37f29b80158199374b209881b9bbf1d451e8b Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Tue, 17 Oct 2023 17:44:38 -0700 Subject: [PATCH 02/14] Add missing September 9th maintainer meeting notes (#84) --- src/SUMMARY.md | 1 + .../maintainer-meeting-2023-09-09.md | 122 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 src/en/maintainer-meetings/maintainer-meeting-2023-09-09.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 29f4eb9cc..e75d8b3f3 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -175,6 +175,7 @@ Maintainer Meetings ---------------------- - [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) - [2023-08-19](en/maintainer-meetings/maintainer-meeting-2023-08-19.md) - [2023-07-29](en/maintainer-meetings/maintainer-meeting-2023-07-29.md) diff --git a/src/en/maintainer-meetings/maintainer-meeting-2023-09-09.md b/src/en/maintainer-meetings/maintainer-meeting-2023-09-09.md new file mode 100644 index 000000000..6a543c882 --- /dev/null +++ b/src/en/maintainer-meetings/maintainer-meeting-2023-09-09.md @@ -0,0 +1,122 @@ +# Maintainer Meeting (09 Sep 2023) +```admonish info +Any decisions taken in these notes may no longer be applicable. +``` + +**Time:** 09 Sep 2023 18:00 UTC + +**Attendees:** +- ElectroSR +- ShadowCommander +- Sloth +- PJB +- DrSmugleaf +- Notafet +- Julian +- Visne +- faint +- TheQuietOne +- keronshb +- Lank + +## Remove component lifestage properties | metalgearsloth +- Remove component lifestage properties (this is a long-term thing but mainly looking at stopping new code adding checks): +- 90% of the time it's a bandaid for other shitty code +- probably needs removing when we go to struct components in the distant future +- Can probably just check the entity lifestage in most bandaid cases instead anyway +- **Fund it** +- **Most component stuff can just check entity instead, not too hard to remove** +- **Removing entity life stage would be much harder** + +## Remove Component.Deleted | metalgearsloth +- adds unnecessary overhead to some codepaths like TryGetComponent\ / HasComponent\ +- It's really only useful in cases where something is queued but not removed yet but even then I'm kinda suss +- we can probably start investigating after arch port is stable +- **Do it** +- **How are we delaying component changes to the end of the tick some day who knows** + +## Use the pooled collections instead of List\ / HashSet\ etc | metalgearsloth +- Uses the ArrayPool to back the arrays +- Should reduce heap allocsTM +- https://github.com/jtmueller/Collections.Pooled +- we may need to import it anyway for arch +- **Yes in engine, to replace ObjectPool** +- **Don't sandbox Shared pools** +- **Pool objects shouldn't be returned by methods** +- **I don't like it because it makes spaghetti out of memory management, and is basically just a bad bandaid after you give up doing it properly™️** - PJB + +## Arch and performance | metalgearsloth +- We should get AddComp etc to have content start leveraging minimising archetype changes though not sure how we want to handle it. +- any other overloads we could think of + - HasComp, RemoveComp, TryGetComp, EnsureComp +- how do we handle queries i.e. does content cache our existing queries, how do we handle not having .WithAll\ / .WithAny\ / .WithNone\, do we cache arch queries and just have engine relay them, idk) + - **Use query description in engine** + - **If used from content, validate the types that the query handler asks for as Arch doesn't check (it just crashes)** + +## NetEntities and handling unknown entities to the client | metalgearsloth +- NetEntities and handling unknown entities to the client: client may get netentity for something it might not know about yet (due to streaming or whatever else). How do we handle this and what's going to be the best way 3 years from now, e.g. some kind of handle for netentity + entity and entitymanager just updates the field when it comes in? +- Right now client just leaves the entityuid and code just checks for trygetcomp / deleted and it will just suddenly work when the entity comes in but with the entityuids no longer matching (and the entity may not exist yet) this is no longer possible +- Like: +- Do networked comps just store NetEntity? This is kinda ugly and adds dictionary overhead to everything +- Do we somehow put a ref on entitymanager then update it when the gamestate comes in and the entityuid automagically updates? +- **https://discord.com/channels/310555209753690112/900426319433728030/1147795695286362112** + +## Refactoring UpdateBoundStateMessage / whatever the fuck UI is doing to compstates | metalgearsloth +- do we just dump all the data on components +- any data not already comps just dump on a dedicated UI component? +- **"You can scroll two points down for the BUI entities topic"** + +## Changing TryComp\(out var comp) to TryComp(out T comp) for most usages | metalgearsloth +- We had this discussion a long-ass time ago, like 4 years ago +- the latter is shorter +- I preferred it but we ended up using the former +- I think performance is almost identical +- bottom text +- **If we enforce it, enforce it with an analyzer** + +## BUI entities | PJB +- Opening BUI just creates an entity that handles the UI logic. UI data is in that entity's components. We can do composition for various types of behaviors like interaction range. Move it all to content. PVS filter it so only target player has vision over it. One entity per BUI session (player). +- Do we give a shit about optimizing UI states if two players view the same UI? Right now this allows re-using the data but it seems like such a minor thing it's not worth making the system more complex over +- gooey booey looey +- **When you code it, ez clap, we're all in agreement** + +## Disallow using Math and MathF | moony +- and make people use the type-specific functions instead that .NET 7 added +- so for example Math.Pow(x, y) would be double.Pow(x, y) +- Math/MathF are only defined for a limited set of types and are overall a bit more "magical" for what types they allow (due to overloading), so being explicit about the type is cleaner and allows that implied API to be extended (MyNumberType.Pow(x, y) would be what you'd expect to exist instead of initially guessing Math.Pow(x, y)) +- all the functions on Math/MathF have equivalents on the type being operated on for the C# builtin types +- including the constants, so for example float.Pi exists +- also the divide between MathF and Math is just plain confusing most of the time +- **When you write an analyzer for it, for engine only** + +## *"the thrilling case of the missing documentation "* | mirrorcult +- ok can we admit “just ask us for access to edit the dev wiki” is a failed prospect. no one actually knows you can do that and if they do know they dont want to bother with the friction of finding out who to ask and waiting just to submit a fix. as a result the dev wiki is extremely atrophied +- oh my god PLEASE can we move it all to mediawiki or something, i dont care what it is wikijs was a bad idea and i just want something that anyone can edit and add articles to. please +- we really desperately need to do a full audit over the docs, not necessarily like add new stuff rn because i get thats effort but just make sure its up to date information and all useful pages are actually discoverable +- maybe think about mirroring codebase changes to docs site once we get something better like mediawiki. this would probably involve just linking to the docs page in GH and discord as the source of truth +- we REALLY need to make the docfx sites more visible and linked in more places (and docs in general but), discord channels/pins/github/forum/ingame literally everywhere please (and maybe give them better domain names theyre really bad rn) and also + - add a ‘component glossary’ section to docfx which just shows all types that are registered components and what docs/fields they have. like half of the people in <#560845886263918612> ask for something like this and we just have to tell them ‘uhhh look in your IDE’ which is good when they already have the component they're looking for but terrible for when theyre trying to discover potential components they can use for some behavior + - topy was working on this at some point but they are inactive now. if possible just revive their branch we really need this +- **When You Document It** +- **We'll host it for whoever wants to experiment with shit** +- **I saw the search bar on mdbook and I'm convinced** +- **Replace wikijs with mdbook** + +## Early Access Roadmap +- **nothing on this roadmap matters except early access trailer.** +- A trailer for Steam + - Also the >>>>**screenshots**<<<< for steam and the website + - holy shit we have **replays** now +- gamemodes/antags + - dynamic [c#16548](https://github.com/space-wizards/space-station-14/pull/16548) + - revolutionaries [c#18477](https://github.com/space-wizards/space-station-14/pull/18477) + - 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 + + +Crashes / Critical bugs: (when are we moving these to GitHub) +=> till next time +like and subscribe +smash that button +~~did you know only 6% of contribs join this meeting?~~ According to YouTube's statistics, From 318ea595cf621cabeb43882504251edbf6b888f4 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Thu, 19 Oct 2023 12:41:31 -0700 Subject: [PATCH 03/14] Update conventions.md for Entity --- .../general-development/codebase-info/conventions.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/en/general-development/codebase-info/conventions.md b/src/en/general-development/codebase-info/conventions.md index fd2e14906..8dc514cc6 100644 --- a/src/en/general-development/codebase-info/conventions.md +++ b/src/en/general-development/codebase-info/conventions.md @@ -316,10 +316,10 @@ Transform(uid).Coordinates; ### Public API Method Signature All public Entity System API Methods that deal with entities and game logic should *always* follow a very specific structure. -All relevant `EntityUid` should come first. +All relevant `Entity` and `EntityUid` should come first. +The `T?` in `Entity` stands for the component type you need from the entity. +The question mark `?` must be present at the end to mark the component type as nullable. Next, any arguments you want should come afterwards. -And finally, all the components you need from the entity or entities should come last. -The component arguments shall be nullable, and default to `null`. The first thing you should do in your method's body should then be calling `Resolve` for the entity UID and components. @@ -327,11 +327,11 @@ The first thing you should do in your method's body should then be calling `Reso Example (click to expand) ```csharp= -public void SetCount(EntityUid uid, int count, StackComponent? stack = null) +public void SetCount(Entity stack, int count) { - // This call below will set "stack" to the correct instance if it's null. + // This call below will set "Comp" to the correct instance if it's null. // If all components were resolved to an instance or were non-null, it returns true. - if(!Resolve(uid, ref stack)) + if(!Resolve(stack, ref stack.Comp)) return; // If the component wasn't found, this will log an error by default. // Logic here! From 4c8b90d60d93192c5e9459856039e6024603cb71 Mon Sep 17 00:00:00 2001 From: Vasilis Date: Fri, 20 Oct 2023 05:54:35 +0200 Subject: [PATCH 04/14] Make runthis.py troubleshooting a bit more friendly (#80) --- .../setup/setting-up-a-development-environment.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 0ea9a92f9..717ae7c75 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 @@ -25,9 +25,9 @@ If you're **unfamiliar with Git**, or just don't know how to proceed, follow the We have an automatic submodule updater so you don't have to worry about running `git submodule update --init --recursive` all the time. -Run `RUN_THIS.py` inside the repo you downloaded with Python. Preferably from a terminal too. This should take a few seconds so if it instantly stops you probably aren't using Python 3.7+ or something. Try checking out the troubleshooting at the bottom of this page. +Run `RUN_THIS.py` inside the repo you downloaded with Python. Preferably from a terminal too. This should take a few seconds so if it instantly stops then check if you are running Python 3.7+ otherwise keep reading. -**If running `RUN_THIS.py` immediately opens and closes a window: do not worry.** This does not mean that it failed. The script closes automatically upon completion, so if you want to verify that it worked properly, check the submodule `/RobustToolbox/` and verify that all the files are there. +**If running `RUN_THIS.py` immediately opens and closes a window: do not worry.** This does not mean that it failed. The script closes automatically upon completion, so if you want to verify that it worked properly, check the submodule `/RobustToolbox/` and verify that all the files are there. If not try checking out the troubleshooting at the bottom of this page. Note: If you have any issues when getting started with missing files it's recommended you run `git submodule update --init --recursive` by hand once in case something went wrong with python. From f9e76c3de4ec93ddc47eb7cd596a20b4d178b1a1 Mon Sep 17 00:00:00 2001 From: Vasilis Date: Sun, 22 Oct 2023 20:20:20 +0200 Subject: [PATCH 05/14] PDA messaging proposal [Julian, VasilisThePikachu] (#76) This is based of Julians PDA messaging proposal with some little tweaks. Looking into getting this heavily scrutinised as I was just throwing some of my own ideas in there and Julians doc is a little old so i dunno if anything is missing. --- src/en/proposals/pda-messaging.md | 109 ++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/en/proposals/pda-messaging.md diff --git a/src/en/proposals/pda-messaging.md b/src/en/proposals/pda-messaging.md new file mode 100644 index 000000000..8766a2fb1 --- /dev/null +++ b/src/en/proposals/pda-messaging.md @@ -0,0 +1,109 @@ +## PDA messaging program and server + +[Julian, VasilisThePikachu, Unapproved] + +*(Taken by [Julian doc](https://hackmd.io/iu2yK9bcQb-veuCOLl-FYw?both#Optional-Channels-and-Department-based-Channels) in hackmd and modified a lil. Mostly replacing "email" to "message", "Email address" to "user/user id" and adding some of my own twists. Julian was fine with this if i understood correctly (i was in vc with em))* + +*(This is mostly taken from how PDA messages work in ss13)* +Allows sending messages to others using PDAs + +### What this adds and why +Simple, Messaging via the PDA! +Messaging someone via the PDA should be made when you need to get the attention of a special someone. Example as HoS you want to ask detective to come over to investigate an item. It's easier to get their attention cause of their PDA vibrating then hoping they are monitoring their channel. Another usage is the heads planning Captain a suprise birthday party. Something like that would require all heads getting together in one place. + +This is **not** a replacement to the radio channel. Theres no "common" channel, it would be easier to spoof being someone (just need their id), past messages on that same id can easily be exposed and its far more cumbersome to message someone over PDA then just using the radio. + +### Message storage +Messages are stored on a server most likely will be stored in telecoms. There can be one server per station, others on the same station won't be used unless the first one loses power or gets destroyed. + +*Optional* The active server synchronises itself with all of the inactive servers on the same station (This happens inside the system directly, no device networking here). + +### One active / Multiple inactive server model + +(This talks about some refactor stuff and Julian told me they forgot to paste the link, im keeping it to be safe in case its actually useful.) + +The one active / multiple inactive server model uses the system that will get refactored into its own system from the crew monitoring server [link text]() + +The messaging client system will use the `GetActiveServer` method of the message server system to retrieve the active server if the client doesn't have a server set yet or that server timed out. *This is also from the system that gets refactored out.* + +### Sending and receiving messages + +When sending a message to someone via the program the PDA sends the message together with an 'user id' to the server and the server will send the message to the target device. Of course there will be a character limit (say... 100 characters?) + +When a PDA recieves a message it plays the PDAs ringtone and vibrates, showing the sent message on the chat. This message can also be viewed on the PDA via a program. + +Notifications can be disabled if desired. + +This user id could be generated into the ID card so that if you get a new PDA your messages are kept as long as you are using the same ID card. Late joiners will get assigned a uid when they arrive on the station. Potencially HoP or RD can move your UID to the a new ID card with the ID comnputer rendering the old ID card useless. This can also prevent powergaming by someone changing their UID to see others messages. + +This UID will receive messages for as long as it is in the station and in a PDA. + +If its not in station the messages can either fail to send or be added in a queue to be sent when it reenters the station. + +Since the UID is stored on the ID. That means that if you manage to get your hands on someones ID you can chat as them and potencially (if added) read their messages. + +### Users list + +When opening the PDA messaging app, you will be able to start a chat session with everyone connected to the server (aka everyone with a PDA) + +They will be listed by name and job title like this "Vapor-Tail (Captain)" + +*Optional* Add the ability for people to not be allowed to initiate a conversation with an option. This can be useful for high command staff like captain from getting message spammed by clown and others at the start of the shift. + +### Optional: Detomatix PDA Cartridge + +(find the original item in the tg wiki here: https://tgstation13.org/wiki/Syndicate_Items) + +The detomatrix is... a zip bomb in easy to say terms. Allowing you to send a spoofed message that when opened by the target fast enough bricking the PDA and its ID (instead of exploding... even though thats funnier maintainers please allow this) + +It will have a chance to fail and have an even lower chance of working on "high profile" PDA's like the Captains. + +It could be used as a way to get people to turn off their messanger function in fear to not being up next if someone screams in radio about it and could be useful. + +### Optional: Multiple network support + +The server is able send on the wireless and the wired network because it saves what network the registered devices are on along with the user id and the network address. + +This requires devices to be able to register themselves with two device net ids at once (which should only be done if it is really needed). + +### Optional: Channels and Department based Channels +Channels are special groups that relay the messages sent to them to users who are subscribed to that channel. + +Channels can be created and they can be deleted by the channel creator. + +When registering to a server the client also sends the job of the inserted ID so the server can put them into special department channels. + +Department channels can't be joined, left or deleted. + +### Optional: RDs messager admin management console +The research director and potencially Captain get a console which connects to the message server via device net that can be used to view and manage all messages and groups. +It uses device net with an `AccessComponent` on the message server so the management functions can be hijacked by traitors that got their hands on an ID card with the right access. (This requires [device net access restrictions](https://hackmd.io/gPjP95_zRUiT-bX4hKxE6w) to be implemented. + +### Optional: pAI as a chat assistant. +This will add new gameplay for the pAI ghost role. Allowing the pAI to chat as their master on their behalf. Could have a little pAI icon in the chatbox to show it was sent by the pAI and not the actual player. pAI's for a while have been kinda boring and may deserve their own design doc of ideas but this is one of my ideas that come to mind. + + +### Concerns +When initially asked about this I was met with some concerns. This section is to address them + +Discord discussion start: https://discord.com/channels/310555209753690112/310555209753690112/1160244698112327830 + +##### Why PDA messaging over plain radio? Would this upset radio balance and reduce coms over radio? +First of all why: +If you play the game you can quickly realise how getting someone's attention god forbid multiple, can be... not an easy task to say the least. You either are lucky and the person you want is just so happening to be monitoring the chatbox or they are busy and not paying attention. In the end missing your message until you resend it or try to look with them. This is just not fun and is just annoying. PDA messaging can solve this. + +As to if it will upset radio balance: Highly unlikely it will be. Mostly cause: +1. PDA messaging wont let you get the attention of multiple people at once (common). PDA messaging can reach one person at the time (unless we get department groups but even then). You will have to jump through a lot of hoops if you JUST wanna use messaging. Radio is easier and faster to talk into and gets to multiple people at once. +2. Sending a PDA message is more of a chore then just using the radio channel, PDA messaging will at least need a minimum of 6 steps to open the PDA, go to the app section, start the app, find the person, write the message and send. And if you keep the chatbox on it would just take up a good chunk of your screen. Or you could just do ":c Captain hamlet ate uranium" +3. Messages are stored and logged. Someone steals caps PDA? Well now all of their messages are up on display. With radio unless they had command channel already they would never learn of any past messages. If two syndies decide to use PDA messaging rd can just grab their chatlogs. Same with syndies using it to communite with others. +4. PDA messaging has a pretty small character limit, if you wanna say something long radio is the place. + +May be the wrong section but admins can also use this to act as "Central Command" so instead of having to subtile message someone they can just send a message to their PDA. + +##### It reduces everyone else's situational awareness since people can't see all radio messages anymore. +I highly disagree, I doupt it will reduce situational awareness more then it already is. I have already went over how someone monitoring the radio channel for messages directed to them is already a chore. PDA messaging names can easily be changed by using someone elses ID therefore its a good idea to not go to maints like they told you to and instead show the message to security. + +##### Why not use fax? +Is this really a question? First of all not everyone has a fax, second you have to be close to hear it go off printing. And unless you check your fax periodicly for new faxes messages can be missed. And even if you do check it its probably boykisser ASCII spammed 10 times. Also why are we using *faxes* in 2563 or whatever year SS14 takes year in. + +These were all the conserns I could find from discord. From 6f728f803136a7ef3cb9be109c89eb8a4a5caded Mon Sep 17 00:00:00 2001 From: Kevin Zheng Date: Sun, 22 Oct 2023 20:46:50 -0700 Subject: [PATCH 06/14] Link approved design docs --- src/SUMMARY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index e75d8b3f3..5fa6f76da 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -117,6 +117,9 @@ 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) ---------------------- From b65c7c437a952fa37747659ae60d3142508b280e Mon Sep 17 00:00:00 2001 From: Kevin Zheng Date: Sun, 22 Oct 2023 21:08:40 -0700 Subject: [PATCH 07/14] Add feature proposal template --- .../general-development/feature-proposals.md | 8 +++++-- src/en/proposals/proposal-template.md | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/en/proposals/proposal-template.md diff --git a/src/en/general-development/feature-proposals.md b/src/en/general-development/feature-proposals.md index 5e17ea20c..478b5f0f0 100644 --- a/src/en/general-development/feature-proposals.md +++ b/src/en/general-development/feature-proposals.md @@ -4,9 +4,13 @@ If you are considering adding or reworking some major component of the game it's ## How do I make a proposal? -Just follow [our guide](../meta/guide-to-editing-docs.md) on editing any part of this site and PR your proposal as a page under the "Design Proposals" section found in the sidebar between "Space Station 14" and "Server Hosting". +1. Make a copy of the design proposal template located at `src/en/proposals/proposal-template.md`. -Proposals that get approved by a maintainer will be merged to this site, which is basically the green light for you or someone else to go ahead and implement it. +2. Write your proposal (see [guide to editing docs](../meta/guide-to-editing-docs.md)). + +3. When you are ready for your proposal to be reviewed, make a pull request. + +4. Your proposal is approved when a maintainer merges it. This is a green light for you or someone else to go ahead and implement it. A maintainer will then link your proposal to the side bar. *Note to maintainers: edit `src/SUMMARY.md`* ``` admonish tip "Unfinished Proposals" If you don't think that your proposal is ready for maintainer scrutiny, but still want feedback on it you can PR it as a draft. Drafts are less likely to attract people looking to get down to brass tacks, but still let people comment and give advice. diff --git a/src/en/proposals/proposal-template.md b/src/en/proposals/proposal-template.md new file mode 100644 index 000000000..c22ae575e --- /dev/null +++ b/src/en/proposals/proposal-template.md @@ -0,0 +1,24 @@ +# Short, Properly Capitalized Title + +Your title should convey the basic jist of your proposed changes. It should be short because the text will be linked in the sidebar. + +**Authors:** foo, bar + +The names that you use on GitHub and/or Discord. This is optional but strongly recommended, since: + +- This acknowledges credit where it is due +- People who are confused about the written intent can use this information to contact the authors + +## Abstract + +A very short, maybe three sentence summary of what this proposal is about. A high level "overview" or "what this adds". + +## Background + +Summarize any information that is needed to contextualize the proposed changes, e.g. the current state of the game. + +Also link any relevant discussions on Discord, GitHub, or HackMD that are relevant to the proposal. + +## The rest? + +Is entirely up to you. From d6dc59be80a34ce8a3284ecf109105ddf7f42399 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 25 Oct 2023 00:31:56 +0200 Subject: [PATCH 08/14] Basic article about debugging watchdog dumps --- src/SUMMARY.md | 2 + .../assets/images/hosting/scsi-while-true.png | Bin 0 -> 21174 bytes src/en/assets/images/hosting/windbg-open.png | Bin 0 -> 86607 bytes .../maintenance/debugging-server-lockups.md | 234 ++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 src/en/assets/images/hosting/scsi-while-true.png create mode 100644 src/en/assets/images/hosting/windbg-open.png create mode 100644 src/en/server-hosting/maintenance/debugging-server-lockups.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 5fa6f76da..cca0e8136 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -135,6 +135,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 ============== 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 0000000000000000000000000000000000000000..48e0e6ea3ad75bba83a28f1fa780769830caf07e GIT binary patch literal 21174 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 OsbA8*n0w(?;Qs+n@bD%8 literal 0 HcmV?d00001 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. From cd06526a729f8366007113d0848c0ac8d9e1b15d Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 25 Oct 2023 00:50:26 +0200 Subject: [PATCH 09/14] Fix example error in docs example page I spent more time than I should've to notice why the code I copy pasted didn't work --- src/en/meta/docs-example-page.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ``` `````` From 3e58a78bd4e3ff01a6c2f87d78bc0bf4a732c55c Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sat, 28 Oct 2023 04:09:05 +0200 Subject: [PATCH 10/14] Add redirect for port forwarding guide (#92) --- book.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/book.toml b/book.toml index 4e8865d84..50f6ad0f7 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" From 74045725a50efd6aa71ada975686cf412ddfd566 Mon Sep 17 00:00:00 2001 From: ike709 Date: Fri, 27 Oct 2023 23:37:56 -0700 Subject: [PATCH 11/14] Genpop Security Design (#87) --- src/SUMMARY.md | 2 ++ src/en/proposals/genpop_security.md | 55 +++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/en/proposals/genpop_security.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index cca0e8136..43e98400f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -123,6 +123,8 @@ Design Proposals ---------------------- +- [Security Genpop Rework](en/proposals/genpop_security.md) + Server Hosting ============== 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 + From 62e102d822ec9a925a8d086627506435e68efa75 Mon Sep 17 00:00:00 2001 From: ike709 Date: Sat, 28 Oct 2023 16:23:29 -0700 Subject: [PATCH 12/14] Fix the Design Proposals splitter in SUMMARY.md (#96) --- src/SUMMARY.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 43e98400f..1494c3ba1 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -117,12 +117,12 @@ 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) ---------------------- +- [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) Server Hosting From 52b42fb62b4f135d250ce39966ff2539a51e5893 Mon Sep 17 00:00:00 2001 From: Kara Date: Sun, 29 Oct 2023 19:52:09 -0700 Subject: [PATCH 13/14] apparently hub rules had 2 valid pages ?? --- book.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/book.toml b/book.toml index 50f6ad0f7..10586853b 100644 --- a/book.toml +++ b/book.toml @@ -118,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" From 821b1129c7dc1fb72ed76a1652bf29dc3ef9d643 Mon Sep 17 00:00:00 2001 From: Tom Leys Date: Mon, 30 Oct 2023 18:54:30 +1300 Subject: [PATCH 14/14] Add proposal: Game Director (#95) --- src/SUMMARY.md | 2 + src/en/proposals/game-director.md | 210 ++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 src/en/proposals/game-director.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 1494c3ba1..c78ea644f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -124,6 +124,8 @@ Design Proposals - [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) + Server Hosting ============== 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