Skip to content

[Funky port] Salvage ruins#5

Open
Terkala wants to merge 11 commits intosyndicate-ss14:masterfrom
Terkala:Salvage_Ruins
Open

[Funky port] Salvage ruins#5
Terkala wants to merge 11 commits intosyndicate-ss14:masterfrom
Terkala:Salvage_Ruins

Conversation

@Terkala
Copy link

@Terkala Terkala commented Mar 16, 2026

About the PR

Added the Salvage Ruins system that has been live on Funky for several months.

This is intended to replace the Debris magnet option, but nothing about this breaks the debris system, it's simply disabled in the YML config of the magnet.

Why / Balance

Salvage Debris are boring RNG of random walls and floors. This system makes it much more dynamic looking, and makes it look like actual pieces of space stations.

There are a number of YML settings to configure the ruins to either spawn smaller, or have better/worse loot, or to use your own specific server's maps for the ruins. It reloads the map on server startup, so if a downstream repo changes the ruin_maps.yml to their own specific server's maps, it will make ruins that look like their own server's destroyed stations. And stay up to date automatically with any map updates.

Technical details

Calling out here that this code IS slightly different from Funky's salvage magnet code. Funky's code also redefines the loot table mechanics a lot, and I left that out here. I also had to change a bit of the back end code about how it generates due to Funky's version still being based on our old pre-Macrocosm codebase. Just wanted to call it out.

A lot was done on the back end to make this performant and not lag the server. Here's the path flow for how the code works:

  1. At server startup, it loads the maps to be used for ruins into memory and builds a costmap from the raw YML of each of the maps. This is essentially an X/Y grid with markers for if there's a wall, window, floor, etc. It ignores any of the items or entities on the map.
  2. When the salvage magnet pulls a ruin, it performs a floodfill on this costmap. The floodfill expands out to mark what floors/walls to load from the map. It then goes to an outer edge of this floodfill (at random) and performs another floodfill. It repeats this 5 times. This gives somewhat irregularly-shaped ruins, due to performing many smaller floodfills rather than one big one.
  3. Next it decides if a wall/window/floor is destroyed, based on RNG when spawning them. Each tile has a chance to spawn broken, which makes it not built onto the map-in-memory of what floor tiles it's going to spawn.
  4. Then it spawns loot/mobs on open floor tiles using the odds system in YML.
  5. Then it spawns the actual grid using normal magnet logic.

This system was 100% created by me, and I specifically am licensing it under MIT for my effort porting it here to Macrocosm.

Media

image

Requirements

  • I have read and am following the Macrocosm Pull Request Conventions .
  • I have added media to this PR or it does not require an in-game showcase.

Breaking changes

Changelog

🆑 Terkala

  • add: Added Salvage Ruins

@Terkala Terkala changed the title Salvage ruins [Funky port] Salvage ruins Mar 16, 2026
Copy link
Contributor

@kipdotnet kipdotnet left a comment

Choose a reason for hiding this comment

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

* [x]  I have added media to this PR or it does not require an in-game showcase.

Please dont check this box if you havent added media. This PR is significant enough to need a media showcase

@Terkala
Copy link
Author

Terkala commented Mar 16, 2026

This implementation had a bit of a frame hitch when grabbing the ruins. Updated to hopefully fix that and add an image to showcase.

@Terkala
Copy link
Author

Terkala commented Mar 16, 2026

It's worth noting that this in its current version spawns it a bit far away from the station, and spawns bigger ruins. But those are both parameters controlled via YAML if people want it to spawn smaller ruins or spawn them closer so salvage has an easier time getting to them.

@taydeo
Copy link

taydeo commented Mar 16, 2026

_Macro or _MACRO?

@Terkala
Copy link
Author

Terkala commented Mar 16, 2026

_Macro or _MACRO?

I thought it was supposed to be '_Macro'. Well crap. Fixed. Also Github hates renaming folders

Copy link
Contributor

@mqole mqole left a comment

Choose a reason for hiding this comment

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

hefty review. sorry

in general, im definitely still a bit ignorant on what lotsa this does, but my general observations are that the cs should definitely be broken down a lot more. its a touch spaghetti in there and using helper methods to break some of this code up would do a lot to make it easier to read.

im not too familiar with the use cases here (uploading map files to make ruins out of i assume? only put that together at the end oops) but it does seem like a bad idea to have so much about what prototypes are defined as what tiles being hardcoded. it would be really nice if there was the potential for people to have an easy time modifying the list of what is considered to be in each category.

take all my other comments with spoonfuls of salt

break;
// Macro start - Adding RuinOffering to the salvage system
case RuinOffering ruin:
option.Title = Loc.GetString("salvage-magnet-ruin");
Copy link
Contributor

Choose a reason for hiding this comment

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

asking someone smarter than me. how do we feel about hardcoded string here. is it worth

Copy link
Author

Choose a reason for hiding this comment

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

I could make it fancier and have it show the name of the station (it actually does that in funky, but I left it out for simplicity/consistency sake, since this pattern makes it look more like the other magnet options). But this is just the link to the FTL file.

using Robust.Shared.Serialization.Markdown.Value;
using Robust.Shared.Utility;

namespace Content.Server.Salvage;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
namespace Content.Server.Salvage;
namespace Content.Server._MACRO.Salvage;

Copy link
Contributor

Choose a reason for hiding this comment

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

remind me to go over these comments a bit later with a fine tooth comb. i definitely want to make sure there is some more clarity on the minutae of what is being changed because i am insane from doing upmerges, but i also dont want to step on toes & this is getting to be a chunky review lol

Copy link
Contributor

Choose a reason for hiding this comment

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

macro dir pls

# Ruin maps that can be used for salvage magnet ruin offerings.
# These maps are used to extract floor and wall tiles using flood-fill.
# Recommended to keep the total number of maps 5 or less. More maps will slow server startup. Make sure the maps selected are mostly station-like
# Avoid any stations that have large amounts of asteroid walls or xeno-walls. The ruin system was not designed to parse those types of maps.
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah this is what i mean with like, allowing people to define their own walls. makes for a quick and easy customisation

Copy link
Author

Choose a reason for hiding this comment

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

Added the ability for people to define their own walls. I'll still keep the customization notes here, since it relies on people properly understanding the system before setting their own maps that don't match this pattern.


- type: salvageMagnetRuinConfig
id: Default
floodFillPoints: 25 #if you increase this, also increase the ruinSpawnDistance, otherwise the ruins will spawn ontop of the magnet
Copy link
Contributor

Choose a reason for hiding this comment

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

it would be nice if cs for distance had some clamps so the computer did the work of increasing distance for you instead of having to do it manual

Copy link
Author

Choose a reason for hiding this comment

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

The problem is that both the floodFillPoints and the floodFillStages combined to make a differently sized magnet pull. And I couldn't figure out a good equation that would approximate the size, since the system is so random (partly by design, because well, it's supposed to have a lot of variation)

@mqole mqole added Licensed All code in this PR is licensed under MIT with permission obtained from all authors. S: Awaiting Changes and removed S: Needs Review labels Mar 17, 2026
@hivehum hivehum added the Category A: Universally Desired all microcosms want this feature. voting must be unanimous agreement label Mar 17, 2026
@Terkala
Copy link
Author

Terkala commented Mar 18, 2026

Pretty sure build error is unrelated

@hivehum
Copy link
Contributor

hivehum commented Mar 18, 2026

Pretty sure build error is unrelated

i'm rerunning it but i'm pretty certain that test fail is related

Copy link
Contributor

@mqole mqole left a comment

Choose a reason for hiding this comment

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

quick glance before i leave for work

Comment on lines +50 to +54
/// Parameters: CostMap, CoordinateMap, WallEntities, WindowEntities
/// CostMap: A dictionary of Vector2i and int. The Vector2i is the position of the tile, and the int is the cost of the tile.
/// CoordinateMap: A dictionary of Vector2i and string. The Vector2i is the position of the tile, and the string is the prototype id of the tile.
/// WallEntities: A list of (Vector2i, string PrototypeId). The Vector2i is the position of the wall, and the string PrototypeId is the prototype id of the wall.
/// WindowEntities: A list of (Vector2i, string PrototypeId, Angle Rotation). The Vector2i is the position of the window, the string PrototypeId is the prototype id of the window, and the Angle Rotation is the rotation of the window.
Copy link
Contributor

Choose a reason for hiding this comment

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

theres a way to do this in syntax for the summary block. i forget what exactly. @FancyPlanks will be able to tell you

break;
case SalvageOffering wreck:
var salvageProto = wreck.SalvageMap;

Copy link
Contributor

Choose a reason for hiding this comment

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

untouch

@hivehum hivehum added the IMP approval This PR has been voted on and approved by IMPstation. label Mar 24, 2026
@portfiend
Copy link
Contributor

i'd appreciate if this PR had a clearer description of what is actually added by it! would help with voting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Category A: Universally Desired all microcosms want this feature. voting must be unanimous agreement IMP approval This PR has been voted on and approved by IMPstation. Licensed All code in this PR is licensed under MIT with permission obtained from all authors. S: Awaiting Changes size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants