Skip to content

Utilized NetIds to get drops for structures and barricades rather than find by root.#2

Open
Jdance-Media wants to merge 2 commits into
RestoreMonarchyPlugins:masterfrom
Jdance-Media:master
Open

Utilized NetIds to get drops for structures and barricades rather than find by root.#2
Jdance-Media wants to merge 2 commits into
RestoreMonarchyPlugins:masterfrom
Jdance-Media:master

Conversation

@Jdance-Media
Copy link
Copy Markdown

@Jdance-Media Jdance-Media commented Jan 19, 2026

Earlier I discovered that BarricadeDrop.FindByRootFast utilizes GetComponent in order to obtain the BarricadeDrop. Nelson likes to return transforms for new plants and finding barricades in a radius, so this is called fairly often.

By utilizing the NetIdRegistry and therefore its built-in dictionaries, you save 31.64 - 48% in tick speed in comparison to the FindByRootFast way. I've tested this alongside RBMKBlaze in relation to a plugin on LC and it gives a noticeable improvement.

            NetId netId = NetIdRegistry.GetTransformNetId(__instance.transform);
            if (netId == NetId.INVALID)
                return;
             netId.id--;

            BarricadeDrop drop = (BarricadeDrop)NetIdRegistry.Get(netId);

This is the new standard and improved way to get BarricadeDrop from a Transform. Tons of plugins use the old FindBarricadeByRootTransform way and it can be incredibly problematic.

Jdance-Media and others added 2 commits January 19, 2026 14:25
- StructureHelper.ForceDropStructure: dropReplicatedStructure goes
  through ClaimBlock(2u) (StructureManager.cs:445), so drop is at
  counter-1 (transform at counter), not counter-2. The previous value
  pointed to either an unassigned slot or the previous block, returning
  null or an unrelated object.

- BarricadeHelper.FindBarricadeDrop: 'return null' inside the foreach
  exited the whole loop on the first non-registered transform. Changed
  to 'continue' so other results in the radius still get checked.

- RaycastHelper.GetBarricadeTransform(Vector3) /
  RaycastHelper.GetStructureTransform(Vector3): same foreach early-exit
  bug, also changed to 'continue'. Added drop != null check before
  returning so an invalid type cast falls through to the next match.

- TransformBase.UpdatePosition: was calling GetTransformNetId(Transform)
  twice on the same Transform. Single lookup, then try BarricadeDrop
  cast; if null, try StructureDrop cast on the same netId.

- StructureHelper: deleted the commented-out FindStructureDropByPosition
  block (no callers in repo, dead code).
@RestoreMonarchy
Copy link
Copy Markdown
Member

Hey, thanks for the PR, sorry I'm only getting to this now lol.

I pushed a fix commit (6b61e29) directly to your branch with a few small things I noticed while going through it:

1. StructureHelper.ForceDropStructure: counter - 2 was off by one

dropReplicatedStructure internally calls ClaimBlock(2u):

// StructureManager.cs:434
public static bool dropReplicatedStructure(Structure structure, Vector3 point, Quaternion rotation, ulong owner, ulong group)
{
    ...
    NetId netId = NetIdRegistry.ClaimBlock(2u);  // line 445
    ...
}

And ClaimBlock returns counter+1 before advancing the counter:

// NetIdRegistry.cs:28
public static NetId ClaimBlock(uint size)
{
    NetId result = new NetId(counter + 1);
    counter += size;
    return result;
}

So if old counter was N: drop gets N+1, transform gets N+2, new counter = N+2. Drop is at counter - 1, not counter - 2. The -2 was either landing on an unassigned slot or grabbing something from a previous block.

2. BarricadeHelper.FindBarricadeDrop: foreach early-exited on first miss

The return null inside the foreach exited the whole loop the first time GetTransformNetId returned INVALID, so other transforms in the radius never got checked. Changed to continue. Same fix in RaycastHelper.GetBarricadeTransform(Vector3) / GetStructureTransform(Vector3).

3. TransformBase.UpdatePosition: double GetTransformNetId on same Transform

Was calling it twice on the same Transform. Collapsed to one lookup, then try Get<BarricadeDrop> and fall back to Get<StructureDrop> on the same netId. Both work because the offset pattern is the same:

// BarricadeDrop.cs:77
internal void AssignNetId(NetId netId)
{
    _netId = netId;
    NetIdRegistry.Assign(netId, this);                        // drop @ netId
    NetIdRegistry.AssignTransform(netId + 1u, _model);        // transform @ netId+1
    if (_interactable != null)
    {
        _interactable.AssignNetId(netId + 2u);                // interactable @ netId+2
    }
}

// StructureDrop.cs:62
internal void AssignNetId(NetId netId)
{
    _netId = netId;
    NetIdRegistry.Assign(netId, this);
    NetIdRegistry.AssignTransform(netId + 1u, _model);
}

So GetTransformNetId(t) - 1 always points to the drop (whether barricade or structure).

4. Deleted the commented-out FindStructureDropByPosition block

Nothing was referencing it.

Going to run it on a test server to double check everything's good, then merge. Thanks again!

@Jdance-Media
Copy link
Copy Markdown
Author

Whoops, I appreciate the fixes. You understand the concept though. 🤣

It will speed things up though.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants