#TimberAPI

1 messages · Page 8 of 1

humble steeple
#

just making sure

stone shoal
#

Yes

humble steeple
#

kk

#

You don't do a release build on github using github actions?

stone shoal
#

No, not anymore at least

humble steeple
#

Did the yml break?

severe solar
#

imagen using github to host mods ChillBar_puke

humble steeple
#

Github is usually THE place to get the LATEST update of anything.

#

its straight from the dev, no middle man, no steam, no bs

severe solar
#

if the dev commits KEKW

humble steeple
#

This is true. lol

stone shoal
# humble steeple Did the yml break?

I completely rewritten the codebase and the CI doesn't work on that anymore.
It requires game assets which is just anoying to update
I need to upload it to 2 other places already
It makes my local build more complex just to make CI also working

humble steeple
#

ah

stone shoal
#

No one looks at github releases anyway, had it automaicly upload to mod.io, but now there is a steam as well so at some point Ill just make a upload mod that can do both 🙂

humble steeple
#

Would you do me a solid and push this latest build to github so i can mess around with it and possibly contribute to the project if you want?

#

side note: downloading that steam updater thing now and testing that out.

stone shoal
#

It's not super easy and straight forward setup

humble steeple
#

lol i'm good dude. I'm fairly competent with c#. 😛

stone shoal
#

Well it's a custom setup with some weird stuff 🙂

humble steeple
#

Well, this should be fun then. 😛

stone shoal
#

Because nuget of bepinex just decided to stop working so I needed something else

humble steeple
#

If i can't figure it out then screw it, but hey at least i tried right? lol

#

Bam it worked

#

thank you

#

also i didn't need that mod, simply closing it, unsubscribing, and resubscribing fixed it.

#

Which i did before i installed the mod. lol

#

hey whatever, it works now, idgaf how it works, it does and thats what matters lol

spring radish
humble steeple
#

Yea, i'll test that next time. 😄

cinder fern
#

so you actually only needs Moddable Bindito + TimberApi = crash

stone shoal
#

In that case it's pretty clear what the problem is and cannot be fixed at this moment

#

Maybe I will check if I feel enough for more complex problems. But so far there wasn't really a good other way

cinder fern
#

oh and I see it's not a Harmony patch, but actually Reflection:

        specService.GetType().GetField("_cachedBlueprints", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(specService, new Dictionary<Type, List<Lazy<Timberborn.BlueprintSystem.Blueprint>>>());
        EarlyLoadPatcher.BlockLoading = false;
        specService.Load();
#

that's why you get a Null Ref there, the wrapped instance doesn't not have _cachedBlueprints

stone shoal
#

Ah yea doesn't get thru extension

spring radish
#

hmm, am I doing something wrong here, I'm trying to add two NineSliceVisualElement with the UIBuilder,

#

I have their background images set differently, but the UI shows the same image for both.

#

it uses the sprite from the first element for both,

#

if I change the order in which I add them to the root, then the image changes,

#

and the only different is:

      modItem.Root.Add(unavailableImage);
      modItem.Root.Add(downloadPendingImage);

vs

      modItem.Root.Add(downloadPendingImage);
      modItem.Root.Add(unavailableImage);
#

it's weird because the NineSliceButtons next to them are fine,

stone shoal
#

How did you create the elements ?

spring radish
#
      var unavailableImage = _uiBuilder.Build<UnavailableImage>("UnavailableImage");
      modItem.Root.Add(unavailableImage);
      var downloadPendingImage = _uiBuilder.Build<DownloadPendingImage>("DownloadPendingImage");
      modItem.Root.Add(downloadPendingImage);
#

UnavailableImage uses unavailable-image as the class,

#

DownloadPendingImage uses download-pending-image as the class

stone shoal
#

Can you show the class in as hole

#

And did you add them as transient in bindito or singleton ?

spring radish
#

as transient:

      Bind<UnavailableImage>().AsTransient();
      Bind<DownloadPendingImage>().AsTransient();
stone shoal
spring radish
stone shoal
#

Yeah seems just fine

#

It's done how it should be

#

Need to sleep now, but can see if I can replicate it

#

modItem is just an empty visual element ?

spring radish
#

It's the mod row in the mod list, so it has a checkbox, text element, and maybe Mod Settings button,

#

I can zip my working copy if that'll help debug, but I assume you'll want a smaller reproduction case anyways

#

you can also just apply those files on top of my git repo and comment out the parts that make the images optionally visible (because I didn't bother to include the files that detect the current state)

stone shoal
#

Didnt check your code much

#

But the ui oarts are build fine

#

Weird behavior. Can only rhink that kt has a reference to it or something

#

You dont have other mods enabled?

spring radish
#

only:

- Harmony (v2.3.3)
- More Mod Logs (v0.1.0)
- Mod Manager (v3.0.4)
- Mod Settings (v0.7.2.0)
- TimberApi UIBuilder (v1.0.0.1)
- Steam Update Buttons (v0.1.2)
- Tool Finder (v0.0.5)
- Web UI (v0.1.4)
#

If I convert one of the images (both are NineSliceVisualElement), into a NineSliceButton, then the images show differently

#

of course it uses VisualElementBuilder instead of ButtonBuilder too then

spring radish
#

The uxml looks correct:

    <ui:Image name="ModIcon" class="unity-image mod-item__icon mod-item__icon--cloud" />
    <ui:Label name="ModName" text="Web UI" class="unity-text-element unity-label mod-item__name" />
    <ui:Label name="ModVersion" text="v0.1.3" class="unity-text-element unity-label text--yellow mod-item__version" />
    <ui:VisualElement name="WarningIcon" class="warning-icon" />
    <Style></Style>
    <Style>.unavailable-image {
    background-image: resource("sprites/statusicons/stranded");
}

.unavailable-image {
    height: 28px;
    width: 28px;
    margin-left: 7px;
}
</Style>
    <NineSliceVisualElement name="UnavailableImage" class="unavailable-image" />
    <Style></Style>
    <Style>.download-pending-image {
    background-image: resource("ui/images/game/ico-child-grow");
}

.download-pending-image {
    height: 28px;
    width: 28px;
    margin-left: 7px;
}
</Style>
    <NineSliceVisualElement name="DownloadPendingImage" class="download-pending-image" />
    <Style></Style>
    <Style>.update-button {
    background-image: resource("ui/images/buttons/migration/allow-emigration");
}

.update-button:hover {
    background-image: resource("ui/images/buttons/migration/allow-emigration-hover");
}

.update-button {
    --click-sound: "UI.Click";
    height: 28px;
    width: 28px;
    margin-left: 7px;
}
</Style>
    <NineSliceButton name="UpdateModButton" class="unity-text-element unity-button update-button" />
stone shoal
stone shoal
#

@spring radish did you already found the problem?

spring radish
#

not really. I found that if I add unity-button class to one of the images (not both), then it behaves correctly.

#

so that's my workaround for now

stone shoal
#

@spring radish GetModListView does not exist ThinkingIT, is it an extension method of yours ?

#

Foudn iit in the github

#

Okay okay

#

I have it at least replicated

#

Altough I don't quite think it's much of a TimberApi problem, but more like how unity and USS work in combination ThinkingIT

#

It's not the cache stylesheet

#

It's not the creation order that matters either

spring radish
#

yea, super weird

stone shoal
#

It's really just the position of the element

spring radish
#

position?!?

#

in that first one wins, yea

stone shoal
#

yeah

#

But it doesn't even use the same classname

#

Which is just weird

spring radish
#

yea

#

and did you try adding unity-button class?

#

did you try adding to both?

stone shoal
#

Wym ?

spring radish
#

in the image classes, add a line for AddClass unity-button

#

if you only add it to 1 image, then everything looks fine,

#

if you add it to both images, then there's an even weirder behavior

stone shoal
#

And when swapped around it's invisible thonkeyes

spring radish
#

do you get the mouseover effect?

#

it's the 2nd image when mouseover, otherwise the 1st image?

stone shoal
spring radish
#

heh

#

Quicker to test with -skipModManager 🙂

stone shoal
spring radish
#

I wondered if it's the number of classes, but nope it has to be that specific class.

#

or at least adding unity-text-element instead doesn't seem to have any effect

#

I'm wondering if it miight be a Unity bug,

stone shoal
#

Yeah checking that out now

spring radish
#

btw, I noticed that UIBuilder seems to add an empty Style element. Is that accurate, or does the UXml dumper I'm using missing something.

stone shoal
#

I would only expect an empty one if you didn't add styling to it. But not when you do

spring radish
#

yea

stone shoal
#

But maybe if you initialize an element with new it already has an inline stylesheet or something

spring radish
#

hmm, I could move the styles into one class, then it would put them into a single style element right?

stone shoal
#

Yes but they should not work on other elements, at least that was my expectation always

#

But with the exporter it feel different, altough the exporter might not represent the whole truth shrug

#

Since the stylesheet is linked to the object and when exporting it isn't anymore

#
        <Style>
            .download-pending-image {
                background-image: resource("ui/images/game/ico-child-grow");
            }

            .download-pending-image {
                height: 28px;
                width: 28px;
                margin-left: 7px;
            }
        </Style>

Doesn't even feel like it works in unity ThinkingIT

spring radish
#

ack, yea, moving it to other classes doesn't work

stone shoal
#

Okay the <style> brackets don't work in the unity editor at all

#

So I think that's just an export visually wrong

#

The style's I create should react as files anyway just the same as other StyleSheets

#
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:tb="Timberborn.CoreUI" xsi="http://www.w3.org/2001/XMLSchema-instance"
         engine="UnityEngine.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd"
         editor-extension-mode="False" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="Timberborn.CoreUI file:/G:/Development/Timberborn/TimberPrint.Unity/UIElementsSchema/Timberborn.CoreUI.xsd">
    <ui:VisualElement>
        <Style src="/Assets/Mods/TimberPrint/AssetBundles/Resources/UI/Views/Poggies.uss" />
        <Timberborn.CoreUI.NineSliceVisualElement name="DownloadPendingImage" class="download-pending-image" />
        
        <Style src="/Assets/Mods/TimberPrint/AssetBundles/Resources/UI/Views/Poggies_other.uss" />
        <Timberborn.CoreUI.NineSliceVisualElement name="DownloadPendingImage" class="unavailable-image" />
    </ui:VisualElement>
</ui:UXML>
#

This looks fine

spring radish
#

yea

#

as you say the uxml export is probably wrong

#

It's something I added to the Unity code

#

because it didn't have it,

stone shoal
#

Ah okay

#

Altough if I export them to files and import it in the UXML as I think it would convert to ingame

#

It seems to work

#

Soo.... maybe I still do something wrong

#

But I don't have the mental energy to go deeper atm. For me it's already a wonder I came this far

#

If you want to test something, you could test like making a fragment in game. And than adding those 2 elements in there and see if it's the same behaviour

#

Otherwise it's maybe something with that box that conflicts

#

You can also as a workaround just set the image to the object itself as you would do with the older UIBuilder with the IAssetloader. Pretty sure this can't go wrong

#

Very weird bug though ThinkingIT

spring radish
#

I'm not sure I understand the workaround,

stone shoal
#

Testing if it works 🙂

spring radish
#

so it's not just the background image, because I tried setting a different width

#

and it affected both

#

if I put the images outside of the ModItem row, it still reproduces,

stone shoal
#

It's so weird...

#

Like sure if it had the same classname I could maybe see that it become global or something

#

But it's not even the same class

spring radish
#

yep

#

also reproduces if I add it at the bottom of the main menu list,

#

so it's not something from the mod panel

stone shoal
#

Hmm than there is something broke with it I guess.

#

Altough I had so many elements next to each other while testing and nothing was wrong

#

Most presets are buttons or something though

spring radish
#

yeaaa

#

and I haven't tried testing on Update 6, just to get a different Unity version

stone shoal
#

Think it would be the same

#

You didn't use it in update 6 ThinkingIT ?

spring radish
#

I didn't have two images next to each other no

stone shoal
#

Ahh

spring radish
#

I only added that today

#

back-porting the commit to update 6 wouldn't be impossible, just have to deal with a couple of merge conflicts,

stone shoal
#
  public class UnavailableImage(IAssetLoader assetLoader) : BaseBuilder<NineSliceVisualElement>
  {
    protected override NineSliceVisualElement InitializeRoot()
    {
      return UIBuilder.Create<VisualElementBuilder>()
        .SetStyle(style =>
        {
          style.backgroundImage = new StyleBackground(assetLoader.Load<Sprite>("sprites/statusicons/stranded"));
          style.width = new Length(28, Length.Unit.Pixel);
          style.height = new Length(28, Length.Unit.Pixel);
          style.marginLeft = new Length(7, Length.Unit.Pixel);
        })
        .Build();
    }
  }
  public class DownloadPendingImage(IAssetLoader assetLoader) : BaseBuilder<NineSliceVisualElement>
  {
    protected override NineSliceVisualElement InitializeRoot()
    {
      return UIBuilder.Create<VisualElementBuilder>()
        .SetStyle(style =>
        {
          style.backgroundImage = new StyleBackground(assetLoader.Load<Sprite>("ui/images/game/ico-child-grow"));
          style.width = new Length(28, Length.Unit.Pixel);
          style.height = new Length(28, Length.Unit.Pixel);
          style.marginLeft = new Length(7, Length.Unit.Pixel);

        })
        .Build();
    }
  }
stone shoal
stone shoal
spring radish
#

I have the code in a git repo, so I can just switch to the old branch and cherrypick the commit,

stone shoal
spring radish
#

mmm, it's about the same amount of work to do it either way

stone shoal
#

I want to fix it but don't even know where to start and can't really think clearly anyway

spring radish
#

the conflict is in the Configurator more than anywhere else,

stone shoal
#

Of the bug or the work ?

spring radish
#

to do the cherry-pick

#

okay, so in Update 6 it does not reproduce

#

with TimberApi (v0.7.8.0)

#

but I assume the UIBuilder didn't change between u6 and u7?

stone shoal
#

So it is a unity bug. Funny 😛

#

Altough it's hard to complaing about it to unity, if I can't replicate it in the unity builder

#

Maybe I need to export it to an asset bundle and try to load it ingame and see if that replicates the bug

#

Oh... I haven't updated my editor!

#

Installing it, will check out if the bug can be replicated in the editor than

#

Thanks for testing it in previous version, to be fair didn't expect it to work KEKW. Thought it was just a me problem

spring radish
#

Correct on 6000.0.16f1, Broken on 6000.0.41f1

#

I don't know that I care enough to try on whatever 0.7.1 was built with (6000.0.36f1),

stone shoal
#

IDK

#

Will test it in unity if it's broken I need to see if newer versions is still broken gotta make an post to unity

#

Otherwise asking pmduda to update unity version pog

spring radish
#

That's why I was thinking to try 6000.0.36f1

stone shoal
#

How you know its broken on 0.16f ?

spring radish
#

0.6.9.4 uses 6000.0.16f1 and doesn't require the work around

#

0.7.2.1 uses 6000.0.41f1 and does the wrong thing without the work around

stone shoal
#

Then how so specific .36f1 ThinkingIT

#

Which version was that

spring radish
#

If I didn't delete the backup of 0.7.1 yet

stone shoal
#

You have the game backed up with updates 😛 ?

spring radish
#

for experimental yes, in case it breaks in horrible ways

#

I can rollback

#

yea, I still have a backup of 0.7.1.2 which uses 6000.0.36f1

#

So which editor version were you testing on?

stone shoal
#

41f1

#

Should be the current version of TB

spring radish
stone shoal
#

Yeah I am testing it now

spring radish
#

which version did you test on earlier?

stone shoal
#

9f1 🙂

#

It was old

spring radish
#

very

stone shoal
#

Altough no problems...

spring radish
#

😕

#

0.6.5.1 used 6000.0.14f1

spring radish
#

yea, I saw, it's random too

#

I should check it's not a wine bug,

stone shoal
#

Im on windows

spring radish
#

yea, let me copy the buggy version to my windows machine to test

#

same issue

#

so it's not wine then

#

hmm, how do I get Steam to launch the game without updating it,

#

offline mode?

stone shoal
#

No clue

spring radish
#

6000.0.36f1 shows the same bug

stone shoal
#

Trying to test UXML ingame

#

They are invisible and I don't know why ThinkingIT

#

Ah okay found out why

#

It works

#

Dangit

#

So they changed something, somehow, somewhere

#

Otherwise it should not work in neither versions

#

@spring radish, for now I think best thing to do is just use the work around. If i'm feeling better (hope some day). I might recheck if I can extend it, and maybe test next week some more and post something on unity for it.

spring radish
#

yea, that's my plan

#

thanks for taking a look

stone shoal
#

I tested a UXML example with 2 UXML files that only has a stylesheet + the visual element and it worked out

#

The only difference I can think of is that the stylesheet is not loaded inside the element in the unity's way. But I place the stylesheet in the element.

#

But... it kinda should be there shrug

#

The Visual element doesn't have the stylesheet in this scenario, but the container from the UXML has

#

Okay even if I add the stylehssets manually to the element when just using the element it seems to work fine...

#

Then my stylesheet is just different somehow currently

#

Thanks unity 🌈

cinder fern
#

hmm about the issue with Moddable Bindito, right now even if I provide _cachedBlueprints, there is no way for you to modify it anyway because you set it through Reflection

#

so my code cannot provide that field even, because I can't know when you set it and so set the actual instance with it too

#

unfortunately I can't really do it from my side, no way to patch it. maybe you can check if that one does not exists, you check for wrapped._cachedBlueprints instead?

spring radish
#

Does it need to actually be replaced with a new dictionary? Could it just be Cleared instead?

spring radish
#

because then you could add a _cachedBlueprints field to your override and set it to the same instance as the wrapped class.

cinder fern
stone shoal
#

Well because its done woth reflections it should work. Instead the other way around

#

If I just casted the instance it doesnt know. But now it just checks for that field in the current instance

stone shoal
#

The class should just have a _cachedBlueprints which should be used for it's blueprints

#

Even if I remove the glunky code part needing to reload the blueprints. It still requires access directly to the cachedBlueprint to add my blueprints to it shrug.

#

If there would be an AddBlueprint it would maybe be possible. But that doesn't really make much sense for Timberborn to do.

cinder fern
#

can't you just clear it instead of replacing it entirely?

#

you can still access it right?

stone shoal
#

What is the difference between replacing and clearing... It's crashing because it doesn't exist

#

Yeah I think I can

cinder fern
#

when you replace it, (by using Reflection's SetValue), there is no way for my code to provide any way for you to "connect" it back to the original instance.

#

if instead you use GetValue for example, and Clear it, I can make a _cachedBlueprints field and refer to the original one

stone shoal
#

But I don't want to keep this code alive for always though. This was more a workaround to quickly fix for experimental. Later on I want to add new values.... which is totally duable the moment I am typing this

#

Can I do a cast like (SpecService) even if it's your wrapper class ?

cinder fern
#

no unfortunately not.

stone shoal
#

That sucks

#

So I always need to relay on a reflection sadBlobRegor

cinder fern
#

well... easiest would be, check if _cachedBlueprints exists, and if not, look for wrapped._cachedBlueprints instead. but then it's too specific just for my mod HappyFT

stone shoal
#

How can I check for wrapper

cinder fern
#

wait let me check your code again

stone shoal
#

I ain't going to add your mod as a dependency

cinder fern
#

to see where you actually apply it to

stone shoal
#

GeneratedSpecLoader

cinder fern
#

no, not if you are using reflection

stone shoal
#

I see

#

Would make it more confusing than just use reflection directly

#

Then it's like why do I do first a null check

cinder fern
#
specService.GetType().GetField("_cachedBlueprints", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(specService, new Dictionary<Type, List<Lazy<Timberborn.BlueprintSystem.Blueprint>>>());
#

so, you are looking for _cachedBlueprints in the specService. this I can provide. but the latter part, the SetValue call, I can't because there is no way for me to know it.

#

so, instead, you can call GetValue, and then call Clear()?

stone shoal
#

So this should work than ?

cinder fern
#

so it would be

var dict = specService.GetType().GetField("_cachedBlueprints", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(specService) as Dictionary<Type, List<Lazy<Timberborn.BlueprintSystem.Blueprint>>>;
dict.Clear();
stone shoal
#

Yeah have that in the zipped version

cinder fern
#

or you could use the way I use in #1357827899931234426, everyone is happy! HappyFT

#

and I suppose I have to keep it private right?

stone shoal
stone shoal
cinder fern
#

no, I mean, if you want stuff to run before the ISpecService Load

#

then just inject yourself as a dependency, not that you add my mod.

stone shoal
#

And I don't want to do stuff before ISpecService load

#

If I would just wanted that I just use my singletonloader that loads before ISingletonLoader

cinder fern
#

alright, that looks good, let's try it now

#

so users need to update both TimberApi and Moddable Bindito

stone shoal
#

If it works I can upload it

cinder fern
#
MissingMethodException: Method not found: bool Timberborn.WorldPersistence.ISingletonLoader.HasSingleton(Timberborn.WorldPersistence.SingletonKey)

wow...

#

that's a huge change

cinder fern
#

yep new update

stone shoal
#

Good 🙂

#

Better than problem with TimberApi

#

For me at least

cinder fern
#

yep can confirm Moddable Bindito + TimberApi can run together now. no idea if any mod can actually use it but at least no more crash 😂

#

I will upload it now

stone shoal
#

This change is fine, doesn't change much on my end.

#

Only bit annoying is when I'm gonna fix this I probably can't just cast it which makes code uglier sadBlobRegor

#

Gonna try it anyway, maybe it just checks for the field anyway and the cast is just comiler complaints

vast otter
stone shoal
#

Doesn't it ?

vast otter
stone shoal
#

I guess that makes sense ThinkingIT

vast otter
#

well will do 2 files for now but would have been neat

stone shoal
#

But why are we allowed to have files with unknown specs though ThinkingIT

vast otter
#

it hard crashes

#

for Toolgroup 😉

#

when i splited it up to 2 files it loaded so not the content but what types is allowed for toolgroup ThinkingIT

vast otter
stone shoal
#

Yeah the base game doesn't allow it

stone shoal
vast otter
#

hmm ya true as thats the new info needed, but its still 2 files so not sure its worth the hassle

brisk ether
#

Forwarding here for more visibility. I’m pretty stuck at this point so any advice would be appreciated.

brisk ether
#

Okay, so I figured a lot of this out so far, but now I'm stuck again.

The old code had this: panelBuilder.AddComponent(panelContent.Build()); where:

UIBoxBuilder panelBuilder = uiBuilder.CreateBoxBuilder() ...
and
var panelContent = uiBuilder.CreateComponentBuilder().CreateVisualElement();

but I cannot for the life of me figure out how to get the panelBuilder to add the panelContent to it

#

maybe this?
panelBuilder.AddComponent<FragmentBuilder>(_ => panelContent);

brisk ether
#

#🤖mod-creators message
If someone has a chance to help me here. I got this far but it isn't working. I feel like I'm missing something since the old code has SetFlexDirection and such but the only place I can see it in the current UI Builder code is in the BaseElementBuilder but no idea how that's supposed to work

stone shoal
brisk ether
#

I have actually mostly got it working 🙂
I just now cannot decipher how to make the text white (light?)
#🤖mod-creators message

stone shoal
#

SetColor I think ThinkingIT

brisk ether
#

I had completely missed that VisualElementBuilder exists so when I fixed that part (instead of FragmentBuilder in the Panel and BoxBuilder in the Interface) it got me to that

austere tangle
#

12:22:49 TimberApi.Tools.ToolSystem.ToolService.Load() failed after 00:00:37.8202104 😭

austere tangle
#

YA, and a new unity version, too.

#

6000.0.46f1

vast otter
# austere tangle 12:22:49 TimberApi.Tools.ToolSystem.ToolService.Load() failed after 00:00:37.820...

when does it happen for you?
i am able to load into a game with tapi ThinkingIT
my mod list:

Modded: true, official
- Harmony (v2.3.3)
- More Mod Logs (v0.1.6)
- TimberApi (v0.7.12.1)
- Bob Platforms Extended (v0.7.1.0)
- Bobingabout Script Pack (v0.7.5.0)
- Bob Storage (v0.7.1.0)
- Automation (v2.0.6)
- Mod Settings (v0.7.2.0)
- Configurable Tubeway & Zipline (v7.3.1)
- TimberApi UIBuilder (v1.0.0.1)
- Cutter Tool (v0.7.1.2)
- DamDecoration (v4.0.0)
- KnatteMaterials (v2.1.0)
- DamDecorations_DecorationExtention (v4.0.0)
- Emberpelts (v0.7.4.0)
- Employment Manager (v0.1.3)
- ExtendedFloodgates (v2.0.1)
- Forest Tool (v0.7.2.1)
- Frog Statue (v3.1.1)
- Goods Statistics (v0.7.3.1)
- Mod Manager (v3.0.4)
- MoreGroups (v3.0.3)
- Path Extention (v3.0.3)
- Planting Override (v0.7.3.1)
- SmartPower (v1.13.3)
- Staircase (v3.0.4)
- Steam Update Buttons (v0.1.5)
- TimberUi (v7.2.0)
- TImprove 4 Modders (v7.2.0)
- Tool Hotkey (v7.1.1)
- Water Extention (v3.0.2)
- Water Extention PowerEdition (v1.0.3)
austere tangle
#

Not sure what mods conflicts, but TAPI failed to load

vast otter
#

should be one of these:

- Bench
- Birch

- Bobingabout Vertical T Power Shafts
- Bobingabout's Housing Optimize
- Construction Queue
- Convenient Large Water Wheel
- BuildingPath
- Dirt
- Ladder
- Ladders for Emberpelts
- Live at workplaces
- Lunch Break
- Mixed Beavers
- Configurable Growth
- Configurable Pumps
- Faster Underwater Movement
- Minimap
- Moddable and Unlockable Recipe
- No more Breeding Pods
- Pipette Tool
- Super Cursor
#

try pipette tools? (as that add to toolbar?) but automation works :S

austere tangle
#

Pipette tools could be, since even in previous 0.7 version failed to add icon in the toolbar

vast otter
#

compered our mod lists and got a list of one you have but not me 😛

austere tangle
#

It's not Pippete tool ! Still working

vast otter
#

Wait vertical power shaft crash for me

#

Did not use it so could just remove it 😉

stone shoal
#

Sooo... It's not broken?

austere tangle
#

It seems OK, you can breath again 🤣

spring radish
brisk ether
#

Bug maybe in the box builder code?

TimberApi.UIPresets/Builders/BoxBuilder.cs
29:    protected string BackgroundClass = "api__box--nontransparant";
168:            .AddClass("api__box--nontransparant", builder => builder
172:            .AddClass("api__box--transparant", builder => builder

Should this say transparent and nontransparent (not transparant)

brisk ether
#

transparant is in the code
transparent is the correct spelling of that word ?

#

I guess not a bug, but a typo

stone shoal
#

Hmm yeah seems like a typo

#

ThinkingIT also don't have a method to change that,

brisk ether
#

@nurmr helped me here: #🤖mod-creators message

stone shoal
#

Yeah, but might be better if you didn't have to do that 😛

#

Ad could just do .Transparent or something

brisk ether
#

Yeah, like how the GameLabel has .Header()?

stone shoal
#

Yea

#

Just easier, unless you have to do it 100 times you can make a preset of it for yourself ofc 😛

brisk ether
#

Yeah, going to work on cleaning up my UI code tomorrow perhaps

#

Random question, is there a non-tapi way to do this?
var singletonLoader = DependencyContainer.GetInstance<ISingletonLoader>();
I used it because it was how the original code loaded items from the save file

brisk ether
#

No

#

Just inside PostLoad

stone shoal
#

Than just retrieve it with depndency injection

brisk ether
#

Oh I see

stone shoal
#

like:

  private readonly UIBuilder _uiBuilder;
  private readonly ModManagerBox _modManagerBox;
  private readonly ModRepository _modRepository;
  private readonly ITooltipRegistrar _tooltipRegistrar;
  private readonly VisualElementLoader _visualElementLoader;
  private readonly IAssetLoader _assetLoader;

  public TestClass(UIBuilder uiBuilder,
    ModManagerBox modManagerBox,
    ModRepository modRepository,
    VisualElementLoader visualElementLoader,
    ITooltipRegistrar tooltipRegistrar, IAssetLoader assetLoader)
  {
    _uiBuilder = uiBuilder;
    _modManagerBox = modManagerBox;
    _modRepository = modRepository;
    _visualElementLoader = visualElementLoader;
    _tooltipRegistrar = tooltipRegistrar;
    _assetLoader = assetLoader;
  }
brisk ether
#

yeah, I learned how to do that between writing that line and asking now 😐 (I just didn't realize it was part of DI)

stone shoal
#

@brisk ether Not sure why I made a non transparent the default. Are boxes default more transparent thatn non ThinkingIT

brisk ether
#

The ModSettings boxes are transparent. The boxes for the buildings on the right are not
The Well-Being Overview is transparent

#

The Settlement Management panel is mixed

stone shoal
#

settings panel is not right ?

#

ingame

brisk ether
stone shoal
#

I guess i make it transparent by default

#

Even thoug the method NonTransparent really gives me itches

brisk ether
#

maybe call it Solid or Opaque?

stone shoal
#

I like solid but would it make sense ?

#

w/e it's not that NonTransparent will be used much I suppose 😛

#

Fixed the typo so your override should break with it 😄

brisk ether
#

Yeah one moment

#

But yeah, now my mod only has dependencies on ModSettings and TimberApi.UiBuilder 🙂

#

(Nothing against Tapi, just didn't need it if I can use DI for things)

stone shoal
#

Everyone trying to remove Tapi sadBlobRegor

#

😛

#

But yeah the UIBuilder probably will barely ever break

#

Ok i've set everything to upload

brisk ether
#

testing now

#

It would help if I put the updated mod in my mod folder instead of just the dlls in the project 😰

stone shoal
#

nice

brisk ether
#

So, using NonTransparent makes it transparent

stone shoal
#

Nice

#

Might forgotten to change the strings

#

Im gonna go to the market, will upload afterwards

brisk ether
#

No rush on my end. Thanks 🙂

#

But yeah, the updated zip works 🙂

stone shoal
#

Updated

spring radish
spring radish
#

TimberAPI seems to (sometimes? always? unsure?) sort Solid Power Shaft before the regular Power Shaft

#

they both have _toolOrder: 29

ebon sparrow
#

looks like a game issue, we will fix it in one of upcoming updates

spring radish
#

eh, if it sorted in alphabetical order then it would be fine.

#

but adjusting it in the game will fix it too

stone shoal
#

Wasnt this already a long time ThinkingIT

#

Pretty sure ive said something about same order before

spring radish
#

I could easily have missed it ¯_(ツ)_/¯

#

back at #1064983064020799498 message

brisk ether
#

Bug in TimberApi UIBuilder or did I do something wrong here?

            var panelContent = _uiBuilder.Create<DefaultListView>()
                    .SetName("CameraList")
                    .SetMakeItem((Func<VisualElement>)(() => {
                        var ve = _uiBuilder.Create<DefaultListViewItemWrapper>();
                        ve.ModifyRoot(builder => builder
                                              .AddComponent<VisualElementBuilder>(veb => veb
                                                                  .AddComponent<GameTextLabel>(lbl => lbl
                                                                                      .SetName("TextTestLabel")
                                                                  )
                                              )
                        );
                        return ve.Build();
                    }))
                    .SetItemSource(_screenshotService.CameraData)
                    .SetBindItem(
                            (Action<VisualElement, int>)((ve, i) =>
                                    ve.Q<Label>("TextTestLabel").text = _screenshotService.CameraData[i].CameraName)
                    );

Ignore the mess, I'm still working out how this actually works

brisk ether
#

Bug in my thinking 👆

I had to make a class that inherited DefaultListViewItemWrapper and now it works 😄

brisk ether
#

Could I get some guidance on this?
#🤖mod-creators message
You mentioned that the 2 classes are not required. but when I try to not have the two classes, I get various errors I can't make sense of.
Or I get a recursive stack overflow with 200k lines and a 30 MB log file

It's possible I just don't know enough about C# yet and it's a simple thing I'm missing but I just don't get this

spring radish
#

I think the "base type" should be NineSliceButton (or some other base class), not the subclass

#

i.e. MyClass : Button<BaseClass>

#

not MyClass : Button<MyClass>

#

and calling UIBuilder.Create<BaseClassBuilder>()

#

So maybe try class TimberLapseButton : LocalizationButtonBuilder<LocalizationButton>?

brisk ether
#

Thanks 🙂

brisk ether
#

I tried that and Rider doesn't like it either.
And then this doesn't work right either:

panelBuilder.AddComponent<TimberLapseButton>(
        builder => builder
                .SetLocKey(TimberLapseSetCamerasButtonLoc)
                .SetName("SetCamerasButton")
);
#

If I remove the <LocalizableButton> part, the button class no longer throws errors but then the other errors persist

#

This seems to work so far, about to go test it in the game

#

Yeah, that worked. Thanks @spring radish LoveIT

#

I'm excited to have a single button class for my code that can be adjusted instead of making 3 different classes or endless gross looking repeated tweaks to the presets

spring radish
#

So the trick was BaseBuilder<LocalizationButton>?

brisk ether
#

Yeah, it seems so

#

I played around with ~10 different things until Rider "approved this message"

spring radish
#

Lol

brisk ether
#

Bad joke I guess

spring radish
#

i.e. until Rider stopped complaining and compiled the code without error.

brisk ether
#

Is it intentional that the only UI preset sliders in the UI builder code that has a SetValue method are
GameMinMaxSlider and GameTextMinMaxSlider?
I can and probably will write my own eventually, but it feels weird that the other preset sliders don't include this by default

panelContent.AddComponent<GameTextSliderInt>(
        builder => builder
                .SetLowValue(TimberLapseFrequencyHelpers.FrequencyMin)
                .SetHighValue(TimberLapseFrequencyHelpers.FrequencyMax)
                .ModifyRoot(
                        sBuilder => sBuilder
                                .SetStyle(style => {
                                    style.marginBottom = new Length(10, LengthUnit.Pixel);
                                })
                                .SetValue(TimberLapseFrequencyHelpers.ToInt(_timberLapseManager.Frequency))
                )
                .SetName("FrequencySlider")
);
stone shoal
#

Maybe it was a mistake

brisk ether
#

Not a big deal either way.

stone shoal
#

Minmax slider was also just a bit of a quick thing kf why not

#

And then it was instantly used

brisk ether
#

Lol

keen flint
#

TimberApi.Tools.ToolSystem.ToolService.Load() failed

#

While loading the save

brisk ether
#

Can you share the full crash log?

keen flint
brisk ether
#

KeyNotFoundException: The given ToolGroupId (subgroup_thoseplatforms) cannot be found.

#

Maybe an issue with that mod Those Platforms?

keen flint
#

Thanks. I'll try to talk to that modder

brisk ether
#

You’re welcome.

keen flint
#

Oh, someone already mentioned to that mod.

severe solar
#

Probably different section, but cannot find how the left one is called

stone shoal
#

Add BottomBarSpec to your blueprint

#

with Section 0

severe solar
#

I so dont understand how that should work

#

"magic"

stone shoal
#

You know how blueprints work ?

severe solar
#

Yes and no

#

bc i know how single layers work

#

but that spec in spec shit

#

no clue xD

#

bc its not clear from the code

stone shoal
#

Just add the second one in the same file

severe solar
#

as there is no bottombarspec field in ToolSpec

severe solar
#

I might have added incorrectly

vast otter
severe solar
#

Sorry, forgot to mention it works now 🙂 added the thingy TheBloodEyes mentioned

#

Thanks @vast otter LoveIT

severe solar
#

Thank you @stone shoal Im foverer in your favor, my favorite modder much loves

calm copper
#

@stone shoal are the tool specification files required to have unique names even if they are located in separate folders? I had several files named ToolGroup.json in the blueprints hierarchy, and got errors during the load.

250509T005954.929 [EXCEPTION] [TimberApi.Tools.ToolGroupSystem.ToolGroupService.GetToolGroup] KeyNotFoundException: The given ToolGroupId (automationsignalstoolgroupid) cannot be found.
   at TimberApi.Tools.ToolGroupSystem.ToolGroupService.GetToolGroup (System.String id) (at <5b41fe7e63b344c19c0564b729944abe>:0)
   at TimberApi.Tools.ToolSystem.ToolService.Load () (at <5b41fe7e63b344c19c0564b729944abe>:0)
   at (wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Timberborn.SingletonSystem.SingletonLifecycleService.LoadSingletons_Patch2(Timberborn.SingletonSystem.SingletonLifecycleService)
   at (wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Timberborn.SingletonSystem.SingletonLifecycleService.LoadAll_Patch1(Timberborn.SingletonSystem.SingletonLifecycleService)
   at Timberborn.SingletonSystem.SingletonLifecycleUnityAdapter.Start () (at <ba126410857740d8933279b72b4b61c8>:0)

There are no other errors that would tell that there is a file name collision. The issue got resolved when I gave unique names to the toolgroups files.

stone shoal
#

Every same name file is getting merged

#

But I am bot 100% sure. Mayke Enka made it so that path is included if it should be merged

calm copper
#

Well, if the file name is used to merge the blueprints, then making it unique is a must.

median plinth
#

@stone shoal Does TimberAPI still have PickObjectTool?

stone shoal
median plinth
#

Hmm, can't seem to find it

stone shoal
#

Maybe I did delete it ThinkingIT

#

Cant you find it in the source or discovery?

median plinth
#

my VSCode didn't find the reference and neither did I find it when using ILSpy. Found it in the github tho, so I'll probably copy it from there and try to add it to my mod

stone shoal
#

There were probably too much stuff broke at that point and me not being able to program really for last 6 months

#

I can always just readd it if it works

#

I hope to be able to fix the temp disabled features by next month if the recovery keeps going

median plinth
#

all the best to you my friend

brisk ether
#

So I have a question:
I have a few UI Classes I made BatchControlLabel and BatchControlNineSlice to be able to use the style sheet builder code (among a few other reasons)
But I'm a little confused what the correct way to write AddComponent methods on the Nine Slice class is. I have the following (incomplete) code where I want to build the UI out:

var rootBuilder = _uiBuilder.Create<VisualElementBuilder>()
        .SetFlexDirection(FlexDirection.Column);

rootBuilder.AddComponent<BatchControlLabel>(
        builder => builder
                .SetLocKey(HeaderLocKey)
                .Header()
);

var headerBuilder = _uiBuilder.Create<BatchControlNineSlice>()
        .SetFlexDirection(FlexDirection.Row);

headerBuilder.AddComponent<BatchControlLabel>();

rootBuilder.AddComponent<BatchControlNineSlice>(_ => headerBuilder);
var root = rootBuilder.BuildAndInitialize();
return new(_eventBus, root);

But if I want to add components to the headerBuilder like I did for the rootBuilder, the attached image was what I found in the BaseBuilder class but it throws an error.
Am I missing something obvious with C#/TApi UI Builder code here?

#

The rest of the class from the photo above :

stone shoal
#

Why not use the AddComponent from the base builder and just pass the data thru ?

brisk ether
#

Because I'm a newb and not sure how to do that 😰

stone shoal
#

I added another AddComponent though so you can add builders into it. Now you have to add a .Build to it

#

Instead of Root.Add There should be a AddComponent IIRC

brisk ether
#

This?

public BatchControlNineSlice AddComponent<TComponentBuilder>(Func<TComponentBuilder, TComponentBuilder> builder)
        where TComponentBuilder : BaseBuilder {
    _bcNineSliceBuilder.AddComponent(builder);
    return BuilderInstance;
}
        
public BatchControlNineSlice AddComponent<TComponentBuilder>() where TComponentBuilder : BaseBuilder {
    _bcNineSliceBuilder.AddComponent<TComponentBuilder>();
    return BuilderInstance;
}
stone shoal
#

Yea

brisk ether
#

💯 thanks yeah, idk why I didn't see that as an option.

stone shoal
#

Altough the first one works ?

#

Pretty sure you cannot do that yet ThinkingIT. Or I am just reading it wrong

brisk ether
#

if I have Root.AddComponent, it says cannot resolve symbol AddComponent

stone shoal
#

Yea with the root it's normal, but I expected you needing to do builder.Build(). idk what my problem was than shrug

#

Root is just an unity element so you don't have any easy options than anymore. at least for modifying it

brisk ether
#

Yeah, idk. I guess I could also just learn proper UXML 😛 But this feels nicer than that so I'm trying to make it work

#

My head was swimming trying to make sense of the UXML stuff

stone shoal
#

UXML isn't that hard either 😛

#

The only thing I dislike the most is I cannot just make a singular item and reuse it. instead you need to write the whole component everytime

brisk ether
#

So, I guess my question here is: When would UXML be worse but I think you just answered that?

stone shoal
#

I think mine is a bit more complex in the earlier states, but after having some setups it gets faster and easier to reuse

brisk ether
#

It feels like I could easily with TAPI UI Builder write a utility mod that is all the UI elements I reuse in multiple mods ?

#

relatively easily*

stone shoal
brisk ether
#

Makes sense

severe solar
#

Yea, thats is a big plus for TAPI UI as i can then also use them and dont need to make them

#

TheBloodEyes so smurt!

cinder fern
stone shoal
#

If you manually add it to somewhere timberborn has wanted it it might not work for TimberApi

#

no clue how your code works

#

If your building doesn't have a PlaceableBlockObjectSpec it won't be converted

vast otter
cinder fern
stone shoal
#

Is it a actual copy or a runtime copy

cinder fern
#

so what I do =

  1. Add the path (something like "Buildings/Hospital") to the Buildings.Folktails Paths.
  2. Add a AssetProvider that when loading the prefab, simply give it an empty placeholder.
  3. In PrefabGroupService, after they are all loaded, replace the placeholder with the copy of Medical Bed.
cinder fern
stone shoal
#

Then it wont work

#

Or ThinkingIT

#

No dont think so

#

Since it does t have a spec

cinder fern
#

which spec? it should have everything the original Medical Bed has.

#

did you load the list for your custom bottom bar way before that?

stone shoal
#

It loads the specs

#

It doesnt load a path

cinder fern
#

hmm I don't understand, how does that work for other Prefab though? it's loaded through the PrefabGroupSpec like "Buildings.Folktails" right?

stone shoal
#

No

#

Its bot loafed by a path

#

Its converted by the placeable spec

#

Then it will use the prefab name to build the correct tool

#

Im pretty sure you have a unique prefab name for your tools

#

If you make a toolspec it might just work fine

cinder fern
#

like I just need to place a JSON file there "just in case" there is TimberApi right?

#

oh nvm found it PlaceableObjectToolSpec. Simply a JSON file with PlaceableObjectToolSpec with PrefabName right?

stone shoal
#

You need a toolspec. In the first link you can see what needs to be in it

stone shoal
#
                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 
                }
cinder fern
#

well I asked @austere tangle to just give me a prefab instead lol

full acorn
#

Has the new version deprecated the UIBuilder system?

stone shoal
#

update 7 doesn't include UIBuilder

full acorn
#

Ah fair enough!

#

Time for me to learn Unity's UIBuilder then? 😛

vast otter
stone shoal
stone shoal
full acorn
#

Aaaah right ok, yeah I see it, thank you!

cinder fern
#

@stone shoal well with the new #1382243128253087895 , if they have TimberApi, the new buildings are not showing again...

#

and this time I didn't use Moddable Bindto or even Harmony...

cinder fern
#

if I tried to add Faction.Folktails as well to add PrefabGroups directly there, then now somehow your script still load it before it's loaded

#

because I can't add Materials and Needs and Goods any earlier because there is no info at that time

stone shoal
#

Not sure what specs you mean but I generate buildings based on prefabs

stone shoal
#

Because harmony doesnt do both patches

#

I need fractions to generate specs and you reload the specs again and add new ones

#

Why would you reload it in first place?

#

Aside from that if you just generate the jsons for TimberApi bottombar of the added buildings it might work

#

But some mods might going to be incompatible when using generated specs. Or other aspects of TimberApi

#

Meanwhile TimberApi is currently broken I believe since experimental is now live. And i am on holiday

brisk ether
#

It was working for me in experimental at least last I checked earlier today

#

(Unless I don't have mods that use the broken things)

stone shoal
#

Than it might not be broken. Thought it crashed in exp. Maybe user error

#

If i could have a better way to use the prefabservice and dont require factions to be loaded it would be easier

cinder fern
stone shoal
cinder fern
#

because those info aren't available to me at that time yet. I can't list all factions within the Provider because it's used by the provider itself

#

oh well, I just rolled back the original version, and then just release this one without TimberApi compatibility then... I can't generate the specs because the user choose them dynamically.

stone shoal
#

You know what they picked so you can generate them?

#

How do you know what buildings there are if you dont have the info?

cinder fern
#

yeah based on the file name only, not from the game. so I have the faction ID only

cinder fern
stone shoal
#

For the configuration?

cinder fern
#

so right now:
FactionSpecService -> SpecService -> AssetLoader -> IAssetProvider

IAssetProvider is where I am putting in a custom prefab group in. the content is cached in a file.

#

at FactionSpecService, I put in the other info (needs, materials etc)

#

for Materials I need to know what material other factions have

#

so I can't know that before FactionSpecService finished loading

#

btw, I see that you still call FactionSpecService.Load in TimberApi loading code, how come that info is not in? I already added that info at FactionSpecService.Load

#
    public new void Load()
    {
        base.Load();

        OriginalFactions = Factions;
        factionOptionsProvider.AddMissingFactions(Factions.Select(q => q.Id));

        AppendData();
    }
stone shoal
#

The faction is probably already loaded. But your code isnt

#

You are bot loading the faction before i do

#

Its weird you reload the faction anyway instead of just depend on it and add to it after the load

cinder fern
stone shoal
#

Csn you share it? I csnt look it up on phone

stone shoal
#

The init code

#

Thats yours

cinder fern
#

it's simply a loading specs code:

public void Load()
{
    Factions = _specService.GetSpecs<FactionSpec>().ToImmutableArray();
}
stone shoal
#

Okay

#

You arent going to add a dependency anyway so not going to bother any further.

#

Without that info(ToolSpec) there is not much to do

cinder fern
#

how do I make it run before btw?

#

easy to add a dependency to run after, but before is harder

#

I can make a branch version with TimberApi depenendecy

#

or maybe just use reflection type.

stone shoal
#

No clue. Bindito doesnt provide much for that. But if you have TimberApi as a dependency you can easily use earlyLoadableSingleton and make sure your asset provider has the data at that point ready

cinder fern
#

so I could replace your ToolSpecificationService with mine with an extra constructor

#

or... actually it's easy lol. I remove your service, add it using a Provider

#

I totally forgot about that

stone shoal
#

No clue, but sure. If it breaks make sure they know its on your end

cinder fern
#

so basically:

this.RemoveBinding<ToolSpecificationService>();
this.Bind<ToolSpecificationService>().ToProvider(MyClass).AsSingleton()
stone shoal
#

There is a remove binding?

cinder fern
#

TimberUI provides that

#

simply scans the registry and remove it

#

I even provide RemoveMultiBinding (all or a specific type) lol

stone shoal
#

Migjt have been easier than transpiler

cinder fern
#

yep

cinder fern
#

hi do you remember how we solved the issue back then? 😂 back then I replaced the SpecService and now I do not replace it anymore but how come it crashes 😅

#
NullReferenceException: Object reference not set to an instance of an object
  at TimberApi.SpecificationSystem.GeneratedSpecLoader.PostLoad () [0x00057] in <514fe957c82a4375b887fa4e42e2be35>:0 
  at TimberApi.SingletonSystem.SingletonLifecycleServicePatcher+<>c.<LoadAllPrefix>b__0_1 (TimberApi.SingletonSystem.ITimberApiPostLoadableSingleton singleton) [0x00000] in <0673fedbcca9497a90c561275f1aa775>:0 
  at TimberApi.SingletonSystem.SingletonLifecycleServicePatcher.LoadSingleton[T] (System.Collections.Generic.IEnumerable`1[T] singletons, System.Action`1[T] action) [0x00012] in <0673fedbcca9497a90c561275f1aa775>:0 
  at TimberApi.SingletonSystem.SingletonLifecycleServicePatcher.LoadAllPrefix (Timberborn.SingletonSystem.ISingletonRepository ____singletonRepository) [0x00032] in <0673fedbcca9497a90c561275f1aa775>:0 
  at (wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Timberborn.SingletonSystem.SingletonLifecycleService.LoadAll_Patch1(Timberborn.SingletonSystem.SingletonLifecycleService)
  at Timberborn.SingletonSystem.SingletonLifecycleUnityAdapter.Start () [0x00000] in <9117b1294fcf4df390fc07f3eef2285e>:0 
#

so back then I added a "fake" _cachedBlueprints for it I think, but now I don't need to do that anymore because it's there now, in the original SpecService

#

hmm I don't understand how your code can crash. it should work perfectly fine though ThinkingFT

    public void PostLoad()
    {
        foreach (ISpecGenerator item in specificationGenerators)
        {
            generatedSpecAssetRepository.AddSpecRange(item.Generate());
        }
        ((Dictionary<Type, List<Lazy<Timberborn.BlueprintSystem.Blueprint>>>)specService.GetType().GetField("_cachedBlueprints", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(specService)).Clear(); // This line crashes
        EarlyLoadPatcher.BlockLoading = false;
        specService.Load();
        factionSpecificationService.Load();
        EarlyLoadPatcher.BlockLoading = true;
    }
#

specService does have _cachedBlueprints

#

oohhhh I know why, it's due to publicizer! since my new class ModdableSpecService inherits SpecService but through the publicizer, it thought _cachedBlueprints was a public member. So your BindingFlags.NonPublic would not get it I think. so a fix would be BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public. Or since you have Harmony anyway, you can just use AccessTools.all or use .Field("_cachedBlueprints") instead (Harmony extension method).

calm copper
#

I'm getting this in experimental. The game seems working, though.

stone shoal
calm copper
stone shoal
#

No idea to be honest, the only thing i do eith the early stuff is calling base game stuff earlier

#

So might also be there if tapi was disabled. If the mod causing it doesnt deoend on tapi

lunar folio
languid ermine
lunar folio
#

yes, i just removed it and now its working fine again. Thank you all for your help

warm valley
#

ModdableBindito errors are due to TimberAPI or ModdableBindito?

cold acorn
warm valley
#

Thanks

cinder fern
#

yep, unfortunately depends on which mod you need. 7.1.1 = works with TimberApi and 7.1.2 = works with Automation

quick robin
#

Using the 7.1.1 version fixed it for me, as I don't use automation

spring radish
stone shoal
#

Well not to my awereness

#

I never tried it haha

#

I don't have anything that requires internet connection though, maybe the mod manager

spring radish
#

Yea, that's pretty much what I replied, and the commenter is 100% sure that I'm wrong.

stone shoal
#

They do that sometimes

#

That's why they are a redditor 🙂

#

I found the reasoning very neet,

#

Because it's an API

#

Well, you ain't 100% incorrect if you thinking about webbased stuff.

spring radish
#

yep

#

baaack in my day, APIs didn't need none of this internet nonsense

stone shoal
#

API just means Application Programming Interface. Has nothing to do with internet connection KEKW

spring radish
#

Yep

stone shoal
#

If my game would just update I can test it

brisk tide
#

Just wanted to post here in case you (@TheBloodEyes) don't read #🚀mod-users , but I'm in agreeance with you in that I don't think the two are really compatible at this point (but I would love to be proven wrong). You can see just a snippet of the attempts I've made trying to get the 2 to work in that channel, but if it saves you time/stress, then at least there's a positive that came from me testing this out 👀

#

Didn't want you possibly spending the same amount of unhealthy fun time I did on this (was fun at times) :p

stone shoal
#

Well if i just need to do as he says its nkt much work

#

But if its alot of work, he should probably fix it.

#

Just didnt have time to check it out yet

brisk tide
#

I tried that

#

This was the stack trace with it

#🚀mod-users message

#

Again I’d love to be proved wrong, but also didn’t want someone else to go though it all in the event they inevitably come to the same conclusion

cinder fern
# brisk tide I tried that

This patch work for me (no crash in the game), in C# you cannot get a private member from a base member.

    static FieldInfo FindCacheField(Type type)
    {
        var field = type.GetField("_cachedBlueprints", AccessTools.all);
        return field is null
            ? type.BaseType == typeof(object) ? throw new FieldAccessException("Field not found") : FindCacheField(type.BaseType)
            : field;
    }

    public static void ClearCache(object __instance)
    {
        var fields = __instance.GetType().GetFields(AccessTools.all);
        var specServiceField = fields.First(q => q.Name.Contains("specService"));
        var specService = (ISpecService) specServiceField.GetValue(__instance);

        var cacheField = FindCacheField(specService.GetType());        
        var cache = cacheField.GetValue(specService);
        var clear = cache.GetType().GetMethod("Clear", AccessTools.all);
        clear.Invoke(cache, null);
    }

    public static IEnumerable<CodeInstruction> Patch(IEnumerable<CodeInstruction> instructions)
    {
        var list = instructions.ToList();

        var index = list.FindIndex(q => q.opcode == OpCodes.Callvirt && q.operand is MethodInfo method && method.Name == "Clear");

        // Go back two `ldarg.0` instructions
        var startIndex = list.FindLastIndex(index - 1, q => q.opcode == OpCodes.Ldarg_0);
        startIndex = list.FindLastIndex(startIndex - 1, q => q.opcode == OpCodes.Ldarg_0);

        // Clear that part
        // Don't remove the first ldarg.0 as it's a label for a branch
        list.RemoveRange(startIndex + 1, index - startIndex);

        // Insert our ClearCache method
        list.Insert(startIndex + 1, new(OpCodes.Call, typeof(ModStarter).Method(nameof(ClearCache))));

        return list;
    }
#

this is the patch btw, because I don't want to copy the DLL:

    void IModStarter.StartMod(IModEnvironment modEnvironment)
    {
        var harmony = new Harmony(nameof(TestMod));
        harmony.PatchAll();

        var t = AccessTools.TypeByName("TimberApi.SpecificationSystem.GeneratedSpecLoader");
        var method = t.Method("PostLoad");

        harmony.Patch(method,
            transpiler: typeof(ModStarter).Method("Patch"));
    }
#

but much easier if the code author add it in, no transpiler needed, only need to find the member in the parent class as well

#

wonder if it's easier if I put in a shadowed member with the same name there lol

brisk tide
#

Aha, so AccessTools.all instead eh

#

Could be safe and cover both, but that’s really up to you two

stone shoal
brisk tide
#

Nah, I didn’t find anything recent on the repo so I just went by what I could find without building either of your mods

#

I was trying to make a compatibility/patch mod that just patched the problematic part that was suggested previously

#

Going the AccessTools.all or shadow route is completely different though and makes sense

stone shoal
#

I just have try it yet

#

But haven't opened rider

brisk tide
#

I wasn’t going to rebuild both entire environments with what I might assume you both had, so I was going off of the information I read here. I had my own goal(s) way before this though as I had in mind a compatibility mod patch that other games have, so I was approaching this from that angle as the 3rd party

#

Well that should be a lot easier for you as they said

#

Optimistically speaking I did say I’d love to be proved wrong, but this got the solution correctly from the sound of it, so I count that as a win

stone shoal
#

Before I had a legend called hytone which helped me with these small fixes

#

But since update 6 it's broken down so much, just trying to keep it up for now

#

Maybe some day

brisk tide
#

Gets overwhelming trying to keep up with it all depending on the environment

#

Especially when not paid to do so

#

Speaking of, you don’t keep TimberAPI on the repo, do you? Or at least not on the public repo

stone shoal
#

I do

#

Not sure if everything is pushed atm though

#

It's in update_7 branch

brisk tide
#

I’ll have to look when I’m back at my desk. I still wouldn’t bother rebuilding it all depending on your setup as I don’t like doing that for multiple reasons

stone shoal
#

It's not a easy setup KEKW

#

Mostly due bepinex nuget is broken on my pc so I had to do it differently

#

For some reason my network connection doesnt establish some stuff anymore. Just like all my cloud saves are broken on any platform and I cannot start a download/update on steam before restarting the client

brisk tide
#

I’d imagine, but it’s more I just don’t like doing that if it’s another modders thing unless asked or unless it looks like something I can help with as a 3rd party

#

Safest approach sounds like both sides adding said small fix though, but glad I’m the one that ran with the BindingFlag.public knowledge as that was a major chicken and egg scenario

cinder fern
#

but even with it (and even with FlattenHierachy, which is not included in that), you cannot grab the private variable from base. you have to traverse to the base type

cinder fern
#

so with the new move to #1422778917366005770 using Harmony, I receive this error instead:

ArgumentException: An item with the same key has already been added. Key: Package_Algae

System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <4780199c95764436ade50bbd58f63488>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) (at <4780199c95764436ade50bbd58f63488>:0)
System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] keySelector, System.Func`2[T,TResult] elementSelector, System.Collections.Generic.IEqualityComparer`1[T] comparer) (at <56bcb176486e400396fc9557eca2a147>:0)
System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary[TSource,TKey,TElement] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] keySelector, System.Func`2[T,TResult] elementSelector, System.Collections.Generic.IEqualityComparer`1[T] comparer) (at <6bb08d37de124a778ca2954872cc5e3e>:0)
Timberborn.Workshops.RecipeSpecService.Load () (at <6064568cf4f24a9abe05482a8954f025>:0)
Mods.MoreModLogs.SingletonSystemPatch.ErrorReporter (System.Action fn) (at C:/Users/Norman/Documents/src/Timberborn-MoreModLogs/SingletonSystemPatch.cs:61)
(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.SingletonLifecycleUnityAdapter.Start () (at <37714495c7b34fbf87491c89893567c4>:0)
#

any idea why? I was adding new Goods and Recipes into the Specs.

stone shoal
#

You sure it's a TimberApi problem? I don't remember doing something with goods

#

Unless package_algae is an building and it's added twice to the buildings

cinder fern
#

it does not crash if I don't enable TimberApi

#

the stack trace crash is from RecipeSpecService

#

so I added it by adding stuff to the _cachedBlueprints right after SpecService.Load.

#

since all other methods are generic and cannot be patched

stone shoal
#

only thin I can think out of my head is if you do a prefix and block the rest

#

im changing the load order so if that patch is removed it crashes

cinder fern
#

nope, only thing I do is to run a postfix and add a few items to the list

#

nothing for prefix

#

btw, I do read all the Lazy<T> in there to get the info, then after that append a few (values are already calculated but wrapped inside Lazy because the type need it)

#

does reading the Lazy<Blueprint> trigger anything?

cinder fern
#

well fixed for Packager because I am making a separate version to generate JSON files for now

stone shoal
#

I really csnnot remember much of it

#

I dont do much with specs except blocking the load function and than executing it myself

#

Sadly enough my recovery only lasted for about 2 months so yeah...

cinder fern
#

so there is this strange bug, I finally found out because apparently TimberApi was trying to call PrefabGroupService.Load somewhere earlier than it should?
#🚀mod-users message

#

for example, a proper run without TimberApi, I add my own service as a dummy IPrefabGroupProvider, so its Load should be called before PrefabGroupService.Load:

#

However, with TimberAPI, for some reason PrefabGroupService.Load is called before it even though PrefabGroupService depends on it and cause data to be unintialized:

stone shoal
#

I also load all the other required services

cinder fern
#

well, the above log shows the MSettings.Load isn't called until after it

#

specificially the dependency chain is something like this: PrefabGroupService -> IEnumerable<IPrefabGroupProvider> -> one of my MyPrefabGroupProvider -> MSettings

cinder fern
stone shoal
#

Okay?

#

I just move the load order of few parts, to the most earliest state and disable the load calls if they happen before that

#

Maybe that's the problem

#

@cinder fern is your patch add something to a list when the load method is called as a dictionary it will do it twice

#

Probably

#

Altough with this harmony is I prefix block it and yours is a postfix it shouldn't trigger I believe

cinder fern
#

no Dictionary is involved btw

#

this is for PrefabGroupService, not SpecService

#

so from the source:

    public void Load()
    {
        EarlyLoadPatcher.BlockLoading = false;
        
        ((GameSceneSerializedWorldSupplier)worldEntitiesLoader).Load();
        
        specService.Load();
        factionSpecificationService.Load();
        factionService.Load();
        prefabGroupService.Load();
        
        EarlyLoadPatcher.BlockLoading = true;
    }

you manually call the Load methods of those services. but everything in between is not called, as well as the Load of all their dependencies (for example, IPrefabGroupProviders)

stone shoal
#

And sll other loads ate indeed done in normal order

cinder fern
#

no, the DI guarantees that all dependencies's Load are called before that.

#

so look at PrefabGroupService constructor:
public PrefabGroupService(ISpecService specService, IAssetLoader assetLoader, IEnumerable<IPrefabGroupProvider> prefabGroupProviders)

#

that means, before PrefabGroupService.Load is called: ISpecService.Load is called, IAssetLoader.Load is called and all IPrefabGroupProvider.Loads if any of them are ILoadableSingleton

#

in your code above, you didn't call any IPrefabGroupProvider.Load

#

so PrefabGroupService.Load is called before any IPrefabGroupProvider.Load is called when it should be after.

stone shoal
cinder fern
#

it does though...

stone shoal
#

The DI only determens the order of instaniation of classes. And that makes them registered in the same order for the singletons

stone shoal
cinder fern
#

#🤖mod-creators message

stone shoal
cinder fern
#

well anyway in that case it's not my mod's fault that TimberApi changed the expected behavior then

stone shoal
#

I don't use ILoadableSingleton

stone shoal
cinder fern
stone shoal
# cinder fern it does though...
    public void LoadAll()
    {
      this._loadableSingletons = ImmutableArray.ToImmutableArray<ILoadableSingleton>(this._singletonRepository.GetSingletons<ILoadableSingleton>());
      this._nonSingletonLoaders = ImmutableArray.ToImmutableArray<INonSingletonLoader>(this._singletonRepository.GetSingletons<INonSingletonLoader>());
      this._postLoadableSingletons = ImmutableArray.ToImmutableArray<IPostLoadableSingleton>(this._singletonRepository.GetSingletons<IPostLoadableSingleton>());
      this._nonSingletonPostLoaders = ImmutableArray.ToImmutableArray<INonSingletonPostLoader>(this._singletonRepository.GetSingletons<INonSingletonPostLoader>());
      this._unloadableSingletons = ImmutableArray.ToImmutableArray<IUnloadableSingleton>(this._singletonRepository.GetSingletons<IUnloadableSingleton>());
      this._updatableSingletons = ImmutableArray.ToImmutableArray<IUpdatableSingleton>(this._singletonRepository.GetSingletons<IUpdatableSingleton>());
      this._lateUpdatableSingletons = ImmutableArray.ToImmutableArray<ILateUpdatableSingleton>(this._singletonRepository.GetSingletons<ILateUpdatableSingleton>());
      this.LoadSingletons();
      this.LoadNonSingletons();
      this.PostLoadSingletons();
      this.PostLoadNonSingletons();
      this._initializedSuccessfully = true;
    }

This determens the load order, anything that uses PostLoadSingletons are always loaded after the load method

cinder fern
#

so anyway, my point was, the ILoadableSingleton.Load of dependencies were supposed to be called before the main class/using class's ILoadableSingleton.Load

stone shoal
#

They do it only loads even earlier

#
    public void Load()
    {
        EarlyLoadPatcher.BlockLoading = false;
        
        ((GameSceneSerializedWorldSupplier)worldEntitiesLoader).Load();
        
        specService.Load();
        factionSpecificationService.Load();
        factionService.Load();
        prefabGroupService.Load();
        
        EarlyLoadPatcher.BlockLoading = true;
    }

This is loaded before anything else

cinder fern
#

yeah which causes unexpected behavior because when prefabGroupService.Load() is called, it's normally expected that all dependencies' Load if any, were called?

stone shoal
#

Yes, so unless you change the expected behaviour as well and overwrite the whole clas replacing it with your own it might crash

#

If it requires more

cinder fern
#

why do you need to call it early btw, why don't just intercept/patch the Load methods?

#

I don't see how I can intervene with this behavior from my side

stone shoal
#

I intercept them by disabling them at original point and call them at the earliest point in the scene load cycles

#

Thus early

#

I don't know how you can cause problems really ThinkingIT

#

Only thing would be a patch I assume

#

Something is done twice in a dictionary

#

This was beforehand mostly the case of the spec service being loaded twice

#

due _cachedBlueprints

cinder fern
#

no this issue is not related to the ISpecService at all

#

so normally, this is this:
PrefabGroupService -> my service (through IPrefabGroupProvider) -> MSettings

#

so, the load order called should be MSettings.Load, MyService.Load, then PrefabGroupService.Load.

#

but you called PrefabGroupService.Load out of the DI cycle, so MyService.Load was not called and MSettings.Load was not called, so there is no data

stone shoal
#

Im not really calling it out of the DI cycle, I'm moving it out of the ISpecificationLoad cycle

#

But aside of that yes, that's correct

#

Since providers wouldn't have loaders in Timberborn

cinder fern
#

well they are interfaces, so say tomorrow the dev wants to add make an IPrefabGroupProvider to be ILoadableSingleton, it's totally acceptable.

#

and that's what I am trying to do to have my services run before it.

stone shoal
#

Yes

#

I can try one thing and after that I'll be brain dead again

#

If I make it at all KEKW

#

Not sure why I haven't thought of this before, so I kinda doubt it's gonna work

#

It's probably gonna break other mods of you now though

#
        ((Dictionary<Type, List<Lazy<Blueprint>>>)specService.GetType()
            .GetField("_cachedBlueprints", BindingFlags.Instance | BindingFlags.NonPublic)!
            .GetValue(specService))
            .Clear();
#

With this I need the reference to the _cachedBlueprints and replace it with new values

cinder fern
#

other mods do modify the _cachedBlueprints after the Load. not sure where you execute that one though

stone shoal
#

How do they modify it if it's readonly ?

cinder fern
#

it's not? it's a Dictionary

stone shoal
#

public readonly Dictionary<Type, List<Lazy<Blueprint>>> _cachedBlueprints = new Dictionary<Type, List<Lazy<Blueprint>>>();

cinder fern
#

and even the value is List<Blueprint>

#

_cachedBlueprints[SomeType] = list?

stone shoal
#

thonkeyes right

cinder fern
#

I never replace the whole thing

stone shoal
#

The most confusing thing in C# IMO

#

readonly, anyway do whatever you want with it

cinder fern
#

well it only apply to the variable itself. the content of the object no one can guarantee. if you want readonly, you use FrozenDictionary or ImmutableDictionary

stone shoal
#

Wtf is a LoadedAsset

cinder fern
#

not sure what it does but it's basically a wrapper of an Asset (GameObject etc)

#

I don't remember why it's wrapped

stone shoal
#

It doesn't crash

#

It still regenerates the whole specService but it did that before so hopefully not a problem

vast otter
#

then the question does more groups still work 😛

stone shoal
vast otter
#

meaning both move of things and added groups works 🙂

stone shoal
#

Ehhh

#

I saw extra groups at least

vast otter
#

stairs should be moved to its subgroup

stone shoal
#

But more groups just use the normal spec stuff not really the generated things. So should not really give problems if i get in the game in general

cinder fern
#

because it tries to group stuff into a group that does not actually "exist"

#

like Flywheels, I guess because it only exists in a subgroup

vast otter
cinder fern
#

I think so

#

that's the stack trace

vast otter
#

but is this after the new tapi version beta?

cinder fern
#

no, it has been happening for a while

#

but they can disable TimberApi while using CF to export so I guess it's fine and don't need to be fixed

#

as mods that give buildings with TimberApi usually give them to all factions anyway

#
    ImmutableArray<BuildingToolGroup> GroupBuildings(IEnumerable<NormalizedPrefabSpec> buildings) => [.. buildings
        .Select(q =>
        {
            var objSpec = q.PrefabSpec.GetComponentFast<PlaceableBlockObjectSpec>();
            var toolGroup = ToolGroups[objSpec.ToolGroupId];

            return (q, objSpec, toolGroup);
        })
        .GroupBy(q => q.toolGroup, (k, list) => new BuildingToolGroup(
            k,
            [.. list
                .OrderBy(q => q.objSpec.ToolOrder)
                .Select(q => q.q)]
        )).OrderBy(q => q.ToolGroupSpec.Order)
    ];

the code that crashes btw

#

I realized by doing this LINQ it's not very helpful because the stack trace does not show what exact line causes it lol

cinder fern
# stone shoal <@296010056401682442> does this solve it ?

yep with this the order is called properly now:

MSettings.AfterLoad called
[ModdableTimberborn] PrefabGroupService Load was called.
[ModdableTimberborn] Modified prefab 'BeaverStatue.Folktails' using 'ConfigurableFun.Services.PrefabModifier'
vast otter
#

loading my mods and checking them 2

#

(even if i expect them to not break 😛 )

#

checked these mods and no crash in FT or IT

- Harmony (v2.4.0)
- KnatteMaterials (v7.0.0)
- Mod Settings (v0.7.10.0)
- More TopBars (v7.0.0)
- TimberUi (v7.8.2)
- TImprove (v7.6.0)
- TImprove 4 Modders (v7.6.0)
- TImprove 4 Mods (v7.2.2)
- TImprove 4 UI (v7.10.1)
- 1x1x2Storage (v2.4.5)
- Automation (v2.7.1)
- Water Extention (v7.0.2)
- Water Extention PowerEdition (v7.0.2)
- Bob Platforms Extended (v0.7.9.0)
- Bobingabout Script Pack (v0.7.9.8)
- Bob Storage (v0.7.9.0)
- Configurable Tubeway & Zipline (v7.4.2)
- TimberApi UIBuilder (v1.0.2.0)
- Cutter Tool (v0.7.1.2)
- DamDecoration (v7.0.1)
- TimberApi (v0.7.8.0)
- DamDecorations_DecorationExtention (v7.0.0)
- ExtendedFloodgates (v7.0.0)
- Extra Terrain Tools (v0.9.3)
- Flywheels (v3.1.0.61)
- Forest Tool (v0.7.2.2)
- Frog Statue (v7.0.0)
- Goods Statistics (v0.7.3.1)
- Ladder (v3.0.4)
- MaterialPlzNoCrashes (v7.0.1)
- More Tunnels (v0.7)
- Path Extention (v7.0.1)
- MoreGroups (v7.0.2)
- Tiny Tubeway Station (v0.7.9.1)
- Tubeway Bridges (v0.7.9.0)
- Tubeway Levee (v0.7.9.0)
- Tubeway Top Connection (v0.7.7.0)
- Staircase (v7.0.1)
- Steam Update Buttons (v0.1.6)
- TimberCommons (v1.13.0)
- zxuiji - Append Vanilla Resources (v0.7.0.01)
- Underground Path (v7.10.8.0)
- Torii Gates and Lanterns (v2.2.0)
- Unstuckify (v2.0.2)
- Water Extention Irrigation Towers (v7.0.2)
- Zipline Levee (v0.7.9.0)`
stone shoal
#

The only problem now would be if you require a generated prefab before the Prefab Load method wich cannot be controlled that flow

#

Unless adding the prefabservice to your class even though you don't need it

#

Will try to upload it tomorrow

cinder fern
#

I mean normally you can't do that in the game to begin with?

stone shoal
#

For the generated parts could be used as any normal spec

stone shoal
cinder fern
#

well yeah I mean, if you do something unusual, you should expect something unusual happening right lol?

stone shoal
#

Had another idea way back how to fix it in another way

#

Never able to test-make it htough

cinder fern
#

well, for ModdableTimberborn, I just add ISpecModifier, ISpecTailRunner and ISpecFrontRunner, same for PrefabGroupService

#

so basically if you need something run earlier/later than those services, you can

#

and all of them use Bindito I believe, except the TailRunner which needs Harmony, so you get all the proper DI flow

#

btw I was thinking about a fun project similar to More Groups but do not replace the game's Tool bar 😛 why did you make a whole new toolbar back then btw?

#

can't you patch/overwrite certain stuff instead for more groups?

stone shoal
#

More groups doesn't have anything to do with the new toolbar

#

The bottombar rework is to allow multiple layers of bars

#

and ability to modify it all with specs

#

Before hand mods also crashed without it if a group had the same order so you had to make sure everyone had an unique order

cinder fern
#

can't you patch them instead?

stone shoal
#

patch what ?

#

And how would it be specs if you need code to patch it ThinkingIT

#

ofc you can path it from the spec but not able to make multible layers

#

The problem of duplicated order would also still exist

cinder fern
#

I will try later

vivid rampart
#

Hi I was told you come here as this mod seemed to bug my save game

#

They didnt go for fun activities (I did have the fun mod too)

#

I deactivated this and it worked

vast otter
#

you could try this alpha build and see if it then works:
#1064983064020799498 message

vivid rampart
#

I am useless 😄

vast otter
#

steps to test it:

  • Download the zip
  • open folder %userprofile%/Documents/Timberborn/Mods
  • unpack zip inside above folder
  • run the game and disable timberapi with a ☁️ icon (to return to steam download enable the one with a ☁️ and disable one with a 📁 icon)
  • test if it crashes or not when loading a save
  • report back the findings 😉
stone shoal
#

Updated for steam

vivid rampart
#

Thanks

blissful kindle
#

noticed flywheels / white paws / etc is looking for a newer version of the timberapi - is that a known issue?

austere tangle
#

@stone shoal , you have uploaded TAPI with the wrong version (0.7.8.0) in the manifest file. It should be at least 0.7.12.3 Most mods that use TAPI are nuked out 🤣

stone shoal
stone shoal
blissful kindle
#

hmm i got some weird error log, can i share in here?

#

i can't tell what mod it's from (not a programmer so harder for me :|)

vast otter
blissful kindle
#

ok i got this error with trying to load whitepaws after the timberapi updates, so i'll share this here. and i got a separate error for the coil, i'll share that in mod users

vast otter
blissful kindle
stone shoal
#

Did i mess up again 🤔

#

Idk

spring radish
#

I run Timberborn with the thread limiter, and the call to ModManagerUI.SteamChecker.IsRestartCompatible when exiting the Mod Manager after installing/updating a mod fails (because the parent process is gone).

stone shoal
#

what ?>

#

What has that todo with TimberAPI ?

spring radish
#

ugh, I put it in the wrong channel 😔

calm copper
#

I wasn't commenting here for too long. Which is technically good (no complains => no comments). But just to leave some kudos for TAPI LoveIT

#

@stone shoal , thanks for your great job! (which doesn't make me complaining, lol)

stone shoal
#

Thanks anyway

calm copper
green vale
vast otter
spring radish
#

TimberAPI has been replaced with Moddable Tool Groups

neat burrow
vast otter
#

after its updated to support the new mod
gives equal functionality but some differances

stone shoal
#

On steam it should not crash anymore though

spring radish
spring radish
#

and maybe also change the name to something like TimberApi (obsolete in 1.0)?

stone shoal
spring radish
#

Mostly for the name in manifest.json so that appears in the mod loading screen.

severe solar
spring radish
#

Could you upload 0.8 to mod.io as well. Some people are still trying to use v0.7.12.2 on 1.0.12.6 (#🚀mod-users message)