#TimberAPI

1 messages ยท Page 6 of 1

stone shoal
#

I slapped them

calm copper
#

Congrats! A very good number ๐Ÿ™‚

stone shoal
#

I know right

#

Very roundy

calm copper
#

I like binary round numbers, tho kekw

primal wind
#

Does the building spec "RecipeIds" not support #append?

austere tangle
#

Nope. Hope will be soon un the base game.

primal wind
#

darn, was trying to use it for my botkit mod that I'm trying to make, would've also switched my bentos mod to it

stone shoal
#

At least I don't know why it wouldn't

primal wind
#

Well I tried it, couldn't see my recipes in the list unless I simply missed it

austere tangle
#

Was working at the first versions of TAPI ... ๐Ÿ˜ญ

stone shoal
#

Does a full replace with only yours do work? otherwise either the specification is wrong, you don't have TimberApi not installed or I did something wrong

primal wind
#

I just realised, I haven't check if my copy is up to date, lemmie check that

stone shoal
#

It has been in there for quite a few updates though

#

If you make a empty BuildingSpecification.Tester.json file in your specification folder it should crash

primal wind
#

apparantly I need to update the mod manager too

primal wind
#

tried updating, had tapi load after modmanager and had a crash. Found this: drive_c/users/steamuser/Temp/Mechanistry/Timberborn/. Was an unusual crash though as some progress dialog appeared before it quit

#

was manual update btw, removed the one mad manager had made

#

was in the folder I just mentioned btw with a crash dump

#

the archive is the folder zipped

stone shoal
#

I have never seen such stack trace

#

Probably something from mimic

stone shoal
primal wind
#

well disabling the TBMPL stuff did get past the crash so you were probably right about it being his, just assumed it was tapi as that was all I touched. Maybe I need to update the TBMPL core too ๐Ÿ˜

#

but updating tapi didn't resolve the inactive building spec situation ๐Ÿ˜ฆ

stone shoal
primal wind
#

deleted the folder mod manager made and downloaded directly from mod.io

stone shoal
#

How are you trying to use the buildiner specification

#

Whats your setup

stone shoal
# primal wind

There are optional, do you have a base specification it can depend on ?

primal wind
#

Uh, That's the name in of the vanilla buildings

stone shoal
primal wind
#

m_Name: Refinery.Folktails

stone shoal
#

There -> these*

#

BuildingSpecification.Refinery.Folktails.optional.json

#

Finally, if the file name ends with .optional.json for example NeedSpecification.Beaver.Sport.optional.json, it modifies an existing Specification only if it is already present in the base game or a different mod but is otherwise ignored. This allows you to support compatibility with other mods as well as older versions of the game.

primal wind
#

Isn't that supposed to be used when updating an existing object?

#

hmm, guess I'll try without the .option then

stone shoal
#

ThinkingIT Wait do I generate them as well

#

I can't test this now but I use the name from
var buildings = prefabService.GetAll<Building>();

#

So if you log all building names from that it should have the one you want

#

If it doesn't it won't work

#

Maybe the name doesn't use . as seperation

primal wind
stone shoal
#

Ye because it isn't a full spec, you were right about using the .optional

#

But the logic behind it was just wrong ๐Ÿ™‚ so I was confused

#

It's not beacuse am existing object, but an existing specification. Unless you meant purely the specification with object and not building my bad.

primal wind
#

did clue me in to what the issue might've been though, complained of missing "BuildingId"

stone shoal
#

You could just remove the Id in it's whole

#

Since it's optional it doesn't matter

#

But if the specification name doesn't mater that might be a problem, which I think where it goes wrong

spring radish
#

Another way to say it is that it crashed in c++ code instead of c# code (which 95% of the game is written in)

stone shoal
#

@primal wind Looks like it's broke as far I can see now

#

Not sure when it bee fixed hopeefully this week

spring radish
#

I don't even understand why it crashed, the top of the stack is roughly:

Timberborn.Modding.ModLoader:TryLoadManifest (Timberborn.Modding.ModDirectory,Timberborn.Modding.ModManifest&)
Timberborn.Modding.ModLoader:TryLoadMod (Timberborn.Modding.ModDirectory,Timberborn.Modding.Mod&)
Timberborn.Modding.ModRepository/<GetMods>d__16:MoveNext ()
#

which is managed code, so why a native crash?

#

unless the call to GetModDirectories was super lazy, and only runs when TryLoadManifest actually tries to reference Path the first time,

#

and the it could totally be a native crash, becuse that calls into the steam api which was not working,

#

but IsModDirectory should already have run on the path, so would have crashed earlier,

stone shoal
#

Since I don't do much with the loading mods

spring radish
#

There are so many mods loaded in that log that I have no idea what could have caused it,

#

or that it's more likely to have been caused by a bad interaction between two mods, and not an individual mod itself.

#

i.e. I doubt it's TimberAPI's fault,

#

and would like to see a smaller reproduction (i.e. same crash with fewer mods active)

compact pewter
# spring radish which is managed code, so why a native crash?

