Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3mo xeno archeology (first phase) #33370

Open
wants to merge 79 commits into
base: master
Choose a base branch
from

Conversation

Fildrance
Copy link
Contributor

@Fildrance Fildrance commented Nov 17, 2024

About the PR

Re-doing of xeno archeology, mostly done by legendary EmoGarbage.
This PR implements part of https://docs.spacestation14.com/en/space-station-14/departments/science/proposals/xenoarch-redux.html and creation of pathway to fully implementing this design doc, and more possibilities!

Stuff that PR is addressing:

  • interaction with artifact now is much more clear - new artifact UI tells exact story and much easier to understand. Also progression through artifact is clearly visible with neat 'unlocked nodes' indication.
  • new and very neat way to unlock nodes (will create much more different situations!)
  • new ways node activation works makes it easier to use artifacts in civil (or military) purposes
  • artifact graph generation now is parametrizable
  • some effect/trigger code also were moved to shared!

Stuff that PR is not implementing:

  • device to remove or add nodes
  • effect-modifying nodes (like 'activate with offset x', or 'activate 2 times')
  • new triggers and effects (:sadge:)
  • meaningful (non-random, value-based) way that graph generator can use for choosing effect of node
  • Artifact Glue
  • Resequencer
  • Arti-nUKer
  • foam / chemicals effects should have clear description of what they will produce (exact chemical)
  • guide book is not updated. shieeeee....
  • amount of research points is dependent on amount of durability node have in a reverse way (less durability - more points), which contradicts idea from design doc
  • most of 1-time only nodes still have more then 1 durability point (making artifact to have container, making it into a drill etc)

job done:

  • new artifact system (giant refactoring, moved huge chunks to shared, artifact graph API)
  • new artifact generation (quite parametrizable from yml + tests)
  • new artifact analyze console UI
  • migrate artifact triggers
  • migrate artifact effects
  • change artifaxium effect (currently removed, need to clean up and update in separate PR!)
  • clean up old systems / components / prototypes
  • update yml
  • new node scanner

Side effects:

  • Removed artifact crusher activating node (as there is no 'current' node). Maybe we are going to return it in some way shape or form later.
  • Some of effects were separated from one effect with random results to effect with certain result, more predictable stuff
  • Some effects disabled from being chosen on artifact generation to not mess up with new way to activate nodes
  • Artifact does not have 'activate node' action for now (as it is badly blending with new node activation system)
  • Mass destruction evens were removed until value-based graph generation will be introduced
  • All effects now can happen on any node depth (will be changed in next PR)
  • More 'obscure' effect descriptions had to be changed to more direct and easier to understand
  • New point extraction mechanics is... not quite easy to understand
  • Way that nodes are activated after unlocking is not really intuitive at first time

Why / Balance

Implementation of design doc to make archeology more involving, less random, introduce richer system for interactions with artifacts.

Technical details

  • Artifact nodes are entities now. Triggers and effects are bound to it and usually not to artifact itself, which may be confusing in some scenarious
  • XenoArtifactComponent contains references for nodes/segments using NetEntities. Due to this every request for node/edge info requires request to system, which wraps it into nice methods (AddNode, GetNodeIndex, GetNode, GetDirectPredecessorNodes, etc.) but inside it still have to iterate over EntityQuery sometimes to get required node component.
  • Point made above is getting much worse due to UI calling those node-related methods on each Draw! But it somehow holds <_<
  • BaseXATSystem (base type for XenoArtifactTrigger systems) is bound (kinda) to registration of Relay events in SharedXenoArtifactSystem.InitializeXAT - its not obvious, but it works.
  • ReactionEntityEvent was introduced by Emo to bypass most of chemistry stuff for checking artifact triggers.
  • BaseQueryUpdateXATSystem is derived from BaseXATSystem and is generally used for artifacts requiring usage of Update loop in regards of some kind of artifact state - collecting artifact dmg, covering it with gas etc.
  • Graph creation algorythm was made to never re-use different triggers in one artifact. This means that graph node count is limited to max number of different triggers we have. This could be improved by creating some different sub-types of triggers, but currently this problem is not touched.

Media

https://www.youtube.com/watch?v=e-i975ANjNA

Requirements

Breaking changes

All old Artifact-node related components, systems and yml were changed, moved or deleted. New stuff is not 1-to-1 compatible.

Changelog

🆑 EmoGarbage404, Fildrance

  • add: new ui for analysis console, new ui for node scanner. Artifact node activation is now different.
  • remove: artifacts cannot create massive distruction events, become guns or music instruments. Sentient artifacts cannot activate nodes.

Copy link
Contributor

@FairlySadPanda FairlySadPanda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, OK, I've at least gone through 85% of this. I got about as far as the ftl files and skimmed the node generation and traversal code, but otherwise got through everything.

This is like, six different PRs in one; it's a full rebuild of xenoarch that can't live alongside the current xenoarch codebase.

I've gone through and found a lot of codebase nitpicks whilst trying to understand the code, but I think there's simply way too much here for one PR.

It's not helped by the really large amount of systems and code in general. There's a lot of systems for individual types of triggers and effects; I can't help but think a partial class-based approach would be much more readable.

I'll start on actually testing this out tomorrow so I can give UI/UX feedback and generally see if this works out without being RNG hellscape.

OVERALL COMMENTS FROM JUST READING IT:

  1. The "XAT/XAE" jargon is not helpful and doesn't match normal Wizden conventions. "Xenoarch THING Effect/Trigger" is easier to read.
  2. There's a tonne of systems here that do very small amounts of work individually. Feels a bit redundant. Depends on Wizden conventions tho.
  3. Lots of small code quality quibbles, they can entirely be ignored.
  4. This really needs a better strategy to get broken out. I get that Wizden merges are pulling teeth, but this needs a maint to sit down and be able to give it an updoot, and at the moment it took me, a lowly contributor, nearly four hours to eat through, and I've not even checked this code other than compilation and a smoke check yet.

On 4: you're asking for a maint to probably spend at least a day on going over this. I think the best strategy for this is figuring out how to sidecar this into the current codebase and roll out expansions to it to add more effects, before swapping out the current Xenoarch. That shouldn't involve going backward.

Realistically getting this down to like, one trigger, one effect, etc, and worrying about content afterward would be where I'd start.

namespace Content.Client.Xenoarchaeology.Equipment;

/// <summary>
/// This handles...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove redundant docstring (or explain what this class does)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed it, sry :3

if (!TryGetAnalysisConsole(ent, out var analysisConsole))
return;

if (_ui.TryGetOpenUi<AnalysisConsoleBoundUserInterface>(analysisConsole.Value.Owner, ArtifactAnalyzerUiKey.Key, out var bui))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DRY, this is the same work as lines 26-27 using a different entity so make a method.

{

}
public sealed class ArtifactCrusherSystem : SharedArtifactCrusherSystem;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid unneccesary file changes in an already chonky PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sign fine... but please do notice that it took me 20 minutes to enforce remove on last line to perfectly revert changes due to (i think) editor config defaults...

_audio = _ent.System<AudioSystem>();

if (BackPanel.PanelOverride is StyleBoxTexture tex)
tex.Texture = _resCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently just calling random paths is a thing in SS14 UI code but magic strings being elevated up to STATIC_CONST is commonly cleaner.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently just not asserting existence of the file and just going "whoop-dee-doo I guess we'll do something arbitrary" is also common in SS14 UI code :death:

Not your fault; the rot consumes


var comp = _ent.GetComponent<AnalysisConsoleComponent>(owner);
_owner = (owner, comp);
Update((owner, comp));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally avoid cuddling alloc (rows that contain =) with non-alloc work. A whitespace denotes a change in activities.

var foo = "hello world";
Debug.Log(foo);

is fine, but for any more than one alloc de-cuddle.

var foo = "hello world";
foo = $"{foo}!";

Debug.Log(foo);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see that i can use _owner to pass into Update in this line, but overall i'm not 100% sure i understand what you are talking abou there. dotnet have a lot (and i mean A LOT) of tools to optimize code to make stupid shit developers do run better without making them drop readability down. And creating reference for object on current method stack is like 100% not the thing that really worth optimizing Q_Q

/// This is used for an artifact that is activated after a certain amount of damage is dealt.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(XATDamageSystem))]
public sealed partial class XATDamageComponent : Component
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good example of why these need renaming. If you don't read "XAT" this is just a damage-tracking component, not something that triggers something.

