#TimberAPI
1 messages Ā· Page 4 of 1
crashes the game when finish building an engine
ignore lang.. just ProductVersion
kk, im not that far on my IT run
I wonder how it goes there. Could you use FileVersion as that seems ok?
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
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
RotatingSun is broken?
Is fixed for normal game, still crash the game in editor ...
ah yeah
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 š
Why not?
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 ?
Yea, all plants are generated to be there. You need to override it with a specifications
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
Pfft you could check ij the code
i think its Fields
Look into the generate files
Looks like its the plant/tree prefab name
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
fast and done but know that with latest mod manager its easy to get right version of mods for experiemental š (you have a switch if experimental version or stable version)
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
Ya I only asked cuz I didn't see TimberAPI and Bepinex listed anymore. I figured them out though
Can't wait to test latest variation of water extension
Need the big irrigation towers now more than ever though lol
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.
I don't quite understand the points you are saying. If you don't have those specifications it does not crash ?
And there are probably breaking changes in last update
yes, without those there is no crash
so my playthrough if on current patch needs to be vanilla? saddage
Well, everything else seems to work just fine. It was just the BuildingSpecification files that caused my crash ... even custom mod buildings with their own builtin recipes still work perfectly fine
The only other trouble I had was with Automation mod ...
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?
An error message could. Cant quite fix a statement 
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.
but yeah, it was in mod-creators if you feel like searching pretty sure
Button scaling

#š¤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
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
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
Well it crashes on a postfix on yours so doubt will be TimberApi
But maybe just need a rebuild
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
Weird button issue? Still dont understand
hmmm
Of you mean missing tools, that would have 0neffect
no main menu entry buttons are missing frames
Oh
maybe my mod causes this? lol
Well gtg for now
no worries
The mobile fast type aids was real

Good to know
Had it to do with a harmony patch ?
Nope, pmduda renamed a Panel
Understandable
Ez fix 
yep
the stacktrace was a wild goose chase, it was really just a simple nullref "can't find that" situation
@orchid sage what was the rename?
yeah, NewMapPanel to NewMapView
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?
issue added on github: https://github.com/Timberborn-Modding-Central/TimberAPI/issues/95
@stone shoal how are dlls loaded? Are they loaded custom or via BepInEx?
We both load them in but bepinex is first
Mine is "loaded" just getting the reference windows saved for the dll
So if i have it be a plugin as well as a TAPI mod its fine?
Bo idea what you mean
i guess i can better explain later
I found this: https://thunderstore.io/package/RiskofThunder/FixPluginTypesSerialization/ and im trying to make it work, but so far sadly not working.
// 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.
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
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
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
I might be able to make something like this, but you won't know which values are able to be used. Is this a problem š ?
I am not sure the builder (options 2) was possible had the same problem, not knowing which builder it should connect to
Yeah, fair point, you'd need a reference document
you could have a constructor with loads of optional parameters, but that might get unweildy
Alot would still be used or not be used without knowing
I suppose that would essentially be the last option
These things exists, only not sure yet how to use them as an object
Wym ?
Having a function with named parameters to help with discovery, would essentially be the same as the last option in that list
This would be good!
Except it's not discoverable without docs
@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"));
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
I will ship for the Timberborn just a class with consts with all presets names
Noice
// 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
?
Hmm, ok that's not as ideal
I would have thought you could have just registered the interface š¦
containerDefinition.BindPreset<SliderBuilder>().To<TestPreset>(); might be able to add an helper like this 
gedtting an error for it now though fixed it
@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?
Pfff
preasure preasure
No pressure meant! I can just use something temporary for now!
Sorry, didnāt mean to pressure you š
I believe the syntax will be different, but it will still function the same. It created UI. When it gets out I can help converting it to the new syntax
Noice! Thank you
Needed to eat, sorry for the cliff hanger
.
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 asUIBuilder, 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.
Oh nice! Thatās amazing thank you kindly!
I dont think its too hard to make, now I have a working concept. But need to fix the scrolling firt
Fair enough! I'm looking forward to the idea of Cards
Is ot for your new faction?
Aye, got to do a bunch of UI work, so the ability to make customised presets will be great
Good timing then 
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.
[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)
Does the mod have a dependency on TimberApi ?
mmm, no Timber-Commons is teh dependency for WaterExtension
We need the crash archive. I use both mods, and, no crash
MM, Water Extension has both as a dependency, sorry.
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
Post the crash archive into https://discord.com/channels/558398674389172225/1064824959697944666 and will take a look into
Re-downloaded Timber-Commons manually through mods.io instead of the ModManager and the crash is now gone. There seems to be a corrupted file from the ModManager download/update. Sorry for the time.
Never click on Mod Manager window until the download button will resume the default color. This, to avoid broken downloads !
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.
If you install TimberApi you get it. That is if you have the bepinex nuget config
But it seems like its not in the docs or disappeared
I tried it and stumbled upon the .net version. Not like it cannot be fixed, but I used to v4.8
It's not made for framework though
@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
Smoll problem, I don't know how to make it able to use a preset in another preset atm
Gives a bindito circular loop
Oh nice! Well 250ms is barely any time so even a 4x is negligible
Hm, that aināt funā¦
@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 
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 
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
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
Invert the dependency - IPreset can have an event and repository can subscribe to that event
well, i'm short on time so no more explaini g atm
it's really kinda specific
No problem 
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
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.
Getting code completion is hard 
__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.
@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
Ayy nice!