Because log shows only "Managed Stacktrace:". First time TryLoadManifest was called before any mod was loaded/started and crashed trying to reload manifests after mods were enabled/started. I guess one of the mods tries to load another and messes up manifest path (or path is ok but the game doesn't have access to it).

well disabling the TBMPL stuff did get past the crash

I'd try to delete TBMPL folders and redownload through mod manager. If no success - try to reenable them one by one

vast otter
#

Mod io Mod manager also broke

primal wind
# spring radish or that it's more likely to have been caused by a bad interaction between two mo...

True but TB loads mods in order and TAPI was 3rd in the order, just after harmony and mod manager so I don't see a reason for other mods to have had a chance to do something besides when tapi is loading one. On a related note it would be very much appreciated if you could add an info/debug log message about which mod and/or mod file tapi is trying/addressing/whatever way you wanna put it before it actually tries them. If you could also add in info/debug logs about which parameters/functions are being attempted that would also help. Could build it as a separate mod called tapidbg due to how much extra time that would take and thus only be desirable for short term use instead of main tapi

stone shoal
primal wind
#

hmm, well if you manage to do something about that issue then please ping me again about it. For now I'm going to assume it was partially tapi's fault but not entirely, meaning tapi made an assumption somewhere it shouldn't but it would never have been an issue if another mod didn't highlight that assumption with it's own poor code

stone shoal
#

I dont even do anything with Loading anymore

stone shoal
#

I can't even get it to crash

#

With mimics mods

stone shoal
#

It always can be a fault but without knowing what mods toghether causees it out of 30 mods, who knows

spring radish
#

and you can test if it's a steam issue by adding -feature-NoSteam to the game's launch options.

#

which should stop the Couldn't connect to the Steam client. Is it running and do you have the game in your library? appearing in the player log

#

Let me know if you ever see Successfully connected to the Steam client. under Linux, btw -- I just can't get it to work.

spring radish
#

any easy way of getting a line of text from the user in game?

#

something like the district renaming dialog?

#

or name change dialog,

stone shoal
spring radish
#

yea, Timberborn.CoreUI.InputBoxShower will probably do

#

need to figure out how to make a new hotkey too, KeyBindingSpecification probably,

stone shoal
spring radish
#

yea, that might be a follow up option too

stone shoal
#

And you could almost copy the InputBoxShower code for making it pop up, it just pushes a visual element to the panelstack

compact pewter
spring radish
#

yea, I figured out how to add a spec too

compact pewter
stone shoal
compact pewter
#

both. It is perfect LoveIT Most UI elements I touched were a bit tricky to reuse or adapt. This one is an exception

stone shoal
#

I think I resud the name dialog for TimberPrint before, when I hadn't updated TimberApi

compact pewter
#

As I tried to do similar thing but UnityUI stylebuilder is protected/internal or w/e not available. I couldn't figure out how tf did you get it HappyIT

stone shoal
#

This is how you would done that part in the unity stylesheet builder

#

This was mine, now you can just do .Width(100)

builder.AddClass(
    "HelloWorld",
    propertyBuilder => propertyBuilder
        .Add(Property.Width, 100)
        .Add(Property.Height, 100)
        .Add(Property.PaddingLeft, 100)
        .Add(Property.PaddingRight, 100),
    PseudoClass.Hover, PseudoClass.Checked
);
compact pewter
#

Yeah in the end I decided to deal with the game's ui. Unity UI sounds great (and definitely much better than old one. ImGUI is life thoughLoveIT ) but it tries to feed me uxmlemlements waaaay too much

stone shoal
compact pewter
#

At least Dear Imgui is always there for us when Unity is not looking HappyIT
At least your builder makes uielements much easier to use. Not sure I agree with style builder as it's kinda same as inline styles but it is nicely done and does it's job well

stone shoal
#

Maybe a

propertyBuilder.AddStylePropert(new StyleProperty() {
  width = 10,
  height = 20,
})
propertyBuilder.AddStylePropert(new StyleProperty() {
  width = 10,
  height = 20,
}, PseudoClass.Hover)

thonkeyes

compact pewter
stone shoal
#

You can just modify the text values directly

#

I don't think I understand it to well for what you saying ๐Ÿ˜›

compact pewter
#

yeah event or state ? Idk the right term. I might be mistaken/misremember afaik uitoolkit was kinda like uielements/web for end user interfaces (but worse) and immediate mode is meant for editor ui. If you ever saw if (button) { ... handle click ... } that was 100% imgui

compact pewter
# stone shoal What would your idea be to have a better something for styles? To be fair just a...

I think styles are fine/good and builder approach fits ui really well. Using style builder for individual elements instead of building a theme kinda feels bad as it's similar to using inline styling instead of css and I was strongly adviced against doing so ๐Ÿ˜„ Afaik unity discourages it too as one style/theme is cheaper to draw. Idk if it is noticeable when laid over procedural water mesh and textures HappyIT

stone shoal
#

I tested to creat a bunch:

100_000 stylesheets with 1 class and 1 modifier -> 1,2 seconds
100_000 classes in 1 stylsheet with 1 class and 1 modifier -> 0,7 seconds

100_000 stylesheets with 1 class and 3 modifier -> 1,77 seconds -> 47% increase
100_000 classes in 1 stylsheet with 1 class and 3 modifier -> 1,0 seconds -> 42.86% increase
#

And would not have huge impact, creating a VisualElement and mofiying it's styles directly was much slower

compact pewter
stone shoal
#

But ye, it's not a big big issue since most things are just generated once and than not touched. At most you need to wait a few seconds longer in the loading screen if someone goes really wild

compact pewter
compact pewter
#

@stone shoal btw do you have plans or desire for "normal"/non-api mods?

compact pewter
#

like a mod for people not moders ๐Ÿ˜„ Idk what to call it. Simply curious

austere tangle
#

players ! Modders are also people ๐Ÿ˜ฎ

compact pewter
compact pewter
stone shoal
young tendon
#

Did you ever get around to looking into this?

stone shoal
young tendon
calm copper
#

@stone shoal Remember I reported a spamming error when using MinMaxSlider (#1064983064020799498 message)? It seems to be Unity issue: https://discussions.unity.com/t/unity-6-uitoolkit-layout-update-is-struggling-to-process-current-layout-with-minmaxslider-in-editor/1538464

As for the misaligned dragger (#1064983064020799498 message), I fixed it like this:

            .AddSelector(".api__min-max-slider--small > .unity-min-max-slider__input > .unity-min-max-slider__dragger > .unity-min-max-slider__min-thumb", builder => builder
                .MinHeight(16)
                .MinWidth(16)
                .MarginTop(-6)
                //.MarginLeft(-7)
            )
            .AddSelector(".api__min-max-slider--small > .unity-min-max-slider__input > .unity-min-max-slider__dragger > .unity-min-max-slider__max-thumb", builder => builder
                .MinHeight(16)
                .MinWidth(16)
                .MarginTop(-6)
                //.MarginLeft(-2)
            )

I guess, the left margin was added to "center" the circles on the dragger, but it breaks the dragger layout. I think it also needs to be adjusted.

#

The bad thing about the spamming error is that it drops FPS to the floor: from 144 down to 22. So, until they fixed it, I'll be using two regular sliders ๐Ÿ˜ฆ

#

Btw, nice stylesheet builder ๐Ÿ‘Œ . I spent some times figuring out how it works, but then it was clear and easy to use.

stone shoal
#

Did you fix the errors?

calm copper
#

I didn't find a way. Unity devs said they are investigating, but it can take years. I checked where the error comes from.

    public override void Update()
    {
        int num = 0;
        if (base.visualTree.layoutNode.IsDirty)
        {
            while (base.visualTree.layoutNode.IsDirty)
            {
                changeEventsList.Clear();
                if (num > 0)
                {
                    base.panel.ApplyStyles();
                }
                base.panel.duringLayoutPhase = true;
                base.visualTree.layoutNode.CalculateLayout();
                base.panel.duringLayoutPhase = false;
                UpdateSubTree(base.visualTree, changeEventsList);
                DispatchChangeEvents(changeEventsList, num);
                if (num++ >= 10)
                {
                    Debug.LogError("Layout update is struggling to process current layout (consider simplifying to avoid recursive layout): " + base.visualTree);
                    break;
                }
            }
        }
        base.visualTree.focusController.ReevaluateFocus();
    }

For some reason they cannon settle layout fast enough. Thus, the error. But bobody nows why MinMaxSlider causes it.

stone shoal
#

Can't it be done in TickableComponent or maybe event triggered ?

calm copper
stone shoal
#

Ah

calm copper
#

I checked MinMaxSlider code. I think I have ideas why it happens. maybe I'll paly with own implementation.

stone shoal
#

You should be able to create it yourself I think. Never tried to make a core element though

calm copper
#

Regarding the margins. At the top and bottom are regular sliders for the reference. The first minmax slider is from TAPI, the other one is my local copy with the left margins removed.

stone shoal
calm copper
stone shoal
#

Like when does the hover effect trigger, is it around where the button is or very off center ?

calm copper
#

Let me double check, but I'd notice. I spent hours with this damn control ๐Ÿ™‚

stone shoal
#

Hmm weird

#

Maybe unity just updated it and fixed it ๐Ÿ˜›

calm copper
#

Fixed what exactly?

stone shoal
#

Because at the very beginning it wasn't bugged iirc

calm copper
#

Ah, that. Maybe.

stone shoal
#

You could not click on the handle (button) around the edges

#

It was a few pixels away of the image

calm copper
#

Given MinMaxSlider throws errors now, they definitely changed it compared to the earlier versions.

spring radish
#

It wiggled a bit at 0:16ish

stone shoal
#

Does happen in the game as well sometimes

spring radish
#

Ahh okay

calm copper
#

The common problem of this control is "floats". There are a lot of roundings there. Basically, it's the problem of that "cannot handle layout" problem.

#

For some reason, resolvedStyle.width can be non-round. I don't know if it's by design, but for the control it was a problem.

#

My fix was just forcing rounding each time it's used.

spring radish
#

Ahh, that's what I was going to suggest.

#

Either round or use fixed point number (not sure if c# has something like that)

#

Python has a Decimal type

calm copper
#

Here fixed point would not help. It wasn't the losing precision issue. It was literally a code logical problem. They were using non-round width to set positions, and then they used the positioned controls to calculate a new width ๐Ÿ™‚ Not a surprise the system couldn't stabilize at some edge case values.

spring radish
#

Ahh, c# has System.Decimal

#

heh, yeaaa, that's not going to work

calm copper
#

And I was surprised how Unity does layout calculation. I thought they maybe have a hierarchy or something, but they just run a loop until all controls reports "not dirty" (no values changed during the last layout update call). If the layout cannot become clean in 10 loops, the error is written and updater terminates, leaving the whatever state. As a result, you could see one of the thumbs flickering in UI.

primal wind
#

Either tapi still doesn't support modifying the recipe lists or I'm doing something wrong, someone mind taking a look and checking for me?

#

playing on greedybuilders btw

primal wind
#

What's up with this btw? ```
/// <summary>
/// This class only deserializes specification jsons, so this is not used
/// </summary>
/// <param name="value"></param>
/// <param name="objectSaver"></param>
public void Serialize(BuildingSpecification value, IObjectSaver objectSaver)
{
throw new NotSupportedException();
}

stone shoal
primal wind
#

why's it not implemented?

stone shoal
#

Because it only deserializes...

primal wind
#

then what's the point of a spec that's never deserialised?

stone shoal
primal wind
#

isn't that needed to convert the json to binary though?

stone shoal
#

You either are talking about something else or you read it wrong

#

Serialize method is not implemented

#

Deserialize is

#

Deserialization is json -> object

primal wind
#

hmm, fair enough I suppose. as for the recipe Ids, I don't see anything that actually deserialises them

stone shoal
#

lines 37 ?

primal wind
#

that's only passing the list along, not deciding if something is an ID or not

#

either way I'm still not getting the recipes I declare showing up in game

stone shoal
primal wind
#

don't forget the #append/#remove support, I want to switch my bentos mod to full json

primal wind
#

"RecipeIds#append"/"RecipeIds#remove"

#

like base game specs do in most lists

stone shoal
#

That isn't what people implement, that's how merging of specification jsons. If you make a specification it will has that

primal wind
#

sweet

stone shoal
#

Makes sednse that it does not work if the configurator isn't even recognized

primal wind
#

what did you need to do to fix that, or are you still working on that?

stone shoal
#

No clue can't even rename my namespace atm

stone shoal
#

Some are working but recipes not kek

#

Changing the recipe ids doesn't do much anymore

#

I have a feeling that before it wasn't done in the inventoryInitializer or initialization was later

#

@lofty lark Are Manufactory components still placed on the prefabs ?

#

Answer is probably that it is replaced with the ManufactorySpec, Since that one seems to work ๐Ÿ™‚

#

@primal wind

primal wind
#

sweet, it uploaded yet?

stone shoal
#

Not yet

primal wind
#

lemmie know the version when you do so I can set the req on my bento and botkit mods

#

@vast otter whenever you're ready you mind doing those bot kit icons for me? Simple tool box with the relative FT/IT logos in the top right will be enough

austere tangle
# stone shoal <@808437936924262420>

No way ๐Ÿ˜ฎ After more than 2 years (see this : #1064983064020799498 message), can add new recipe ? Guess, better later then never. TY ๐Ÿ˜ ๐Ÿ‘

primal wind
#

lol XD

stone shoal
#

Added: 4 jan 2023

#

xD

austere tangle
#

Nope, when I send the message I pinpointed , was broke again. (middle 2023). From that moment I counted ...

#

But, important is to have that option again ๐Ÿ‘†

stone shoal
#

Well rip

#

Might be handy to make an issue next time instead, saying it on discord can be done as well but if I am not actively working on it I probably forget it within a week MomijiHype

primal wind
stone shoal
#

@primal wind @austere tangle should be live on mod.io and steam now

primal wind
#

sweeet ๐Ÿ™‚

lofty lark
primal wind
#

welp appears to have broken choo choo, I'll reload without that active to see what else breaks (if anything)

#

also is there an option to disable this type of output? ```GENERATING SPECS
LOADING SPECS
beaverbust.ironteeth
362
beaverstatue.folktails
362
bell.ironteeth
362
bench.folktails
...

#

nuts, height shower mod broke too ๐Ÿ˜ฆ

stone shoal
#

Frick

#

debugs

austere tangle
#

Simple floodgate triggers knoked out, too ๐Ÿ˜ญ

primal wind
#

looks like those are the only 2 of my installed mods that broke ๐Ÿ™‚

stone shoal
#

Whats the error

#

It should not break anything I think

austere tangle
stone shoal
#

UIBuilder isn't compatible anymore ThinkingIT

primal wind
stone shoal
#

I did not change it unless a clean solution does that ThinkingIT

primal wind
#

I just figured you'd want to see where it broke, I'm not expecting this to be a tapi issue

stone shoal
#

Don't know enough about C# building process of dependency loading

#

But seems like my build for some reasons changed some internal data so the mods don't know it anymore or something like that

primal wind
#

got couple min left on a TLDR vid to watch then I'll try

#

just entered the ground news ad bit so quitting the vid there, let's about this build ๐Ÿ™‚

austere tangle
#

Just wait to load ...., and wait ....

primal wind
#

right behind you ๐Ÿ˜„

stone shoal
#

Third here ๐Ÿ™‚

#

Yep crashign

#

Don't understand why though, Im prety sure I have updated TimberAPi before without making everything else crash ThinkingIT

primal wind
#

maybe it was that configurator thing being different now?

#

yep, still got a crash, not sure if was height viewer though, gonna check the log now

austere tangle
primal wind
#

yeah it was height shower again ๐Ÿ˜

#

maybe it's the way they linked in the 1st place?

austere tangle
#

and, simple floodgate triggers ...

stone shoal
#

Wait.....

#

I just wanted to fix a small issue mans_sad and go back to hobby stuff

primal wind
#

yep, always the way

austere tangle
#

YA, a code that works from the start, do nothing ๐Ÿคซ

stone shoal
#

Well it didn't work remember ๐Ÿ™‚

austere tangle
#

In the first half of 2023, was working, remember ?

stone shoal
#

Oh ye but Timberborn also broke it ๐Ÿ˜› not only me

#

I fixed mine part and still was broken

austere tangle
#

True

stone shoal
primal wind
#

I suggest abandoning the try/catch part of it, or at least adding a log that says X does not have member Y in the catch statement

stone shoal
#

22-9-2024 is that less or more than 48 days ago ThinkingIT

primal wind
#

that way you can actually see when the code is attempting to use something that don't exist

austere tangle
#

Anyway, maybe dev's will add in the U7 as game feature, so, could be a unnecessary headache ๐Ÿค”

stone shoal
#

The problem now has nothing to do with the BuilderSpecification

austere tangle
#

Could you comment building spec and send the TAPI ? To check if something with the built is the culprit ..

stone shoal
primal wind
#

FINALLY! ๐Ÿ˜„ ๐Ÿ™‚

austere tangle
#

You, but me, without simple fllodgate trigger, my beavers are a dead meat ๐Ÿ˜ญ

primal wind
#

currently my botkit mod fully overrides the list as a left over from trying to get it to work with 7.7.0, now I just need to try with #append

stone shoal
#

Seems like I cannot fix this

primal wind
austere tangle
primal wind
#

uh, just install some normal dams at the top where you want the overflow to go

austere tangle
#

Is good for health on badtide ๐Ÿคฃ

primal wind
#

always assume overflow

#

and I don't just mean when playing ๐Ÿ™‚

#

the mark of a good programmer/gamer is that they always assume the worst case scenario can and will happen eventually

austere tangle
#

True, like increase in water flows before drought or badtide ๐Ÿ˜›

primal wind
#

yep, though I thought it was the reverse XD

austere tangle
#

About 2-3 days before ,,,

stone shoal
#

@median plinth Whenever possible could you recompile your mod with the latest version of TimberApi. Im pretty sure this solves everything without changes.

primal wind
#

g2k

stone shoal
#

Either something in unity/Timberborn changed with UIToolkit which made UIBuilder do some changes and everything broke or I maybe changed something somewhere. Or it's just random C# stuff which I don't know enough about.

median plinth
primal wind
#

My bentos are fully json made now ๐Ÿ™‚

stone shoal
#

At least something good from the update mans_sad

primal wind
#

I'll just update the mod req and wait on 7.7.2 to be uploaded ๐Ÿ™‚

#

I think there's a memory leak somewhere as TB just crashed on me, no new mods, only removed mods

median plinth
#

@stone shoal can confirm, recompiling solves the crash

#

I just wonder why

primal wind
#

must be static linking occuring somewhere then

stone shoal
#

But I am pretty sure that would not matter

spring radish
#

btw, was there a plan to support #append with a mod filter with a patch to JsonMerger? I'm trying to figure out if it would still be useful or not,

stone shoal
#

Not specificly that, and not sure if I am going to add it like that specificly but yes

#

From next week I am starting to plan in time for modding again

#

Altough this will be firstly documentation, then finishing the loggin feature + console

calm copper
#

And there is no clear link that would give GitHub repository. I had to google for it.

primal wind
spring radish
#

No I mean with a suffix like #append#Tobbert.Ladder so that it's only appended if the ladder mod is present.

primal wind
#

oh, that's an interesting idea

spring radish
#

so that faction mod authors can add "optional" buildings that only activate when the other mod is present,

primal wind
#

hmm, prob with that is that it puts the problem of support many mods on those faction authors

spring radish
#

yea, which is why I wasn't sure how useful it would actually be

primal wind
#

in other words it converts a "many to one" to a "one to many" problem which I'm not a fan of

#

it's like going from multi-threaded to single-threaded, never a good idea when multi-threaded is already working well

stone shoal
calm copper
#

Icon ๐Ÿคฆ I'm too old...

#

I was looking for a link, like "Github" ๐Ÿคฃ

stone shoal
#

Shit happens

primal wind
#

I thought I was old at 35 going on 36, I haven't made the mistake of not look for icon yet, just hold old are you?

#

I make plenty of spelling mistakes though XD

calm copper
#

I'm 48. When internet became a widely available thing, I was already drinking alcohol ๐Ÿคฃ

primal wind
#

nice, though I don't get the fascination with alcohol. I occasionally drink it, maybe once a year at most, never really pulled me in

#

similar deal with fags. back when I was a I kid I nabbed my dad's fags, took 1 puff and decided then and there I would never smoke in my entire life

#

been the same decision every time I tried

calm copper
stone shoal
# median plinth I just wonder why

I changed the class with a new method and it keeps working shrug. Probably has something to do with an updated unity version or because something weird happend in the project and I renamed an unrelated project manually.

median plinth
#

Curious

calm copper
#

@stone shoal 0.7.7.2 broke my custom GameTextMinMaxSliderBuilder2 which was a simple copy of GameTextMinMaxSlider<TBuilder>. I didn;t see anything in the changelog. Was there changes to the preset classes hierarchy?

calm copper
#

Nm. It's Rider got a glitch after the mod update.

compact pewter
stone shoal
#

I have made the tool system for the bottom bar for wel... tools. And everything must be done with tools (which is 99% the case) but for example the settings box isn't a tool. It can't and should not be switched to. But should be displayed in the bottombar

#

I don't think it's a supar great system but don't know either how to change it since UI en Tools are seperated systems. How would you allow UI only sections ThinkingIT

#

Should those elements even need to use the ToolSpecifications

compact pewter
#

Could you clarify a bit?
Right now bottom toolbar has nothing to do with tools, it is made entirely of UIElements and switching tools/groups done in event handlers. ToolButton knows about UI button but not the other way around. Do you need UI button to know about tool or what's the problem?

#

btw I think default cursor tool handles settings button in some special way - might want to look into that
Edit: don't hesitate to RTFM me I probably didn't pay enough attention reading tapi code. And questions are out of curiosity

stone shoal
# compact pewter Could you clarify a bit? Right now bottom toolbar has nothing to do with tools, ...

Original bottombar are tools, but the "tool" is already implemented in the button so the tool is kinda lost. And you can only get the tool if you already know the tool.

I reworked it to make the whole bottombar to specification based and splitted UI and tools. These things allowed to

  • Customize any button UI to any other UI or custom ones
  • Easily changing order of buttons (and other stuff)
  • Multiple rows (with many other patches)

At a later time I implemented the interface IUnselectableTool But this is just for scrolling IIRC.

What I want is also able to only have UIElements inside the bottombar (I think). But not sure how to do that nicely, also not sure if it's really that much of a problem. It would limit to adding things like a toggle button in the BottomBar, but does such thing even need to be in there

stone shoal
#

Maybe it's just a non issue thonkeyes and only settingbox is special and not that much of a workaround required for it as in you need 1 extra class to enable the box instead of doing it somewhere else

compact pewter
stone shoal
#

And at the beginning was like what if you want to add a Timbe in between kek. But with the IUnselectableTool you could do this if you really really want to.

#

Sooo... just forget about all of this ๐Ÿ™‚

#

#1303754962387468328 message This on the other hand is the probably the correct fix for the current issue why I was rechecking this feature.

stone shoal
#

Okay made it possible to have generic tool specifications

#
Id = "Cursor",
Type = "GenericTool",
Layout = "GrouplessRed",
Order = 0,
NameLocKey = "Cursor",
DescriptionLocKey = "Cursor",
Icon = "Sprites/BottomBar/Cursor",
DevMode = false,
Hidden = false,
ToolInformation = new
{
    BottomBarSection = 0,
    ClassName = typeof(CursorTool).FullName,
}

ClassName can either be the full name with namespace or without. Should only be 1 match if there are multiple tools with same class name it throws an error

#

ThinkingIT How would I know about the icon for a fall back one

stone shoal
#

@young tendon What mod is yours with the CutterTool and ForestTool

#

I think I found it... Forest Tool?

#

Alright that fully works ๐Ÿ™‚

young tendon
#

Yeah, Forest Tool and Cutter Tool. On steam or mod.io.
Ok, so you've managed to load the mapeditor with the mod installed? HappyFT

stone shoal
#

@quiet delta Was there any specific reason why you first extract all the #append and #remove actions and later apply them after each other instead of just changing it instantly?

    public JObject Merge(IEnumerable<JObject> jsons)
    {
      JObject mergedJson = (JObject) null;
      foreach (JObject json in jsons)
      {
        JsonMerger.ProcessCustomTokens((JToken) json, JsonMerger.AppendKeyword, (ICollection<JsonMerger.ArrayModification>) this._arrayAppenders);
        JsonMerger.ProcessCustomTokens((JToken) json, JsonMerger.RemoveKeyword, (ICollection<JsonMerger.ArrayModification>) this._arrayRemovals);
        mergedJson = JsonMerger.MergeJsons(mergedJson, json);
      }
      this.ProcessArrayAppenders((JContainer) mergedJson);
      this.ProcessArrayRemovals((JToken) mergedJson);
      return mergedJson;
    }
stone shoal
#

I think it is due wanting to add everything from all mods first before removing anything ThinkingIT

#

Or maybe it's because of [Error : Unity Log] InvalidOperationException: The parent is missing. MomijiHype Wait that can't be it... json confuses me

quiet delta
#

I don't remember tbh. Maybe this approach was cleaner for some reason ๐Ÿค” although adding all elements before removing anything makes sense too.

stone shoal
#

@vast otter very very WIP but the idea for this one at least works.

{ "TestList", new List<string> { "AAA" } },
{ "TestList#append@true", new List<string> { "CCC" } },
{ "TestList#remove@true", new List<string> { "CCC" } },

Results in: AAA, it got removed and added

{ "TestList", new List<string> { "AAA" } },
{ "TestList#append@true", new List<string> { "CCC" } },
{ "TestList#remove@false", new List<string> { "CCC" } },

Results in: "AAA, CCC", removal is disabled

{ "TestList", new List<string> { "AAA" } },
{ "TestList#append@false", new List<string> { "CCC" } },

Results in: "AAA", appending is disabled.

#
{ "TestList@false", new List<string> { "AAA" } },

Results: crash (if it's the only one because the property doesn't exist anymore now)

{ "TestList@true", new List<string> { "AAA" } },

Results: works as normal

#
{ "TestList", new List<string> { "AAA" } },
{ "TestList@true", new List<string> { "BBB" } },

Results: "AAA, BBB" it get's merged with the other "TestList" in same json, and will replace the whole list in a merge

#

I want it to make it support properties as well but for now I start with lists

vast otter
#

Noice ๐Ÿ˜ŽHappyIT WorkHardIT

primal wind
#

How about just making a separate spec file like PrefabGroupSpecification.Buildings.GreedyBuilders.mod.Tobbert.Ladder.json? where everything between mod. and .json is the ID of the mod to apply the configuration to. In the case of multiple overrides of mod configs could use something like PrefabGroupSpecification.ModOverridesOrder.GreedyBuilders.json to declare the order of override priority

spring radish
#

How do I use a generic tool specification? Is there an example?

#

ahh, SettingBox is a simple example

stone shoal
#

CursorTool is also one of them

#

Pretty much any timberborn tool that does not use a factory or needs extra data beside the dependency injection. Which is also the use case for this update.

stone shoal
# vast otter Noice ๐Ÿ˜Ž<:HappyIT:887645571333103658> <:WorkHardIT:887645570842394655>

What do you think about the file name specs? My idea goes further than just required mods so that you could use mod settings for example. And I think that such files could get very ugly fast.

As side node, I am not sure yet if I want to do just the @ condition action or just make the full on .patch modifier which will work something like this
https://rimworldwiki.com/wiki/Modding_Tutorials/PatchOperations#PatchOperationReplace
And then in json format. With this you have more fine control about what is changed

For example:
At the moment you can't quite change a value like the points in this example

{
  "ConsumptionEffects#append": [
    {
      "NeedId": "Thirst",
      "Points": 0.3
    }
  ],
  "Weight": 2
}

With the patch operations you could look for the thirst need Id and change it's points.

austere tangle
#

append means that you add something. To change, use #remove and #append ....

vast otter
#

Im fine with any way that i can tell the game:

only do this edit/append if mod x is enabled

stone shoal
stone shoal
#

And not sure if people care about being able to have more control in that aspect

#

idk if this would just be confusing or actual usefull kek

{
  "ConsumptionEffects@change('NeedId')": [
    {
      "NeedId": "Thirst",
      "Points": 0.6
    }
  ],
}

^ uses NeedId as a search modifier which is the only part that needs to match and changes the Points to 0.6

vast otter
#

for me i only see a need for append/removal but if its not to hard to add it, go for it ๐Ÿ˜‰

spring radish
#

would that also work to set the GroupId for a ToolSpec when a mod is present (like More groups)?

#

like maybe:

{
  "GroupID": "Storage",
  "GroupID#KnatteAnka.MoreGroups": "Subgroup_MGTanks",
}
spring radish
#

where the expression inside the square brackets is used to select the list element to merge the value into

#

and the first example in css like syntax might be GroupID:mod(KnatteAnka.MoreGroups)

vast otter
#

this was a new bug ๐Ÿ˜ฎ
if the text is 2 lines some is hidden as the next icon is drawn on top

#

its soon released with decoration extention

#

(and not a critical problem)

stone shoal
vast otter
#

Hmm will test it

#

(tomorrow)

vast otter
#

ok ya its the same in base game so will workaround it

stone shoal
vast otter
#

Ya its fine will work around the limitation and have suggested yo change the ancor point from top to bottom left

stone shoal
#

you have ancor points in visual elements ?

#

It's probably due a fixed offset from the hovered element and height always goes from top to bottom in css (which unity pretty much uses just a old/minimal one)

#

So the offset should need to change at runtime which isn't really a simple or nice thing

#

Or maybe a wrapper around the element with a higher height and have it's child fix to the bottom

#

Not sure, but I think this part is still timberborn original. If you could make a issue on github I could maybe fix it someday. Kinda low on energy last few weeks

compact pewter
#

iirc tooltip box is on the same UIDocument but separate VisualElement/overlay from panels and is positioned by its own component or singleton. Sameish for dropdowns and storage choices. Might be different for bottom bar specifically then maybe hovered VE takes priority in sorting?
Edit: it is just Label with text, something like this code. Idk why it wraps though. Demolish is long too but it doesn't wrap.

    <ve name="ToolGroup" class="tool-group" >
      <ve name="ToolGroupButtonWrapper" class="bottom-bar-button" >
        <ve name="" class="bottom-bar-button--main" >
          <Button name="ToolGroupButton" class="unity-text-element unity-button bottom-bar-button__icon bottom-bar-button__button bottom-bar-button--clickable" >
            <ve name="Frame" class="bottom-bar-button__inner-item bottom-bar-button__frame" />
          </Button>
        </ve>
      </ve>
      <ve name="" class="tool-group__tooltip-wrapper" >
        <NineSliceVisualElement name="" class="bg-box--brown" >
          <Label name="Tooltip" class="unity-text-element unity-label tool-group__tooltip game-text-normal" />
          "Demolish buildings and resources"
        </NineSliceVisualElement>
      </ve>
    </ve>
stone shoal
#

Nvm you are about knattes problem i guess?

stone shoal
compact pewter
#

@vast otter that gave me an idea - maybe using non-breaking space would help? html entity code ย  iirc

vast otter
stone shoal
#

anyone using the specification generator feature ThinkingIT? ISpecificationGenerator

stone shoal
stone shoal
#

@mod(TimberApi.Debug;OtherMod) or just @mod(TimberApi.Debug)@mod(OtherMod)

spring radish
#

for both or either?

#

down that path lies madness,

#

Does ModA;ModB mean A and B have to be enabled? (or A or B has to be enabled).

#

@mod(ModA)@mod(ModB) is probably the simplest?

spring radish
#

another idea: Make it possible to enable/disable append/remove with mod settings,

#

maybe something like @modsetting(ModA.OptionA) which would need to be a boolean

#

from: #๐Ÿค–mod-creators message

stone shoal
stone shoal
#

If not done by emka itself

spring radish
#

yea, you could just use Unity's PlayerPrefs.GetInt

#

that'll work for Mod Settings that use the default ISettings binding,

#

I don't know how many mods are using FileStoredSettings

vast otter
stone shoal
quasi igloo
#

I have an issue, I wonder of someone in here could help me with it.

#

6 mods involved here.
Harmony, Ladders, Emberpelts and Ladders for Emberpelts are enabled for all tests.

Add TimberAPI, it works fine.
Add Bob Storage, it works fine.
Add both, and specifically only while loading a Folktails game, I get that error.

I'm pretty sure the error would happen with only those 2 mods.

stone shoal
quasi igloo
vast otter
quasi igloo
#

okay, that actually loaded

#

I enabled the ExtraLargePile and it worked, and UndergroundTank and it worked, so I'm guessing it has an issue with me using UndergroundWarehouse.Folktails

#

it exists as a background compatible prefab name on the underground pile

#

UndergroundWarehouse.Folktails hasn't existed in Vanilla since U2. In U3 it was changed into the Underground pile, and you can't even load U2 games in U3 or newer, because of the huge change in the storage system.

#

so there's really no reason for the tag to be on there.

#

to test, I did this.
if this still crashes, I'm stuck, because if I don't add the backwards compatible tag here, I'm basically screwing everyone over who's already used the mod

#

okay, it actually worked.

#

I also think it's kinda dumb that it's only a problem with TimberAPI. if the game engine doesn't care if you're using a prefab name that something else has as a backwards compatibility name, TimberAPI shouldn't either.

#

At least I can fix the mod now.

quasi igloo
vast otter
#

Ya it should not care for creating specification if it has backwards compatible names๐Ÿค” in older version of the game it was not allowed to have a building with one name and an other building with it as backwards conpatible name but that was fixed in u5 or u6๐Ÿค”

spring radish
#

Interesting thread: #๐Ÿš€mod-users message. I wonder if TimberAPI should show which mod a Tool comes from

#

It would have to be based on the location of the ToolSpecification file,

stone shoal
spring radish
#

The base game ones don't

stone shoal
#

None does

spring radish
#

oh, you mean the prefab ones don't either

stone shoal
#

All buildings are generated by their prefab

#

For custom tools which almost no one uses yet would have one, or are done by code if they want to

stone shoal
#

For prefabs it might be able to point it back to the prefab group specification files somehow

#

Not specific a TimberApi thing though, everyone could do that ๐Ÿ˜›

spring radish
#

yea, the reason why I though of TimberAPI is because it already reimplements the Tool bar

#

so maayabe adding tracking of where tools are loaded from wouldn't be too impossible,

stone shoal
#

Yea, unfortunately since timberborn is pretty generic with most things getting info back where it came from can be tricky

spring radish
#

but they're loaded from prefabs yea,

stone shoal
#

Yea I use the prefab collection from timberborn, so you would have to track it already down before it goes in there. And also know from which specification it would have been loaded

#

Getting locations from specifications would probably hardest part

spring radish
#

Which spec the toolgroup?

#

really it needs to be attached to the ToolSpecification

stone shoal
#

Not sure what it is called nowadays, there is a specification where people define the buildings

#

Before in update 5 it was just in faction specification

spring radish
#

The PrefabGroupSpec?

stone shoal
stone shoal
#

But I don't even have the energy to get through my work day, so something like this will likely not happen by me and would also be on a low prio compared to other things

spring radish
#

yea, totally

stone shoal
#

I can however try to help you here and there if you are stuck and wanting to make it

spring radish
#

Instead of relaxing and watching some YouTube videos, I spent the evening setting up my new PC so I could update my mods on the steam workshop so they'd have the Mod tag.

spring radish
#

Steam content is tagged with Mod or Map depending on how it's uploaded,

stone shoal
#

You upload mods manually instead of ingame ?

spring radish
#

I couldn't get Timberborn working under Steam, so I used SteamCmd to upload initially, except it can't set tags ๐Ÿ˜•

stone shoal
#

I see

spring radish
#

With new PC, I can now upload in game, so i't s a non-issue now

stone shoal
#

Neet

spring radish
#

and I got a nice increase in graphics quality & fps

stone shoal
#

Thats always good TobbertEZ

stone shoal
#

@spring radish not 100% if you were the one who asked about properties but...

{
  "TestString": "Hello,",
  "TestString@mod(TimberApi.Debug)": "Hello, World.",
  "TestList": [
    "BBB"
  ],
  "TestList@mod(TimberApi.Debug)": [
    "ZZZ"
  ],
  "TestList@mod(TimberApi.Debug)@mod(TimberApi.TesterMod)": [
    "CCC"
  ],
  "TestList@mod(test)": [
    "DDD"
  ]
}

Properties are also working.

Results in:

{
  "TestString": "Hello, World.",
  "TestList": [
    "BBB",
    "ZZZ",
    "CCC"
  ]
}
cinder fern
stone shoal
cinder fern
stone shoal
#

Although it has some limitations, but with this version way les than before

#

Like wildcards are not supported in selectors eg .myclass > * is not possible. But it's also not recommended to do by unity standards

#

Sadly no documentation though sadBlobRegor

cinder fern
#

you have CSS in game development now? DamFT

stone shoal
#

"CSS" yes, It's USS

#

It's like CSS but outdated

#

Here are almost all ingame components as presets you can use

#

And is also an exampe how you can make your own

cinder fern
#

thank you!

stone shoal
#

Just WIP

coral glen
#

@stone shoal
I am getting below error while starting the game.

v0.6.9.3-b880551-xsw
ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length
System.String.Substring (System.Int32 startIndex, System.Int32 length) (at <20a025bba6874f73adca28fec451f638>:0)
PumpExtender.ExtendablePumpSettings.ExtractPumpName (System.String prefabName) (at <1f0ecefd4dff4c698b8f813f7db26505>:0)
PumpExtender.ExtendablePumpSettings.OnAfterLoad () (at <1f0ecefd4dff4c698b8f813f7db26505>:0)
ModSettings.Core.ModSettingsOwner.Load () (at <9508e8c86d724f229ef86851c667d051>:0)
(wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Timberborn.SingletonSystem.SingletonLifecycleService.LoadSingletons_Patch2(Timberborn.SingletonSystem.SingletonLifecycleService)
(wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Timberborn.SingletonSystem.SingletonLifecycleService.LoadAll_Patch1(Timberborn.SingletonSystem.SingletonLifecycleService)
Timberborn.SingletonSystem.SingletonLifecycleAdapter.Start () (at <2cf8a69d91ab4139baf8d8d9e11adc45>:0)

stone shoal
coral glen
#

I just subscribed and trying to start the game.
It didn't get to the menu also. before that only it's crashing. @stone shoal

vast otter
#

have you tried with only Pump extender and its dependenty?

have you tried disable tbmpl mods so its not a collision of mods?

coral glen
#

will try.

coral glen
# vast otter have you tried with only Pump extender and its dependenty? have you tried disab...

Same with all TBMPL mods disabled.

v0.6.9.3-b880551-xsw
ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length
System.String.Substring (System.Int32 startIndex, System.Int32 length) (at <20a025bba6874f73adca28fec451f638>:0)
PumpExtender.ExtendablePumpSettings.ExtractPumpName (System.String prefabName) (at <1f0ecefd4dff4c698b8f813f7db26505>:0)
PumpExtender.ExtendablePumpSettings.OnAfterLoad () (at <1f0ecefd4dff4c698b8f813f7db26505>:0)
ModSettings.Core.ModSettingsOwner.Load () (at <9508e8c86d724f229ef86851c667d051>:0)
(wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Timberborn.SingletonSystem.SingletonLifecycleService.LoadSingletons_Patch2(Timberborn.SingletonSystem.SingletonLifecycleService)
(wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Timberborn.SingletonSystem.SingletonLifecycleService.LoadAll_Patch1(Timberborn.SingletonSystem.SingletonLifecycleService)
Timberborn.SingletonSystem.SingletonLifecycleAdapter.Start () (at <2cf8a69d91ab4139baf8d8d9e11adc45>:0)

vast otter
#

Then the step is to disable a few mods at a time until you find the culpit for why pump extender crashes

coral glen
#

maybe with water beaver/white paws.

stone shoal
#

If he does something weird with it thats not as a normal punp it can cause problems maybe

cinder fern
#

@stone shoal hi, any doc or sample mod I can look at for making a new tool? specificially, I will make a new area selection tool, similar to the tree cutting area marker

#

I guess I will look at the Forest Tool or the Cutter Tool on the Steam Workshop

stone shoal
#

How you should make the tool itself is up to you

young tendon
cinder fern
calm copper
#

TAPI doesn't work in U7, right? It's not just me? ๐Ÿ™‚

brisk ether
#

Correct

stone shoal
#

Not sure when its fixed there are some things to checkout

#

If I have time and energy I'll try the weekend

#

Probably fixed around next weekend for sure

calm copper
stone shoal
#

Already fixed some issues, but the tool system needs some bigger chances due there are no deserializers anymore

calm copper
stone shoal
#

And haven't looked at the bottom bar, yet but I saw at lease some errors

stone shoal
#

Like they check if it should be a string/int and they transform it into that etc..

#

Don't think it's going to be tooo bad. Just a small rework to convert my ToolSpecification to a ToolSpec with blueprints. And make the specification generator work with blueprints

spring radish
#

It might be nice to split out the parts that don't have anything to do with the bottom bar into a separate dll (or even separate mod).

#

like the UI builders,

stone shoal
cinder fern
#

hi I have a mod I would like to upgrade to U7 that uses TimberAPI, should I temporarily disable the feature that uses TimberApi or just wait?

#

I do not mean to rush you or anything, just ask for some estimation of when TimberApi U7 will be available, thanks.

stone shoal
#

I fixed the compiiling errors but it's crying about some public modifier crap

cinder fern
# stone shoal What is the feature you use ?
    public void Load()
    {
        const string LabelName = "Coords";

        panel = builder.Create<VisualElementBuilder>().SetName("HeightShowerContainer").AddClass("top-right-item")
            .AddClass("square-large--green")
            .SetFlexDirection(FlexDirection.Row)
            .SetFlexWrap(Wrap.Wrap)
            .SetJustifyContent(Justify.Center)
            .AddComponent<LabelBuilder>(
                LabelName,
                (builder) => builder
                    .AddClass("text--centered")
                    .AddClass("text--yellow")
                    .AddClass("date-panel__text")
                    .AddClass("game-text--normal"))
            .BuildAndInitialize();

        lblCoords = panel.Q<Label>(LabelName);
        layout.AddTopRight(panel, 7);

        SetVisibility(false);
    }
#

this is all ๐Ÿ˜›

stone shoal
#

I can't use the goddang new specs shit

#

It pretty much depends on this dumb error

#

Which I have no clue why it's happening

cinder fern
#

Publicizer accidentally publicize something that it should not maybe? because the access modifier got changed into public?

stone shoal
#

hmm

#

might be

cinder fern
#

but is it an interface? then that's weird

#

because everything in an interface has to be public.

stone shoal
#

No it's a class

#

A record actually

cinder fern
#

maybe for that one, refer to the original DLL without going through the publicizer?

stone shoal
#

HMM hard to test without publicizing xD

cinder fern
#

oh dear ๐Ÿ˜„

#

and see if you can compile it with the publicizer?

stone shoal
#

Does not like that

#

Butttt maybe I can just remove the publicizer from the dll that includes that record

cinder fern
#

an easy way to find out way to try is to set ILSpy to C# 8 before record, to see what that class actually look like.

stone shoal
#

luckily they have so many

stone shoal
cinder fern
stone shoal
#

Have to specificly do that than ๐Ÿ˜›

cinder fern
# stone shoal

record is just a sugar syntax. behind the scene it add : IEquatable<ComponentSpec> and a generate a bunch of members

#

so if you want to see how the class actually look like in IL, you decompile it in C# 8

stone shoal
#

ThinkingIT is this going to work angel

cinder fern
#

maybe you need a <Reference Exclude="..." /> before?

#

I am not sure

#

one way to find out ๐Ÿ˜›

stone shoal
#

This way no difference, but the publicizer also adds things that say it has been publicized and in that class there exists non

#

Like this

#
        <Reference Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.BlueprintSystem.dll" Publicize="false">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
        <Reference Exclude="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.BlueprintSystem.dll" Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.*.dll" Publicize="true">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>

No luck

#

I guess I just create a new DLL and test specs with it

cinder fern
#

try it to be 3 entries, something like this:

<Ref Include="*">
<Ref Exclude="that-assembly">
<Ref Include="that-assembly">

stone shoal
#
    <ItemGroup Condition="$(UseLocalTimberbornSource)">
        <PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.2"/>

        <Reference Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.*.dll" Publicize="true">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
        <Reference Exclude="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.BlueprintSystem.dll">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
        <Reference Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Bindito.*.dll">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
    </ItemGroup>
#

If I just do this it still has the blueprint imported

cinder fern
#

hmm what if you try this:

#
        <Reference Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.*.dll" Publicize="true">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
        <Reference Update="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.BlueprintSystem.dll" Publicize="false">
        </Reference>
stone shoal
#

wtf is udpate

cinder fern
#

or:

        <Reference Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.*.dll" Publicize="true">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
        <Reference Update="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.BlueprintSystem.dll">
          <Publicize>false</Publicize>
        </Reference>
cinder fern
stone shoal
#

FacePalmLotus lets try things again. I am editing in the wrong csproj

#

Okay the exclude/include in one works

#

I got less errors ThinkingIT

#

But I extend, which still complains... because it's on toolsystems ofc...

#

@quiet delta, publicizing the ComponentSpec dll results in Error CS0507 : 'ToolGroupSpec.EqualityContract': cannot change access modifiers when overriding 'public' inherited member 'ToolGroupSpec.EqualityContract'.

@severe solar had this problem as well at the beginning. Altough he said it was fixed when updating unity. Not sure if this was just coincidence and maybe it's not yet publized ThinkingIT.

But might be a real problem if that makes it impossible to publicize.

#

Anything that comes in though with it will create this problem, extending existing spec. Or just directly ffrom ComponentSpec

cinder fern
#

does TimberAPI need Unity IDE? if not I can clone the code and see if I can try something

cinder fern
#

okay could you commit the current code please, I will try it ๐Ÿ˜›

#

I have incentive to make this one go public as soon as possible lol

stone shoal
#
    <ItemGroup Condition="$(UseLocalTimberbornSource)">
        <PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.2"/>

        <Reference Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.*.dll" Publicize="true">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
        <Reference Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Timberborn.BlueprintSystem.dll">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
        <Reference Include="$(SolutionDir)Timberborn\Timberborn_Data\Managed\Bindito.*.dll">
            <DestinationSubDirectory>libs/</DestinationSubDirectory>
        </Reference>
    </ItemGroup>

In the end this was already enough, don't need to exclude it even

cinder fern
#

wouldn't that cause conflict though? you are refering to two assemblies with the same members?

stone shoal
quiet delta
stone shoal
quiet delta
#

you can try generate your own equality members ๐Ÿค”

spring radish
quiet delta
#

and set proper access modifiers

cinder fern
#

is the problematic code on Git, @stone shoal ? I can compile it just now

#

what do I need to do?

stone shoal
stone shoal
#

And UseLocalTimberbornSource should be true with a Timberborn symlink in the solution root folder

cinder fern
#

yes, I am on update 7, could you point me to the project/class please thanks

stone shoal
#

Otherwise you are using an quite outdated dlls

cinder fern
#

yeah I modified the projects a little bit to use files on my file system

#

it is using U7 asssemblies I extracted ๐Ÿ™‚

stone shoal
#

Maybe i just need to reclone itt and test if that works than KEKW

#

How did you build it .-. because I get another error even without those

cinder fern
#

no just let me try to build to make sure it's right

#

which file are you having the issue right now?

stone shoal
#

TimberApi.Tools, ToolGroupSpec

cinder fern
#

thanks, got it, I was building the wrong project ๐Ÿ™‚

#

same as yours

stone shoal
#

Alright

cinder fern
#

you think using Reflection to fix these 5 easier?

#

it's just an issue with access modifier now, no more inheritance issue

stone shoal
#

Reflections won't let me extend the ToolGroupSpec, and are so slow and anoying to work with

cinder fern
#

huh how so? ToolGroupSpec is public isn't it?

#

Timberborn.ToolSystem.ToolGroupSpec is public, I checked the original assembly. It's not exactly slow you know once you made one static method for it ๐Ÿ˜›

stone shoal
# cinder fern `Timberborn.ToolSystem.ToolGroupSpec` is public, I checked the original assembly...

Not using publicizer isn't going to do it. Reflections are so anoying to work with. Specially in a modding scenario, otherwise it's mostly fine. Even with static magic it's still slower except some cases, it's probably neglectable but with the extra time it takes to work with shrug.

And I have like over 30 erros without publicizer. Not sure if that's all because some won't be checked for some reason.

quiet delta
#

but its (record) hidden equality members may be protected/private

stone shoal
#

How does your publicier work ThinkingIT

quiet delta
#

I have no idea if it works xd

#

I didnt check if it works with these new ComponentSpecs

#

if it won't I will probably add some if to not publicize these members. For bepinex one I guess you have to write some script that will revert this

stone shoal
#

I don't mind a extra step in the setup time, since I don't use CI/CD anymore for publishing.

quiet delta
#

shouldn't be

#

it's a regular static c# script

#

iirc

cinder fern
#
namespace TimberApi.Tools;

public static class  AccessExtensions
{

    static readonly BindingFlags PrivateInstances = BindingFlags.NonPublic | BindingFlags.Instance;
    static readonly FieldInfo ToolButtonServiceToolGroupButtonsField = typeof(ToolButtonService).GetField("_toolGroupButtons", PrivateInstances);
    static readonly FieldInfo ToolButtonServiceRootButtonsField = typeof(ToolButtonService).GetField("_rootButtons", PrivateInstances);
    
    static readonly FieldInfo ToolGroupButtonToolGroupField = typeof(ToolGroupButton).GetField("_toolGroup", PrivateInstances);

    static readonly PropertyInfo BuilderPriorityToolToolGroupProp = typeof(BuilderPriorityTool).GetProperty("ToolGroup", PrivateInstances | BindingFlags.Public);
    static readonly PropertyInfo ToolToolGroupProp = typeof(Tool).GetProperty("ToolGroup", PrivateInstances | BindingFlags.Public);

    public static List<ToolGroupButton> Get_toolGroupButtons(this ToolButtonService s)
    {
        return (List<ToolGroupButton>)ToolButtonServiceToolGroupButtonsField.GetValue(s);
    }

    public static List<IToolbarButton> Get_rootButtons(this ToolButtonService s)
    {
        return (List<IToolbarButton>)ToolButtonServiceRootButtonsField.GetValue(s);
    }

    public static ToolGroup Get_toolGroup(this ToolGroupButton b)
    {
        return (ToolGroup)ToolGroupButtonToolGroupField.GetValue(b);
    }

    public static void SetBuilderPriorityToolToolGroup(this BuilderPriorityTool tool, ToolGroup? toolGroup)
    {
        BuilderPriorityToolToolGroupProp.SetValue(tool, toolGroup);
    }

    public static void SetToolToolGroup(this Tool tool, ToolGroup? toolGroup)
    {
        ToolToolGroupProp.SetValue(tool, toolGroup);
    }

}
cinder fern
#

I can compile your project now ๐Ÿ˜„

#

above is all I needed to write ๐Ÿ˜›

stone shoal
#

To be fair, it probably doesn't because the generation is not updated yet

#

Has nothing to do with that though

#
            var json = JsonConvert.SerializeObject(new
            {
                Id = priority,
                GroupId = "Priority",
                Type = "PriorityTool",
                Layout = "Default",
                Order = (int)priority,
                Icon = $"Sprites/Priority/Buttons/{priority}",
                NameLocKey = "CAN NOT BE MODIFIED",
                DescriptionLocKey = "CAN NOT BE MODIFIED",
                Hidden = false,
                DevMode = false,
                ToolInformation = new
                {
                    Priority = priority
                }
            });

            yield return new GeneratedSpecification("Tools", $"ToolSpecification.{priority.ToString()}", json);
        }
#

They aren't called that anymore, or setup like that. With the new blueprints

cinder fern
#

this is one solution if you are interested in (don't know why my local branch is update_7_luke but the Github fork is update_7):
https://github.com/datvm/TimberAPI/commit/40aec050480b440b40c51d825a601d2b1bef1357

the above change + this to the csproj = can compile:

        <Reference Update="$(GameAssemblies)\Timberborn.BlueprintSystem.dll" Publicize="false" />
        <Reference Update="$(GameAssemblies)\Timberborn.ToolSystem.dll" Publicize="false" />
stone shoal
# cinder fern this is one solution if you are interested in (don't know why my local branch is...

As said previously, I don't want to use this solution. But with your help we at least fastly aknowledged the problem. If I cannot fix this problem within next week I'll use it for time being.

If it wasn't for me being sick the last 2 weeks, and now getting another fever with huge headache. It probably would already be fixed YA_BlueMad.

The solution I want to go for, if it's working would be:

  • Create a new console project in TimberApi, to publicize dll's with the same script they use Github link

This way if there are some changes within their publicizer I can also use it, and might even be better than bepinex publicizer with less obfusication with attributes.

#

Is it just my dumbass project or pc. Or is nuget just refusing to work.

cinder fern
#

yeah you want a publicizer that doesn't publicize those generated methods. I can't believe there isn't already one that you can specify an exception. Like don't publicize members with this name

cinder fern
stone shoal
stone shoal
#

But to be fair, my cloud saves also always crashes with ANY game on ANY platform

#

@cinder fern What happens if you try to install Mono.Cecil on a any TimberApi project within the nuget package manager

cinder fern
#

sorry I already deleted the project ๐Ÿ˜›

stone shoal
#

np

cinder fern
#

try dotnet add package <package name> from the console?

stone shoal
cinder fern
#

okay this is very strange, I am checking BepInEx.AssemblyPublicizer source code to ignore generated record methods, but it should already ignore them:

#
        if (!methodDefinition.IsPublic)
        {
            if (!ignoreCompilerGeneratedCheck && !options.PublicizeCompilerGenerated && methodDefinition.IsCompilerGenerated())
                return;

            if (attribute != null)
                methodDefinition.CustomAttributes.Add(attribute.ToCustomAttribute(methodDefinition.Attributes & MethodAttributes.MemberAccessMask));

            methodDefinition.Attributes &= ~MethodAttributes.MemberAccessMask;
            methodDefinition.Attributes |= MethodAttributes.Public;
        }
#
    public static bool IsCompilerGenerated(this IHasCustomAttribute self)
    {
        return self.HasCustomAttribute("System.Runtime.CompilerServices", "CompilerGeneratedAttribute");
    }
#

I don't know why BepInEx publicize all of them, because these members definitely are CompilerGenerated

#

oh I see, PublicizeCompilerGenerated is not on by default

#

so the publicizer accidentally publicize this property only even though it should not have. In the contrary, it correctly leaves PrintMembers as protected:

    [CompilerGenerated]
    protected virtual bool PrintMembers(StringBuilder builder)
    {
        return false;
    }
#

so it's actually a BepInEx bug, we can fix that

#

found it:

            // Special case for accessors generated from auto properties, publicize them regardless of PublicizeCompilerGenerated
            if (!options.PublicizeCompilerGenerated)
            {
                foreach (var propertyDefinition in typeDefinition.Properties)
                {
                    if (propertyDefinition.GetMethod is { } getMethod) Publicize(getMethod, attribute, options, true);
                    if (propertyDefinition.SetMethod is { } setMethod) Publicize(setMethod, attribute, options, true);
                }
            }
#

so for some reason, they have this special logic

#

which they publicize record's EqualityContract as well

#

I removed that piece of code and now the publicized class is correctly kept as protected:

#

the correct code should be (I added IsVirtual check):

            // Special case for accessors generated from auto properties, publicize them regardless of PublicizeCompilerGenerated
            if (!options.PublicizeCompilerGenerated)
            {
                foreach (var propertyDefinition in typeDefinition.Properties)
                {
                    if (propertyDefinition.GetMethod is { } getMethod && !getMethod.IsVirtual) Publicize(getMethod, attribute, options, true);
                    if (propertyDefinition.SetMethod is { } setMethod && !setMethod.IsVirtual) Publicize(setMethod, attribute, options, true);
                }
            }
#

since if they publicize a virtual method, further developer can do nothing with it

stone shoal
#

Make a PR on them ThinkingIT ?

cinder fern
#

yeah I will. but will probably take them a long time to publish it. I can publish a temp Nuget package if you want to

stone shoal
#

I can do that for time being

cinder fern
#

or I can push a Nuget package and you use that one for now

#

until they push a fix

stone shoal
cinder fern
#

no but you can clone it, and refer to it as a local project

stone shoal
#

Ah yea

cinder fern
#

you can use Git Submodule if you don't want it to be outside of your project

stone shoal
#

I think i'll just add it to my repo and have it locally until fixed with license

#

Thanks for the fix

cinder fern
#

you're welcome

stone shoal
#

Altough I need to do stuff, and am already tired. Will try to fix Tapi tomorrow with it

#

Or maybe in the evening who knows

languid bay
#

huzzah

cinder fern
spring radish
cinder fern
stone shoal
stone shoal
#

Alright, seems the fix is in 0.4.3 so ill just uise that one

#

Fix 1 issue, get 99 back

#

Stupid bepinex feed

#

Probably just problem with my pc but still KEKW

spring radish
#

oof,

#

I had code that compiled fine for Update 6 a month ago, throw errors during compile (about missing assemblies, etc).

#

Nothing should have changed in that month, it's compiling against the same Timberborn code.

stone shoal
#

I changed from bepinex feed unity editor dll's to localized downloaded unity editor dll's they provide.
But those are not publicized so I got other errors, because apperently some are internal for the UIBuilder KEKW

#

Dimension apears to be internal, not sure how that has not yet been a problem with modding though

#

@spring radish you were indeed correct, not sure if this was changed in the 0.7.0.2 version or I just missed it.
Because it complains about BuildingSpec. So how can it complain about that when mods suppose to not be loaded

#

Specifications should not do anything if a mod is not loaded

#

If I disable the mod it doesn't throw the error YA_Confused

#

So it's enabled even though it's not started ThinkingIT

spring radish
#

enabled, but the dlls are not loaded,

#

yea

#

for the missing refs, I can only assume that the .Net dlls for 0.6.9.0 and 0.6.9.4 are slightly different,

stone shoal
#

I think it's just a double bug. While ingame the assetsbundle stuff just looks am I enabled. Yes? okay let's go. Even though the modding scene has not been initialized

spring radish
#

It's a bug in the option,

#

it shouldn't skip loading the dlls

#

based on eMka's response

stone shoal
#

@quiet delta Can this be fixed MomijiHype? The new feature skipModManager which is only for mod developers should not skip the list and not start mods. It should skip the list with the pre enabled list.

Current:

    public void Awake()
    {
      if (this._fileService.HasDocumentsPermissions && !ModManagerScenePanel.ShouldSkipModManager())
      {
        ModRepository modRepository = this.CreateModRepository();
        if (modRepository != null && modRepository.Mods.Any<Mod>())
        {
          if (this.AutoStartingInEditor)
          {
            this.LoadModsAndStartGame();
            return;
          }
          this.InitializeModManagerPanel((IEnumerable<Mod>) modRepository.Mods);
          return;
        }
      }
      this.StartGame();
    }

Should be (pretty sure):

    public void Awake()
    {
      if (this._fileService.HasDocumentsPermissions)
      {
        ModRepository modRepository = this.CreateModRepository();
        if (modRepository != null && modRepository.Mods.Any<Mod>())
        {
          if (this.AutoStartingInEditor || ModManagerScenePanel.ShouldSkipModManager())
          {
            this.LoadModsAndStartGame();
            return;
          }
          this.InitializeModManagerPanel((IEnumerable<Mod>) modRepository.Mods);
          return;
        }
      }
      this.StartGame();
    }
spring radish
#

They know, see #๐Ÿš€mod-users message and #๐Ÿค–mod-creators message

stone shoal
#

Ohh

#

Too much going on, didn't see

stone shoal
#

@quiet delta, I am trying to use the [Context("Bootstrapper")]. But it gives me isn't instantiable due to missing dependency:. The context is working as I can log it but a child context can't use it's singletons.

Beforehand everything what was in the bootstrapper could be injected into a child. But this has changed or removed ThinkingIT.

I was using this to keep a cached version of the prefab specifications and just generate whenever there would be a new version available. Which for prefabs is never after the first time.

#

Small test

#

[Error : Unity Log] BinditoException: ChildPlay isn't instantiable due to missing dependency: TestingBootStrapper. Dependency chain: ChildPlay => TestingBootStrapper.

quiet delta
#

not 100% sure, but I think .AsExported() option is for this case

#

you can try it

stone shoal
#

Was that always there

quiet delta
#

nope, new thing

stone shoal
#

Yep works

#

hmm

#

Don't understand the usecase compared to other behaviour shrug

#

Just making sure something isn't used outside of it I suppose

quiet delta
#

yes, something like that

stone shoal
#

Wait can I export it from MainMenu as well to Game

#

It will just be trashed right ThinkingIT Testing. Yeah it's not there anymore than

#

So it's just for bootstrapper ๐Ÿ˜›

quiet delta
#

yes, it should work for child context only, in our case Bootstrapper => the rest

stone shoal
#

Yeah but I could see something like

  • Do some logic in main, push it to the other scenes
  • Goes to Game
  • Comes back to main, wants to refresh with a load state and push the new one to rest
#

No idea when you would want to use it KEKW. But I also don't think it would be the weirdest thing

quiet delta
#

well we have to pass faction id or map name from main menu to game when starting new game, so maybe there actually are some use cases for this behavior ShrugIT

stone shoal
#

Would help all with loading issues if before game configurators are loaded the faction was already known tbh.
Edit: forgot I changed the loading order to access prefabs so specs can be generated on it before anything else. This can't solve that

stone shoal
#

WTF

stone shoal
#

[Error : Unity Log] Exception: Multiple blueprints found for Timberborn.SoundSystem.AudioMixerGroupRetrieverSpec

#

How did it become multiple

#

Ahh, I at least got in game. With like 3 out of 6 dll's

#
        harmony.Patch(
            harmony.GetMethodInfo<FactionSpecService>(nameof(SpecService.Load)),
            harmony.GetHarmonyMethod<EarlyLoadPatcher>(nameof(Test))
        );

Struggled 30 minutes or so with this...

#

Patched the wrong class FactionSpecService -> SpecService

stone shoal
#

Time to fix the next bug

#

Enabling Tools system

#

I think it crashes on generating them ThinkingIT

quiet delta
#

Make sure that there exists at least one spec that you are trying to get from SpecService, because there is a bug that it will throw NRE if it won't find any

stone shoal
#

ThinkingIT although I knee that. It feels not the issue. Since my patch isnt being called that should prevent that method call.

#

But also have not yet tried to fix the generators so.. maybe

stone shoal
#

Timberborn.BottomBarSystem.BottomBarPanel.Load () (at <5554b898465f4cbcb2aad4741c1f9eb3>:0) This is so confusing

#

harmony.GetMethodInfo<BottomBarPanel>(nameof(BottomBarPanel.Load))
I am patching that method, but it's not logging

#

If I do the patch in a different location it works

#

But this one is special because it needs to unpatch when it's not ingame

#

Except it looks like it's not even patching anymore while registring the patch...

#

Okay, so the patch is somehow too slow. Even though the patch method is called before the crash ThinkingIT

stone shoal
#

Yashhh

#

I think I patched the wrong class previously when testing

#

But I changed the SceneManager to ContextManager which will trigger when a new context will be loaded.
Since Timberborn now also uses their [Context] attribute the scene manager patch is not as early as before which failed to patch a configurator

#

New error unlocked MomijiHype

#

We're finally at the not completely converted Spec's. So almost fixed I think.

spring radish
#

oh? So some steady (albeit annoying) progress

stone shoal
#

@quiet delta, I might have a small problem with the new blueprint system.

You are only allowed to have 1 typed name (only class name counts namespace is excluded).
Extending with that I cannot use a existing spec and extend onto it.

Do you know if it still might be possible to create an extension of a blueprint somehow?

public record TimberApiToolGroupSpec : Timberborn.ToolSystem.ToolGroupSpec
{
    [Serialize]
    public string Type { get; init; }

    [Serialize]
    public string? GroupId { get; init; }

    [Serialize]
    public string Layout { get; init; }

    [Serialize]
    public string Section { get; init; }

    [Serialize]
    public bool DevMode { get; init; }

    [Serialize]
    public bool Hidden { get; init; }
}
#

ThinkingIT maybe I could just add a seperate spec with the additional data and fetch that from within ToolGroupSpec. This should not create problems right

#

And I can go from either way, from the additional data spec to the ToolGroupSpec

quiet delta
#

idk, if it isn't possible it will have to be in the future, because building's specs are using inheritance ๐Ÿค”

#

you can try using SpecAlias attribute

#

but I doubt naming is the problem here

stone shoal
#

Naming of the probs are not the problem. Just double names of the spec classes

stone shoal
# quiet delta idk, if it isn't possible it will have to be in the future, because building's s...

I don't think inheritance in itself is a problem. But previsouly I used the ToolGroupSpecification files with a different deserializer. Since that's not automatic I can say I want to have all ToolGroupSpec's but convert it to my class instead of the Timberborns class.

Which I don't think you guys would need in the game since it would just be a completely new spec with additional data. Instead of the same spec with data added

#

If that makes sense ๐Ÿ˜…

quiet delta
stone shoal
stone shoal
#

ThinkingIT, Expected making a ToolGroupExtensionSpec would be a bit smoother.

foreach (var toolGroupSpecification in toolGroupSpecificationService.ToolGroupExtensionSpecs.OrderBy(x => x.Layout).ThenBy(x => x.GetSpec<ToolGroupSpec>().Order))

Does not quite feel nice

quiet delta
#

or is it something else

stone shoal
#

Preferably, the game can just run fine with their logic and me not needing to patch usecases where ToolGroupSpec normally would be used.

#

I just want to add extra params to an existing spec.

quiet delta
#

in that case I think the best approach would be to add new specs (components) to the blueprints with original ToolGroupSpec

stone shoal
#

Ye that's what I am trying to do now. But I need to do quite some .GetSpec<XXX>() within loops, which don't seem very nice to do. Not sure what the performance impact would be though.

#

I don't think they are mostly in loadable singletons so it doesn't have that much of an impact.

stone shoal
stone shoal
#

(โ•ฏยฐโ–กยฐ)โ•ฏ๏ธต โ”ปโ”โ”ป

#

GeneratedSpecs are now later than the SpecService... but it caches now instead of getching it on demand with the IAssetLoaders

#

How am I going to update the SpecService with generated specs

cinder fern
#

not sure if you like this approach but in one of my mod, writing a Bindito.Core.IContainerDefinition.Unbind helps a lot ๐Ÿ˜›

stone shoal
#

Not sure how that would help

#

I need the SpecService, to add to an existing spec. But how can I need it and generate it

cinder fern
#

think of it like Harmony patching but with official capacity (i.e. you are not stuck with a static method)

#

if SpecService doesn't let you expand on it officially, you can Unbind it and wrap it with your own implementation. similar to Decorator

stone shoal
#

That would not solve that I require it to be active before the generator can be active

cinder fern
#

yes... and what runs before everything else? ๐Ÿ˜›

#

the Configurator

stone shoal
#

Either I am writing it wrong, or you are reading it wrong ThinkingIT

#

The SpecService needs to be ran before the generator can be ran due other dependencies for the generator. So I cannot just unload it

cinder fern
#

but you can inject yourself to prepare for it? I am not sure what generator is but if it's inside the DI system still, then I don't see why not.

#

in that case, inject yourself before/wrap the generator?

stone shoal
#

It's a dependency loop

cinder fern
#

that's impossible. something has to be before something else ๐Ÿ˜›

stone shoal
#

Well with this update it now has to be at the same time. Or I need a way to add to it later on

cinder fern
#

anyway after I am done with this mod, I am happy to look at it if you still need some manpower ๐Ÿ˜›

stone shoal
#

Maybe something with modified blueprints, but i don't understand how to use that yet

cinder fern
#

I am working with the Specs thingy right now

#

but I have Harmony so it's a bit easier for me

stone shoal
#

Same but also won't solve this problem ๐Ÿ˜›

#

@cinder fern You know the usecase and how to use the ModifedSpecs option is for ?

#

Since it looks like if you still use GetSpecs it doesn't do anythin

cinder fern
#

not sure why, that's the only code point I see is invoking it

#

I think I have seen something before... that uses something similar... I can't recall it

quiet delta
#

Are you providing generated specs using custom IAssetProvider? If so it should be loaded before SpecService

stone shoal
#

Unless maybe just using the asset loader and just checking the names ThinkingIT

calm copper
#

@stone shoal Remember, long time ago, in TAPI, the sliders didn't have the horizontal line visible? At some point it got fixed. Did you do anything? Do you remember what?

stone shoal
#

I didn't change anything

calm copper
#

idk, I just recall there was the problem, and then it gone. In the meantime, while you're fixing TAPI for U7, I thought I can quickly make styles for MixMax slider myself. It works fine in Unity, but not in the game.

stone shoal
#

With just unity USS ?

calm copper
stone shoal
#

That's neet

calm copper
# stone shoal With just unity USS ?

Yes. I create Minmax Slider in Unity, apply styles and the preview works fine. When I make the asset and load it in the game - no horizontal lines.

stone shoal
#

Maybe timberborn makes it invisible

#

It has a global thing to remove all styling of unity at first

#

Or maybe its disabled with an option idk

calm copper
calm copper
#

Hmm, obviously, the game does something to the controls. I just created MinMaxSlider and added my style that addresses the elements by their names (e.g . #unity-thumb-min). Clearly, the thumbs style worked (the sprites are there), but instead of the dragger controls, I got an empty button to the right. Hmm.

@quiet delta any idea what's happening here? Why cannot we just make a control and apply a style to it?

quiet delta
#

are you using uxml and uss files or is it generated by the code?

calm copper
#
    var stylesheet = _assetLoader.Load<StyleSheet>("UI/Controls/TimberbornStyle");
    var element = new MinMaxSlider();
    element.styleSheets.Add(stylesheet);
#

The rectangle to the right of the control seems like a button 9-slice. And it definitely shouldn't be there. As far as I can tell, the #unity-dragger transforms into this thing when the height is large enough (10-20px), when it's too small (1-2px), it's just not visible.

#

I think, I got it. Unity doesn't see the images. And it's really strange since it does see the thumbs images!

quiet delta
#

oh, ofc, I forgot about it. It's one of my biggest problems with UI toolkit & modding - you can't define your own images in your uss files, as they can be only loaded from original Resources (or addressables iirc), so only the built in images can be set this way. You have to set backgrounds/sprites etc from the code

quiet delta
calm copper
quiet delta
#

you can send me the uxml and uss you started with, I will take a look why the images loaded properly

calm copper
stone shoal
#

I thought I had custom images working with USS ThinkingIT. If you use USS and UXML and the image in same project

#

Could be wrong

calm copper
stone shoal
#

What does your uss look like ?

calm copper
#
#unity-dragger {
    background-image: resource('UI/Backgrounds/bg-pixel-4');
    min-height: 4px;
    height: 4px;
}

#unity-thumb-min {
    background-image: resource('UI/Images/Buttons/circle-on');
    min-width: 16px;
    min-height: 16px;
}

#unity-thumb-max {
    background-image: resource('UI/Images/Buttons/circle-on');
    min-width: 16px;
    min-height: 16px;
}

#unity-tracker {
    min-height: 1px;
    background-image: resource('UI/Backgrounds/bg-pixel-2');
}
#

It doesn't complain about the buttons. But it does about the backgrounds.

#

Maybe, I need to refresh the project ๐Ÿ™‚

stone shoal
#

Im not sure if it was a problem with USS as wel but I had a weird ass problem that it would not compile correctly if I had the UIBuilder open of unity

#

So, do you have your UXML UIBuilder open in unity while compiling ๐Ÿ™‚ ?

calm copper
stone shoal
#

When you press that button, do you have the UIBuilder open of the UXML?

#

The editor of it, pretty sure it was called UIBuilder

stone shoal
calm copper
stone shoal
#

ThinkingIT, I thought you were using UXML ?

calm copper
#

I make resources in Unity, compile them, then load from the game.

stone shoal
#

Okay, save it. Close it and than press the build button

calm copper
stone shoal
calm copper
#

The error from the log, it says exactly what's wrong: the image is not found. Even though, it should be.

stone shoal
#

capitals are correct ?

#

Did you recheck the path with newest update?

calm copper
stone shoal
#

shrug something must be wrong

#

Why does it say pixel-22

#

Can't remember there being that many ThinkingIT And i your USS you have bg-pixel-2

#

nvm, that was from your own

quiet delta
#

it should be 'UI/Images/Backgrounds/bg-pixel-2' (you are missing Images directory in the path)

calm copper
#

trying...

#

It's a progress! The margins I can fix easily, but the "empty button" to the right makes me guessing. I didn't request it. Anyways, thank you @quiet delta !

#

So, we cannot use custom sprites/textures in the controls. Ack.

#

FYI the uss:

#unity-dragger {
    background-image: resource('UI/images/backgrounds/bg-pixel-4');
    min-height: 1px;
    height: auto;
}

#unity-thumb-min {
    background-image: resource('ui/images/buttons/circle-on');
    min-width: 16px;
    min-height: 16px;
    margin-top: -6px;
}

#unity-thumb-max {
    background-image: resource('ui/images/buttons/circle-on');
    min-width: 16px;
    min-height: 16px;
    margin-top: -6px;
}

#unity-tracker {
    min-height: 2px;
    background-image: resource('UI/images/backgrounds/bg-pixel-2');
}
#

The path cases are different, but it seems it's not the problem.

quiet delta
#

there could be an additional IVisualElementInitializer, that would search for property like "--mod-background-image" and would load image from provided and set it, similarly to what UISoundInitializer is doing currently. Maybe it's something that TimberApi could offer, maybe it could be built in into the game ๐Ÿค”

calm copper
#

I still need the "blackjack and stuff" from outside ๐Ÿคฃ

#

In fact, forget the park.

austere tangle
#

Never say "TAPI is falling", or, without More Group, bottom bar will be a disaster ๐Ÿคฃ

stone shoal
#

Can check it out if it's neccesary after I get TimberAPI back to be working

#

The SpecGenerator is just.... not wanting to go

#

For the spec generator I need the faction objects, which require the SpecService sadBlobRegor

quiet delta
#

I have a similar problem, as I want to get rid of GetModifiedSpecs method, so the Blueprints would apply their modifiers themselves when calling GetSpecs.

#

so I may come with some solution

#

in a month or so xd

stone shoal
#

Adding specs don't sound tooo hard (I think). But changing existing specs with the generated specs absolute no clue.

#

For example, adding my ToolGroupExtensionSpec into the existing ToolGroupSpec files.

quiet delta
#

oof, looks like a pain indeed, because all of this immutability.

stone shoal
#

Was it really slow so that it had to be cached ?

quiet delta
#

I didn't check it, it just felt right to cache deserialized blueprint instead of processing it over and over. On the other hand we didn't want to deserialize them all at once during the Load of each scene (mostly because invalid blueprints from the game would crash in main menu)

stone shoal
#

Yeah understandable

#

I myself like caching as well KEKW

#

Maybe just additional functionality to addon to it or modify it. Altough that's probably more a modding requirement than a basegame one.

stone shoal
#

@quiet delta I know it's stupid but how comes that if I run SpecService.Load again after I cleared _cachedBlueprints it complains about a blueprint receiving it twice ThinkingIT

#

Is it cached at multiple places ?

#

Oh it does not even add a duplicate ThinkingIT

stone shoal
#
        // Reloads the spec server, because everything is cached now. This is unoptimized but it is how it is for now.
        // Might give problems with faction specs if they would have changed.
        specService.GetType()
            .GetField("_cachedBlueprints",BindingFlags.Instance|BindingFlags.NonPublic)!
            .SetValue(specService,new Dictionary<Type, List<SpecService.CachedBlueprint>>());
        
        EarlyLoadPatcher.BlockLoading = false;

        specService.Load();
        factionSpecificationService.Load();
        
        EarlyLoadPatcher.BlockLoading = true;
#

Yes...

#

Well tomorrow I can fix the generators and see if it worked out

#

It's awefully ugly but, it's the only way I can see

spring radish
#

If it works, sounds good

stone shoal
#

It seems to complain about "specs" being unproperly deserialized. Well obviously because they are still like the old specifications

#

But it at least tells that the generated stuff is actually loaded by the blueprints. Before the game can complain about specs

#

With the exception of FactionSpec. can't generate those ๐Ÿ™‚

quiet delta
#

That's the one that probably doesn't need to be generated at runtime anyway

stone shoal
#

Exactly

stone shoal
#

old:

var json = JsonConvert.SerializeObject(new
{
    Id = prefab.PrefabName,
    GroupId = placeableBlockObject.ToolGroupId,
    Type = "PlaceableObjectTool",
    Layout = !wonder ? "Default" : "WonderDefault",
    Order = placeableBlockObject.ToolOrder,
    Icon = labeledEntitySpec.ImagePath,
    NameLocKey = labeledEntitySpec.DisplayNameLocKey,
    labeledEntitySpec.DescriptionLocKey,
    Hidden = false,
    DevMode = placeableBlockObject.DevModeTool,
    ToolInformation = new
    {
        prefab.PrefabName
    }
});

new:

var json = JsonConvert.SerializeObject(new
{
    ToolSpec = new
    {
        Id = prefab.PrefabName,
        GroupId = placeableBlockObject.ToolGroupId,
        Type = "PlaceableObjectTool",
        Layout = !wonder ? "Default" : "WonderDefault",
        Order = placeableBlockObject.ToolOrder,
        Icon = labeledEntitySpec.ImagePath,
        NameLocKey = labeledEntitySpec.DisplayNameLocKey,
        labeledEntitySpec.DescriptionLocKey,
        Hidden = false,
        DevMode = placeableBlockObject.DevModeTool,
    },
    PlaceableObjectToolSpec = new {
        PrefabName = prefab.PrefabName 
    }
});
#

I'm not 100% sure yet, but the thing I might dislike about the new blueprint system is the lack of default options.

#

Previsouly I could just fill any empty or missing properties. This way the whole spec becomes null so need to default it on multiple places.

#

Something like GetSingleSpecOrDefault returning a default class might be neet ThinkingIT

#

That way you can make the spec optional and act as if it would be on there anyway in places that would make sense

#

Use case example:

var json = JsonConvert.SerializeObject(new
{
    ToolSpec = new
    {
        Id = "SettingBox",
        Type = "GenericTool",
        Layout = "GrouplessRed",
        Order = 1000,
        NameLocKey = "CAN NOT BE MODIFIED",
        DescriptionLocKey = "CAN NOT BE MODIFIED",
        Icon = "Sprites/BottomBar/Options",
        DevMode = false,
        Hidden = false,
    },
    GenericToolSpec = new {
        ClassName = typeof(SettingBoxTool).FullName
    },
    BottomBarSpec = new
    {
        Section = 2,
    },
});

The BottomBarSpec is in this case 2. But for almost all specs it's 0.
But that spec retrieved in multiple parts of the codebase, which all require a null check and defaulting to 0. Which is not handy when refactoring or if it is required in another place and need to check what the default value was again.

#

That said, you could argue why isn't it in the ToolSpec or just always add it.

#

Which in my scenario might just be unique, and the reason is that my ToolSpec isn't neccesary a bottombar. But it requires to be there as a default fallback

spring radish
#

couldn't you assign a default value in the class?

#

oh, it's not a class, it's a record

#

the base game uses a class that inherits from BaseComponent

#

errr, for some specs

#

BasicDeserializer has a GetDefault function

#

ahh, you have to mark the field as optional,

#

eg: ```cs
[Serialize(isOptional: true)]
public int Section { get; init; }

stone shoal
#

But it needs to exist with the current system

spring radish
#

ohhh, that would only work for

BottomBarSpec = new {},
stone shoal
#

Which isnt much lf a problem for me generating. But I when creating a new tool makijg that required feels bit much

spring radish
#

yea

#

Why don't you defined an extension method on SpecService?

stone shoal
#

I was just thinking about it

#

Altough it can't be cached sadly, and needs to be on blueprint instead

spring radish
#

That's how I "hide" my reflection

#

Why on blueprint instead of SpecService?

#

blegh, SpecService is internal

#

shouldn't be an issue if it's publicized,

stone shoal
#

SingleSpec in SpecService is wanting a single spec of all files.
I need to be on Blueprint for the GetSpec because I want to get another spec within a existing blueprint

spring radish
#

why don't use use ?. accessors?

#

i.e. instead of blueprint.GetSpecOrDefault<BottomBarSpec>().Section I think it would be blueprint.GetSpec<BottomBarSpec>()?.Section

stone shoal
#

That would return a null

spring radish
#

even if Section is an int?

#

what about blueprint.GetSpec<BottomBarSpec>()?.Section ?? 0 then?

stone shoal
#

Yes because section does not exist

stone shoal
#

Requiring to check up a default value of an input whenever I need it.

#

And when refactoring it's worse

spring radish
#

you mean when you want a default value that isn't the "zero" value?

stone shoal
#

Yeah

spring radish
#

sounds like you want SerializeAttribute to have a default value?

stone shoal
#

it does, with optional (Ithink )

#

But it's not the spec itself

spring radish
#

no, then it defaults to the "zero" value,

#

I mean to set the default value to something else,

stone shoal
#

Can't you just fill in the default value and set it to optional. Then the default value won't be overriden ?

spring radish
#

?

#

I mean something like:

    [Serialize(default: 2)]
    public int Section { get; init; }
stone shoal
#
public record BuilderPriorityToolSpec : ComponentSpec
{
    [Serialize(true, null)] 
    public Priority Priority { get; init; } = Priority.High;
}
spring radish
#

(isn't supported in the code at the moment)

stone shoal
#

I think this should work just fine right ?

spring radish
#

I don't think records allow that

stone shoal
#

It doesn't give me an compile error at least

#

Will check it out later

spring radish
#

yea, that seems to work,

#

is that not sufficient?

stone shoal
#

No, because it's not the class..

spring radish
#

oh, because the spec is null,

stone shoal
#

GetSpec gives null.. so a default value in a non existing object will not

#

But with the extension method I can problably just add it

#

Check if it exists or create new

#

Altough who knows, maybe it is just better to let the users fill it in all the time shrug

#

Seems just a bit too much work ๐Ÿ˜…, while it's 99% the same

spring radish
#

so, you could do:

public record BuilderPriorityToolSpec : ComponentSpec
{
    public Priority Priority { get; init; };

    public static BuilderPriorityToolSpec Default = new BuilderPriorityToolSpec {
        Priority = 2;
    };
}

and with usage:

var p = (blueprint.GetSpec<BuilderPriorityToolSpec>() ?? BuilderPriorityToolSpec.Default).Priority;
#

kinda ugly though

stone shoal
#

I would prefer to make a GetSpecOrDefault method. Which would return a new instance of the spec when not existing

spring radish
#

yea, you may even be able to define a way to register Spec defaults (maybe via a binding)

#

although it would be nice to define it near the spec,

#

like: Bind..UseThisFunctionToGetADefaultFor...ThisSpec

stone shoal