#Anything inheriting WildfrostMod cannot be abstract/generic

1 messages · Page 1 of 1 (latest)

jagged valve
#

Bootstrap.cs attempts to instantiate anything inheriting WildfrostMod.
Even if class is abstract or has any generic parameters.
Location: Bootstrap.CreateModInstances()

This makes it impossible to create custom base class for the mods:

public abstract class CustomModBase : WildfrostMod
{
    public CustomModBase(string modDirectory) : WildfrostMod(modDirectory)
    { /* ... */ }
}

public class CustomMod : CustomModBase
{
    // ...
    public CustomMod(string modDirectory) : base(modDirectory) { /* ... */ }
    // ...
}

Because Bootstrap.cs will attempt to instantiate CustomModBase.cs, which is not allowed (as it is abstract).

Making Bootstrap.cs ignore types with Type.IsAbstract (and probably Type.IsGenericTypeDefinition) will open the doors for very useful tooling SandlingComfy

For example - helper methods which entire community uses can be standardized and delivered as a separate mod.
(Until this point, the only way for doing so would be to ask everyone to setup a Rozlyn source code generator, but it has a lot of downsides)

#

Anything inheriting WildfrostMod cannot be abstract/generic

slow jackal
#

I mean I’d say that was by design, but I can’t update the game anyways anymore, if u want tho u could make a mod with highest priority and override the bootstrap

slow jackal
jagged valve
jagged valve
# slow jackal I mean I don’t see anything that it’d actually bring which wasn’t already possib...

To be honest, it's mainly for adding static methods to mods:

public abstract class WildfrostMod<T> : Wildfrost where T : Wildfrost<T>
{
    public static T Instance { get; }
    public virtual string LogPrefix { get; }
    public WildfrostMod(string modDirectory) : base(mosDirectory)
    {
        if (this is not T inst)
            throw /* ... */;
        Instance = inst;
    }

    public static void Log(object value)
    {
        Debug.Log($"{Instance.LogPrefix} {value}");
    }

    public static CardData Card(name)
    {
        return Instance.Get<CardData>(name);
    }
}

public sealed class MyMod : WildfrostMod<MyMod>
{
    public override string LogPrefix { get; } = "[MMD]";
}

And now it's simpler to mod things:

// Within MyMod.cs:
Log("Hello Home!");
var temp = Card("Gnome");

// Outside MyMod.cs;
MyMod.Log("Hello World!");
var temp = MyMod.Card("Gnome");

// In methods:
// (Not the best example)
public static bool HasGnome<T>()
    where T : WildfrostMod<T>
{
    // We now have access to an instance of the mod - not only it's Type. This is the most crucial point.
    return (bool)WildfrostMod<T>.Card("Gnome");
}

// Usage:
Log(Helpers.HasGnome<OtherMod>();

Essentially, we can extend API of WildfrostMod with custom static methods, while making it as easy as adding : WildfrostMod<MyMod> at the end of regular mod.

But you are right, it doesn't do a lot of impossible things - just allows to make method usage easier, and unify more logic between mods.

jagged valve
slow jackal
#

im still not sure wht its for but good luck

jagged valve
#

Ha-ha-ha) konoobLUL

slow jackal
#

it looks like what u want is basicaly "using static classname"

#

which is alr a thing in c#

#

as for generics i have no ideas in what situations it can be useful

jagged valve
#

It's basically just so the mods can have a reference to an instance of a mod

slow jackal
#

they already can?

jagged valve
#

Yeah, but you need to use MyMod.Instance.MyExtensionMethod at the moment

slow jackal
#

for non static methods?

jagged valve
#

And with custom generic base class you can drop .Instance part

#

Yep

slow jackal
#

i dont see how that changes anything

jagged valve
#

It's purely for sugar-coding I would say

#

Globally, all that changes is that if anyone defines new base class - they can provide useful tools which everyone else can use by simply inheriting their class

slow jackal
#

all of that could have bene done with an interface as far as im aware

jagged valve
#

For example, I can write this thing in a base class:
And standard Add method

#

Now only I need to CPU/RAM optimize this thing, and everyone else get the benefits of it

jagged valve
slow jackal
#

interfaces would take much less space than generics

jagged valve
#

They take less space when you define then, but more in usage

#

I just prefer MyMod.Method() usage than MyMod.Instance.Method() in most cases.

slow jackal
#

valid?

jagged valve
#

Yep, compiles fine

slow jackal
#

i meant

#

valid as in

#

youre valid for wnting that

jagged valve
#

Ah konoobLUL

#

Appreciated then SandlingFlower konoobLUL

slow jackal
#

yea

#

ye it just wasnt designed that way

#

but u can do wtv u want

jagged valve
#

Specifically in our case, we have a Loader.cs class, which loads all PNGs from the disk in parralel.
It also combines PNGs from the disk with sprites from Addressables (Sprites and SpriteAtlases)
But it categorizes resources by WildfrostMod, so it can unload them on Events.OnModUnload

slow jackal
#

u dont need to unload asets btw

jagged valve
#

Oh, right, because Builders are not destroyed when mods are unloaded?

#

And they still need those sprites

slow jackal
#

i dont remember ngl

jagged valve
#

Fair SandlingICANT

slow jackal
jagged valve
# jagged valve Specifically in our case, we have a `Loader.cs` class, which loads all PNGs from...

If you were to use it - you would have to load sprites like this:
Loader.GetSprite<MyMod>("Assets/{guid}/{file}.png");
Or:
Loader.GetSprite(MyMod.Instance, "file")

But with a generic base class (see image), I can simply provide a helper:
Sprite GetSprite(string name) => Loader.GetSprite(Instance.GUID, name)
With usage:
Sprite val = MyMod.GetSprite("Gnome");

It's much shorted, and also if you use OtherMod.GetSprite("Gnome") - you will access other mod's storage.
Which is neat in your case, though I feel like it conflicts with current standard with all addresses being in the same namespace, essentially.

jagged valve
#

And you can get them using this address

slow jackal
#

uh, huh i see

slow jackal
jagged valve
#

Not really, because you need GUID

slow jackal
#

?

slow jackal
jagged valve
#

Yeah, this will work, just that the usage becomes long again konoobLUL
MyMod.Instance.GetSprite

slow jackal
#

arent static exnteion methods also a thing in like

jagged valve
#

And if you use it within your mod itself, it becomes this.GetSprite or Instance.GetSprite

slow jackal
#

new .net

#

i dont really keep track of new features

jagged valve
#

Also heard about it, but haven't tried it

#

If it will make it so we don't need to use Instance. or this. - that would be amazing konoobLUL

slow jackal
#

this can be omitted

#

but ye tahts just sugar

jagged valve
slow jackal
jagged valve
slow jackal
#

have u never tried lol?

jagged valve
#

It simply haven't worked on my side konoobLUL

slow jackal
#

as for omitting instance uh

#

prob smth also exists

#

idk

#

i dont like sugar

#

i prefer readable code

jagged valve
#

Valid point GradNCxMinaCoolA

#

In any case, if we ever need custom base class for mods, be it generic or not - we now have a way 02Shrug