Nodebox: Visual Scripting for UGC (now) at your fingertips
Posted 10 hours ago
Or, some funsies from the development

S&box Reflection or "How To Tear Your Balls Off"

* If you are familiar with the default C# reflection

I knew I really wanted nodes like Add<T> and not AddFloat, AddDouble. Which lead me to the `TypeLibrary` global.
I didn't expect to have any reflection when I thought of starting this project, but Facepunch actually gave me something that kinda works.
C# generics can be fucky by themselves, but with the `TypeLibrary` it all multiplies tenfold.

Ok, what type do you think this returns?
TypeLibrary.GetType<Drive<float>>().TargetType
That's Correct!
TypeLibrary.GetType<Drive<float>>().TargetType == typeof(Drive<>) // true
TypeLibrary.GetType<Drive<float>>() == TypeLibrary.GetType(typeof(Drive<>)) // and this is, also, true
Yeah, it doesn't work with generics, it's in the docs, thankfully.
Now, if you want to create an instance with generic arguments, you can only do
TypeLibrary.GetType(typeof(Drive<>)).CreateGeneric<Node>([typeof(float)], ...);
It came out fine in the end, but this cost me a couple headaches to implement around.

Next, what do you think this returns?
TypeLibrary.GetType<Drive<float>>().GenericArguments
Yeah, maybe, now, you understand why I needed the generic type's TypeDescription.
TypeLibrary.GetType<Drive<float>>().GenericArguments // [ typeof(T) ] (name of the generic argument)
typeof(Drive<float>).GetGenericArguments() // [ typeof(System.Single) ] (actual generic argument, from a closed generic type)
This one actually forces me to write overrides like this shit into every node
public override Type[] Generics => [typeof(T)];

I still have a lot of fucking around and finding out yet to do though
If you have any suggestions, message me on discord or something (@manonox)

I have yet to see a more disorganized math library

Disclaimer: this ain't Facepunch's fault
I almost lost my voice after laughing in a discord vc for a solid 10 minutes, after seeing the MathX static class.

WE FUCKING HAVE THEM ALL, LADIES AND GENTLEMEN
Math, MathF and the elusive... MathX

Like, let's make MathA, MathB, MathC, MathD, ...
I despise C# sometimes. They forgot to add some cool methods to MathF, so they added them in Math..?
Also, I don't know if Microcock can add static class extensions or they would break stuff, but this is just insanity.

I have a plan to implement everything as extension methods on float/double/int and vectors, just so I don't have to come near this mess.

Some vector types(including Rotation, Angles and Color) are missing a ton of methods, especially Vector2Int and Vector3Int.

Also, how the fuck does C# not have a Pow method for ints?
// Awful
public static int Pow(this int x, int exponent) => (int)Math.Pow(x, exponent);

// Awful, Not whitelisted
public static int Pow(this int x, int exponent) => (int)System.Numerics.BigInteger.Pow(x, exponent);
Or, maybe, I'm just a whiny bitch, idk

I almost bounced back to hating frontend

Razor is cool, Xml/Html is.. something, SCSS is great
But the whole time, Intellisense was screaming at the top of it's lungs that I have some ambiguities between classes or whatever the fuck.
Facepunch, please fix it ASAP, I beg of you, I once had half my .razor file irreversibly nuked by Intellisense replacing html/xml stuff with a using directive (you can't undo, if you don't notice it immediately).

In-engine "Highlight Selected" thingy centers the rects at the top left of your screen for (Center,Center)-aligned WorldPanels.
That would be fine, if I could just set the alignment to (Left,Top), but it breaks labels for some reason.
(And the render bounds get fucked too)
(See #7389)

And gradients don't work with transparency, boowomp :(

Also, we definitely need a VSCode extension that shows you which CSS properties and values are usable in S&box. (and or their caveats) Won't come from Facepunch themselves, but I hope some frontend engineer get's mad enough. Or, maybe, it's only me.

Weak-ass IEnumerable<T>

A short one, how come are these not in C# by default?
public static IEnumerable<(int Index, T Item)> Enumerate<T>(this IEnumerable<T> ie)
{
    var max = ie.Count();
    return Enumerable.Range(0, max).Zip(ie);
}

public static void ForEach<T>(this IEnumerable<T> ie, Action<T> action)
{
    foreach (T item in ie) action(item);
}