Ofc I cannot initialize a non element builder now š, Could just make an abstrac method which solved it 
@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();
Yoooo thatās SICK!!
Thatās some grade A stuff
Only bit struggling about if presets are even usefull now 
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 
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?
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?
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();
C# as a whole
I was watching Tobbert and Ratchet make this amazing patching class system and I understood none of it
we can throw that out the window possibly

someone made something better already
Oh! Thatād be good to try then! Was it Twiner?
I ran into the same error BTW, crashes on tick
oh rip
I just want to make plank⦠pleese game⦠let me ElectricalNodeSpecification
(āÆĀ°ā”°)āÆļøµ ā»āā»
I guess preset system got useless within 2 weeks
uiBuilder.Build<TestButton, LocalizableButton>(); If you want to build it instantly
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 š
I am just messing around with things that don't make sense
Probably overcomplicating things by x1000
Why write one line when you can write a whole class? 
One
, pesant numbers
Oh donāt worry, Iāve written an electrical network system 
And you say this is complicated

He big brainz
I have, but its not finished for your usecase yet
// 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.
Takes about 2,5 seconds to build 10_000 x 13 elements = 130_000 elements
Did you build it in the release mode? 130k elements in 2.5 seconds doesn't seem fast to me.
To be fair release nor debug mode takes pretty much the same
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 
Pog

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
[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 š
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?
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
.
With my other idea this would be just 3 lines, but you could only change backgrounds.
Funny animations
_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
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
.
Starting to like the new builder
. Will be so much easier to maintain and actually do stuff in. And removing unity as a whole again 
@stone shoal Wow! The builder looks really cool. Never used them tbh, but the difference between Unity and the builder looks huge.
Thanks. Now is pretty much able to do anything the USS/UXML can do too, but without unity
I don't quite understand what you mean with the difference between Unity and the builder looks huge.
I mean, you code examples: with pure Unity and with the builder. The latter is much more compact and readable.
Ohh so yea unity builder can get very large fast
I have to admit, i dont completely understand ypur question
Addmin the selecter types descendent and child as a property or as a seperated function call
It will add a > or a between items
eg. .test > .test2 or .test .test2
OOh, i see, in that case option 1 makes more sense to me
.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 š
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 
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 
The space between selectors is annoying as hell tho
Since you don't really know the difference between a normal one or that one
Why is there 4 arrows down? From the builder code I don't see how is it happening.
I guess, you use regex for the first argument parsing. May be use optional parameters to avoid parsing altogether? Or require a strict syntax, e.g. "no whitespaces". This way regex can be replaced with a simple split.
There are just 6 visual elements stacked in each other
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.
Oh that part of the code is not shown. Since it already exists. The part shown is just building the stylesheet
The styling of those 7 items are determined by those selector parts
The add properties are the stylings applied
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 
if it works it works
String vs functions is a 20 tick difference in building the stylesheet
No regex - good! š
Excepted regex to be fast though
But maybe not if you aim to do it within miliseconds
Good coding practices not always give good performance š I had to stop using ImmutableHashSet due to this.
Yeah, though with regex it wasn't much cleaner :P. almost the same
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.
@full acorn VisualElement element builder code previewer
?
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
This would be awesome! Making UI today is tricky and slow.
Is it from the game or from the Unity editor?
It's from an assetbundle exported from unity.
Added a small QoL method .AddBackgroundImage("DebugMod/myfirstassetbundle/Testing")) so you don't have to bother with fetching the image from an asset loader
Ah, I thought it's a demo of the code previewer š
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
Just don't use immutable collections 𤣠Yesterday I've removed all immutables from my code and improved its performance 10x times.
I use them quite some in TimberApi. But well its just once since.. Yeah they immutable 
.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 
Oh wait, need to make the caching system still 
Hello, can anyone tell me I need in order to mod a mod that uses the TimberApi
Depends on what you want to make
I want to adjust the cost of an item the mod allow me to build
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
If you only want to play with it you can just edit the json
I have looked at all json in the mod but cant find the costs
Right is in the prefab
Than you need to make a mod and change it with the BuildingSpecification
If I have the raw files for the mod what do I need in order to compile the file into a working mod
Dont know what you mean
Check oy the doc
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?
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
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
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.
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
Phind approves of TimberAPI
It is actually even helpfull with correct info
The asset part isn't quite there in the docs
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
Not yet
, the new builder will
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
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
Scrollview is just an image that changed name, but since I didn't have the script to generate the USS anymore. I just swept it under the rug, because I wanted to change the UIBuilder.
Which I now actually did. Except the last part
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
Oh nice! Nicely done!
No pressure or rush to finish, itās no biggie! š
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"
Do you have the correct components?
Could it be missing animitations included in meshy file?
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
hmm and its not that they are delcared in any other file to load them? š¤
- well that is what you said š¤
hehe
i was really not expecting this to be there
well i knew it was there but had not gotten to it š
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
š¤ got the error report?
[Info : TimberAPI] Bots for faction Waterbeavers doesn't exists, falling back to Folktails
(still loading though)
ya maybe is some fixes that now base game can handle better
(from hardcoded to defication)
AH-AH
It worked !
somehow discord doesn't want me to upload an image but it's there
okay, time to mutilate it horribly
Because you dont have any bot models for water beavers?

Nice
oh i fixed my specification so that it calls the right bot of course
And then no error?
If you could make an issue on github 
Mecs? š
that's an idea š
do they fit inside doors?
what is that š¤
i tried to load a save after destorying some building i shouldn't have
but otherwise everythign was seemingly fine
i could load the same save normally later š¤
Guess just corrupted file
Idk
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
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
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 
No idea
About 50% done with buttons
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 
Noice! Did you get the delete button from the entity panel? Or is that not a button?
Hmmm⦠this is a good question, I may need to revisit it when itās not 4am
I feel like the ābuttonā at the end is a good thing
Delete button you mean the ine of destination?
The deconstruction button, aye
What does it look like? circle with trashcan ?
Aye aye!
Ah in which case ignore me
Well not specific for destroy, but any icon than
Yeah fair enough
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
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
You tried making a USS class for it š ?
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 
Fair enough! Is that an example of the use?
It was just a copy paste of the cycler button
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.
Thanks!
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
Ahh, well then that explains quite a bit. So the various previews in the example are used to show various elements and their designs.
Well, I did get a panel working later on, but still a longs ways off from what I'd like. Most of the tools I looked at either added fragments to existing building ui's, or just didn't have an own one.
Thanks for the feedback
I can't remember any tool that adds fragments 
The boxes you see like the settings box are panels that implement IPanelController
Found it in the automation tool, for showing the active rules and such. Uses quite close implementation to the api ui fragment example.
Thanks for the update on the interface I can check out. Hope to get back to it later today. 
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
Hello, I need help installing this mod and other mods that this mod requires in Timberborn. Can you help me?
Are you trying to do it on experimental ?
no
I'm not good at English because I only know German
Thank you
TimberAPI is broken on update 6?
ya and will probobly not be needed in the same way with new mod support.
we just have to get out mods converted to new mod version to be able to release some mods
Already done that
Anything in BepinEx?
Already fixed it though, missed a patch
, 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 š

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
Well good start, The red wall of text are just al placeable Tools
Tomorrow converting the rest of the tool specifications
Did check again and it still crash with my latest version but its a new error message that say Timberapi
Stange, some modded buildings do work right ?
ya tested with Frog statue and TAPI and it did work
Alright
no, because it has not been tested good
Probably mising some things as wel
You didn't add it as a dependency ?
no i forgot to do that š¦
Can you add dependencies without needing tyhem ?
Kinda found it still weird the load order mattered though
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
I see
tested Pathextention on both IT and FT from a clean start and no crash
But if i load a save after one is loaded it crashes
@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.
What the actual F, no idea why that would happen. Probably because I load the prefab collection as first, but then why would it work if the mod is loaded after. It's loading all specifications
is it not unloading specifications when loading a new save?
It reloads asset bundles, but I still do nothing special except forcing that PrefabCollection system is firstly done. But this is done with a patch the load order can't change this xD
WAit i think it tries to load Spec file that is optional = do not load if it does not exist already
Do you change existing PlaceableObject specifications ?
not yet
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.
ya the first crash i had(replied to)
but looks like the double load crash is becasue it tries to load specifications again 
Latest crash is just TAPI + Frog statue installed
Will try next with only TAPI
Oh yeah that problem is in there
Atm you cannot go back to main menu and start another game
base game do replace if it already exist 
?
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
not 100% sure
Seems ok, I added this to our backlog
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
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
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.

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
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 š
What ?
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
by using ToolSpecification
SO you ned up needing to customize all orders
well it has not happened yet
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
Understandable if it's actually x10 but I thought I already changed that tbh
Maybe I just need to make a export button now so you can export them
i did a Batch file to create Toolspecifications where i decalare Base file to use, Faction to create and Prefabname š
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 š
Is the alpha version working with update 6?
"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
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
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?
Aren't those 2 statements the same ?
currentyl only water extention pump/pipes will be moved to water tab if TAPI is installed
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)?
š® ya also that moved to path but will not group other buildings
only ones that are at bottom bar(same tier as settings) will move not in a bar
Yes if people want to use subgroups feature, they need to implement it to make it work.
Okay that make sense.
Having pipette tool and timber API enabled crashes the game.
Nope windows.
Yeah saw the converstion. Also with only pipette tool enabled ( not timber API) the game doesn't crash.
yeah have latest version of both.
timber api 7.0
pipette tool - 2.0.2
Because it requires TimberApi? Or does timberborn load it no matter what
For some reason it is still triggering the custom search while it is able to find it normally
No. I just installed TimberApi. To test if sub categories are there are not. My bottom bar is becoming too long now.
Pipette tool doesn't need Timber API. But if both of them are there game crashes.
I think because original tools aren't compatible with my tools
The only big downside, since if you want a custom tool you kinda need to use TimberApi else the bottombar won't work.
TAPI manifest should have harmony as req?
Yes, didnt exist when I uploaded it
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
The system has not been modified and requires the same amount of items
hmm werid that it works in U5 to just change where an item is placed
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 ?
U5 version ya
https://mod.io/g/timberborn/m/more-groups
Sprites location is changed now tho
here is an example how files looks like in u5
to move Logpile to Subgroup_MG_Piles
Is this ebcause of timberapi 
its to help with that ya
No the image
š® 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
does it not read existing building? like staircase exist in base game i only want to change location 
But this doesn't happen in the base game right ?
wait thats toolgroup i talk about toolSpecification
That one is required
Btw I don't get the error 
I don't see the group either xD
PlaceableObjectTool
But they indeed should already exists with the prefab
How is the woodenStairs called in mod io ?
hmm will have to check more not sure i have time before 1w holiday
So only more groups should be enough to see it ?

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 ?
yepp
Dang I thought it didn't do that
it takes the longest part and use that;)
Was it also looking like that with TimberApi when not using subgroups 
ya compareable ya
better than hiding things š
Ah no it looks "good" with timberApi
I guess I am just too used to my own fixes
And also working just fine 
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.
@vast otter Removed the *10 order
@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.
Ofcourse I will update mine :P, Don't know about tobbert probably as well.
Thanks. 
Will wait for @severe solar's reply.
It actually already was before, so don't think its much work
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
Great. 
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)
I always update to the latest version, you cannot reverse back to 0.6.1.0. I can't test it so it's 0.6.2.0
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 :)
Reimplement/redesign what is required with the use of the base game.
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
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)
Not really, you would have done that either way 
Not worth it for just CameraTweaker - I will wait for you. I am rooting for some nice UIBuilder and DependencyContainer rewrite :)
How did your UI look like for camera tweatk ?
Kumare wrote that. Idk. There was an ingame HUD overlay with buttons.
A whole settings panel separate from the normal settings. And probably more
Oh well - RIP me - I guess
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
Red is the only thing that isn't implemented, blue is implemented by base game except configs which is now mod settings.
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
Nice š
One of the devs said yesterday that the game might get an ingame console. What are you envisioning with "external console"?
Same as bepinex
Or webpage?š¤
web is evil, run while you can~~~ š
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'.
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.
The ToolService isn't something you need to deal with, that's only a automatic system for buildings
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
That's for 6, it was all working in U5, though the specification / mod structure is now different than in U5.
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
I'll check it out, now that I know better what to look for. Thanks
You're saying I don't need to use the TimberApi tool service to create a tool anymore?
Think sprites should be possible to be loaded without unity asset bundle but not sure what path it gets
Preferably you use the TimberApi way to create tools, but maybe I am miss understanding what you mean with ToolService
The Icon service of the ToolService is just for internal fixes
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.
The documentation does show how to access any image using an extra .json file, but since I am not handling it myself, but passing to the TimberApie, I thought I'd ask how it's done. But perhaps the new U6 handling will load the toolspecification without timberapi... Hm. I'll guess I'll take another look at TimberPrint...
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"
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 š
Don't look at toolprint š for tools, I need to convert that yet to TimberApi
But loaded specifications is now not done by timberapi but by base game same with loaded assetsš
It should be pretty much identical as before, except the icon path you use
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.
That's fine, and I highly recommend adding tools with TimberApi and NOT with the base game as they aren't compatible.
That's becasue the bottombar is completely different
Which is required for the 3rd rows
So I've read. Yes, will definetly develop with TimberApi integrated, just try not to assume it is doing everything š
If there are any other features that you are missing, that are not in the base game now let me knwo
What you mean with , just try not to assume it is doing everything :wink: ?
That I'll look into a bit more which parts I should be using from Timberborn, and what TimberApi is supporting on top. I had until now thought TimberApi was still doing most of the mod integration.
Oh no, I only converted the helper tools like SpecificationGenerator and the bottombar rework. I am not adding stuff whatever the base game does š
That I can understand. š
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.
Config system is replaced with the mod settings mod
crash.. 7.0.0
did you go to main menu from game?
yep, and change faction
known issue
also this?
No, but seems like an prefab with the same name ?
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
custom faction ?
nope, just iron/folk... it will have the same source of error it seems, it just crash somewhere else
so question is it tapi or the mod that is at fault hard to know atm
He says he doesn't have a mod installed
I only have tapi
Nvm this is the same exception as #1064983064020799498 message
then how do you have a 3rd faction 
So I suppose you came from a loaded game before ?
instead of going to the menu, I loaded another map from the game
Same issue
This will be the same error as before
It seems to happen even if load the same game during play (if was at least one autosave) š¤
ya any reload of scen cause the crash
It has a cached directory to store ObjectSpecifications since prefab changes are kept between scene changes.
Will be fixed tomorrow
@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
I start my game always from an existing save

What kind of crash ?
Property Id not found
ya feels like it has not loaded base game items specifications(Dynamic specification?) when my added file is loaded
Maybe my object specification loader it wrong or too early in some cases 
or not run?
not a critical bug
want me to do an issue on github? (with link to above chat)
Sure
found some more things that i added to: https://github.com/Timberborn-Modding-Central/TimberAPI/issues/103
it is around the bottom bar
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
@vast otter How does it use the toolspec from folktails though 
it tries to load all Specs even Folktail ones and fails becasue Folktail prefab is not loaded
Do you have manually added toolspecifications for your own building
?
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 
this works to show the error
and its base game item
ya but what is happening is that Staircase.folktails does not exist so it crashes but if renamed to Staircase.folktails.optional = no crash
Ye okay makes sense
Though is it my problem 
I kinda don't think so. This is just how they have implemented it
na im fine with the .optional
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
If you're just sharing the same asset across factions then you can just ditch the .<faction> part entirely. TB uses .Common for shared assets so I would suggest following that paradigm for sanity's sake
Has nothing to do with this, he is just chaging the ToolSpecification of an building. Which is a faction building. Therefore not always loaded. And if you want to override values on specifications that aren't always loaded the .optional should be used.
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.
This page documents the native mod support coming to Timberborn in Update 6. The new system makes the most common modding tasks easier to accomplish, less prone to errors, less prone to compatibility issues, and overall makes the game more fun to experiment with.
I know about the .optional, that was one of the 1st things I read in the new TB modding guide/s
ya just not noticed that it was used also now by tapi but its fine
I was referring to the source mod, if it's using just one asset across factions then could ditch the multiple IDs
ya but most of my mods have a faction specific variant
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
go for it you may joink my icons i add later if you want š
Why are they not sorted by name on same Pos?
PoweredLevee is before Downward Power Shaft

