R2Northstar / NorthstarLauncher

Launcher used to modify Titanfall 2 to allow mods to be loaded
MIT License
281 stars 126 forks source link

My take on the plugin system #530

Open F1F7Y opened 1 year ago

F1F7Y commented 1 year ago

We all can agree that plugins can be a useful tool. In my opinion the plugin system as it is now is insufficient and too bothersome ( especially the version system ) to use.

How

All engine libraries ( can't check rtech rn ) expose a function called CreateInterface which takes a string as an argument. Calling this with a valid interface string returns a pointer to a global class instance connected to the string constant. We already use this ( although our way is taken from ttf2sdk and should be updated to be better ).

Personally I think we should copy this system and expose our own CreateInterface function and our own interfaces. This would mean a plugin would be partially independent of the version of the interfaces we expose meaning unless one of the interfaces you were using had a breaking update you wouldn't have to update.

Example

Let's say we expose "NSSquirrelFuncs001" and "NSCorePluginInterface001"

If one wants to add new functions to the squirrel interface we would just expose both NSSquirrelFuncs001" and "NSSquirrelFuncs002" keeping compatibility.

If we for example wanted to change a function in "NSCorePluginInterface001" we would only expose NSCorePluginInterface002" breaking only the plugins which use this interface.

Using deprecation and other methods we could slim down the plugins effected by interface updates even more.

What even is the pointer that CreateInterface returns

It's a pointer to a class. The idea is you only should use the abstract class from which it inherits but since you get the full instance of the class you can even use other functions ( eg: iterator in g_pcvar ).

C

C compatibility would still be kept as classes are basically just structs with a pointer to the vtable ( struct of virtual functions ) at the start.

This was written on a phone so there may be mistakes. I also probably forgot some other talking points I had.

Ending notes

Mimicking the CreateInterface system also encourages people to check engine libraries.

I'm open to implementing this on my own, just wanted to spark discussion, if someone has an opinion too long or not fitting for GitHub make a thread in discord referencing this issue.

F1F7Y commented 1 year ago

As this has been getting quite some attention I'd like to clear some things up:

Only custom systems ( eg Atlas ) and northstar helper functions ( plugin inform helpers, ... ) should be exposed. For example the squirrel setter/getter s should not be in an interface and the plugin should rather either get them from the modules or reconstruct them.

I dont think northstar should split up into separate dlls each implementing a set of interfaces. The only split i think makes sense would be client ( including listen server ) and dedicated.

We should prioritize providing feature full interfaces to reduce plugins having to hook game functions. Script has showen us that not having full control over game scripts can easily lead to conflicts.