Skip to content

Custom InnerNetObjects - #92

Open
D1GQ wants to merge 20 commits into
NuclearPowered:masterfrom
D1GQ:master
Open

Custom InnerNetObjects#92
D1GQ wants to merge 20 commits into
NuclearPowered:masterfrom
D1GQ:master

Conversation

@D1GQ

@D1GQ D1GQ commented Mar 23, 2025

Copy link
Copy Markdown

Introducing Custom InnerNetObjects


This PR introduces a set of improvements to make working with custom InnerNetObject easier, and more intuitive. The changes include:

  1. Comprehensive XML Documentation:

    • Added detailed documentation for key methods to improve code clarity and developer experience.
    • Examples and usage instructions are provided to help developers quickly integrate custom InnerNetObject prefabs.
  2. Utility Methods for Prefab Handling:

    • Added methods like GetNetObjPrefab<T>, SpawnNewNetObject<T>, and SpawnNetObject to simplify the process of retrieving, instantiating, and spawning custom InnerNetObject prefabs.

Key Changes:

1. GetNetObjPrefab<T>

  • Purpose: Retrieves the prefab for a custom InnerNetObject of type T.
  • Usage:
    var prefab = InnerNetObjectManager.GetNetObjPrefab<MyCustomObject>();

2. SpawnNewNetObject<T>

  • Purpose: Spawns a new InnerNetObject locally and on the network of type "T".
  • Usage:
    var newObject = InnerNetObjectManager.SpawnNewNetObject<MyCustomObject>(ownerId: 1, spawnFlags: SpawnFlags.None);

3. SpawnNetObject<T> (Extension Method)

  • Purpose: Spawns an existing InnerNetObject instance on the network.
  • Usage:
    var existingObject = new MyCustomObject();
    existingObject.SpawnNetObject(ownerId: 1, spawnFlags: SpawnFlags.None);

@Pietrodjaowjao

Copy link
Copy Markdown
Contributor

i just dont get the InnerNetObject attribute, it seems really unecessary since this can be done by checking subtypes in the assembly

@Galster-dev

Copy link
Copy Markdown
Contributor

I think example class should be an actual simple example of what you can do with this instead of just a stub.

@D1GQ

D1GQ commented Mar 23, 2025

Copy link
Copy Markdown
Author

i just dont get the InnerNetObject attribute, it seems really unecessary since this can be done by checking subtypes in the assembly

The first reason is do to the issue with abstract monobehaviors and compiling it into il2cpp, second reason is I feel like it's more consistent using a attribute as the original class with Reactor, now I'm probably going to change the method of loading the prefab for it.

If y'all really want it to just be a custom subclass then I'll rework the logic.

D1GQ added 2 commits March 23, 2025 13:06
Replaced InnerNetObjectAttribute with IgnoreInnerNetObjectAttribute, now automatically registers InnerNetObjects.
Added more methods to load prefab.
@D1GQ

D1GQ commented Mar 23, 2025

Copy link
Copy Markdown
Author

i just dont get the InnerNetObject attribute, it seems really unecessary since this can be done by checking subtypes in the assembly

I've added some changes.

@miniduikboot miniduikboot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hey there, sorry for the lack of feedback. I've been busy and hoped other Reactor devs would've been active as well. I've read through the PR and made a few comments. I'm not fundamentally opposed to an API like this, but I think this has a few limitations that make it unsuitable for an environment where optional mods exist.

Let me know if you still want to push this PR forward

Comment thread Reactor/Networking/Attributes/IgnoreInnerNetObjectAttribute.cs Outdated
Comment thread Reactor.Example/ExampleInnerNetObject.cs
Comment thread Reactor/Utilities/InnerNetObjectManager.cs
Comment thread Reactor/Networking/Attributes/IgnoreInnerNetObjectAttribute.cs Outdated
Comment thread Reactor/Networking/Attributes/IgnoreInnerNetObjectAttribute.cs
/// This method searches through the AmongUsClient.Instance.NonAddressableSpawnableObjects array
/// to find a prefab of the specified type. If no matching prefab is found, an exception is thrown.
/// </remarks>
public static InnerNetObject? GetNetObjPrefab<T>() where T : InnerNetObject

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is it possible for this object id to desync between clients? For example, when multiple mods add objects, they may load in a different order, or a mod that is declared optional declares a net object as well (which shouldn't happen, but I think it is reasonable foreseable misuse)

@D1GQ D1GQ Jul 10, 2025

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

In theory it shouldn't be possible because in IgnoreInnerNetObjectAttribute Register collects all the valid innernet object with prefabs then on IL2CPPChainloader.Finished everything is loaded in alphabetical order to try to prevent this problem, as long as everyone has the same mods everything should be synced up.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

as long as everyone has the same mods

That isn't checked if the mod is not registered as RequiredOnAllSides. So either the API needs to be limited to these mods

namespace Reactor.Example;

// The `IgnoreInnerNetObject` attribute is used to prevent this custom InnerNetObject
// from being automatically registered by Reactor.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should users of this API also declare this attribute?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Only to stop reactor automatically registering the innernet object

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't get why you'd not want to register this net object. It's supposed to be an example of the API in use, would normal users want to use this attribute?

Aka, should this be the other way around: put an attribute for Reactor to register it? That would also interact better with mods that are already created

@miniduikboot miniduikboot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sorry for the delay, I keep forgetting about Reactor PR's. Let me know if you're still interesting in pursuing this

namespace Reactor.Example;

// The `IgnoreInnerNetObject` attribute is used to prevent this custom InnerNetObject
// from being automatically registered by Reactor.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't get why you'd not want to register this net object. It's supposed to be an example of the API in use, would normal users want to use this attribute?

Aka, should this be the other way around: put an attribute for Reactor to register it? That would also interact better with mods that are already created

/// This method searches through the AmongUsClient.Instance.NonAddressableSpawnableObjects array
/// to find a prefab of the specified type. If no matching prefab is found, an exception is thrown.
/// </remarks>
public static InnerNetObject? GetNetObjPrefab<T>() where T : InnerNetObject

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

as long as everyone has the same mods

That isn't checked if the mod is not registered as RequiredOnAllSides. So either the API needs to be limited to these mods

// Increase array length by one because of beginning if check in InnerNetClient.CoHandleSpawn()
var list2 = innerNetClient.SpawnableObjects.ToList();
list2.Add(new());
innerNetClient.SpawnableObjects = list2.ToArray();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Minor: This is converting the list to an array and back for each item. Can this be done at once for all InnerNetObjects?

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.

4 participants