#TimberAPI

1 messages Ā· Page 4 of 1

wispy crypt
#

smart power broken? looked like it worked this morning

#

maybe didn't pay attention enough

burnt wasp
austere tangle
#

crashes the game when finish building an engine

burnt wasp
#

ignore lang.. just ProductVersion

wispy crypt
median plinth
#

I wonder how it goes there. Could you use FileVersion as that seems ok?

burnt wasp
#

Yes, I can use that and I probably will. But I don't know how it got there. Only TAPI has this, other plugins display it correctly

median plinth
#

seems older versions of timberAPI don't have the hash on their product versions either. Strange, we didn't change anything on our publish pipeline

orchid sage
#

RotatingSun is broken?

austere tangle
#

Is fixed for normal game, still crash the game in editor ...

orchid sage
#

ah yeah

lofty lark
#

Just a small question regarding timberAPI : is it possible to add a subgroup to the trees / crops toolbars ? In case I want to make genetically engineered super crops šŸ˜…

lofty lark
#

well plants are not put in the plant group through the "placable block object" like regular buildings, they are put in the tree/crop group depending on whether they have the "tree component" or "crop" script

#

but i suppose when it comes to building the toolbar it's just another toolgroup ?

stone shoal
lofty lark
#

Do you know how the groups are called ? I don't have access to that info so best I can do is try to guess them.

#

I'll try to poke at it tomorrow

vast otter
#

Looks like its the plant/tree prefab name

crude shuttle
#

is there any way to pin TimberAPI and other like mods to the top of the google doc?

#

like i was thinking BepInEx, TimberAPI and Mimic's core needed mods, then all the rest of the mods after that since you need these essentially first

vast otter
crude shuttle
#

Oh neat, I'm finally updating everything after my last map got locked at 0/0 fps @ 1x speed. Going in the forever map folder

crude shuttle
#

Can't wait to test latest variation of water extension

#

Need the big irrigation towers now more than ever though lol

languid ermine
#

Just opened an issue on github (https://github.com/Timberborn-Modding-Central/TimberAPI/issues/94) ... Were there any breaking changes in the last experimental update?
My personal change of some buildings' recipes via BuildingSpecification, just stopped working - causing the game to crash when trying to start/load a game/settlement.

GitHub

I have a few BuildingSpecificaton files changing the recipes on some buildings (from WaterBeaverFaction). From today's experimental update they cause the game to crash (on InGame it seems, not ...

stone shoal
#

And there are probably breaking changes in last update

languid ermine
crude shuttle
#

so my playthrough if on current patch needs to be vanilla? saddage

languid ermine
orchid sage
#

My mod is also broken since last update and I suspect TimberAPI needs updating before I can fix it (no pressure, just sayin' for the evidence stack).

#

I also could just be shifting blame, who can tell?

stone shoal
orchid sage
#

I posted one earlier but it's quite the stacktrace. At the time you seemed to think it had to do with the new button scaling IIRC. I'd need to search to find it again. Alternatively, I can induce it again tomorrow if need be.

orchid sage
orchid sage
#

#šŸ¤–mod-creators message

#

found it

#

it could be my end but I see nothing wrong with my harmony overrides

#

weird is all I can say at the moment

stone shoal
#

Ah yea, you could not find any reason to be it on your side?

#

I was waiting for youbto figure that out at that moment

orchid sage
#

no, but I tbh have not searched for more than say an hour

#

Other mods have my eyes. Like I said, no pressure, I'd say its 50/50 whose fault it is

stone shoal
#

Well it crashes on a postfix on yours so doubt will be TimberApi

#

But maybe just need a rebuild

orchid sage
#

maybe it could be that simple

#

What left me suspicious was the weird button issues with TimberAPI atm, the lack of frame or whatever in the main menu

#

that was probably just me not wanting to fix my mod and selling myself an excuse though lol

#

I'll take a look at it soon anyways

stone shoal
orchid sage
#

hmmm

stone shoal
#

Of you mean missing tools, that would have 0neffect

orchid sage
#

no main menu entry buttons are missing frames

stone shoal
#

Oh

orchid sage
#

maybe my mod causes this? lol

stone shoal
#

Well gtg for now

orchid sage
#

no worries

stone shoal
orchid sage
#

I fixed it, twas my mod ofcourse

#

lol

stone shoal
#

Good to know

#

Had it to do with a harmony patch ?

orchid sage
#

Nope, pmduda renamed a Panel

stone shoal
#

Understandable

orchid sage
#

or some dev anyways

#

just had to get the new name lol

stone shoal
#

Ez fix UmaruGlasses

orchid sage
#

yep

#

the stacktrace was a wild goose chase, it was really just a simple nullref "can't find that" situation

nova gale
#

@orchid sage what was the rename?

orchid sage
#

yeah, NewMapPanel to NewMapView

vast otter
#

New problem noted with tapi to fix for stable release
If you scroll on a toolbar with no buildings only submenus it crashes:

Reproduction:

Mods:

  • TAPI
  • Modmanager
  • More groups

Steps:

  • Launch a game
  • Press on storage
  • Scroll and hold shift
  • Crash

Error:

v0.5.5.0-4e59a84-xsw
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <cb3602b5bf2148caa08db7780ec02b19>:0)
Timberborn.Common.ReadOnlyList`1[T].get_Item (System.Int32 index) (at <e72b32c80c554ad0b291a8046b9dd76f>:0)
Timberborn.ToolSystem.ToolbarButtonRetriever.TryGetPreviousVisibleButton (System.Collections.Generic.IReadOnlyList`1[T] buttons, Timberborn.ToolSystem.IToolbarButton& previousButton) (at <8608220f7fd6421f80d51e6c557cfbe9>:0)
Timberborn.ToolSystem.ToolButtonService.TryGetPreviousToolButton (Timberborn.ToolSystem.IToolbarButton& toolButton) (at <8608220f7fd6421f80d51e6c557cfbe9>:0)
Timberborn.ToolSystem.ToolSelector.ProcessToolbarInput () (at <8608220f7fd6421f80d51e6c557cfbe9>:0)
Timberborn.ToolSystem.ToolSelector.ProcessInput () (at <8608220f7fd6421f80d51e6c557cfbe9>:0)
Timberborn.InputSystem.InputService.CallInputProcessors () (at <3f98b95327c94694824c1907abb85ac0>:0)
Timberborn.InputSystem.InputService.Update () (at <3f98b95327c94694824c1907abb85ac0>:0)
#

"Fix" Disable if no buildings is shown?

severe solar
#

@stone shoal how are dlls loaded? Are they loaded custom or via BepInEx?

stone shoal
#

Mine is "loaded" just getting the reference windows saved for the dll

severe solar
#

So if i have it be a plugin as well as a TAPI mod its fine?

stone shoal
#

Bo idea what you mean

severe solar
#

i guess i can better explain later

stone shoal
#
// Old, lacks ability to be extended easily, specially with complex components
_box.AddPreset(test => test.Sliders().SliderDiamond(10, 100, builder: builder => builder.SetLowValue(10).SetHighValue(100)));

// New option 1, There is no way to make the options discoverable by which preset type they belong (slider, buttons, etc)
// Builder Func would still be available here, eg. builder => builder.SetLowValue(10)
_box.AddPreset("SliderDiamond", new SliderOptions(10, 100)); // Diamond slider with a value of min: 10, max: 100
_box.AddPreset("Button", new ButtonOptions("text.locKey", 10, 10)); // locKey, height, width

// New option 2, other option
_box.AddPreset("SliderDiamond", builder => builder.SetLowValue(10).SetHighValue(100));
_box.AddPreset("SliderDiamond", builder => builder.SetLocKey(10).SetHeight(10).SetWidth(10));

// Wish I was possible. or something similar
_box.AddPreset("SliderDiamond", 10, 100); // Diamond slider with a value of min: 10, max: 100
_box.AddPreset("Button", "text.locKey", 10, 10); // locKey, height, width
#

@median plinth, @severe solar, @full acorn. Any thoughts? which one would be best.

full acorn
#

Hmmmmm

#

This is a difficult choice

#

I'm not sure on the possibility here, but what about something akin to

_box.AddPreset(UI.SliderDiamond, config => {
  LowValue: 10,
  HighValue: 100,
  LocKey: "text.lockey"
})
#

Aside from that, option 2 is my preference

severe solar
#

OOoh, so you create a preset, and just get the preset. So the creation is split from the initialization.

#

i very much like that

#

i dont like 1, as i like to add what is appropriate

#

I prefer option 2 in that instance, as 3 is basicly 1, if you were to give all of the paramaters a default value.

#

you dont know which apply, as the ones that dont, will just be ignored

stone shoal
#

2 is so long though for just setting a text, which is 90% the case of the button. And for the slider I think it might be required to set some values

#

With the usage of 2, would adding a Name as a parameter be good. You need this name to be able to find the element afterwads for controls

stone shoal
#

I am not sure the builder (options 2) was possible had the same problem, not knowing which builder it should connect to

full acorn
#

Yeah, fair point, you'd need a reference document

#

you could have a constructor with loads of optional parameters, but that might get unweildy

stone shoal
full acorn
#

I suppose that would essentially be the last option

stone shoal
#

These things exists, only not sure yet how to use them as an object

full acorn
# stone shoal Wym ?

Having a function with named parameters to help with discovery, would essentially be the same as the last option in that list

stone shoal
#

Except it's not discoverable without docs

stone shoal
#

@full acorn Options 2 would pretty much only viable way, else you would require reflections to get the props.

    [Configurator(SceneEntrypoint.InGame)]
    public class PresetConfigurator : IConfigurator
    {
        public void Configure(IContainerDefinition containerDefinition)
        {
            // Is this a problem to register them like this
            containerDefinition.MultiBind<IPresetBuilder<SliderBuilder>>().To<TestPreset>();
            
            // Not sure yet if I can make this possible, might make it possible to make custom builders (probably never going to happen). Might require reflections :(
            containerDefinition.MultiBind<IPresetBuilder>().To<TestPreset>();
        }
    }

    public class TestPreset : IPresetBuilder<SliderBuilder>
    {
        public string Id => "DiamondSlider";
        
        public SliderBuilder Build(SliderBuilder builder)
        {
            return builder
                .SetLabel("HelloWorld")
                .SetHeight(100)
                .SetWidth(100)
                .SetLowValue(10)
                .SetHighValue(100);
        }
    }

    public interface IPresetBuilder<TBuilder> : IPresetBuilder
    {
        TBuilder Build(TBuilder builder);
    }

Usage:

builder.AddPreset<SliderBuilder>("DiamondSlider", builder => builder.SetName("Test"));
full acorn
#

Nice! Would also be good to have a Struct with the IDs in some sort of structure, so for the ID you can do UI.Slider.DiamondSlider or something

stone shoal
full acorn
#

Noice

stone shoal
#
            // Is this a problem to register them like this
            containerDefinition.MultiBind<IPresetBuilder<SliderBuilder>>().To<TestPreset>();
            
            // Not sure yet if I can make this possible, might make it possible to make custom builders (probably never going to happen). Might require reflections :(
            containerDefinition.MultiBind<IPresetBuilder>().To<TestPreset>();
#

But what about this way of registering

#

iirc I cannot fetch all multibinds with an generic type, need to do it for each type. So I someone else can't make another builder

#

And is also maybe a slightly bit anoying way to register ThinkingIT ?

full acorn
#

Hmm, ok that's not as ideal

#

I would have thought you could have just registered the interface 😦

stone shoal
full acorn
#

OOoooh that could be good

#

nice and concise too

stone shoal
#

gedtting an error for it now though KEKW fixed it

full acorn
#

@stone shoal Quick question; I'm about to start working on the UI for a new mod - should I hold off until the new UI system is in place?

severe solar
#

preasure preasure

full acorn
#

No pressure meant! I can just use something temporary for now!

#

Sorry, didn’t mean to pressure you šŸ˜…

severe solar
#

Nono, im joke

#

Sorry 😦

severe solar
full acorn
#

Noice! Thank you

stone shoal
# full acorn <@144547314718081024> Quick question; I'm about to start working on the UI for a...

Needed to eat, sorry for the cliff hanger ohlsippyn.

Depends on how you want to make it. atm it's pretty much impossible to create actual component parts and reuse them easily. The upgrade is mainly over the preset system.

So what we said earlier in this chat is that you won't be able to give options in the preset with the new system and only get the builder with it. So to minimize changes you can do that already, except that not all parameters are nullable atm.

The general functionality of building will probably stay the same eg. SetWidth, SetHeight, SetLocKey

Other things that might be added/modified

  • Preset stuff
    • Being able to make your own presets
    • Using preset inside a preset factory, website example: Card, CardBody
  • Accessing the UIBuilder UIBuilder.ComponentBuilder, going to try a more accessible way for this
  • FragmentBuilder, BoxBuilder. Same as UIBuilder, everything is too fixed
  • new: Access to a builder with just the visual element
  • new: Way to add UXML files (prebuilded)
    • Adding them with a string or manually
    • Accessing them with a builder afterwards

Might look like alot but probably won't be that much refactoring for user side. Since you only use the fragment/box builder once for a component.

full acorn
#

Oh nice! That’s amazing thank you kindly!

stone shoal
#

I dont think its too hard to make, now I have a working concept. But need to fix the scrolling firt

full acorn
#

Fair enough! I'm looking forward to the idea of Cards

stone shoal
full acorn
full acorn
#

Yeah very well timed

untold kraken
#

TimberAPI 0.6.3.1 and Timber-Commons 1.3 currently conflict and crash when loaded together. No idea which one makes the the crash. Loading either alone without the other has no crash.

untold kraken
# untold kraken TimberAPI 0.6.3.1 and Timber-Commons 1.3 currently conflict and crash when loade...

[Error : Unity Log] Exception: Method static System.Reflection.MethodBase IgorZ.TimberCommons.WaterService.DirectWaterServiceAccessor+WaterSimulatorWaterDepthsPatch::TargetMethod() returned an unexpected result: null
Stack trace:
HarmonyLib.PatchClassProcessor.RunMethod[S,T] (T defaultIfNotExisting, T defaultIfFailing, System.Func`2[T,TResult] failOnResult, System.Object[] parameters) (at <474744d65d8e460fa08cd5fd82b5d65f>:0)
Rethrow as HarmonyException: Patching exception in method static System.Reflection.MethodBase IgorZ.TimberCommons.WaterService.DirectWaterServiceAccessor+WaterSimulatorWaterDepthsPatch::TargetMethod()
HarmonyLib.PatchClassProcessor.ReportException (System.Exception exception, System.Reflection.MethodBase original) (at <474744d65d8e460fa08cd5fd82b5d65f>:0)
HarmonyLib.PatchClassProcessor.Patch () (at <474744d65d8e460fa08cd5fd82b5d65f>:0)
HarmonyLib.Harmony.PatchAll (System.Type type) (at <474744d65d8e460fa08cd5fd82b5d65f>:0)
IgorZ.TimberDev.Utils.HarmonyPatcher.Patch (System.String patchId, System.Type[] patchTypes) (at :0)
IgorZ.TimberDev.Utils.HarmonyPatcher.PatchRepeated (System.String patchId, System.Type[] patchTypes) (at :0)
IgorZ.TimberCommons.WaterService.DirectWaterServiceAccessor.PostLoad () (at :0)
Timberborn.SingletonSystem.SingletonLifecycleService.PostLoadSingletons () (at <86c1f5b125c14aec854cc56f64ca5fa5>:0)
(wrapper dynamic-method) Timberborn.SingletonSystem.SingletonLifecycleService.DMD<Timberborn.SingletonSystem.SingletonLifecycleService::LoadAll>(Timberborn.SingletonSystem.SingletonLifecycleService)
Timberborn.SingletonSystem.SingletonLifecycleAdapter.Start () (at <86c1f5b125c14aec854cc56f64ca5fa5>:0)

stone shoal
untold kraken
#

mmm, no Timber-Commons is teh dependency for WaterExtension

austere tangle
untold kraken
#

MM, Water Extension has both as a dependency, sorry.

stone shoal
#

This is not an issue with TimberApi at least, you should try to contact igor. Maybe he has an mod thread here else you could ping him in #šŸ¤–mod-creators. Or todor might able to help you. But looks to me like an game update issue

austere tangle
untold kraken
austere tangle
calm copper
#

From the TimberAPI docs: https://timberapi.com/making_mods/#decompiling-timberborn

The NuGet package Timberborn.GameLib you installed earlier allows you to see the general structure of the game. However, it’s recommended to decompile the game to see how exactly it works.

Where is that "earlier"? None of the topics in TOC explain it. And search for Timberborn.GameLib in the manger doesn't give anything neither.

stone shoal
#

But it seems like its not in the docs or disappeared

calm copper
stone shoal
stone shoal
#

@full acorn registering 10K presets (exluding whatever bindito needs to do), takes around 250ms. Should be fast enough right

#

Not sure how slower pc's do these things, but I guess just a x2

stone shoal
#

Smoll problem, I don't know how to make it able to use a preset in another preset atm

#

Gives a bindito circular loop

full acorn
#

Oh nice! Well 250ms is barely any time so even a 4x is negligible

#

Hm, that ain’t fun…

stone shoal
#

@ebon sparrow, I am not sure if this is me just trying to do weird stuff, since I have not much experience with dependency injection other then Timberborn.

I have a interface IPreset which I multibind to many preset classes
I have 1 singleton repository which has the IEnummerable<IPreset> in the constructor
But I want to use the repository in one/or multiple IPreset classes, which leads to a circular dependency

Is that something normal in all DI's? I can understand it but also seems like it should be possible to do ThinkingIT

#

Would you maybe also have an another way to do such thing? Thought of maybe registering themself in a LoadableSingleton

#

Is that where a provider maybe is for thonkeyes

river quail
#

circular dependencies are fine in a sense as long as they don't call eachother in a way that causes a processing loop

#

but I don't think I really have sufficient context to provide better input

stone shoal
# river quail but I don't think I really have sufficient context to provide better input

Timberborn aside how would you do it in another DI?

  • Filling a list in a repository of classes, based on a interface, that can be fetched based on a string
  • Make the repository accessible in the classes with DI
  • Since filling the repository is done in constructor time, and using it after. There would not be a conflict (aside if you make one yourself by fetching in a loop)
#

Any pattern that is common to be used for such thing

ebon sparrow
#

Invert the dependency - IPreset can have an event and repository can subscribe to that event

stone shoal
#

I don't quite understand that one.

ebon sparrow
#

well, i'm short on time so no more explaini g atm

stone shoal
river quail
#

I don't do a whole lot of DI

#

lots of IOC (though i don't think of it like that when I do)

#

if the circular dependency is just "I pass this to IPreset Ctors who collect data out of it and then lose the reference to the Repo"

#

I don't think thats of any concern

stone shoal
#

No reference on the repo is only used on a later time, where all IPreset and repo ctors are finished

#

Guess it's not much of an issue, but just need to make a small workaround for bindito. or maybe with what pmduda said.

stone shoal
#

Getting code completion is hard sadcat

stone shoal
#
__result = uiBuilder.Create<ButtonBuilder>()
    .SetLocKey("HelloWorld")
    .SetWidth(100)
    .SetHeight(100)
    .SetBackgroundColor(Color.blue)
    .Build();

__result = oldBuilder.CreateComponentBuilder()
    .CreateButton()
    .SetLocKey("HelloWorld")
    .SetWidth(100)
    .SetHeight(100)
    .SetBackgroundColor(Color.blue)
    .Build();

Not too much different at this point, except that anyone can make any kind of builder, for example the fragment and box builder would be the same as an element builder with less workarounds.

stone shoal
#

@full acorn

var existingElement = new LocalizableButton();

uiBuilder.Create<ButtonBuilder, LocalizableButton>(existingElement);

If you need to load an existing element, probably. If everything will work. Unfortanite that I cannot remove the element type, but probably won't need to be used except some edge cases

full acorn
#

Ayy nice!

stone shoal
#

Ofc I cannot initialize a non element builder now šŸ™‚, Could just make an abstrac method which solved it FacePalmLotus

stone shoal
#

@full acorn
Custom builders, handy if you have some complex style setters and need to be different with any specific item so a preset would still be annoying to use. In overall they could technically be used as a preset as well.

Most simple example, extending an elementbuilder which allows all options from that builder. Then you can extend it with your specific methods and how to build it (optionally). Like setting a background color on the element.

public class BatteryCustomFactionBuilder2 : SliderBuilder
{
    public BatteryCustomFactionBuilder2 SetFactionColor(string faction)
    {
        Root.style.color = faction == "PowerHouse" ? new StyleColor(Color.yellow) : new StyleColor(Color.blue);
        return this;
    }

    public override LocalizableSlider Build()
    {
        Root.style.backgroundColor = new StyleColor(Color.green);
        
        return base.Build();
    }
}

More complex option. be it's own builder from scratch. In this example it also set it's root from a preset in InitializeRoot. This is optional, without the method it would create a new TElement, which is in this case LocalizableSlider. You could also load a UXML preset in here since the IResourceAssetLoader is available here.

public class BatteryCustomFactionBuilder : BaseBuilder<BatteryCustomFactionBuilder, LocalizableSlider>
{
    protected override BatteryCustomFactionBuilder BuilderInstance => this;
    
    private readonly UiBuilder _uiBuilder;

    public BatteryCustomFactionBuilder(UiBuilder uiBuilder)
    {
        _uiBuilder = uiBuilder;
    }

    protected override LocalizableSlider InitializeRoot()
    {
        return _uiBuilder.LoadPreset<SliderBuilder>("TestPreset").Build();
    }

    public BatteryCustomFactionBuilder SetFactionColor(string faction)
    {
        Root.style.color = faction == "PowerHouse" ? new StyleColor(Color.yellow) : new StyleColor(Color.blue);
        return this;
    }
}
#

Usage:
uiBuilder.Create<BatteryCustomFactionBuilder>().SetFactionColor("PowerHouse").BuildAndInitialize();

full acorn
#

That’s some grade A stuff

stone shoal
#

Only bit struggling about if presets are even usefull now ThinkingIT

#

Since you could just make a builder for each preset, and extend on it further on every layer

#

The only thing you don't have than is strings to builders, but I could just make a _uiBuilder.Build("UIBuilderName") or something ThinkingIT

full acorn
#

Presets are still useful I think, it means if someone doesn’t want to make their own ui elements, they don’t have to

#

Right?

stone shoal
#

Well, those builder would be inside TimberApi then šŸ˜›

#

instead of being presets

full acorn
#

Wait, I think I might be misunderstanding what a preset really is

#

Is a preset just a ui component like a list view, checkbox or button?

stone shoal
#

A preset would become a pre setup element.

#

Sec for making an example

#
public class TestButtonPreset : IPreset<ButtonBuilder>
{
    public string Id => "TestButtonPreset";
    
    public ButtonBuilder Build(ButtonBuilder builder)
    {
        return builder
            .SetBackgroundColor(Color.green)
            .SetPadding(10);
    }
}
#

This would make a green button with a padding of 10

#

And you would use it like _uiBuilder.LoadPreset<ButtonBuilder>("TestButtonPreset").Build();, (Inside builders you would not need the .build, just on the uiBuilder)

#

Meanwhile this would now result in the same effect:

public class TestButtonBuilder : ButtonBuilder
{
    public override LocalizableButton Build()
    {
        return SetBackgroundColor(Color.green)
            .SetPadding(10)
            .Build();
    }
}

Usage: uiBuilder.Create<TestButtonBuilder>().Build();

full acorn
#

Huh, interesting

#

I still have much to learn it would seem

stone shoal
#

On what aspect šŸ˜› ?

#

TimberApi?

full acorn
#

C# as a whole

#

I was watching Tobbert and Ratchet make this amazing patching class system and I understood none of it

severe solar
#

someone made something better already

full acorn
#

Oh! That’d be good to try then! Was it Twiner?

#

I ran into the same error BTW, crashes on tick

severe solar
#

oh rip

full acorn
#

I just want to make plank… pleese game… let me ElectricalNodeSpecification

stone shoal
#

(╯°▔°)╯︵ ┻━┻

#

I guess preset system got useless within 2 weeks

#

uiBuilder.Build<TestButton, LocalizableButton>(); If you want to build it instantly

stone shoal
# full acorn Wait wut?

Yeah... forget this one, that ain't going to work (unless you make it completely from scratch)

#

So useless for "presets"

#

Until I can work around that as well šŸ˜‰

full acorn
#

I’ll pretend to understand

stone shoal
#

I am just messing around with things that don't make sense

#

Probably overcomplicating things by x1000

full acorn
#

Why write one line when you can write a whole class? dabhaha

full acorn
full acorn
#

He big brainz

severe solar
#

I have, but its not finished for your usecase yet

stone shoal
#
                // Create builder
                uiBuilder.Create<TestButtonBuilder>("WithAName").Build();
                uiBuilder.Create<TestButtonBuilder>().Build();
                uiBuilder.Create<TestButtonBuilder>().BuildAndInitialize();

                // Create builder and set the a root element
                uiBuilder.Create<TestButtonBuilder, LocalizableButton>("WithAName", new LocalizableButton()).Build();
                uiBuilder.Create<TestButtonBuilder, LocalizableButton>(new LocalizableButton()).Build();
                uiBuilder.Create<TestButtonBuilder, LocalizableButton>(new LocalizableButton()).BuildAndInitialize();

                // Create a builder and return a visualElement
                uiBuilder.Build("WithName", typeof(TestButtonBuilder));
                uiBuilder.Build(typeof(TestButtonBuilder));
                
                // 100% the same as the one above, but different sugar syntax
                uiBuilder.Build<TestButtonBuilder>("WithName");
                uiBuilder.Build<TestButtonBuilder>();

                // Returns the element type given, usefull for things like list elements where you need to set the items.
                uiBuilder.Build<TestButtonBuilder, LocalizableButton>("WithName");
                uiBuilder.Build<TestButtonBuilder, LocalizableButton>();
                
                // Usefull if you want dynamic UI building but need to do things for different types eg. lists.
                uiBuilder.Build<LocalizableButton>("WithName", typeof(TestButtonBuilder));
                uiBuilder.Build<LocalizableButton>(typeof(TestButtonBuilder));
#

All possible ways to either create a builder. or build it instantly, usefull for dynamic runtime builders.
When directly building you cannot give a root element, I thought this would be a very edge case where too many things could too easily bad.

stone shoal
#

Takes about 2,5 seconds to build 10_000 x 13 elements = 130_000 elements

calm copper
stone shoal
#

If you only do new VisualElement it takes around 2 to 2.2 seconds. So cant really optimize much around that

#

And with UXML loading a basic Timberborn input field took around 11 seconds

#

So i'd say that would be more than enough for some UI thats generated once in loading screen

#

Loading 1 asset bubdle of water beavers on the other hand probably takes quite a while RakaSweaty

stone shoal
#

It takes about 1,2 seconds. To create 100_000 stylesheets which all has each 1 class with 1 background-image setter

#
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
stone shoal
#
[Warning: Unity Log] My class is: TimberApi.UiBuilderSystem.ElementBuilders.ButtonBuilder
[Warning: Unity Log] My class is: TimberApi.UiBuilderSystem.Presets.Buttons.ArrowDown

Base class knows which class it actual is šŸ™‚

stone shoal
#

StylesheetBuilder in progress example

#
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
);

This will create a class. with the name HelloWorld, and set the Width, Height, PaddingLeft, PaddingRight. Which only will trigger on a checked radio button that you hover over with your mouse.

In USS it would have been:

.HelloWorld:hover:checked {
  width: 100,
  height: 100,
  padding-left: 100,
  padding-right: 100
}

If you would build it with the unity stylebuilder it would have been

builder.BeginRule(0);

    builder.BeginComplexSelector(31); // This number is important
        builder.AddSimpleSelector(new[]
        {
            new StyleSelectorPart { value = "MyFirstClass", type = StyleSelectorType.Class },
            new StyleSelectorPart { value = "hover", type = StyleSelectorType.PseudoClass },
            new StyleSelectorPart { value = "checked", type = StyleSelectorType.PseudoClass },
        }, StyleSelectorRelationship.None);
    builder.EndComplexSelector();

    builder.BeginProperty("width", 0);
        builder.AddValue(new Dimension(10, Dimension.Unit.Pixel));
    builder.EndProperty();
    
    builder.BeginProperty("height", 0);
        builder.AddValue(new Dimension(10, Dimension.Unit.Pixel));
    builder.EndProperty();
    
    builder.BeginProperty("padding-left", 0);
        builder.AddValue(new Dimension(10, Dimension.Unit.Pixel));
    builder.EndProperty();
    
    builder.BeginProperty("padding-right", 0);
        builder.AddValue(new Dimension(10, Dimension.Unit.Pixel));
    builder.EndProperty();

builder.EndRule();
#

Would the TimberApi StylSheetBuilder be handy wrapper, or would some examples be enough for the original builder?

stone shoal
#
var styleSheet = new TimberApiStyleSheetBuilder()
    .AddClass(
        "HelloWorld",
        propertyBuilder => propertyBuilder
            .Add(Property.Width, new Dimension(100, Dimension.Unit.Pixel))
            .Add(Property.Height, new Dimension(100, Dimension.Unit.Pixel))
            .Add(Property.PaddingLeft, new Dimension(100, Dimension.Unit.Pixel))
            .Add(Property.PaddingRight, new Dimension(100, Dimension.Unit.Pixel)))
    .AddClass(
        "HelloWorld",
        propertyBuilder => propertyBuilder
            .Add(Property.Height, new Dimension(200, Dimension.Unit.Pixel)), PseudoClass.Hover)
    .Build();
#
protected override LocalizableButton InitializeRoot()
{
    var styleSheet = new TimberApiStyleSheetBuilder()
        .AddClass(
            "HelloWorld",
            propertyBuilder => propertyBuilder
                .Add(Property.BackgroundImage, "ui/images/buttons/arrow-up", StyleValueType.ResourcePath)
                .Add(Property.Width, new Dimension(100, Dimension.Unit.Pixel))
                .Add(Property.Height, new Dimension(100, Dimension.Unit.Pixel)))
        .AddClass(
            "HelloWorld",
            propertyBuilder => propertyBuilder
                .Add(Property.BackgroundImage, "ui/images/buttons/arrow-down", StyleValueType.ResourcePath)
                .Add(Property.Height, new Dimension(200, Dimension.Unit.Pixel))
                .Add(Property.Width, new Dimension(200, Dimension.Unit.Pixel))
            , PseudoClass.Hover)
        .AddClass(
            "HelloWorld",
            propertyBuilder => propertyBuilder
                .Add(Property.BackgroundImage, "ui/images/buttons/arrow-down-active", StyleValueType.ResourcePath)
                .Add(Property.Height, new Dimension(200, Dimension.Unit.Pixel))
                .Add(Property.Width, new Dimension(200, Dimension.Unit.Pixel))
            , PseudoClass.Hover, PseudoClass.Active)
        .Build();

    return _buttonBuilder
        .AddStyleSheet(styleSheet)
        .AddClass("HelloWorld")
        .Build();
}

Literally the whole button preset UmaruGlasses.

With my other idea this would be just 3 lines, but you could only change backgrounds.

#

Funny animations

stone shoal
#
_selectorBuilder()
    .AddType(SelectorType.Button)
    .AddName("MyButtonName")
    .AddPseudoClass(PseudoClass.Checked)
    .AddChildSelector()
    .AddClass("MyClass")
    .AddPseudoClass(PseudoClass.Hover, PseudoClass.Active);

// Option 1, what will crash since you cannot end with a `>`
_selectorBuilder()
    .AddType(SelectorType.Button)
    .AddName("MyButtonName")
    .AddPseudoClass(PseudoClass.Checked)
    .AddChildSelector();


// Option 2
_selectorBuilder()
    .AddType(SelectorType.Button)
    .AddName("MyButtonName")
    .AddPseudoClass(PseudoClass.Checked)
    .AddClass("MyClass", Selector.Child)
    .AddPseudoClass(PseudoClass.Hover, PseudoClass.Active);

// Option 2, Will crash because you cannot start with a child
_selectorBuilder()
    .AddType(SelectorType.Button, Selector.Child)
    .AddName("MyButtonName")
    .AddPseudoClass(PseudoClass.Checked)
    .AddClass("MyClass")
    .AddPseudoClass(PseudoClass.Hover, PseudoClass.Active);

@full acorn, @severe solar. What would make more sense?
Both will result in Button#MyButtonName:checked > .MyClass:hover:active

stone shoal
#
var styleSheet = new TimberApiStyleSheetBuilder()
    .AddComplexSelector(builder => builder.AddClass("MyClass"), 
        builder => builder.Add(Property.BackgroundColor, "blue", StyleValueType.Color))
    
    .AddComplexSelector(builder => builder.AddClass("MyClass").AddPseudoClass(PseudoClass.Hover), 
        builder => builder.Add(Property.BackgroundColor, "purple", StyleValueType.Color))

Not bad I suppose ThinkingIT.

#

Starting to like the new builder UmaruGlasses. Will be so much easier to maintain and actually do stuff in. And removing unity as a whole again PandaDevil

calm copper
#

@stone shoal Wow! The builder looks really cool. Never used them tbh, but the difference between Unity and the builder looks huge.

stone shoal
#

I don't quite understand what you mean with the difference between Unity and the builder looks huge.

calm copper
#

I mean, you code examples: with pure Unity and with the builder. The latter is much more compact and readable.

stone shoal
#

Ohh so yea unity builder can get very large fast

severe solar
stone shoal
#

It will add a > or a between items

#

eg. .test > .test2 or .test .test2

severe solar
#

OOh, i see, in that case option 1 makes more sense to me

stone shoal
#
.AddComplexSelector(
    builder => builder
        .AddClass("FirstItem"),
    builder => builder
        .Add(Property.Width, new Dimension(500, Dimension.Unit.Pixel))
        .Add(Property.Height, new Dimension(500, Dimension.Unit.Pixel))
        .Add(Property.BackgroundImage, "ui/images/buttons/arrow-up", StyleValueType.ResourcePath)
)
.AddComplexSelector(
    builder => builder
        .AddClass("FirstItem")
        .AddDescendant()
        .AddType(SelectorType.VisualElement), 
    builder => builder
        .Add(Property.Height, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.Width, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.Padding, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.BackgroundImage, "ui/images/buttons/arrow-down", StyleValueType.ResourcePath)
)
.AddComplexSelector(
    builder => builder
        .AddClass("FirstItem")
        .AddChild()
        .AddType(SelectorType.VisualElement), 
    builder => builder
        .Add(Property.Height, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.Width, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.Padding, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.BackgroundImage, "ui/images/buttons/arrow-left", StyleValueType.ResourcePath)
)
#

But it's not super bad either, and works like a charm šŸ™‚

stone shoal
#

Tested a working, not very clean code string parser

new TimberApiStyleSheetBuilder()
    .AddRegexSelector(".FirstItem", builder => builder
        .Add(Property.Width, new Dimension(500, Dimension.Unit.Pixel))
        .Add(Property.Height, new Dimension(500, Dimension.Unit.Pixel))
        .Add(Property.BackgroundImage, "ui/images/buttons/arrow-up", StyleValueType.ResourcePath))
    
    .AddRegexSelector(".FirstItem VisualElement", builder => builder
        .Add(Property.Height, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.Width, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.Padding, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.BackgroundImage, "ui/images/buttons/arrow-down", StyleValueType.ResourcePath))
    
    .AddRegexSelector(".FirstItem > VisualElement", builder => builder
        .Add(Property.Height, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.Width, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.Padding, new Dimension(100, Dimension.Unit.Pixel))
        .Add(Property.BackgroundImage, "ui/images/buttons/arrow-left", StyleValueType.ResourcePath))
.Build();
#

With this you could write very complex selectors within 1 line, like you would do in USS. Not sure if it will be implemented. Depending on performance

#

To create 100_000 StyleSheets

Base creating empty StyleSheet took 0,4 seconds 
string parse took 8,6 seconds
full code took 4,8 seconds
#

Takes double as much time ThinkingIT

#

Could maybe improve it more, Maybe If I could make a single regex to filter every item it should pretty be as fast as the other part

#

It probably is a handy feature ThinkingIT

#

The space between selectors is annoying as hell tho

#

Since you don't really know the difference between a normal one or that one

calm copper
#

Why is there 4 arrows down? From the builder code I don't see how is it happening.

calm copper
stone shoal
calm copper
#

So, Add(Property.BackgroundImage) is actually applied to the child and the parent, not just child?

#

nm, I still don't get how this builder makes 7 images on the screen. Intuitively, I'd expect that one "add image" would result in exactly one image in UI.

stone shoal
#

The styling of those 7 items are determined by those selector parts

#

The add properties are the stylings applied

stone shoal
#

Reduced the time from 2.5ms(25.000 ticks) for each selector to 300 ticks for each selector

#
var fullList = new List<string>();

string input = "       .FirstItem > VisualElement.Class        #Item.Class   >   .LastItem                ";

string[] childs = input.Split('>', StringSplitOptions.RemoveEmptyEntries);

for (int i =  0; i < childs.Length; i++)
{
    var child = childs[i].Trim();
    
    var descendants = child.Split(' ', StringSplitOptions.RemoveEmptyEntries);

    for (int j = 0; j < descendants.Length; j++)
    {
        var descendant = descendants[j].Trim();
        
        var stringBuilder = new StringBuilder();

        var firstDelimiter = true;
        var hasFirstDelimiter = descendant[0] is '.' or '#' or ':';
        
        foreach (var character in descendant)
        {
            if (character is '.' or '#' or ':')
            {
                if (hasFirstDelimiter && firstDelimiter)
                {
                    firstDelimiter = false;
                }
                else
                {
                    fullList.Add(stringBuilder.ToStringAndClear());
                }
            }

            stringBuilder.Append(character);
        }

        var selector = stringBuilder.ToString();
        
        if(! string.IsNullOrWhiteSpace(selector))
        {
            fullList.Add(selector);
        }
        
        if (descendants.Length > 1 && descendants.Length - 1 != j)
        {
            fullList.Add(" ");
        }
    }
    
    if (childs.Length > 1 && childs.Length - 1 != i)
    {
        fullList.Add(">");
    }
    
}
#

Look how pretty thonkeyes

severe solar
#

if it works it works

stone shoal
#

String vs functions is a 20 tick difference in building the stylesheet

calm copper
#

No regex - good! šŸ‘

stone shoal
#

Excepted regex to be fast though

#

But maybe not if you aim to do it within miliseconds

calm copper
#

Good coding practices not always give good performance šŸ™‚ I had to stop using ImmutableHashSet due to this.

stone shoal
#

But didn't know before how to do it without, because of the spaces. But C# has something for this it seems to ignore them except 1.

stone shoal
#

@full acorn VisualElement element builder code previewer thonkeyes?
Usage:

  • You open the game
  • You open a menu
  • You see 2 text fields
    • One for the StyleSheetBuilder
    • One for the Element builder
  • You Copy paste the code from the root preset in the input
  • You Copy paste the code from the StyleSheetBuilder in the input
  • Press a button
  • It shows the result of the element
#

Instead of needing to rebuild and reload the game to show the result of the builder element

calm copper
#

This would be awesome! Making UI today is tricky and slow.

stone shoal
#

Custom image imported into an asset

calm copper
#

Is it from the game or from the Unity editor?

stone shoal
#

Added a small QoL method .AddBackgroundImage("DebugMod/myfirstassetbundle/Testing")) so you don't have to bother with fetching the image from an asset loader

calm copper
#

Ah, I thought it's a demo of the code previewer šŸ™‚

stone shoal
#

Oh no, i'm not even touching that part yet šŸ˜›

#

Going to finish the builder first, now it's just adding all other methods from existing one. And then I believe one part left is caching the StyleSheet per builder

calm copper
#

Just don't use immutable collections 🤣 Yesterday I've removed all immutables from my code and improved its performance 10x times.

stone shoal
#

I use them quite some in TimberApi. But well its just once since.. Yeah they immutable HappyIT

stone shoal
#
.AddBackgroundClass("FirstItem", "ui/images/buttons/arrow-up")
.AddBackgroundClass("FirstItem", "ui/images/buttons/arrow-up", PseudoClass.Hover, PseudoClass.Checked)
.AddBackgroundHoverClass("FirstItem", "ui/images/buttons/arrow-up", "ui/images/buttons/arrow-down")
.AddBackgroundHoverClass("FirstItem", "ui/images/buttons/arrow-left", "ui/images/buttons/arrow-right", PseudoClass.Checked)

Some helpers to quickly add a background with hover, or a hover effect on a checked toggle

#

I think it's time to start converting all the presets YA_Yuri_Boba_Sip

#

Oh wait, need to make the caching system still sadcat

vivid mango
#

Hello, can anyone tell me I need in order to mod a mod that uses the TimberApi

stone shoal
vivid mango
#

I want to adjust the cost of an item the mod allow me to build

stone shoal
#

Probably just a specification, or maybe a bit of code depending how you want to do it

#

This are the things you can change for buildings recipes

#

Recipes themself you need to export the game assets and look what you need to change

vivid mango
#

I want to change the cost of the ladder mod

#

what it cost in game to build it

stone shoal
#

If you only want to play with it you can just edit the json

vivid mango
#

I have looked at all json in the mod but cant find the costs

stone shoal
#

Right is in the prefab

#

Than you need to make a mod and change it with the BuildingSpecification

vivid mango
#

If I have the raw files for the mod what do I need in order to compile the file into a working mod

stone shoal
#

Check oy the doc

vivid mango
#

I downloaded the mod files from github and found what I wanted to change in the mod what do I do to make a loadable mod to replace the mod I have now?

stone shoal
#

The whole preset class

    public class ArrowDown : BaseBuilder<LocalizableButton>
    {
        private readonly ButtonBuilder _buttonBuilder;

        private string _standardImageClass = "api__button__arrow_down--normal";

        public ArrowDown(UiBuilder uiBuilder)
        {
            _buttonBuilder = uiBuilder.Create<ButtonBuilder>();
        }

        protected override void InitializeStyleSheet(StyleSheetBuilder styleSheetBuilder)
        {
            styleSheetBuilder
                .AddClass("api__button__arrow_down", builder => builder
                    .Add(Property.Width, new Dimension(100, Dimension.Unit.Pixel))
                    .Add(Property.Height, new Dimension(100, Dimension.Unit.Pixel)))
                .AddBackgroundClass("api__button__arrow_down", "ui/images/buttons/arrow-down-hover", PseudoClass.Hover)
                
                .AddBackgroundClass("api__button__arrow_down--normal", "ui/images/buttons/arrow-down")
                .AddBackgroundClass("api__button__arrow_down--inverted", "ui/images/buttons/arrow-down-inverted")
                .AddBackgroundClass("api__button__arrow_down--active", "ui/images/buttons/arrow-down-active", PseudoClass.Active, PseudoClass.Hover);
        }
        
        public ArrowDown WithActive()
        {
            _buttonBuilder.AddClass("api__button__arrow_down--active");
            
            return this;
        }
        
        public ArrowDown Inverted()
        {
            _standardImageClass = "api__button__arrow_down--inverted";
            
            return this;
        }

        protected override LocalizableButton InitializeRoot()
        {
            return _buttonBuilder.AddClass("api__button__arrow_down").Build();
        }

        public override LocalizableButton Build()
        {
            _buttonBuilder.AddClass(_standardImageClass);
            return _buttonBuilder.Build();
        }
    }
#

Usage:

kek = uiBuilder.Create<VisualElementBuilder>()
    .AddComponent(uiBuilder.Create<ArrowDown>().WithActive().Build())
    .AddComponent(uiBuilder.Create<ArrowDown>().Inverted().Build())
    .AddComponent(uiBuilder.Create<ArrowDown>().WithActive().Inverted().Build())
    .AddComponent(uiBuilder.Build<ArrowDown>())
    .Build();
#

I suppose my previous presets were quite bit smaller

public LocalizableButton NewGameNormal(string locKey = null, Length width = default, Length height = default, Length fontSize = default, FontStyle fontStyle = default,
    StyleColor color = default, string scale = default, string name = null, string text = null, Action<ButtonBuilder> builder = default)
{
    ButtonBuilder button = _componentBuilder.CreateButton().AddClass(TimberApiStyle.Buttons.Normal.NewGameNormal).AddClass(TimberApiStyle.Buttons.Hover.NewGameNormalHover)
        .AddClass(TimberApiStyle.Sounds.Click).AddClass(scale ?? TimberApiStyle.Scales.Scale5).SetName(name).SetLocKey(locKey).SetText(text)
        .SetColor(color == default ? new StyleColor(new Color(1, 1, 1, 1)) : color).SetFontSize(fontSize == default ? new Length(13, Pixel) : fontSize)
        .SetFontStyle(fontStyle == default ? FontStyle.Bold : fontStyle).SetHeight(height == default ? new Length(80, Pixel) : height)
        .SetWidth(width == default ? new Length(184, Pixel) : width);
    builder?.Invoke(button);
    return button.Build();
}

But it's also way less readable and way less modifiable

stone shoal
#
100_000 samples, time in ticks. 10_000 ticks = 1 ms, 10_000_000 ticks = 1s

Initialize empty element, base:  13.027.993
Build preset, with caching:      19.793.915 +51%
Build preset, chaging values:    19.666.527 +51%~
Build preset, without caching:   399.178.028 +2964%
Old system, almost:              21.975.094 +68%
#

Using cached USS per preset would probably be faster. If all presets are only used onced, it's probably slower

stone shoal
#
Timberborn total elements going in game: 3_000 elements

Execution time
Base game: 718283(71ms)
Preset builder, cached: 636377(63ms) -11%
Preset builder, not cached: 2925508(292ms) +307%
#

I'm happy enough with this, even if you would make an UI 10 times larger than the base game. It would just take 3 seconds when loading the game.

#

Since most people will use the presets I made it would become pretty fast.

digital briar
#

That looks like a big improvement though

#

Relatively

stone shoal
#

Okay removing the feature that you can start a builder with an existing element

#

I thought this would be usefull for combining UXML with an builder abilities, but then I would rather that people just make a preset for it. Which uses the UXML elements as it's root element.

#

Then the only use case would be.

  • I made a preset
  • But I didn't add something to it, because I want to do it on a different moment for unknown reason
full acorn
#

Phind approves of TimberAPI

stone shoal
#

The asset part isn't quite there in the docs

full acorn
#

Oh that reminds me, does TAPI have its own USS style sheets that it loads for UI elements?

#

I’m trying to narrow down the error with the scroll view builder

stone shoal
#

It has 1 USS file tho, with many many settings for backgrounds

#

like :hover

#

If you look in the TimberApiStyle.cs it's pretty much that setup in USS

#

it something is in a sub section Active it is for :active

full acorn
#

Hmmm, is I’m curious how the scroll view gets its assets for the scroll bar and scroll button, it looks like there was a change in asset names so they show up blank

stone shoal
#

Still need to make the presets though, Im fairly certain the builder itself is finished

#

With 1 small thing left is to make many, many more default builders for either. Localizable or normal variants.

#

Hope it will be done this month, feeling mehh lately and going on weekend

full acorn
#

Oh nice! Nicely done!
No pressure or rush to finish, it’s no biggie! šŸ™‚

lofty lark
#

Hi !
i'm trying to poke at the PrefabCollectionSpecification.Characters file to add in custom bots, but it doesn't seem to be registering.
of course i made it as a .replace, and the file registers properly because it crashes if i remove the folktail bot, and also crash if i call some random crap that doesn't exist, but it doesn't crash when looking for my custom bot, indicating that is actually finds the prefab.

and yet it still displays the message 'cannot find bot for the faction waterbeavers falling back to folktails"

#

any idea what could be wrong ?

#

i'm pretty sure i don't have missnamed stuff like "Waterbeavers" instead of "waterbeavers"

vast otter
#

Do you have the correct components?
Could it be missing animitations included in meshy file?

lofty lark
#

i don't think i'm missing anything

#

oh, unless i don't have the latest game extraction šŸ¤”

#

i doubt there is much difference

#

actually no i have the wood shaving particles and soil particles etc, so it should be good

#

at least recent enough

#

nope, i can't find any bot related script that could be missing

#

but what i'm trying to load is the bot prefab that has all the scripts, what is called with meshy is only the actual 3d model

vast otter
#

hmm and its not that they are delcared in any other file to load them? šŸ¤”

#
  • well that is what you said šŸ¤”
lofty lark
#

i might be an idiot

#

sorry šŸ˜…

vast otter
#

hehe

lofty lark
#

i was really not expecting this to be there

vast otter
#

well i knew it was there but had not gotten to it šŸ˜›

lofty lark
#

but then why would TAPI say "bot for waterbeaver not found" ? is it a leftover from U4 ?

#

if i remember correctly it used to be implicit so that would make sense

vast otter
#

šŸ¤” got the error report?

lofty lark
#

[Info : TimberAPI] Bots for faction Waterbeavers doesn't exists, falling back to Folktails

#

(still loading though)

vast otter
#

ThinkingIT ya maybe is some fixes that now base game can handle better
(from hardcoded to defication)

lofty lark
#

AH-AH

#

It worked !

#

somehow discord doesn't want me to upload an image but it's there

#

okay, time to mutilate it horribly

stone shoal
lofty lark
#

no i have

#

i mean "model"

#

it's actually calling the IT bot through meshy

stone shoal
lofty lark
#

but it's working now

#

it's just that Tapi still writes this message

stone shoal
#

Hmm

#

Even with the blt configuration to folktails?

lofty lark
#

ehehe

#

(size x2)

stone shoal
#

Nice

lofty lark
stone shoal
#

And then no error?

lofty lark
#

well it works, but TAPI still complaisn

#

but that apparently does nothing

stone shoal
#

If you could make an issue on github HappyIT

vast otter
lofty lark
#

that's an idea šŸ˜…

vast otter
#

do they fit inside doors?

lofty lark
#

what is that šŸ¤”
i tried to load a save after destorying some building i shouldn't have

#

but otherwise everythign was seemingly fine

lofty lark
#

i could load the same save normally later šŸ¤”

stone shoal
stone shoal
#

Finished first button completely

#

Correction,

#
.AddComponent<ArrowDown>()
.AddComponent<ArrowDown>(arrow => arrow.Inverted())
.AddComponent<ArrowDown>(arrow => arrow.Active())
.AddComponent<ArrowDown>(arrow => arrow.Small())
.AddComponent<ArrowDown>(arrow => arrow.Large())
.AddComponent<ArrowDown>(arrow => arrow.SetSize(100))

such easy use

stone shoal
#

Splitted ButtonBuilder into 2 LocalizableButtonBuilder, ButtonBuilder. The one uses SetLocKey the other SetText. for buttons that don't require text.

#

It's missing the ninespliced background, so will have to see if that's a problem

stone shoal
#

Added ability for ninesliced images to work, click effect working too now.

#

@ebon sparrow Any idea why the text vanishes when the button is disabled ThinkingIT

stone shoal
#

About 50% done with buttons

stone shoal
#

Think this is about all buttons, at least for now. Since presets are now also easier to make and should mostly be done in it's own class should be sufficient.

#

Adding to an existing preset is not also easily be done so no more need to remake a whole preset if you want to add some margin, just extend it and add your own things šŸ™‚

#

@full acorn, should I use specific name classes or just group them in folders
For example I name everything now [Image/GameClassName][Type] so you have CyclerRightButton and a CyclerRightMainButton.

#

Or should they all be called CyclerRight or CyclerRightButton and because they are in a button preset folder, and with a sub map main you know it's a button or something thonkeyes

full acorn
full acorn
#

I feel like the ā€˜button’ at the end is a good thing

stone shoal
full acorn
stone shoal
full acorn
#

Aye aye!

stone shoal
#

It's probably an empty button with icon

#

Not optimal to do but I guess I could

full acorn
#

Ah in which case ignore me

stone shoal
#

Well not specific for destroy, but any icon than

full acorn
#

Yeah fair enough

stone shoal
#

But it's not worse than we have now so /shrugs

#

You would still need to know the image location though

#

But I can make a preset where you can load in an image as icon

full acorn
#

That might be useful, the difficulty I’ve had with recreating the demolition button is the hover effect - even if I’m using the USS classes

stone shoal
#

In USS it's fairly easy

#
protected override void InitializeStyleSheet(StyleSheetBuilder styleSheetBuilder)
{
    styleSheetBuilder
        .AddClickSoundClass("api__button__cycler-left", "UI.Click")
        .AddBackgroundHoverClass("api__button__cycler-left", "ui/images/game/cycler-left", "ui/images/game/cycler-left-hover")
        .AddClass("api__button__cycler-left", builder => builder
            .Add(Property.Width, new Dimension(11, Dimension.Unit.Pixel))
            .Add(Property.Height, new Dimension(20, Dimension.Unit.Pixel))
        );
}

In the new builder I have an helper class for it for simple buttons, just give it original image and the hover image and done ohlsippyn

full acorn
#

Fair enough! Is that an example of the use?

stone shoal
young tendon
#

The UI builder example in the TimberApi repository seems to be broken. I've spent some time with it, but overall, since I don't know what I'm trying to fix.... Nope. But I see from the messages here a rework is ongoing of the whole system anyways. I have gotten a fragment working, but that's not quite what I want, since it's not related to an existing BaseComponent.
Any suggestions how to get a "box with checkboxes" pop up when I enter my tool? I can't even manage to get the example "previewbox" to show up somewhere, since whatever I tried to replace the broken patches with didn't load.
I'll try again tomorrow, but in the meantime, I'd appreciate another shove in a new direction. Catapult Thanks!

stone shoal
#

The uibuilder and description what you are trying to do has not much in common

#

The UIBuilder only creates visual elements without any logic. Adding a panel when you enter a tool has nothing to do woth that

#

I dont remember what it was called anymore tho, check out some existing tools how they do it. All I remember is that it has a list where you can add your part to it

#

A popup box is also done with a simple tool of Timberborn. Its called something with panel and you can see something of ot in the setting tool in TimberApi

young tendon
stone shoal
#

The boxes you see like the settings box are panels that implement IPanelController

young tendon
stone shoal
#

New Update 6 design probably

#

Each feature that was in TimberApi.dll is now splitted, with only a few remaining in TimberApi that all others need as a base

#

This might be a small inconvience if you need them all since it's a bit anoying to add them in unity. But you only need to do it once

molten coral
#

Hello, I need help installing this mod and other mods that this mod requires in Timberborn. Can you help me?

stone shoal
molten coral
#

no

stone shoal
#

Have you tried following the guide on mod.io ?

molten coral
#

I'm not good at English because I only know German

stone shoal
#

Install the mod manager

molten coral
#

Thank you

coral glen
#

TimberAPI is broken on update 6?

vast otter
stone shoal
#

Can't get in the map editor anymore

#

And I don't even know whats causing it Panic

severe solar
#

delete all code

#

fixed

stone shoal
digital briar
#

Anything in BepinEx?

stone shoal
#

Already fixed it though, missed a patch

stone shoal
#

doggocart, Moved the prefab collection and loading initialization to the beginning of the lifecycle, hopefully not breaking things later on...

#

But now can the specification generation hopefully be done here too so the specifications don't need to deal with weird not yet loaded specifications

#

Hopefulyl this will fix that tutorial doesn't need to be disabled šŸ™‚

stone shoal
#
public class Generator : ISpecificationGenerator
{
    private readonly PrefabGroupService _prefabGroupService;

    public Generator(PrefabGroupService prefabGroupService)
    {
        _prefabGroupService = prefabGroupService;
    }

    public IEnumerable<GeneratedSpecification> Generate()
    {
        Debug.LogError("This is my generator");
        Debug.LogError(_prefabGroupService.AllPrefabs.Length);
    }
}
#

No more need for specific generator for prefab groups, now you can just get the prefabs with the normal service itself

stone shoal
#

Well good start, The red wall of text are just al placeable Tools

#

Tomorrow converting the rest of the tool specifications

stone shoal
#

Okay ToolSystem is up and running for now a bit

#

Now the bottombar...

vast otter
stone shoal
#

Stange, some modded buildings do work right ?

vast otter
#

ya tested with Frog statue and TAPI and it did work

stone shoal
#

Alright

vast otter
#

šŸŽ‰ it was load order problem

#

could you upload current version of TAPI to steam?

stone shoal
#

Probably mising some things as wel

stone shoal
vast otter
#

no i forgot to do that 😦

stone shoal
#

Can you add dependencies without needing tyhem ?

#

Kinda found it still weird the load order mattered though

vast otter
#

hmm could add but then it will be an ! to show something is missing

#

no way to tell Optional mod but still have to be before

stone shoal
#

I see

vast otter
stone shoal
# vast otter šŸŽ‰ it was load order problem

@quiet delta Would it be possible to have a optional dependency option for the dependency system, so you can still provide a correct load other when it is there, but don't give a warning when it's not.

stone shoal
vast otter
#

ThinkingIT is it not unloading specifications when loading a new save?

stone shoal
vast otter
#

WAit i think it tries to load Spec file that is optional = do not load if it does not exist already

stone shoal
stone shoal
#

Nahh should not matter, I force those specifications to be as the same order as the base game...

#

Oh well, it should be a dependency anyway

#

If that fixes it I good enough for me for now.

vast otter
stone shoal
#

Atm you cannot go back to main menu and start another game

vast otter
#

base game do replace if it already exist ThinkingIT

vast otter
#

this is how i replace a base game item by adding the same with my changes and it loads the new one and replaces the original one with my info šŸ˜‰

#

same with Locfiles

stone shoal
#

You needd to place it in the same path don;t you >?

#

For replacing specs

vast otter
#

not 100% sure

quiet delta
#

btw maybe you figured it out already, but Reset of IAssetProvider is called during every scene switch and becasue of that, you are duplicating your cache in GeneratedSpecificationAssetRepository line 30, which will later throw an error in line 27 I think. You should probably do part of this operations in Load, which for bootstrapper singleton will be invoked only once

stone shoal
#

Yes the duplicate error is just something i forgot. I want the specifications to generate every scene, but prefabs will keep their changed values so need to be cached

#

Just need to check if they were made already

vast otter
#

Thought of one thing from U5
can you revert the 10x increse of Order becasue items added by prefab do not get any more space to use without becasue its also incressed by 10x
So its just harder to get what number to add an item to.

stone shoal
#

But then it's harder to add a group in the correct place

#

Hmm x 10 is actually a bad idea I suppose

#
  • 10 is better
vast otter
#

hmm well with mod prefabs having one number and be placed at an other and cant look up ripped assets to see where to place it it just result in harder to add in the correct place

#

if i need to move something i can just place a file and move it to a different spot šŸ˜›

stone shoal
#

If you have 1,2,3,4,5. And want a group in between 3,4 it might be imposible because with 4 it can add behind and with 3 it can add before

#

Than you need to change that building, and have the same problem for 1,2

vast otter
#

by using ToolSpecification

stone shoal
#

SO you ned up needing to customize all orders

vast otter
#

well it has not happened yet ThinkingIT because when i add some thing it offen replace something other.
Think @lofty lark was also very confused with the added number with stuff not placing where you expect them to

stone shoal
#

Maybe I just need to make a export button now so you can export them

vast otter
#

i did a Batch file to create Toolspecifications where i decalare Base file to use, Faction to create and Prefabname šŸ˜›

stone shoal
#

I did not understand any of that šŸ™‚

vast otter
#

I use this to move items to a new submenu
i create one first with correct subgroup and then use this to copy to new names for the other items to add

echo off
cd Specifications
:Init
set Prefix=ToolSpecification.
set Suffix=.json
cls
set /P BaseFile="Basefile to copy? (-.json)"
set /P Faction="Faction to create?"
:start

set /P Question="Prefab name? (n to close,r to restart)"
rem echo on
if /I %Question% == N (
     exit
 )
if /I %Question% == R (
     goto Init
 )
rem @echo on
echo Copying: %BaseFile%.json to %Prefix%%Question%.%Faction%%Suffix%
copy "%BaseFile%.json" "%Prefix%%Question%.%Faction%%Suffix%"
rem @echo off
echo -------------------------------------------------------------


goto start:
#

and when i move stuff to a subgroup/menu i also free up slots that is not used anymore šŸ˜‰

coral glen
#

Is the alpha version working with update 6?

vast otter
#

"Working" it do has some bugs

The bug that is reported is:

  • Crash when loading a game when one is loaded or going back to main menu
stone shoal
#

And you need to have Harmony mod as well, didn't add it yet as a dependency.

#

WIll probably fix those issues in the weekend

coral glen
#

So we can have sub categories for all the mods that add stuff.
Or individual mods have to be updated to use the sub category in the bottom bar?

stone shoal
vast otter
coral glen
#

For example: path extension adds a lot of bridges.
Does @vast otter have to update the mod Path extension to use the sub categories
or
adding timberapi from steam will automatically add the subcategories (No need for update form @vast otter Path extension)?

vast otter
#

only ones that are at bottom bar(same tier as settings) will move not in a bar

stone shoal
coral glen
#

Having pipette tool and timber API enabled crashes the game.

coral glen
#

Nope windows.

vast otter
#

hmm a mac user have the same issue

#

verify that you have latest version

coral glen
#

Yeah saw the converstion. Also with only pipette tool enabled ( not timber API) the game doesn't crash.

coral glen
stone shoal
#

Because it requires TimberApi? Or does timberborn load it no matter what

severe solar
#

For some reason it is still triggering the custom search while it is able to find it normally

coral glen
stone shoal
#

The only big downside, since if you want a custom tool you kinda need to use TimberApi else the bottombar won't work.

vast otter
#

TAPI manifest should have harmony as req?

stone shoal
vast otter
#

Hmm ToolSpecification looks to req more fields that it did before

I get this error message with above minimal mod to move Woodedstaircase to new subcategory
only Loc name error if ToolSpecification is removed

stone shoal
vast otter
#

hmm werid that it works in U5 to just change where an item is placed

stone shoal
#

You doh't have your mod on mod.io ?

#

These are the typoes it needs

#

But maybe it doesn't fall back on the default one It seems

#

What mods do I need to test it ?

vast otter
#

to move Logpile to Subgroup_MG_Piles

stone shoal
#

Is this ebcause of timberapi ThinkingIT

vast otter
#

its to help with that ya

stone shoal
#

No the image

vast otter
#

😮 no if its more items in a group that lenght of bottombar that happens

#

so i want update the mod that creates subgroups and places existing buildings in new places

vast otter
stone shoal
vast otter
stone shoal
#

That one is required

#

Btw I don't get the error ThinkingIT

#

I don't see the group either xD

vast otter
#

ThinkingIT what is the valid thing of Type?

#

for a building

stone shoal
#

PlaceableObjectTool

#

But they indeed should already exists with the prefab

#

How is the woodenStairs called in mod io ?

vast otter
#

hmm will have to check more not sure i have time before 1w holiday

vast otter
stone shoal
#

So only more groups should be enough to see it ?

vast otter
#

ya Moregroups + TAPI is the only req in above zip

#

wanted to rule out mods first šŸ˜‰

stone shoal
#

Mine not working at all

#

Oh TimberApi is not loaded

#

WAIT WUT

#

so the base game has a fed up bottombar when too large

#

Was this always the case ?

vast otter
#

yepp

stone shoal
#

Dang I thought it didn't do that

vast otter
#

it takes the longest part and use that;)

stone shoal
#

Was it also looking like that with TimberApi when not using subgroups ThinkingIT

vast otter
#

ya compareable ya

stone shoal
#

That's... not nice

#

šŸ™‚

vast otter
#

better than hiding things šŸ˜‰

stone shoal
#

Ah no it looks "good" with timberApi

#

I guess I am just too used to my own fixes

#

And also working just fine ThinkingIT

vast otter
#

Whyyyyy

#

will have to check more then

stone shoal
#

Did you maybe load it befoer TimberApi again ?

#

Wait nvm, doesn't matter

stone shoal
#

Okay there are no missing tools, only dev tools have a weird scrolling effect but I am not going to fix this because it's too hard to fix than whats worth it.

#

The order of scrolling just doesn't fit.

stone shoal
#

@vast otter Removed the *10 order

stone shoal
#

It now also supports wonders in all 4 base colors šŸ™‚

stone shoal
coral glen
#

@stone shoal & @severe solar Will timber print and pipette tool work with TimberApi in future?
Can't use TimberAPI and my bottom bar has become huge because of other mods.

stone shoal
coral glen
#

Will wait for @severe solar's reply.

stone shoal
#

It actually already was before, so don't think its much work

severe solar
#

I thought it wasnt in Tapi yet, so i just made some small fixes and kept the tapi code. Should just be some uncommenting and commeting code

spring radish
#

btw, reminder to update the metadata_blob for TimberApi version 0.6.5.0 to add a MaximumGameVersion, otherwise ModManager is offering it for download for timberborn 0.6.1.0

#

and TimberApi 0.7.0.0 seems to work fine with 0.6.1.0 too (currently declares MinimumGameVersion: 0.6.2.0)

stone shoal
viral monolith
#

I looked into TimberAPI and was curious about the update strategy.
From what I saw, the update strategy for U6 looks like: Delete everything, reimplement what is required.
Meaning, that pretty much currently TimberAPI is a shell without functionality (which breaks my game, if installed).
I would have expected fixing broken code instead. I assume lots can be removed from TimberAPI though, as the game provides that itself now (Specification loading + Asset loading + Service (dependency) loading).

If you like, please tell me about what the idea of this update strategy is :)

stone shoal
#

As for now the core feature that is needed was the bottombar, the new UIBuilder will be implemented next where only the Buttons presets are implemented.

#

And "fixing broken code" isn't a update strategy for this update, it is a waste of time. Since people would start building TimberApi mods and need to fix their mod twice

viral monolith
#

Well now you run into the problem that people would reimplement TimberAPI as TimberAPI is not available šŸ˜‹ (Well luckily I don't have that much time)

stone shoal
viral monolith
#

Not worth it for just CameraTweaker - I will wait for you. I am rooting for some nice UIBuilder and DependencyContainer rewrite :)

stone shoal
#

How did your UI look like for camera tweatk ?

viral monolith
#

Kumare wrote that. Idk. There was an ingame HUD overlay with buttons.
A whole settings panel separate from the normal settings. And probably more

stone shoal
#

The UI builder is quite different though

#

So probably not able to reuse that

viral monolith
#

Oh well - RIP me - I guess

stone shoal
#

Not sure though, haven't really tried to use old cold since I have none

#

The building part can technically still be used like that so might be useable

stone shoal
#

Red needs to be done where only UIBuilder is higher prio and dependency container, the others are not really used much.

#

Blue stuff was used almost all the time

viral monolith
#

Nice šŸš€

#

One of the devs said yesterday that the game might get an ingame console. What are you envisioning with "external console"?

vast otter
viral monolith
#

web is evil, run while you can~~~ šŸ˜‹

spring radish
#

It would be very easy to add Player.log to the Http Server mod šŸ™‚

#

Although I don't think I would (or it would disabled by default), because I want it to be safe enough to 'publicly viewable'.

young tendon
#

Hello, could use some quick support. I was developing my tool on U5, had the main parts working (just finalizing UI) and now waited a bit for before attempting the upgrade to U6 / TimberApi. I've got the U6 / Unity modding setup, integrated my scripts, specifications and so forth. Removed integration of the dependency container, etc. etc.
I am having the exception that my Sprite/Icon asset can't be found by the TimberApi - ToolIconService. I've tried the same setup as in U5, and I've also changed the folder structure to reflect what is suggested by the Timberborn Wiki. And then I tried about 20 different combinations.

Honestly, even if U5 I didn't know how the path /string worked for the toolservice, so I am lost as to what to change. I had just based it largely on the timberapi example / basic modding from KnatteAnka. And I haven't found a comparitive system available for U6 yet, as both TimberBlueprint and Tobberts Pipette Tool conflict with TimberApi.

So. Attached error log, and screenshots indicating the folder structure / specification - now set up as TB suggests. I'd appreciate your support.

stone shoal
#

Icons are used in U5 with your general prefix/paths etc like any other asset and with U6 the timberborn asset path

#

Is that error for update 5 or 6

young tendon
#

That's for 6, it was all working in U5, though the specification / mod structure is now different than in U5.

stone shoal
#

prefixes aren't a thing anymore in U6 that's why it is probably not working anymore

#

Check out how to deal with assets with update 6 on their documentation I think it's explained

young tendon
#

I'll check it out, now that I know better what to look for. Thanks

young tendon
vast otter
#

Think sprites should be possible to be loaded without unity asset bundle but not sure what path it gets

stone shoal
#

The Icon service of the ToolService is just for internal fixes

young tendon
#

I think I am misunderstanding you. šŸ˜†
Ok, you just more meant the internal tool icon service. Ok.
I'll just give it another round trying with the U6 documentation.
I'd like to keep my stuff compatible with TimberApi.

young tendon
vast otter
#

I would put the sprite inside the asset bundle amd then it would be
Under resources/cordial/Sprites

Path is then cordial/Sprites/"sprite name without sufix"

young tendon
#

Ok. Thanks. I'll try that first. I'll let you guys know how I got it to run...

#

*if I get it to run šŸ˜…

stone shoal
vast otter
stone shoal
#

It should be pretty much identical as before, except the icon path you use

young tendon
#

Ah, I had assumed above an answer you gave is that it is mostly compatible.

#

Ok, well this clarified quite a bit.
I hadn't spent much time trying to get it working without TimberApi, and just enjoyed playing vanilla U6 for a while. When I saw in some previous posts that the Toolservice was working again, I thought I'd try. But apparently some rethinking is in order overall. Pretty new to this modding business, probably don't know half of what I should.

stone shoal
#

That's becasue the bottombar is completely different

#

Which is required for the 3rd rows

young tendon
stone shoal
#

If there are any other features that you are missing, that are not in the base game now let me knwo

stone shoal
young tendon
stone shoal
young tendon
#

That I can understand. 😁

young tendon
#

I went for the quick win tonight, Re-used an existing sprite from TB. Had to hardcode a few things still missing which were based on the API configsystem and dependency-container, but got my basic functionality back up and running. Thanks for your support guys.

stone shoal
burnt wasp
#

crash.. 7.0.0

vast otter
burnt wasp
#

yep, and change faction

vast otter
#

known issue

burnt wasp
#

also this?

stone shoal
#

No, but seems like an prefab with the same name ?

burnt wasp
#

I don't know, I don't have another mods, I just loaded a map (almost a fresh map) with a different faction right in the game

stone shoal
#

custom faction ?

burnt wasp
#

nope, just iron/folk... it will have the same source of error it seems, it just crash somewhere else

vast otter
#

so question is it tapi or the mod that is at fault hard to know atm

stone shoal
#

He says he doesn't have a mod installed

burnt wasp
#

I only have tapi

stone shoal
vast otter
#

then how do you have a 3rd faction ThinkingIT

stone shoal
#

So I suppose you came from a loaded game before ?

burnt wasp
#

instead of going to the menu, I loaded another map from the game

stone shoal
#

Same issue

burnt wasp
#

This will be the same error as before

austere tangle
#

It seems to happen even if load the same game during play (if was at least one autosave) šŸ¤”

vast otter
#

ya any reload of scen cause the crash

stone shoal
#

It has a cached directory to store ObjectSpecifications since prefab changes are kept between scene changes.

#

Will be fixed tomorrow

vast otter
#

@stone shoal
I now know why game crashes for me with more groups:

Do not work:

  • Launch game with commandline to load an existing save
  • Crash

Works:

  • Launch game without commandline
  • click ok to go to main menu
  • Load game
  • Works
stone shoal
vast otter
stone shoal
#

What kind of crash ?

stone shoal
#

ThinkingIT Property Id not found

vast otter
#

ya feels like it has not loaded base game items specifications(Dynamic specification?) when my added file is loaded

stone shoal
#

Maybe my object specification loader it wrong or too early in some cases ThinkingIT

vast otter
#

or not run?

stone shoal
#

hmm

#

Will check tomorrow

vast otter
#

not a critical bug
want me to do an issue on github? (with link to above chat)

stone shoal
#

Sure

vast otter
vast otter
#

wait i found the exact cause its load IT with an FT Toolspec file

#

Hope this explains it

#

Ok @primal wind got a fix for me
use .optional for ToolSpecs

stone shoal
#

@vast otter How does it use the toolspec from folktails though ThinkingIT

vast otter
#

it tries to load all Specs even Folktail ones and fails becasue Folktail prefab is not loaded

stone shoal
#

Do you have manually added toolspecifications for your own building ThinkingIT ?

#

Even if you do that should not matter unless you have it in the wrong path. Since a exact match of specification + path should override right ThinkingIT

vast otter
# vast otter

this works to show the error
and its base game item

stone shoal
#

Unless you have it in the wrong place ofc

#

Oh wait

#

Need to load iron teeth

vast otter
#

ya but what is happening is that Staircase.folktails does not exist so it crashes but if renamed to Staircase.folktails.optional = no crash

stone shoal
#

Ye okay makes sense

#

Though is it my problem ThinkingIT

#

I kinda don't think so. This is just how they have implemented it

vast otter
#

na im fine with the .optional

stone shoal
#

Would be the same as if you would add a .original with just an ID in the other TimberApi versions.

#

They have it just in reverse, it's always original unless specified otherwise

primal wind
stone shoal
#

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
#

I know about the .optional, that was one of the 1st things I read in the new TB modding guide/s

vast otter
#

ya just not noticed that it was used also now by tapi but its fine

primal wind
#

I was referring to the source mod, if it's using just one asset across factions then could ditch the multiple IDs

vast otter
primal wind
#

fair enough then

#

With the many changes I made to MoreGroups I'll probably not subscribe this time and just rename my copy to GreedyGroups. If I upload it I'll make sure to put in the description it's just a modified copy of your mod

vast otter
#

go for it you may joink my icons i add later if you want šŸ˜‰

stone shoal
#

Why does it keep open mans_sad

#

Maybe that's why the optionbox also was broken

vast otter
#

Why are they not sorted by name on same Pos?
PoweredLevee is before Downward Power Shaft
ThinkingIT

stone shoal
#

Why do things have the same order ?

vast otter
#

true have moved them apart now

#

thought now of that else if a translation has different first letter stuff moves around

primal wind
#

The order thing still confuses me, is it relative to the group or absolute across all groups and tools?

primal wind
#

oh good, that means I have some editing to do 2mw

burnt wasp
#

where is UIBuilder and DependencyContainer?
and this
[Configurator(SceneEntrypoint.InGame | SceneEntrypoint.MapEditor)]

in TAPI 7.0.0 šŸ¤”
or what is the alternative

stone shoal
#

The first 2 arent implemented yet

#

The configurator is bit needed anymore because its in the base game

austere tangle
spring radish
#

nit for BottomBar: when clicking on already open 2nd level group, it should only close the 3rd level menu, not both menus,

#

also if a 3rd level menu is open, and you click on a 2nd level non-sub-group, then it should close the 3rd level menu that you didn't click in

vast otter
spring radish
#

awesome

stone shoal
#

@vast otter What does secodnbar is not correct centered mean

vast otter
#

Actual result image 1:
Expected result image 2:

and it will fill one at each side until max width on any side
or if max on both sides contiue add on each side

but maybe was never implemented in u5 ThinkingIT

stone shoal
#

You want it not to be the center ?

vast otter
#

centered against where you clicked to open the submenu to have less mouse movment

stone shoal
#

Would be way to complex and the game also doesn't do this.

#

How would you do things like

vast otter
#

ok we can skip it
its not a big problem with the many submenus i added that way its still near where you clicket to open a subgroup

stone shoal
vast otter
# stone shoal

the last item should be same place as config button i would say but ya its more advance and then more prone to bug

stone shoal
#

Personally I don't think it looks good either

#

Only if you have like 3 or maybe 4

#

Any thing more than that would look kinda weird imo.

#

But it is possible to make, with the bottombar feature if someone wants to do it.

#

How it now is resembles the base game more, at this point

#

I can't even get into the game anymore

vast otter
stone shoal
#

I want to disable it again for map editor but ahh patching being weird again

#

It is patched but it still complaining that things already exists as it fif it twice

stone shoal
#

Okay took a bit too long... did a post patch so the bottombar configurator was already loaded and so not poatched

#

Were in map editor

stone shoal
#

Fixed the multiple loading issue

#

And added this to object generated specifications

#

If there would the same full path to specification is used twice in 1 load it will crash

#

This could happen when 2 mods would have the exact same prefab name.

#

This check could easily be cheesed by when it's done in 2 different loading times. But hope it can help prevent some confision when specifications aren't what they suppose to be

#

Generating the building specs only cost 40 ms though ThinkingIT

#

Second load 3ms, so checks do kinda cost some computing, but 40 ms is not enough to be bothered

#

@vast otter Was there anything else I said to look for today šŸ˜…

vast otter
#

not that i can think of the things around bottom bar i noted is not critical errors just weird quirks

stone shoal
#

Lets see if I can fix the closing issue then that will be enough for today

#

Then everything should be fixed

#

Next week, new feature migration implementations doggocart

#

@vast otter Was it always the case that if you click on a sub group it closes the whole bar

#

Or is that really new ?

vast otter
#

think its new but before u6 i had not played for a long time

austere tangle
#

Before has closing the subgroup only ....

stone shoal
#

This is 0.5.9.1

#

Seems like this bug was always the case

#

And this as well

austere tangle
#

I don't remember that bug. Sure I reported if it was ...

stone shoal
#

Maybe it was in update 4 different ThinkingIT

#

Since the scrolling stuff

austere tangle
stone shoal
#

True and might not even bad in some cases

#

The closing is probably due to how I exit stuff for right click so I am not 100% if fixable with the limitations I have

#

But I am going to shove this problem for another time when all other stuff is ready since it already existed

#

Requires alot more debugging and testing then when it is a new bug

austere tangle
#

Important is that with TAPI and More Groups, I saved my budget from buying an expensive ultra wide monitor 🤣

stone shoal
austere tangle
#

Nope, I should buy also a new desk. The current one is too small for that kind of monitor šŸ˜…

stone shoal
#

@vast otter someone days 1x2 storage crate is incompatible with TimberApi šŸ¤”

vast otter
#

Ya its weird have no error report thošŸ¤”

austere tangle
stone shoal
#

Probably something else than

vast otter
#

Ya wonder if its corrupt download by steam again

austere tangle
#

Easy fix and, also for updating issue with steam is to force check integrity of game files .

stone shoal
#

Steam making mods corrupt quite alot doesn't it

#

Still have a feeling it's a cause when a mod tries to update when the game is running

vast otter
#

ya i have the same feeling wonder if @quiet delta has any idea if timberborn can fix it

austere tangle
#

Steam should update mods, even in case that is selected "update when game start", and only after, start the game ...

vast otter
#

maybe is some setting for timberborn to tell steam when/how its allowed to download updates

austere tangle
#

Downloding or updating mods is handled by steam, not by the game 😢

quiet delta
#

yeah, I doubt we can do anything about it. When the game starts, everything should be already downloaded by steam

austere tangle
#

Only this settings

stone shoal
#

I have mine on allow backgroudn downloads while playing

#

Because I have stable networking, but if it's updating while i'm playing it might not able to because files are inuse

austere tangle
#

Anyway, none of those settings are working . Can be due to experimental phase of the game or/and the need to subscribe to experimental group ? šŸ¤”

stone shoal
#

Do you know if path extension is working fine ?

vast otter
#

@stone shoal
I use same version as released and use it without any problems.
But he do not have the latest version he has 2.0.0 but latest is 2.0.3

stone shoal
#

I see

vast otter
#

I have added a comment on github to verify game files

stone shoal
#

I just saw that as well

#

Now we wait

vast otter
#

Interesting that we have more problem with faulty updates with steam than mod manager 😜

stone shoal
#

Because with mod manager you choose for it

#

And update all at once

#

And everything is a bit half compatible toghether this experimental as well

stone shoal
stone shoal
#

@vast otter Which mods of yours use the #append and #remove function the most ?

vast otter
#

i only use Append and once per mod but think @austere tangle:s Dirt use remove

stone shoal
#

Which mods šŸ™‚

vast otter
stone shoal
#

Whats the name

#

I am not logged in the web on steam

vast otter
#

Dirt

stone shoal
#

Sorry m,b

vast otter
#

np

stone shoal
#

Dirt is not updated on mod.io ?

vast otter
#

do not look like it want a zip?

#

id 3277709718

stone shoal
#

ye spls

vast otter
#

😮 checked it and he do not use #remove looks like he placed the lumberlack in the same pos as base game and replace that way

#

want it anyway?

austere tangle
stone shoal
#

@vast otter because of the #remove you can now remove a specific building from a faction roght

vast otter
#

Ya should be possible

worn apex
stone shoal
#

But the gits is you make presets, examples can be found in TimberApi.UIPresets

#

And then call get an instance of uibuilder with bindito. And call _uibuilder.Build<presetname>(0

#

Or .Create<presetname>(preset methods). For extra customization if you made a button that have 2 different sizes for example

#

In TimberApi I have a demo mod. I believe it has some examples of using the presets

worn apex
#

thanks, i think i slowly begin to get a grip on it

stone shoal
#

Just a small heads up, make your presets transient ant not a singleton
containerDefinition.Bind<PlusButton>().AsTransient();

#

Did i just delete my debug mod...

stone shoal
#

It might be a biit more confusing at the beginning, but im pretty sure when it's fully finished + docs it will not be too hard

#

Specially not if you just use existing presets, and combine them into new presets

stone shoal
#

By tobbert my GameButton is empty, I don't know why. So maybe my presets don't exist in the uploaded dll

severe solar
#

WORKING LETSFUCKINGGOOOOOOOOO

#

I did need to create this buddy, couldnt find a clean way to do it:

using System;
using TimberApi.UIBuilderSystem;
using UnityEngine.UIElements;

namespace Unstuckify.UIPresets
{
    public static class UIBuilderExtensions
    {
        public static VisualElement BuildAndInitialize(this UIBuilder uiBuilder, Type type)
        {
            var visualElement = uiBuilder.Build(type);
            uiBuilder.Initialize(visualElement);
            return visualElement;
        }
        
        public static VisualElement BuildAndInitialize<T>(this UIBuilder uiBuilder) where T : BaseBuilder
        {
            var visualElement = uiBuilder.Build<T>();
            uiBuilder.Initialize(visualElement);
            return visualElement;
        }
    }
}```
stone shoal
#

But it's also done alot by the game, I guess not by when returning the fragment ThinkingIT

severe solar
#

No, it isnt, in this instance, the functions provided in UIbuilder werent enough

stone shoal
#

I guess I missed that one

#

it is avaiable when using Create test.Create<GameButton>().BuildAndInitialize()

stone shoal
# severe solar

The initialize was only for the click I may hope, or does this also have other effects ?

severe solar
#

i thought the Create was supposed to be doing that

#

or, well build

#

but there wasnt a BuildAndIntialize

#

only Build

stone shoal
#

No create is if you still went to do things with it like making calling the small function to make a small variant.

#

Build is just that you get the visual element it as is

stone shoal
severe solar
#

Already fed it up

#

😦

stone shoal
#

Only use it on the laste element though, that cost relatively alot of compute. Nothing specific to the UIBuilder though

stone shoal
severe solar
#

LocalizableLabelBuilder is not yet bound

stone shoal
#

Lmao

stone shoal
#

Might fix tomorrow

severe solar
#

Thank you, take your time ā¤ļø

stone shoal
#

Presets still empty?

#

Are all presets empty?

spring radish
stone shoal
#

Button with no default size, mostly with text will not be visible if you don't add them. This is because it will become a 0px by 0px button.

vast otter
#

wonder when the next patch hits and how many mods that will stop working ThinkingIT

stone shoal
#

https://mod.io/g/timberborn/m/timberapi Update 0.7.1.1

  • Added missing builders in dependency injection.
  • Created own StyleValue classes, so people don't require to publicize unity dll's.
  • Added BuildAndInitialize to UIBuilder.
vast otter
#

if someone uses these functions remember to set req in your manifest so it at least give a warning

severe solar
#

warning isnt enough Sadge

stone shoal
#

You mean like any other dependency mod ?

vast otter
#

example:

"RequiredMods": [
  {
    "Id": "TimberApi",
    "MinimumVersion": "0.7.1.1"
  }
  ]
#

so if steam is not updating it atleast gives a warning even if they do not see it šŸ˜›

#

hopefully it will not allow to launch in the future

stone shoal
#

Yeah, but it's true warning isn't enough. Hope they will change it to just optional/hard dependency and not allowing it unless specified somewhere in the settings that you don't care

#

Who looks at warnings anyway KEKW

vast otter
#

ya you cant press enter and go to mainmenu if there is a Error message šŸ˜›
you have to disable the mod to get past the error message and maybe as said in setting Allow mod missmatch but is that even needed?
there is a reason why is req...

vast otter
#

currently ya but i dont see a valid reason to launch the game if its req mods is not installed
or allow to start but a popup show: These mods will be disabled becasue its missing dependecis

stone shoal
#

Ye true, didn't know you could press enter instead of pressing the button with a mouse

vast otter
#

😮 that ya added in like the last update

severe solar
#

Cool!

stone shoal
#

atm I don't really have harmony installed while debugging though because bepinex, and I still need bepinex because I don't want to click on that button once every minute. I mostly click start and adding some more debug logs or checking something, or just youtube while it starts

#

If that's an option to automaticly start I can uninstall bepinex champGasm

vast otter
#

well you could do a empty harmony folder just with the manifest to trick it šŸ˜›

#

just the same id but different name

stone shoal
#

Oh it also works with it in, xD

vast otter
#

and me 2 have bepinex but just for the log at different screen šŸ˜›

stone shoal
#

Ye, going to import that as well. And I was thinking yesterday to maybe add mod settings as a dependency ThinkingIT

stone shoal
#

To toggle it on/off, and need it for some other features as well. Why bother with making it an optional mod ThinkingIT.

severe solar
#

then people will not understand that they need to download dependencies of dependencies and gonna cry that they are crashing Sadge

vast otter
#

we will see how it works šŸ˜›

stone shoal
severe solar
#

yea, wtf

#

omgh

stone shoal
#

But does it not download dependencies when you verify ?

severe solar
#

but they forgor

vast otter
#

hopefully mod.io and steam? know that all dep is needed šŸ˜›

stone shoal
vast otter
#

no i do not think it subscribe to dependency when verifying game files

stone shoal
#

Do you think you could trigger that ingame with a mod thonkeyes

severe solar
#

I think so yea

vast otter
#

maybe even if crash start verify game files? šŸ˜›

severe solar
#

Note: Using the "Verify Integrity of Game Files" feature in the Steam Client will also cause workshop items to be downloaded.

vast otter
#

ya but does it download dependecy mods not subscribed to ThinkingIT