XenoarchDamageTriggerComponent is much clearer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this name is bad - true. but.. Unified way of naming actually helped a lot duing development, because whole start of class is just reamarks 'is taht what u are looking for'.
For now i'll rename it XATDamageThresholdReachedComponent

public sealed partial class XATTimerComponent : Component
{
[DataField, AutoNetworkedField, AutoPausedField]
public TimeSpan NextActivation;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only a regular interval and not a random one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't know why Emo left it this way. Maybe better to let it be min-max too?... gonna look into this...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed that thingy, a bit at least...

var targetCoords = Transform(args.Target).Coordinates;

var query = EntityQueryEnumerator<XATDeathComponent, XenoArtifactNodeComponent>();
while (query.MoveNext(out var uid, out var comp, out var node))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's quite a few "if this ever happens, uh, try and trigger this even if it's very far away" effects. This could be messy in some extreme cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elaborate, pls... is this actionable or just the idea of something bad happening in XAT systems?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any more details there? >_> or ideas?

throw new ArgumentException($"node {ToPrettyString(node)} is not present in {ToPrettyString(ent)}");
}

public bool TryGetIndex(Entity<XenoArtifactComponent?> ent, EntityUid node, [NotNullWhen(true)] out int? index)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document public API

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, all of shared methods received loads of xml-doc

if (ent.Comp.NodeVertices[index] is { } netUid && GetEntity(netUid) is var uid)
return (uid, XenoArtifactNode(uid));

throw new ArgumentException($"index {index} does not correspond to an existing node in {ToPrettyString(ent)}");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing a throw here without much in the way of handling above it. A tad spooky.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, i honestly am not sure why its not try-get pattern, i was considering this a problem - but during testing i was REALLY not excited of scenario when some code was adressing invalid index and game would just go along with it and say 'okay, i cannot do that, here is a log that you never going to see, bye!'

I obviously can remake it into try-get, with loads of additional code that will be enforced to make additional checks... i am just not sure i really want that...

@Fildrance
Copy link
Contributor Author

This really needs a better strategy to get broken out. I get that Wizden merges are pulling teeth, but this needs a maint to sit down and be able to give it an updoot, and at the moment it took me, a lowly contributor, nearly four hours to eat through, and I've not even checked this code other than compilation and a smoke check yet.

@FairlySadPanda i was not considering breaking this into parts for several reasons:

  1. i considere that i can 'just finish this up' and not touch the way Emo packed it.
  2. its hard to tear apart - yes, triggers / effects could be whole other PR, but then it just won't work (all effects of 1 artifact should be unique, thus mapping only one we will get only 1 node max on graph). And first PR will still be underable / 4 hour crunch, but without even possibility to test how it actually works.
  3. garbage won't be easy to get thrown away if we will let ALL old systems, UI, ALL old protos alive (it could live for years, thats very bad imo). Emo kinda left some systems alive originally, but overall it still was not 'alive' - as some key protos were changed. I thought it was ok to make a breaking change. I guess we need some word from maintainers on that - just to be sure that we ABSOLUTELY NEED ALL THE OLD ONES.
  4. again, testing (and playtesting) original PR would be impossible (or considering if its balanced), sadly.

All in all, i am too, kinda sad about that PR eating away too much time on review, i spent 4 man-days in sum to just review original Emo work (i was considering if changes are required on every little thing). But i have no idea how to make it better without hurting something in exchange.

@Fildrance
Copy link
Contributor Author

About XAT/XAE convention - we already have old naming convention and as i understand, XAT-XAE was specifically made to be destinguished and not be confused... It honestly makes proto easier to write and read. Other then that i cannot say anything in defence of an idea. I don't think it would be too much work to change it all, if we are confirming it is needed. Maint opinion pls! @chromiumboy ? :D

@FairlySadPanda
Copy link
Contributor

I do think it's a bad naming scheme but breaking the PR apart is probably more important

I might have an idea for this fwiw, it just needs orienting around a feature flag

@Fildrance
Copy link
Contributor Author

Fildrance commented Dec 16, 2024