They should not even have teh same pos
Why do things have the same order ?
true have moved them apart now
thought now of that else if a translation has different first letter stuff moves around
The order thing still confuses me, is it relative to the group or absolute across all groups and tools?
its in each group
oh good, that means I have some editing to do 2mw
where is UIBuilder and DependencyContainer?
and this
[Configurator(SceneEntrypoint.InGame | SceneEntrypoint.MapEditor)]
in TAPI 7.0.0 š¤
or what is the alternative
The first 2 arent implemented yet
The configurator is bit needed anymore because its in the base game
TAPI crashes in Map Editor š®
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
have added that already to my issue https://github.com/Timberborn-Modding-Central/TimberAPI/issues/103
awesome
@vast otter What does secodnbar is not correct centered mean
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 
You want it not to be the center ?
centered against where you clicked to open the submenu to have less mouse movment
Would be way to complex and the game also doesn't do this.
How would you do things like
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
the last item should be same place as config button i would say but ya its more advance and then more prone to bug
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

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
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
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 
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 š
not that i can think of the things around bottom bar i noted is not critical errors just weird quirks
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 
@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 ?
think its new but before u6 i had not played for a long time
Before has closing the subgroup only ....
Not in my test 
This is 0.5.9.1
Seems like this bug was always the case
And this as well
I don't remember that bug. Sure I reported if it was ...
I notice that, but, is minor ...
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
Important is that with TAPI and More Groups, I saved my budget from buying an expensive ultra wide monitor š¤£
Not sure if it's saved, rather a missed opportunity to use it as an excuse
Nope, I should buy also a new desk. The current one is too small for that kind of monitor š
@vast otter someone days 1x2 storage crate is incompatible with TimberApi š¤
Ya its weird have no error report thoš¤
I have TAPI since I have More Groups , and, giga storage from 1X1X2Storage mod, so ....
Probably something else than
Ya wonder if its corrupt download by steam again
Easy fix and, also for updating issue with steam is to force check integrity of game files .
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
ya i have the same feeling wonder if @quiet delta has any idea if timberborn can fix it
Steam should update mods, even in case that is selected "update when game start", and only after, start the game ...
maybe is some setting for timberborn to tell steam when/how its allowed to download updates
Downloding or updating mods is handled by steam, not by the game š¢
yeah, I doubt we can do anything about it. When the game starts, everything should be already downloaded by steam
Only this settings
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
guess is about other games not running ...
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 ? š¤
Do you know if path extension is working fine ?
@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
I see
I have added a comment on github to verify game files
Interesting that we have more problem with faulty updates with steam than mod manager š
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
New update 0.7.1.0
- Added UIBuilder V2.
- Added Dependency Container.
Live on Steam & mod.io
https://mod.io/g/timberborn/m/timberapi
@vast otter Which mods of yours use the #append and #remove function the most ?
i only use Append and once per mod but think @austere tangle:s Dirt use remove
Which mods š
Dirt
Sorry m,b
np
ye spls
š® 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?
Since anyway I had to change the prefab to add new recipes, was the KISS solution š¤£
@vast otter because of the #remove you can now remove a specific building from a faction roght
Ya should be possible
is there some Documentation/Examples on how to use the UI Builder?
Specifically i want to add a Fragment to the Building's UI
Atm not since it only has button presets as well
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
thanks, i think i slowly begin to get a grip on it
Just a small heads up, make your presets transient ant not a singleton
containerDefinition.Bind<PlusButton>().AsTransient();
Did i just delete my debug mod...
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
By tobbert my GameButton is empty, I don't know why. So maybe my presets don't exist in the uploaded dll
WORKING 
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;
}
}
}```
The UIBuilder already has this
But it's also done alot by the game, I guess not by when returning the fragment 
No, it isnt, in this instance, the functions provided in UIbuilder werent enough
I guess I missed that one
it is avaiable when using Create test.Create<GameButton>().BuildAndInitialize()
The initialize was only for the click I may hope, or does this also have other effects ?
oooh
i thought the Create was supposed to be doing that
or, well build
but there wasnt a BuildAndIntialize
only Build
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
ye will add
Only use it on the laste element though, that cost relatively alot of compute. Nothing specific to the UIBuilder though
?
LocalizableLabelBuilder is not yet bound
Lmao
Might fix tomorrow
Thank you, take your time ā¤ļø
This is now added to the Web UI mod. It's disabled by default, but can be enabled via mod settings.
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.
wonder when the next patch hits and how many mods that will stop working 
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.
if someone uses these functions remember to set req in your manifest so it at least give a warning
warning isnt enough 
?
You mean like any other dependency mod ?
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
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 
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...
You can press enter to continue 
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
Ye true, didn't know you could press enter instead of pressing the button with a mouse
š® that ya added in like the last update
Cool!
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 
well you could do a empty harmony folder just with the manifest to trick it š
just the same id but different name
Oh it also works with it in, xD
and me 2 have bepinex but just for the log at different screen š
Ye, going to import that as well. And I was thinking yesterday to maybe add mod settings as a dependency 
OwO
To toggle it on/off, and need it for some other features as well. Why bother with making it an optional mod
.
then people will not understand that they need to download dependencies of dependencies and gonna cry that they are crashing 
we will see how it works š
And they going to say, this mod is NOT EVEN CLOSE as usefull as those other mods I need.
But does it not download dependencies when you verify ?
it does, i think
but they forgor
it's dum that's its needed in the first place ĀÆ_(ć)_/ĀÆ
no i do not think it subscribe to dependency when verifying game files
Do you think you could trigger that ingame with a mod 
I think so yea
maybe even if crash start verify game files? š
Note: Using the "Verify Integrity of Game Files" feature in the Steam Client will also cause workshop items to be downloaded.
ya but does it download dependecy mods not subscribed to 