remarks after playtest with 10+ wizden boiz and galz:

  • filter that controls hand-held only effects is broken last moment somehow
  • its better to play animation WHOLE TIME while it is listening, because that's the most important part - unlocking stage.
  • maybe some simple animation for force-activation of actifact? would be cool.
  • sound effects for successful trigger and for failure (for failed end of unlocking stage).
  • it was considered that gas triggers are occuring too often.
  • gas condenser thing is cool but if it gets 'clogged' by condensing whole canister - u are stuck with only 1 solution... i have no idea how to make it better! DO NOT TOUCH IT ITS FINE, MAKE THEM USE BRAIN
  • node chart is not perfect... there were suggestions to make it rotatable or make it switchable from bottom-to-top to top-to-bottom, but that sounds like a lot of effort for questionable result (we are not going to touch it, its a question of habits, gonna be fine)
  • when rolling initial durability - set max durability, not 'current'. 3/5 roundstart seems wierd.
  • magboot/ sound instrument trigger is broken - they activate all the time even when not close. Maybe lower radius to 1 or 1.5?
  • rad dmg req is too high. Lower it and then check if artifact is self- inflicting radiation if it radiates.
  • it'd be cool if nodes that you CAN unlock currently were somehow highlighted too.
  • it'd be cool if u can add nodes u WANT to activate to node scanner, and scanning also displays what excessive nodes you get and what are u missing (at least numbers?).
  • 10 seconds for activation is sometimes very small, and sometimes very large period. At least make it 15. Maybe make it adjustable? Need to think about that. So in the end - we increment by 5 sec for each trigger player hits correctly, and we are not adding any more if he have something wrong.
  • Maybe its better to fail unlocking right the moment u get invalid set of nodes (disconnected ones, which leads to zero unlocks in the end). But then u could not scan artifact with node scanner and actually see what happund. Need to think about that.
  • Locking old nodes after u unlock new ones seems like interesting strategic thing, but currently it is not. But then again, having all nodes be activatable by 1 touch seems dangerous and bad (LAG?). Maybe at least let extracted amount be maxed on them? Maybe even improve it (as Emo design doc is saying!!!!!!)
  • depth-to-effect based system as a placeholder is kinda must - its really underwhelming with all the random effects we have. THere is basically zero motivation to unlock really hard nodes.
  • There is that hedious PVS bug that latejoiners got - i'm 100% sure its related to branch changes, most likely with some kind of nodes sync... couldn't get it myself but that's a priority problem to fix too

f3
f2
f1
f4

Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot added the S: Merge Conflict Status: Needs to resolve merge conflicts before it can be accepted label Dec 18, 2024
@github-actions github-actions bot added size/L Denotes a PR that changes 1000-4999 lines. and removed size/XL Denotes a PR that changes 5000+ lines. labels Dec 19, 2024
@github-actions github-actions bot removed the S: Merge Conflict Status: Needs to resolve merge conflicts before it can be accepted label Dec 19, 2024
@TheShuEd TheShuEd mentioned this pull request Dec 20, 2024
1 task
@github-actions github-actions bot added Changes: Sprites Changes: Might require knowledge of spriting or visual design. Changes: Audio Changes: Might require knowledge of audio. labels Dec 21, 2024
Copy link
Contributor

RSI Diff Bot; head commit ec338d4 merging into efa76be
This PR makes changes to 1 or more RSIs. Here is a summary of all changes:

Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi

State Old New Status
artifact-activation Added

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A: Core Tech Area: Underlying core tech for the game and the Github repository. A: Science Area: Science department, not including Silicons. Changes: Audio Changes: Might require knowledge of audio. Changes: Map Changes: Might require knowledge of mapping. Changes: Sprites Changes: Might require knowledge of spriting or visual design. Changes: UI Changes: Might require knowledge of UI design or code. D1: High Difficulty: Extensive codebase knowledge required. P1: High Priority: Higher priority than other items, but isn't an emergency. S: Needs Review Status: Requires additional reviews before being fully accepted size/L Denotes a PR that changes 1000-4999 lines. T: Balance Change Type: Balance changes through direct value changes, or changes to mechanics that affect it T: New Feature Type: New feature or content, or extending existing content T: Refactor Type: Refactor of notable amount of codebase T: UI / UX Improvement Type: UI and player facing interactive graphical interfaces
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants