#TimberAPI
1 messages · Page 3 of 1
Hey Siri, direct me to TimberAPI.UIBuilderSystem
The UiBuilderSystem can be found at: https://github.com/Timberborn-Modding-Central/TimberAPI/tree/main/Core/TimberApi/UiBuilderSystem
Where all the specific builders are located at: https://github.com/Timberborn-Modding-Central/TimberAPI/tree/main/Core/TimberApi/UiBuilderSystem/ElementSystem.
The BaseElemementBuilder is included in all types.
I don't know what you stuck at
Skill issue
I suck at everything winks with both eyes

Dang that's heavy
Nah only joking around
How does the game design align to the common singleton pattern? Is it considered a bad practice to use common pattern vs injecting the singleton via Bindito?
The both approaches would work just fine together. I'm just curious.
@ebon sparrow This question is probably to you 🙂
Just to eleborate the case a bit. In the common pattern we have a private constructor in the class and a public static field that returns an instance (which was build somehow). Like:
var system = MyMegaSystem.Instance;
system.DoStuff();
The same code can perfectly work if we inject MyMegaSystem object via Bindito and don't deal with the static field Instance at all.
using statics is generaly bad, as then it is harder to control your dependencies
Dependency injection is a tool to solve this problem
so while you can use both alongside
from architecture point of view, and also from maintainability, it is a step backwards
probably also less buggy aproach, since Bindito ensures proper creation, initialization and destruction of objects
while with common pattern each time you need to solve it yourself
@stone shoal does the specification system limit itself to the current mod or does it allow for cross mod compatibility?
Lets say i make a fluid specification in my mod but allow other modders to specify their own fluids, would that work? or do i need my own system for that?
Crossmods
Thats why you need the .original, that defines its the first one
Other specifications that are the same, but do not have .original will add or overwrite the .original
i see, thats poggers
And it allows for your instance of other mods having those specifications
Thebloodeyes is very smurt 


How expensive the DependencyContainer.GetInstance<T> call is? Do I need to bother to cache its return?
E.g. I can maintain a hash map of the instances that I've already requested. Is it worth it?
Do you use it in a patch ?
No, it's a regular mod code. I can get an instance every time I need it or I can cache it. Just trying to figure out what's the best.
Well if it's just your code i'd say if you use that code, you already abuse it 🙂
Why could you not just do it with bindito binding ?
One case, is a class that doesn't follow the bindito schema. E.g. it can be "simple class" that needs to do something with the game state. I saw some examples in the game. There, the injected instances are all passed in the constructor. My humble opinion is, it turns the code into disaster on the long run.
But getting back to the "abuse". Should I cache or should I not, being abusing the concept?
The concept is to only use it at patches, since you don't have access to bindito there
With a very very few exceptions that it would really not be possible due some ingame loading order you want to avoid
But to simply at your question: No idea both ways are less performant
The container has it also already cached I think
I have a case where new MyClass() is the best way to go. However, the MyClass may want to access, for instance, EventBus. I can pass this instance through all the calling chain, making my code looking like an al dente spaghetti. Or, I may avoid it.
Why do you think that, if i may ask?
Then you can created a dedicated factory, if you dont want it to be a bindito class
And let me guess, this factory needs to be injected? And how would it handle the inherited classes case?
E.g. I have MayBase class and a dozen of descendants.
Feels like you need to use bindito, without more context
How would a factory not be able to do that but your class do
, A factory is nothing else than the creation of thsoe classes ?
You have a few options, and those are it i believe,
- Class on gameobject and use InjectDepencies
- Its a singelton
- Its a class created using a factory where the factory is used to creat the classes with some extra singletons.
A example of 3 is pathfollower inside walker. How i understand it, is that making it a basecomponent is not needed, but they do several other singeltons and therefore created a dedicated factory
And that is why i asked why you feel like that. As to me, it makes the most sense and more than whatever else you can do
A factory class can do it via a generic method. Except, it would be just a decoration around the real stuff. So, technically, we get back to the root question: the performance.
No?
Use 1 of the three options, if you cant, big chance you are doing it wrong
If you want, i can come into a call sometime and explain it better
#1 is an option. Which I don't want to follow due to my reasons, which may be wrong.
Or as thebloodeyes stated, you are inside a patch and injection is not possible
Thats why i asked why not? Maybe you have a valid reason, but to me it looks like you dont understand how it works and therefore want to make something that exists yourself
Ofc you can, but i feel like it would be a shame of your time
In fact, any API has its reasons. As long as DependencyContainer is publicly accessible, people will be using it.
Sadly you cannot limit it to the cases in which it is allowed to be used
I have a reason which is OOP related. I have an object that encloses "a behavior" and acts as defined. I can have two separate classes: the definition and the behavior. Or I can have just one. In the latter case I may (but not necessarily WILL) need to have access to the game state.
In my specific case I believe, that access to the game state will be out of the common case. Thus, I lean towards to the first option: one class for the definition and behavior.
This has nothing to do with you asking advice what's best for performance, which is not using it.
You can do whatever you want and I would not care really. But if you ask what's best, well not using it is. and tobbert stated the options better than I did.
Why not? If my object are created via plain new operand, then may need getting some singletons from the game via DependencyContainer.
Dont use new?
Than use a factory that does that for you, that's just as OOP as anything else
Or import the class that creates the new with bindito and acces it that way
Also just fine
But not importing the singleton in the head of the class because "it does not look good" is not a valid opinion in my eyes.
I noted all your input folks. Thank you.
Except I still don't have an idea if I should or should not be caching the instance from the DependencyContainer. I guess, I will be doing it just in case.
I WILL be using it 5x times more than you can say no 🙂
make it internal if I should not be using it.
I dont understand why though? We twll you its wrong
I said what I know, which is I don't know if caching is more performant than not. Since the dependencyContainer is probably already a dictionary
You ask for advice, we tell you how to do it and you ignore and still do it. Why ask for advice?
You give near to no example of why ot cannot be done how i said it should normally be done
Please, check the answer which I actually have asked. Did I ask shouId I be doing it or not? Nope.
Disclamer: Tobbert is tobbert, and not me 
Sure i guesss... 
I want to help you and tell you how to keep your code in line with everything else. I dont understand why you not listen or even try to listen....
That is true to the extent you think so. I did my best to explain the case, but obviously failed. No claims on my part in this case.
The only thing I heard is you wanting performance, so I adviced to that while also giving you a simple answer
And you said it's "probably a dictionary". Which sounds to me like "do not cach, it doesn't make sense anyway". It's a good answer to the exact question asked.
Btw that "feature" is just a cached instance of bindito 🙂
Therefore the reason of not knowing
Well, I would reasonably assume that Bindito is very efficient under the hood. Just wanted to clarify wrt: the API verion.
wrt?
"with regard to"
Its a saved instance 🙂
I guess, the final answer to my question (which is only important to me, but it's fine): do not cache injections, it's stupid.
Using dependency container is worse peroformance to begin with, so not using it is better 🙂
Of course. Any dependency injection is worse than an old good new. But we live in a world which we cannot change.
No, its worse than the methods i described because its 1 extra function call
I actually have cached it 
Don't worry about micro optimizations before you have a working system. Use the tools at your disposal and if those end up being too resource intensive you can look at optimizing them. But this feels like a case of "i dont wanna do that cuz i dont feel like it" rather than a solid reason
How is calling to Bindito "in general" (via a factory) is better than making a class via new and calling Bindito from there? I do understand how it affects the dependency graph, but the question was about the performance.
At what level are they created? Is it a singleton? Recreated each call?
Funnily enough the creation of an object is rather expensive compared to reusing a class.
Depends. The whole point was in not being tied to it. If a class needs an injection, it gets it. If not, then not. And if "too many classes" need the same injection, I was thinking about caching it.
So you'd DI the factory class but not the specific classes it creates from that factory class?
DI?
Dependency Inject
Ah. As I explained above, it can be done. Except, I don't see a strong need for it. Factory is a good pattern, but as all patterns are - it's not good always.
Well doesn't have to be a factory class ofcourse, could just be a service class that handles the logic, no big deal
And how would it look like? let' say I have a class A, and a dozen of decendants of it.
The way i do it for my liquid logic is that i have a service class that creates the registered instances in a load call and put them in a map and get them when i need it
well you could have an interface which satisfies your needs for A, then create concrete classes based on name or properties
for fluids i just do it based on a string
namespace SteamWorks.Scripts
{
public class LiquidServiceFactory
{
private Dictionary<string, ILiquidService> _services = new();
public LiquidServiceFactory(LiquidService liquidService)
{
_services.Add("Water", liquidService);
}
public ILiquidService GetServiceFrom(Fluid fluid)
{
Debug.LogWarning($"GetServiceFrom {fluid}");
if (!fluid.IsPhysical || fluid.Type is not FluidType.LIQUID)
{
Debug.LogWarning($"GetServiceFrom NOT OK");
return null;
}
_services.TryGetValue(fluid.Name, out var liquidService);
Debug.LogWarning($"LiquidService {liquidService.GetHashCode()}");
return liquidService;
}
public void AddService(string fluidName, ILiquidService liquidService)
{
_services.Add(fluidName, liquidService);
}
}
}
i'm aware its not really a factory class but i couldnt find a better name
Heh. Indeed, it's what I do. The question is how the factory can help me here.
Heeey, code as an example, how usefull 😉
well as i said, it doesnt have to be a factory
just use whatever method works, just make it generalized so you can easily get it using DI
Do you mean I should use intrfaces in C#?! It's ... a good suggestion 🙂
Yeah interface or abstract classes
Sorry I was being sarcastic. Of cousre I use it. There will be no this discussion without OOP inheritance in the first place.
you do you, i'm just giving my 2 cents
Btw, one reason I decided not to keep "dictionaries", is the reload case. Some entities may change between the reloads even if you think they are "singletons". For example, the tool buttons.
Because they are singletons fkr that instance. Reloading the game isnt the same instance. Than you need to save it of you want to persist the data
I was hit by doing fancy stuff with the tools. It's solely my problem, and I'm not going to blame anyone. Just figured out, that the tool and its prefab (block object tool) can be live on reload while being unusable. It's something you should expect being "fancy".
If you mean that prefabs keep the state after reloading yes thats true
And a bit annoying
Isnt true for nodded buildings tho since those are actually being unloaded and reloaded
Needed to change the specificationGeneration for that as well
my thoughts exactly 😅 you never optimise when you write code. You optimise whem you have a working system and you know what is a performance bottleneck
My reasonable expectation on reload would be that if any object, that is derived from Monobehavior, stays alive on realod is a usable object. I figured out, it's not the case at least in some cases. That is OK. I'm just making my code accordingly.
you are hiding your dependencies - they are buried somewhere inside you code, instead of being passed in constructor. Resulting in a messy architecture
it's futile tbh
yeah, I already know :)
This is absolutely TRUE. And I mentioned it. Calling the injector explicitly blocks the ability to properly handle and optimize the DI graph. However, in my case it's not the case. When my logic happens, I don't care about the graph.
you asked "in general"
I tried to elaborate. And failed. Which I also admitted 🙂
My question was not about "can I do this?". It was about "when I do this, how slow it will be"?
I think the best answer is: do it both ways and compare
For me this is asking: how much more gas will I use when I turn my cars AC on
In most cases: more, but negligible. But maybe you live in north pole - and then exactly the same
couse it will never turn on ;)
I ask thebloodeyes always something, but then he tells me why im doing what im doing in the first place. Most times hes right and im doing something wierd which i shouldnt. This is what i tried with you, but you are ignoring my advice and still do it in a unconventional way.
Unless I set it soo cool it will, and also heat up the north pool by doing so, so the AC needs more cooling to do 
If this was my main approach, I would never speak in this chat. Why would I ask something about that I'm being checking myself? In fact, I ask , and DO some stuff in parallel. And that's why I'm not asking for a permission to code my ideas the way I see them.
But you could have checked this yourself?
I actually think this chat isn't a good place for asking performance stats, since no one will know 😅
And I did. No differences found on a small colony and a big colony. But I know something about statistics.
So you still asked?
Yes.
What?! 
What makes you think I would know 
Because you're one of those who contributed to TimberAPI? If you don't know, it's fine.
In my life, I made dozens of services which performance I'm not aware as of today. Not a big deal. For me 
I know around how much things of TimberAPi impact the game, at least where the places matter for me
But there are also quite a few things that are things Timberborn made and I only made it accessable
And for this stuff many people, myself included, would like to say you "thank you"! No jokes, really. Timber API is a cool thing.
A huge project, if you ask me 🙂
@stone shoal just so you know cameratweaker mod is updated for your u4 update 🙂
I know 🙂
Hmm is it possible to have 2 mods to have the same Spec
want to use the same tab for both mods and if i use .Original it does crash if i have both mods installed and if i have .Replace and only have that mod it crashes because it is not loaded
or is i forced to have one mod as a dependency 
would it be possible to allow .Replace to load if no Original is found
Not sure how
Then i keep them as dependent on the other
is there soft depend? Basically if the mod is present hook into it, if its not just ignore it and load your original logic
Not what i know of and my mods is codeless. And the problems i have is that i want both mods to be able to load a new tab without it crashing🤔
So my current approach is to have one mod req the other that has the tab
You can tell in mod.io and in mod.json that mod a req mod b
yeah but then you're forced to use both mods
Ofc you can 
There is a soft dependency, but won't do much if you can't create 2 originals
We had 2 originals before and it worked tho
, maybe something in the bottom bar doesnt like it
It say key already found 
maybe skip it then and give a warning in the console?
Key with Id x already found, using that instead
realistically speaking there should be no accidental matches on those
Better load the original, and have a soft dependency, so the first one is read first
that would be the better option, but more work
Where does it say this
maybe a .shared use at own risk 
Will give you the error code later today
May be later before i can give an error message. Stomach hurting so time take it chill in bed
When using AddPreset(factory => factory.Sliders().SliderIntCircle()
I get warning messages
Image not found for path: UI/Images/Core/scroll_bar
Image not found for path: UI/Images/Core/scroll_button
and the result is this
it probably is just a renaming issue to scroll-bar-nine-slice
Ye needs to be changed but the Python script has gone missing
Sadge
what did the python script do?
it gathers all pngs
so in a nutshell compile a list of all pngs and its location? 
can i view the current file used on github is the question, how it looks like currently
Its in the asset bundle
It generated a uss file and .cs file with all class names for the images
TimberApiStyle.cs lr something
and the assetbundle has not changed since update 2 ich ?
ok
Just have to understand how to open the asset bundle, but thats for next week
Something weird is happening with Harmony in the game. According to the docs, if prefix returns false, then not original, nor any patches that are following in the chain will be called. However, what I observe, is calling both patches even when they both return false.
ChooChoo patches StatusSpriteLoader.LoadSprite so that the prefix always returns false. It should prevent calling any other prefixes that are down the stream in the chain. However, the prefix method on my patch on the same method is always called. Even with the Priority.Last.
Any ideas why?
how's your patch look?
Prefix methods that return void and have no ref arguments are considered side effect free and are always run, regardless of their position.
returning false doesn't skip all the prefixes
I tired both: last and first. In both cases both patches were executed.
Here is my patch: https://github.com/ihsoft/IFTTT_Automation/blob/master/Source/Utils/StatusSpriteLoaderPatcher.cs#L29
But I also tried to copy Tobbert's version. Same effect - both patches get called.
well that is indeed odd
Btw, if I change priority to Last, then __result in my prefix comes non-null. Which implies the previous version has been called.
[HarmonyPriority(Priority.First)]
[HarmonyPatch(typeof(StatusSpriteLoader), nameof(StatusSpriteLoader.LoadSprite))]
static bool Prefix(string spriteName, IResourceAssetLoader ____resourceAssetLoader, ref Sprite __result) {
DebugEx.Warning("*** calling our version for: {0}", spriteName);
__result = null;
return false;
}
This code must be crashing the game unconditionally. However, it doesn't. I get all the logs printed, but the sprite get successfully loaded by the next patch in the chain.
If you change it so that it fails back to the original code, it should fix the crashing issue, but it won't solve double calling of the method. Anway, please, change.
Okay, will try that later
And issues like this make https://github.com/Timberborn-Modding-Central/TimberAPI/issues/76 even more important to consider. It's not a good thing to apply mutiple patches to the same method from different mods.
Well, looking at the IL code, It's obvious why the method is called twice: Harmony simply applies two prefixes! Goot quesiton why.
[Info : HarmonyX] Patching UnityEngine.Sprite Timberborn.StatusSystem.StatusSpriteLoader::LoadSprite(string spriteName) with 2 prefixes, 0 postfixes, 0 transpilers, 0 finalizers
2 prefixes:
* static bool ChooChoo.StatusSpriteLoaderPatch::Prefix(string spriteName, Timberborn.AssetSystem.IResourceAssetLoader ____resourceAssetLoader, UnityEngine.Sprite& __result)
* static bool Automation.Utils.StatusSpriteLoaderPatch::Prefix(string spriteName, Timberborn.AssetSystem.IResourceAssetLoader ____resourceAssetLoader, UnityEngine.Sprite& __result)
the whole patching process is made to handle that, the issue is that you should avoid prefixes where possible and call postfixes. That way they can be ran in sequence
however the nature of how timeberborn code is written makes it harder as most dont have return values you can just change
And, the original will most of the time crash aswell
Yup, that's why we patch it. And if AssetLoader could resolve the paths, the patching won't be needed in the first place.
The problem with that is that i dont know how git works. So instead of making a pr (which i dont know how todo) i just make a quick fix
well do you know how to commit and push?
Sort off
In rider i click rhe select all and then click the arrow
And i have a timberapi project, but i dont know how to update it
Its still 0.4 or aomething
easiest way is to fork the repo on github, then pull that into Rider, make a new branch, commit and push your changes on there, then on github it'll ask you if you want to create a pr to the orignal repo
i can show you how to do it after work (so around 6pm)
So, I found a way to avoid two prefixes executed: store my result into __state from my prefix, throw an exception, and handle it in the finalizer 😱 An absolutely weird way, but it's the best I have for now.
Here is how it looks like: https://github.com/ihsoft/IFTTT_Automation/blob/master/Source/Utils/StatusSpriteLoaderPatcher.cs#L30
So, whatever harmony docs say, it's not true about calling the prefixes. If you can read IL code, checkout HarmonyLib.Public.Patching.HarmonyManipulator.WritePrefixes method. It's the one that generates the actual patch code. It simply enumerates all prefixes on the method and calls them all. The bool results from the prefixes are joined via and and this is checked once to decide if the original method should be called. That being said, the original code won't get called if at least one prefix said "no", but ALL prefixes will be called anyway.
This is this code on GitHub with some comments: https://github.com/BepInEx/HarmonyX/blob/master/Harmony/Public/Patching/HarmonyManipulator.cs#L207
I guess, the vanilla Harmony and the BepInEx version may not be exactly the same.
And here is the "vanilla harmony" code that handles prefixes: https://github.com/pardeike/Harmony/blob/master/Harmony/Internal/MethodPatcher.cs#L735. Indeed, it does cancel other prefixes calling if any one in the chain has returned false. So, it's a bug in HarmonyX. Or maybe an intentional change, but it contradicts the original behavior and the related documentation. 🤦♂️
So, just to sum up. Do not expect you can prevent other prefixes to override your values. The return result only affects the calling of the original method, not the other prefixes on the method.
Topic closed. Harmony != HarmonyX. It was done intentionally, like it or not.
Huh, thats interesting
good find
looks like you can add a check for it though
but yeah a system in api to not having to patch common methods would be best
Yup, the suggested way is verifying for __runOriginal, but for this to work well, all the mods must follow the rule.
Or add the fix to timberapi 😉
And how would work out 
One way is suggested in https://github.com/Timberborn-Modding-Central/TimberAPI/issues/76. Or, the assetloader may become aware about the standard game paths (like "Sprites/StatusIcons") and check if there is a known mod prefix there.
Or, make a patch at TAPI level for StatusSpriteLoader only. Just checking if the icon name starts from a known mod prefix would cover all the cases, and people won't need to patch this method.
So, folks, do you think it's feasibel to resolve the icons thing via TAPI? If not, I'll create a mod. If yes, I can make a PR.
FYI, at the current momemnt my mod and Tobbert's mod are colliding badly (game crashes). Going forward this will only get worse. One way or another, but it has to be addressed.
OOoh, inside TAPI is even better yes
Yes probably not gonna be something I need to maintain
Think im gonna make a specification for it that modders need to add strings to a list
To remove the games prefix
You mean, every resource path would need to be listed explicitly in the spec?
Only the fixed prefix
Like Sprites/StatusIcons
Got it.
I'm trying to add a reciepe to a vanilla building, but even taking example from the more snacks mod, it doesn't seem to work
i'm trying to load this
that is a known bug with U4
do your own prefab and link to base game meshyfile?
Well yes but I was hoping to save myself some trouble 😅
is there anything that has changed with the custom pivot property (in placable block object) ? it seems that the Z-value is entirely ignored
i have uploaded on mod.io (my WB faction) my custom water tower that i just can't get to be placed correctly
the legs are 3m long but the last 1 m is purely decorative. the ground should be two meters under the house.
it used to work i think by setting custom pivot Z=-2 but since V4 it seems to be broken, but now it doesn't
i tried to make it Z=-2; 0; -8, +8 etc but no bueno, they all result in the exact same thing, the pivot stays on the same level as i defined for the base Z (which i need to be 2 otherwise the game complain that there is no occupancy in the Z level that is the base.)
if you try to place it on a 2-tall platform, it places just fine though
(no matter which Z pivot is selected)
Oke, i dont understand completely, but base-z changes the cursor location qswell, so you shouldnt have to change it. Have you looked at the qaterpump how its works there?
But isnt really timberapi related
I think I have it figured out, but I'm assuming that you want the pivot to be at the same height as the floor, rather than the door?
Ok, well it sorta works, but get this weird thing sometimes:
Which is definitely a me issue
But all in all, working as a prefab
Hmm do you have collider and finished and unfinished state?
Not sure if I have a collider, this was from an export of lapantouflemagic's which didn't have the dependencies so it's a bit kneecapped.
I'm assuming the construction site needs a collider?
ya and meshes
Hmm
Looks like the prefab that imported has a nested construction site; the parent has box colliders, the child has a meshy spec
and there is a connection to unfinished state in components?
Aye, unfinished and finished models are set
no idea then 😦
I'm at a bit of a loss too, but the block spec seems to work, hoping it's what lapantouflemagic was looking for
Yep that's the issue that occur if the base level has no occupancy
Ahh right, I get you, hence the base level being the lodge
But can it be placed on flat ground
So if there’s no occupancy for the base level, then there’s no navigable building site, which makes sense looking at the error
Aside from that error, it’s working all correctly
And the pivot (cursor binding) need to be at the floor level to be placable anywhere 😉
And the cursor is always at the Z height set
I see the problem very clearly now
Though tbh I should think of this in the morning
Well, after sleep
GN 👍
And thanks for your effort 😉
@stone shoal so it doesn't seem TAPI related ? A few tiny things have changed in the update placing building upgrades is sometimes a bit more sketchy too
Like the cursor seem to follow occupancy more that just floors
Almost anything unity related has nothing to do with TimberApi
guys, here is a crash that is sent to us in higher quantity. Maybe you would like to do sth about it, maybe you don't - just FYI. If you need any more info about it just ping me
this one is 14% of all crashes we receive
v0.4.9.3-6c7fb02-sw
ModAssetNotLoadedException: Asset (tobbert_moreplatforms) it not loaded
TimberApi.AssetSystem.ModAssetBundle.Load[T] (System.String path) (at <af25edd371414b69b81d2d38ed5d2c5a>:0)
TimberApi.AssetSystem.AssetLoader.Load[T] (System.String prefix, System.String pathToFile, System.String name) (at <af25edd371414b69b81d2d38ed5d2c5a>:0)
TimberApi.AssetSystem.AssetLoader.Load[T] (System.String prefix, System.String path) (at <af25edd371414b69b81d2d38ed5d2c5a>:0)
TimberApi.AssetSystem.AssetLoader.Load[T] (System.String path) (at <af25edd371414b69b81d2d38ed5d2c5a>:0)
TimberApi.ResourceAssetSystem.ResourceAssetLoader.Load[T] (System.String path) (at <af25edd371414b69b81d2d38ed5d2c5a>:0)
Timberborn.ToolSystem.ToolGroupSpecificationDeserializer.Deserialize (Timberborn.Persistence.IObjectLoader objectLoader) (at <65c3f6de70ed4679aa5ac357e1ad3f02>:0)
Timberborn.Persistence.ObjectLoader.Deconvert[T] (Timberborn.WorldSerialization.ObjectSave objectSave, Timberborn.Persistence.IObjectSerializer`1[T] serializer, T& value) (at <5ee48de2acd640e68956ec64c3fc3e37>:0)
Timberborn.Persistence.ObjectLoader.GetObsoletable[T] (Timberborn.Persistence.PropertyKey`1[T] key, Timberborn.Persistence.IObjectSerializer`1[T] serializer, T& value) (at <5ee48de2acd640e68956ec64c3fc3e37>:0)
Timberborn.Persistence.ObjectLoader.Get[T] (Timberborn.Persistence.PropertyKey`1[T] key, Timberborn.Persistence.IObjectSerializer`1[T] serializer) (at <5ee48de2acd640e68956ec64c3fc3e37>:0)
TimberApi.SpecificationSystem.ApiSpecificationService+<GetSpecifications>d__6`1[T].MoveNext () (at <af25edd371414b69b81d2d38ed5d2c5a>:0)
it is not always tobbert_moreplatforms (but somehow in 80% of them it is 😅 )
have you changed that mod to load assets to both ingame and mapeditor? because toolbars load in both and crash if it does not find icon
Could be i guess
You mean group toolbars?
Ya the spec is still loaded in mapeditor and if asset package is not loaded it will crash because asset is not found
Ye tru
x
y
z
or xzy if you are in Unity space
its just like the old usb, you try it once, doesnt work, you turn it around, also doesnt work, switch again and it goes in
Actually one you remember that the fat part is either down or away from you it works first time 😉
Interesting... this is the exact error I get when trying to either edit a map, or create one. Hasn't affected any current saves or new games, however.
I know about the error with editor, but, YET, unable to find the culpritt mod. I'm asking, but, in the same time I'm hopping that is not a combination of mods 😮
Its not moreplatform?
Nope, long time since I change the Scenes to All ...
Question on the UI fragments - For the UI produced when selecting from the toolbar, is that UIPreview? Taking a look through the examples and trying to figure it out
In case of you didn't know. When the language is changed in the game, it gets restarted without exiting. It results in re-applying all the Harmony patches made via [Configurator(SceneEntrypoint.MainMenu)]. As a result, there will be duplicated patches. The workaround is to do the check:
if (Harmony.HasAnyPatches(HarmonyPatchId)) {
DebugEx.Warning("Skip duplicated patches: {0}", HarmonyPatchId);
return;
}
Also, it may be an issue to be addressed at the TAPI level. Should the configurators for the main menu be re-executed at all? It seems people use this stage to do stuff that needs to be executed only once at the game start.
Using IModEntrypoint is another way to workaround it, but it may be not an option if there are resources that are needed during the load.
In year 2023, in a C# DLL that is built under Windows 11 for macOS and Windows, we still can find code that checks for running under DOS. And the only thing it does, is reporting:
This program cannot be run in DOS mode.
Better safe than sorry.
Yeah, .net team is crazy about backward compatibility afaik
won't the same happen if you go back to main menu from game?
Good point. Never tested it. Will check it out.
However, in my code I just added the check just in case. "Better safe than sorry" 🙂
Yup, you're right. It happens if exting the main menu and then loading the game again. A pattern I never considered.
If you want sth to happen only once per session, there is BootstraperConfigurator
containerDefinition.Install like this?
99% sure yes
Thanks, will give it a look.
As of now I do:
if (!Harmony.HasAnyPatches(patchId)) {
Patch(patchId, patchTypes);
}
Works fine and doesn't require setting up mod entry point which can be only one per mod.
IModEntryPoint was made pretty much only for this
Crash starting a new Folktail game (Plains, Normal) with v0.5.5.7 with no mods except ModManager.
Ironteeth start works fine.
Ok, I kept getting crashes so I disabled all my mods except BepInEx Pack and mod manager and some maps and it worked fine. The moment I enabled TimberAPI (I just added it and nothing else), it crashed. Obviously, big problem since every other mod basically needs it
Actually, after reading juf816 above and experimenting, I realized I’m in the same situation. Iron teeth works. Folk tails crashes
Loading in a heavily modded Folktail save after updating to v0.5.5.7 works fine.
Starting the new Folktail game on v0.5.5.6, saving, updating to v0.5.5.7 loading that save works fine.
Can you start a new Folktail game?
Yes, downgrading TimberAPI to v0.5.5.6, starting the new game, naming your game, saving and exiting. Upgrading to v0.5.5.7 and loading that save worked for me.
@stone shoal can you roll back for now
So you need to rollback every time you have a new game? I guess it’s better than a crash 
Definitely 
I guess I did remove the tutorial after all :/
Thought it was working, cleaned up something seems like it did not
Sorry if this is pinned somewhere that I missed, but should the TimberAPI mod currently work with the normal release build (v0.4.9.3)? On mine if I add TimberAPI (even if it's the only mod) it crashes Timberborn.
Whaty does it say
It was just the generic Timberborn crash screen; nothing mod specific. Good news is that before your reply I tried manually removing everything from the Timberborn folder and started clean and I seem to be getting farther now so I'll let you know if it crashes again. Thanks!
Even with just the Timberborn crash screen, the bepinex console is where the error are or in the files
Where can I find the log file? There was no console window open at the time.
You sure you have modding working ?
All working fine now, thanks! Probably user error--I don't know how many times I restarted Timberborn trying to sort that out but starting fresh was the key.
Since TimberAPI 0.5.5.7, adding a new recipe to a buiding is not working again.
...
Do you have DynamicSpecifications installed? Without it the old way of adding specifications works for me (TAPI v0.5.5.8). With it installed, I wasn't able to get it working. But I also couldn't figure out, how the folder/file structure should be. But this is a topic for the dedicated DynamicSpecifications thread.
Works just fine, so maybe what juf said and a mod incompatability
Guess is due to Dynamic specification, maybe will need to migrate to that mod.
Not sure why it would conflict
Tobbert figured it out... He just disabled the feature of TimberApi
https://timberapi.com/ui_builder/ points to 404 on teh TAPI docs website. From the home page: "A comprehensive UI component builder".
Folks, what's wrong with shades of gray in TAPI? I create the toggles like this:
var builder = _builder.CreateFragmentBuilder()
.AddComponent(_builder.Presets().Toggles().CheckmarkInverted(locKey: NeverStopThisGeneratorLocKey, color: Color.green))
.AddComponent(_builder.Presets().Toggles().CheckmarkInverted(locKey: NeverStopThisGeneratorLocKey, color: Color.yellow))
.AddComponent(_builder.Presets().Toggles().Checkmark(locKey: NeverStopThisGeneratorLocKey, color: new Color(0x0, 0xff, 0x0)))
.AddComponent(_builder.Presets().Toggles().CheckmarkInverted(locKey: NeverStopThisGeneratorLocKey, color: new Color(0x50, 0x50, 0x50)))
.AddComponent(_builder.Presets().Toggles().CheckmarkInverted(locKey: NeverStopThisGeneratorLocKey, color: new Color(0x70, 0x70, 0x70)))
.AddComponent(_builder.Presets().Toggles().CheckmarkInverted(locKey: NeverStopThisGeneratorLocKey, color: new Color(0x90, 0x90, 0x90)));
And get THIS:
And here is a difference between new Color(0x0, 0x0, 0x0) and new Color(0x1, 0x1, 0x1). What do I miss?
IIRC unity color takes the rgb values from 0 to 1, not from 0 to 255. Might be that it doesnt like when you give it values over 1
float values?
Color Color_Bronze = new Color(0.94f, 0.69f, 0.01f); ( https://forum.unity.com/threads/how-to-change-text-color-via-code.1251666/ )
?
Thanks, guys. Of course, it's 1.0 range, not 0xff.
looks like color32 is 0-255 or 0x00-0xff
And I was fighting with this "issue" for 30 mins at least.
Color normalColor;
ColorUtility.TryParseHtmlString("#C6D1CB", out normalColor);
Sometimes it's hard to switch between the coding worlds.
ya
Now it looks cute:
I wonder if TAPI has something like "default panel color". It's definitely not Color.white. #C6D1CB is the most close that I could make.
If no color set, TAPI uses just white.
you mean default font color?
in game it is: rgb(204, 204, 204)
0.8, 0.8, 0.8 in float values ofc
@calm copper Everything sorted itself ?
Not itself. The people helped me to undersnatntd the problem 🙂 But yes, it's now resolved.
In fact, I rounded up the values and got exactly this:
static readonly Color NormalColor = new(0.8f, 0.8f, 0.8f);
Just in case this isn't already known, it seems the cause of construction sites being drawn on top of water is dismissing the priority overlay by right-clicking instead of by clicking the button again
Just by modded items I assume ?
all construction
it's not that the construction itself is drawn over the water, it's the priority overlay
but when it's neutral priority it looks like the normal structure
The slider is not shown properly. TAPI 0.5.5.8. Log shows:
230717T182600.932 [WARNING] [UnityEngine.UIElements.StyleSheets.StylePropertyReader.TryGetImageSourceFromValue] Image not found for path: UI/Images/Core/scroll_bar
Any workaround?
So, I didn't find a quick way to patch it, so ended up with a workaround.
_chargeBatteriesSlider = _visualElementLoader.LoadVisualElement("Common/IntegerSlider").Q<Slider>("Slider");
Nop
not sure that's a timber api question, but how do you specify an effect in a need ? for a negative need i have plenty of examples, but for a positive one ? i assume just like "favorablewellbeing" triggers when you're >0 and "unfavorablewellbeing" triggers <0 there gotta be a positive equivalent to "Penalties".
I tried "Effect" but nopynope.
like in early game version potatoes used to buff carriying capacity or somethin
Those were reworked and removed. Now only wellness influences beavers from needs. So its indirect. No way to add bonusses directly
so we can only add debuffs ? that's a shame.
i guess i can make the debuff negative but i'm not sure beaver behavior will make sense then
Do not think it even works
What can be done is have boost per building(for workers) but thats it
It seems that the TAPI stuff like [Configurator] is not being ran on the DLLs that are dependencies to the main mod DLL. What's the recommended way to deal with it? Obviously, I can make an init method in the dep DLL and have it called from the entry point. However, I'd prefer to just tell TAP to handle the whole DLL for the possible configurators in it.
I have no idea what you mean
"EntryDll": "MyMod.dll". This DLL has a dependency to Dep.dll. I want configurators to be ran in both DLLs. Does it make sense now?
AppDomain.CurrentDomain.GetAssemblies() ?
typeof(Configurator).Assembly.GetTypes()
It can be not all the types though...
On the other had, getting all assemblies and filtering out timberborn, unity and tapi libraries will give a pretty short list of the DLLs to patch.
What about all system ones
Hmm, you're right.
I could add it to the mod.json
how many are there
or load everything in a sub file like, dependencies
or lib
In my case it's just one for now. The use case: I make a component as a separate DLL and it's re-used in scope of water extension. Yes, I can provide soucre and have it compiled in scope of the main Water xtension DLL, but it complicates the process.
One way could be a call to TAPI to tell it processing a DLL. Like ConfiguratorRepository.AddRange, but less specific.
ConfigurationRepositorySeeder.AddConfiguratorsFromAssemblyToRepository - this!
If you reuse it isnt it just more a dpenende cy mod
Indeed, it will be a dependency and the main DLL still needs to be modified. But this modification is just one liner. Changing mod.json would be a much more favorable way.
I just though. I can probably make a new mod instead, and ask water extension to depend on it.
Not too welcome to the users, but it it should work.
Most people use nod manager they would not even know
Else you get woth 2 mods 2 of the same dll and thats also quite a risk to take
They will still be opening the main mods page to pick one they need. And there, they will see my dependency that cannot be used alone. Not a blocking issues, but just unnecessary wasting of user attention.
But om gonna sleep
Tbh, the existing Mod.io UI is not too convenient even with the existing number of mods.
See ya then.
You mean, an app that runs outside of the game? Kind of CKAN in KSP?
Yes, the mod manager had also logic for that
Though it coile be improved but UI is all that needs to he done pretty much
Does TimberAPI allow the use of Bottom Bar sections within a group?
Fair 'nuf! Thank you 🙂

Quick question on custom tools, in the docs it states to create a new tool using the normal method. Is there documentation for what this method is? Or is it literally creating a tool in Unity?
Or is this a class I need to create?
It states that it cannot be made with the normal way 
When creating a Tool the original method of Timberborn does not work!
and on the next sentence Follow the step to register your tool to TimberApi ToolSystem.
But then it says Create a new Tool, this step has not changed. which is what I'm confused over
Ah, ok! So just their way of creating tools base-game?
nice, thank you!
Sorry if I keep asking stupid questions 😅
Well it's just the Tool extension, to get the tool ingame as abutton you need the TimberApi way
Gotcha, so it’s just the ‘putting the tool in the game’ thing that TAPI handles?
yes
Running into an interesting quirk with the Button Preset Factory in TAPI's UI Builder. On hover, the text remains white rather than going black the same way the base game ones do.
I noticed that if no colour is provided, then it'll default the style to white. Would this be overriding any sort of effect the hover class will be adding?
(Line 369 of ButtonPresetFactory: https://github.com/Timberborn-Modding-Central/TimberAPI/blob/f23caf659cbd2c9f0597636da78efae374477bc7/Core/TimberApi/UiBuilderSystem/PresetSystem/ButtonPresetFactory.cs#L369C10-L369C10)
Is this something I'm doing wrong or is this expected behaviour?
I cannot get out of this what is going wrong
But the UIBuilder cannot do hover effects
Fair enough, I'm not sure how to explain it, I'm giving the custom component builder a try
But yeah if you want hover effects you probably need to make some USS and UXML in unity
Yeah, I think I'll end up having to do that anyway, since I want a custom button background later down the road
Thank you! 🙂
Last time I checked out UI Builder it wasn't great, but I probably just didn't understand it well enough 

It has quite some limitations I suppose specially with actions like :selector, :hover, :selected since that doesn't exists
Yeah, I've found myself Doing some jank stuff for Flywheels (when I had even less of an idea of what I was doing) and I kept wanting some of the missing CSS type stuff
But hey, it works 
Oh no need to wait for that, that probablt never going to happen 🙂
I believe it's possible, but not a single clue how
Yeah I'm not going to wait for anything like that to change 😂
I believe I saw somewhere about some CSS transpiler to convert it to USS, but can't find it anymore
No idea, someone was making a converter from there assets to USS but well.. that went radio silence
Aww shame, well, USS it is then!
Because the hacky workaround I'm trying doesn't seem to make Unity too happy
Uuuuh, rather than changing the background image of the button (which is acting like a toggle), instead have 2 buttons and show/hide the relevant button
Is it? Well maybe it ain't such a silly idea after all then
There's no way to view the base-game USS styles is there?
Damnit, turns out that (VisualElement).style.backgroundImage does have a setter. Most of the other styles didn't
Everything in style does
, you cannot do (VisualElement).backgrounImage
I thought that there was a few I encountered that didn't, so I assumed none of them did, but now I think I might just be going insane 
because I'm trying them and they all seem to have setters 
Going insane while doing styles in C# for unity is very common
I can;t believe I actually set out to make a UI toolkit at one point... Insane behavior 😂
The uibuilder we have is already so good
And that's precisely the conclusion I've come to, I just took the long route 😂
I think there's also a certain aspect of me not understanding it, to be honest
It's quite confusing I guess, specially since I never made a guide. Because I WANTED TO REVAMP IT.... well that never happend
I feel that, though to be fair, having to go through the Github page and look at the code to see what it;s doing has been great for learning more about TAPI
The TimberApiExample has alot of examples since it has a every type as an example page
True, and that's where I spent most of my time looking, though there were a few niche things that were missing that I looked through
though none of those things have made it into this version which is working now
(I.E. I was barking up the wrong tree)
I believe there are 3 types of styles for an element, and matbe you used one that has no setters? Like ResolvedStyle
Maybe, I might also have just done a silly and tried to set (VisualElement).style
Yea that is also a no go, I think...
Yeah, I imagine I probably did something like that, and then got confused when Rider shouted at me
It does that sometime, very aggresive program. You just need to bite it in it's ears to let it know who's boss.
Gotta misconfigure it every so often 
Ah, well that'll do it!
found a strange interaction between your mod and simply floodgate triggers, when timber api and sft are both enabled and you use the priority tool for buildings, after you exit the priority tool it leaves color splotches behind under buildings and other things effect by the priority tool
not sure if there is anything to be done, just wanted to let you know, all mods still work, so there is no problem there
Are you sure it it's TimberApi related? Pretty much no mods work without TImberApi, but it does not much either as in game interactions
What if you only do TimberAPi
The leaving priority could be indeed my problem, weird no one said something about it yet
tried it with nothing but timber api, mod manager, bepin and simple floodgate, havent tried it without simple flood gate, gimme a sec
just tried it with only timber api, mod manager, and bepin and the colors are still showing up
What if you open another tab and close that one
no change
Do you close it with esc or just clicking ot it?
just tried placing something, and newly placed items dont have the splotch
because normal doesn't have an splosh
And you have the newest API version (6.0.0) ?
just tried closing the tab with escape, right clicking, and clicking back on the tab itself
yes
Then ill look into it why it's not closing anymore
i actually tried dropping a version to see if that fixed it
no change
just found something, if you select neutral and then exit the priority tab the splotches dissapear
to clarify ^, if you select any other priority tab over the items you want at that priority and then select neutral and then close the priority tab it removes all the splotches
But you don't drag the neutral over the buildings ?>
no
also i just tried clicking on the priority tab itself to close it, cause i realized i hadnt tried that for some reason, it works. so it seems to be a problem with using escape or right clicking to close the priority tab that leaves the splotches
Tooo many weird actions tbh
if manually closing works means something other method works which is the same as clickign away
Is there an example for the usage of the Shader System?
Shader system ?
IShaderApllier
And do I apply this script to the game object that has the shader?
So I assume from the example given there, I'd need to load the prefab from the asset bundle or something?
Did you make your own shader ?
I don't think this would do anything than since it is to set on all things
I thought you could just add your shader to the asset bundle and it works, if the shader works in general for the game which might be harder
you can't apply them on a material-by-material basis?
materials have the shaders on them so yes it's material by material
?
Sorry, I didn't phrase that very well
I was referring to the "ShouldApplyShader" function in the shader loader
That determens if the the method apply should run
I don't think it's even loading at all, I've put a debug log into the load method but not seeing anything in the console
Did you add it to the configurator
just containerDefinition.MultiBind<IShaderApplier>().To<PathShaderApplier>().AsSingleton(); this part tho
but than with your class
Hmm, no joy with that, but that's a step in the right direction at least!
Out of curiosity, if ShaderService is internal, and so is throwing an 'inaccessible' error, is that something to deal with?
apologies for what I imagine is a dumb question
wait
I'm an idiot
ignore me
or maybe not? urgh sorry, brain is too fried
Should "DevMode": true be working for a group that is not dev? It always shows to me.
Hmm. It seems to not work even for the root level.
What you mean
I mean my tool with DevMode=true is shown during the non-dev mode.
The shaderservice class is internal but you dont have to usr that. You use the interface
is it a building
No, it's "just" a tool .
{
"Id": "Automation.DebugPickTool",
"GroupId": "AutomationToolGroupId",
"Type": "Automation.Tools.DebugPickTool",
"Order": -1,
"Icon": "igorz.automation/ui_icons/bug-tracker",
"DevMode": true,
"NameLocKey": "IgorZ.Automation.DebugPickTool.Title",
"DescriptionLocKey": "IgorZ.Automation.DebugPickTool.Description"
}
Your own tool?
Did you set the devmode in the factory?
Tools have a property that needs to he set iic
No, thought it works "out of the box" from the specification.
No, might be able to do it maybee but not sure
https://timberapi.com/tools/ doesn't say the factory should deal with the dev mode. I was getting my knowledge from this page.
It's not a big issue, though. My mod is in WIP mode anyway. I just hoped to not reveal too much stuff to the early testers.
The example does it too though
I can take a quick look if I might be able to do it automatically
You can always use hidr
Then its never visible
It's a good idea. I will use it for the releases.
It could be possible but the best way to do it would have the Tool class extended to an ApiTool and that all Tools require the ApiTool (so all custom tools will break)
public virtual bool DevModeTool => false; I cannot set this even when it's made public
Hmm, would also not quite work for already existing Tools 
Another work around for you is just by them in like a WIP group and make that dev only
@rigid fable It is fixed in version 0.6.0.1 could you and maybe @austere tangle check if everything works correctly, made some changed with closing groups
YA, it's fixed now with TAPI 0.6.1 Not sure that I like it. Was more useful with this "bug", mainly to know the buildings site with altered builders priority 
What do you mean
I find more useful to see all time for building site the color for altered priorities , but, Important is that the bug is fixed. Can, anytime to activate the priorities group to see the priorities ...
Ah ye i suppose some people might found it useful
Maybe someone could make a mod that affs a small ui to toggle the modes
Was that kind of bugs that was , quite useful 🐸
@severe solar
@calm copper Maybe you don't need to string check things anymore for that one mod
But I send the exittingToolEvent twice so might also have broken it 🙂
I figured out it's actually easy to do on my side. I create my own super class for Tool anyway. So, it's as simple as this:
public override bool DevModeTool => ToolSpecification.DevMode;
If you have a tool you can already initialize it anyway
?
thanks for the fix, seems to be working great
I'm, not saying it's TAPI issue. I just think that those who are on this channel are the most relevant people to hear it (or prove me wrong).
It seems (I wish to be wrong) that when components are being created in runtime via the BaseInstantiator, the order of methods calls is different. In nutshell, Awake on BaseComponent gets called before InjectDependencies.
Maybe I'm just missing the point, and it was always working this way.
In my case I had to move all the stuff to the Start method.
It was always like this - awake is only for self initialization. You shouldn't call methods or properties on other components
Neither use singletons, since they are not yet injected
It's my fault then. All the way till this moment I thought the injections happens before anything.
Awake -> injection -> load -> start
"The more you learn, the more you realize how little you know."
I'm looking at Timberborn.BuilderHubSystem.BuilderJobReachabilityStatus. Here is its Awake method:
public void Awake()
{
_builderUnreachable = GetComponentFast<IBuilderUnreachable>();
_unreachableStatus = StatusToggle.CreateNormalStatus("UnreachableObject", _loc.T(UnreachableBuilderJobLocKey));
base.enabled = false;
}
The _loc member is injected from InjectDependencies. How does it work if the Awake method is get called before the injection? Or is it a difference between components created via templates and those that are created in runtime?
yeah, it is a difference between template and runtime (tho template is still runtim 😉 )
Asking just in case something can be done in TAPI side : I'm having this issue where I have two variants of the same plant (grape vine North-South and East-West orientation) that produces the same thing.
At first I had a crash when clicking on the planter's prioritize button because they had the same lockkey, which is fair enough, do I changed that.
But now I have the same issue again with the harvester, which crash when you try to prioritize one resource, because it looks it up by resource name and not by which plants make it, and find two things that respond "grape"
I don't suppose the Devs will encounter that issue anytime soon so my other solution is to just make both grape trees produce different things
No "oh that's a trivial patch" by any chance ?
hmm feels more like it should be a component so you can have 2 prefabs in one item
do player need to be able to select
or should it be like walls auto connect to other 
Well it crashes when you try to unfold the list. But ideally played should be able to prioritize "grapes" and pick from either variant indifferently
can some one help me install this mod i feel like im doing it right but i dont know
Just the same as any other mod
as in
will there be a version for U5 preview or are we waiting for release?
there's this for now #🤖mod-creators message
but thats not fully updated for u5 I think
gonna see if my mods work tomorrow
rotating sun works with that version of timber api 
Most things "work"
But all faction specifications need to be changed from "CommonBuildings" to "Buildings"
well that should be an easy change for the building modders
True
Buit knatte's extended floodgates also not work
No idea if they ever did but yea
PlaceableToolObject thing is fixed
:o nice!
with that I think my mods should work after I make the needed changes for new gamelibs
yeah screw the console
also Timber API nearly at 50k downloads 🎉
lmao
do you have a zip for that?
aight
You sire this is because of TimberApi?
Did you update to latest version.
Did you have other mods running.
With this version I cannot even create new game.
[Error : Unity Log] TypeLoadException: Could not resolve type with token 010000b0 from typeref (expected class 'Timberborn.WorldSerialization.ObjectSave' in assembly 'Timberborn.WorldSerialization, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null')
Stack trace:
TimberApi.ToolSystem.ToolService.LateLoad () (at <c9a22965d93b4016bd7e8ebb46ff668d>:0)
TimberApi.Core.SingletonSystem.SingletonSystemPatcher+<>c.<LoadSingletonsPostfix>b__5_0 (TimberApi.Common.SingletonSystem.ILateLoadableSingleton singleton) (at <7f7c42a93b3746089ad6e03614457366>:0)
TimberApi.Core.SingletonSystem.SingletonSystemPatcher.LoadSingleton[T] (System.Collections.Generic.IEnumerable`1[T] singletons, System.Action`1[T] action) (at <7f7c42a93b3746089ad6e03614457366>:0)
TimberApi.Core.SingletonSystem.SingletonSystemPatcher.LoadSingletonsPostfix (Timberborn.SingletonSystem.ISingletonRepository ____singletonRepository) (at <7f7c42a93b3746089ad6e03614457366>:0)
(wrapper dynamic-method) Timberborn.SingletonSystem.SingletonLifecycleService.DMD<Timberborn.SingletonSystem.SingletonLifecycleService::LoadSingletons>(Timberborn.SingletonSystem.SingletonLifecycleService)
(wrapper dynamic-method) Timberborn.SingletonSystem.SingletonLifecycleService.DMD<Timberborn.SingletonSystem.SingletonLifecycleService::LoadAll>(Timberborn.SingletonSystem.SingletonLifecycleService)
Timberborn.SingletonSystem.SingletonLifecycleAdapter.Start () (at <a38ce14644da437795019583808b06f8>:0)
nm, figured it crashes only with some mods installed. No problems with no mods.
However, the place of the crash is quite surprising.
im not sure but mods not working on 5.0 update
What mods do you have installed ? Or, better, drop here the latest crash log archive from Documents\Timberborn|Error Reports folder, to take a look into.
i decided to install update 4.0 but thanks for all
Anyone else having issues with in-game content mod buttons not loading? I get no errors in the BepInEx window and it correctly nests the unmodded objects but doesn't load the buttons for the modded content so I can't actually use it. The screenshot was taken with just the staircase mod and the dependencies installed (API, Mod Manager and BepInEx), assuming TimberAPI issue because it's true for any in-game content mod (also tried extended floodgates and path extention) and they all seem to be loading correcting according to BepInEx window.
thats update 5?
Yes sorry, U5 using TimberAPI 6.2
aaah, no, not TAPI problem, its specific mod problem, sortof. A name was changed in the specifications so all mods need to update that name. You can do it manually by going to all FactionSpecifications and changing the CommonBuildings array key to Buildings.
if you dont know what that means, you will need to wait for all mods to update it.
also verify that you do use correct mod version from the google sheet in #🚀mod-users
On the limit of my knowledge of coding but fixed now, thank you!
offen it will be a newer version than standard version select mod and chose a newer version
Ah so when I'd reinstalled the U5 mods I forgot to manually change the version too 🤦♂️
Just recognized the way linebreaks in lockeys used to work is broken in Update 5.
The change from BepInEx 5.4.21.2 to 5.4.22 is not the culprit, tested that. Something changed from TimberAPI 0.6.1 to 0.6.2 that could cause this? Or is this a change in the game?

Is it a modded building ?
Yes from Knattes Dam Decoration mod.
And I forced the linebreaks for better readability.
Tested some more and \u000D\u000A instead of \r\n is working in Update 5 for forcing linebreaks in lockeys. @vast otter
So I'm going to change that in my translation files.
Hmm wonder how basegame does line break🤔
Some one has asset ripped u5 loc files and can check?
This is copied from the german loc file.
Experimentelle Speicherstände werden separat abgespeichert, da es sehr wahrscheinlich ist, dass die Speicherstände nach Updates nicht mehr kompatibel sind.
In diesem experimentellen Modus <RedHighlight>sind viele Teile des Spiels nicht übersetzt und nur auf Englisch verfügbar</RedHighlight>, ganz unabhängig von deiner Spracheinstellung. Dadurch können wir neue Inhalte hinzufügen und schnelle Änderungen vornehmen, ohne auf zeitintensive Übersetzungen warten zu müssen.
Wir empfehlen dir, unserem offiziellen Discord-Server beizutreten und an den Diskussionen zu den neuen Inhalten teilzunehmen.",Welcome text that is shown to players of the experimental versions of the game.```
Thought the lockey must be in one line.
This is also the way it should be done, No idea if it suppose to support \r\n, I believe it's OS specific
I think it's although application specific. Beginning with the translations I thought the lockeys can only be oneliners. So I tested some codes for linebreaks and the \r\n worked so I used it.
This works, double quotes required.
doppelte Höhe",-```
Nice so a simple enter and "" around text 👍
I have many files to change so I could also change this in all your enEN files too, if it helps you being out of a working pc.
if you can do it and send a zip when done it would be great 🙂
are we geting a new TAPI version for todays update?
was something broken in TAPI?
As I see, nothing
TAPI has a dependency to Timberborn.Gamelibs that publicizes the game and coders use
At least not today than, new game libs also need to beupdated
yeah, what I need is the updated gamelibs
btw where does it go? because this returns 404
I'll upload new gamelibs in 2 hopefully
in 2
?
hours or days ?
whoops, gonna change that to soon, something goes wrong with the publizicing
really ?
ye, had this same thing happen with 0.5.0, but can't remember how I fixed it
Just everything from Timberborn.* and bepinex.*
Timberborn.* and Bindito.*
weird Timberborn.GameLibs does not appear on VS when I go on the https://nuget.bepinex.dev/v3/index.json source
check the "show prereleaes" checkbox
that is it
Going to try to upload now
oh you're doing it?
Going to try
well tell how it went, I have my own package ready to upload too :D
will you update only gamelibs and I set the version or the API too?
Not going to do TimberApi atm
ok
yes, I did <PackageReference Include="Timberborn.GameLibs" Version="0.5.2-r.0" />
if it doesn't break stuff, I should be able to update timber api too
there is no rush, just need to tell people that they need to set the gamelibs version
Tell people as in ?
Most modders do it on unity which has no effect
yeah
Uploaded TimberAPI 0.6.2.1 to mod.io and nuget which has gamelibs updated to v0.5.2.0
unless doing code mods with TimberAPI, there shouldn't be any difference with 0.6.2 and 0.6.2.1 tho
@stone shoal you talked about having ability to load stuff if an other mod is loaded it is possible to to a revers 2 if mod loaded do not load x
No

WHy would you want to have it reversed ?
To disable part of mod that breaks if a mod that affect it is installed. Example disable irrigation towers if water absorption is installed
Would that make sense though? person installs your mod for the irrigation tower, irrigation tower does not exist because some other random mod is enabled 
Well its better then crash was my thought 😜
besides irrigation towers being gone, is it a real example? and if so do you know why it crashed?
I thought my mod worked with any irrigator
mods could talk to each other using a MessageBus like the game has one, but probably only will work on PostLoad
Not loading the mod can have tricky output, but why not at least throw a log? E.g. if I know my mod doesn't work/crashes with another mod installed, I can put it into the package as a "negative dependency". This may help troubleshooting the issues.
"Dependencies": [
{
"UniqueId": "igorz.timbercommons",
"MinimumVersion": "0.1.0"
},
{
"UniqueId": "!water.absorbtion",
}
]
Yeah, looks awkward, but the syntax can be better.
I think that if what TAPI is gonna do is just not load mod X if mod Y is present than the best is to crash
what could be useful is a load priority for mods.
Make X and Y have different priorities so that X always loads prior to Y.
When Y loads it sees that X is present and it disables only what is incompatible with mod X, instead of the entire Y mod
That's exactly what gives "tricky output". Some logging if the condition is met is much simplier.
then the user may not see the log and not realise the mod did not load
We need interface message with a list with warnings
??
A message at the corner with a ! That show info/warning from timerapi
You mean the red box when TimberApi is not compatible with the game ?
No when for example 1 mod is disabled because its missing a dependency
Well than the mod doesn't load and gives a warning that it did not load
I guess that's what Igor said
Well they miss the warning in the log....
Be honest, they miss everything even if you make the full screen red with big text what is wrong
Then they come, My screen is red how do I fix 
So I think I will check for just a warning message
If it crashes in your case they come here show error log, and can delete the mod
For the people that actually read it don't come here and delete the mod
yeah, but not everybody has 2 monitors to see the console with the message
Well alt tab
could also work. But there won't be a option to put anything on screen in any scenario
yeah, but this is y I think letting is crash is better
Yeah same, but a warning message can't hurt. Easier to help what goes wrong
so do a beautiful log and crash
As some who try not to bug you people making all these neat things, everything you can put in the logs to help me understand what's broken or not loading or whatnot; is less I gotta bug you. If ppl don't read, you can't really help that lol. If an error isn't clear, that can be helped/fixed.
Ty all for the time you spend on the struggle bus for this API
Whelp, looks like the latest experimental update (2023-11-13 v0.5.3.0) broke timberapi ... got this error:
[Warning: HarmonyX] AccessTools.Method: Could not find method for type Timberborn.ToolSystem.ToolButton and name OnButtonClicked and parameters
[Error : TimberAPI] Patcher TimberApi.ToolButton failed.

Confirmed ^
He's working on it
@median plinth i heard you were doing things, maybe you could quickly include the following:
public PrefixNotFoundException(string prefix) : base($"Prefix '{prefix}' not found")
{
}```
The change here is the apostrophe or another way that it is clear when an empty string is the reason that it is a empty string and not just a message saying "Prefix not found". This reads like its just a statement instead of having the empty string in between.
https://github.com/TobbyTheBobby/TimberAPI/blob/7a39214b7830f27fcc173a363ac42b76e06b2f84/Core/TimberApi/AssetSystem/Exceptions/PrefixNotFoundException.cs#L7
I did things yesterday yes, dno when I'll have free time next. There's a branch in TimberAPI repo for fixes for 0.5.3, it'd be far quicker if you made the change in that branch directly :)
I believe i dont have access and i dont want TheBloodEyes being angry at me for screwing something up
(big chance)
Thank you for your repsons. Will try it myself 🙂 thanks for the work yesterday 
Hey this looks like the error of @burnt wasp back than for the mod manager
, except it doesn't use TimberAPI besides the dependencies of it.
This was when I tried to compile and run ModManager on the latest version of the game dependencies
oh right you still got the error after removing TimberApi dep ?
what? i just suggest adding thsoe 2 apostrophes to indicate what the prefix is
I don't know anymore, I don't have it open, but I replaced all dependencies with the last one and I got errors with the us prefix, there will be a screen somewhere, I'll find it
This error with prefix
probably had to do with asset not being loaded than (wrong location or name) and if you have TimberApi also installed it falls back to that
and throws an error
And then modmanager probably just try catches it and shows the message in the label
99% sure
But I didn't have TimberApi loaded
(╯°□°)╯︵ ┻━┻
Still probably asset not loaded
which is also not possible

No idea then, no matter. It worked on my PC 
Will try removing TimberApi dep when experimental get's to stable
I don't know, well, of course if I use the old dependencies it works, but in this case there was nothing in the console, so it's hard to say where the problem was
The only thing I did was to use the latest dependencies directly on the game and harmony, so you can reproduce the error
New update of TimberApi will be live in a few minutes
- Control scrolling is still semi bugged
- Code requires to be checked again after it hit stable
Yay! vanilla is so confusing 🤣 need my mods
Awesome! Thx to you! ❤️
i can't seem to get custom yield removing ressource groups (for example a lumberjack that harvests only one special tree) It used to work before though. before i resort to poking pmduda, any chance that could be a TAPI thing ?
What do you mean you can't seem to GET it ?
get it to work sorry
it gives me this error as soon as i hover on top of the icon:
but if i set the tree as a regular "cuttable" it works just fine
ie : to be cut by regular lumberjacks and not the custom one
could you try to say it in bullet points what you want to achieve my brain is mush
- make a custom tree
- in its (cuttable) yielder specification set "ressource group" to "Custom"
- make a custom lumberjack flag
- in its "yield removing building" script set "ressource group" to "Custom"
now the custom tree is set to be cut by the custom lumberjack.
or should be, it crashes because somehow the "custom" ressource group is not created or something, but it used to work
What is a reousrce group ?, what's in the original
the originals are "cuttable" for all trees and such, "Farmhouse" and "AquaticFarmhouse" for their respective crops, "Gatherable" for gatherable stuff (berries, chestnuts, coffee) and lastly "Ruin" for the scavenger but this one might be a bit special.
note that it has never been super clear to me how they are defined. i assumed they are created whenever something claims to be part of a groups (it's not defined by the yield removing script because you can have different buildings cut the same things)
and on the other hand, there is something different but with similar naming which are planter groups (forester, Farmhouse AquaticFarmhouse) for who plants what. and my understanding is that the planter group is only created by the "planter building" script but it is entirely separate from the other property. typically berries are planted by the forester but gatherable, crops can be planted by the farmhouse but haversted by the aquatic one etc.
anyway there is no issue with the planter group, it's just so that you don't get confused if you ctrl-H in the game scrips.
Tried this: ?
done a clean import with tunderkit?
- remove package\timberborn
- import Timberborn
Compared with latest plants maybe removed some script and now you add it your self to 
my thought was that some time before they moved from a component was added in prefab to be added by script if an other component was added
i didn't do a 'clean' import but i ripped the latest version, removed the troublesome folders (audio mixer controller +editor + plugin) and tossed the rest in unity
then i ran thunderkit to exctract stuff from the game until it stopped crashing
but i didn't erase existing stuff
By what you write I think the code just looks for specific string (which they do in many places) and act on that to do something specific. So this is high likely nothing to do with TimberAPI and you probably need to go look into the code. Hopefully you will be able to change it and it just misses a specification or something 
well then you can have an old script still in your files but does not exist ingame
but i looked in the newest versions of the farmhouses etc and saw no new scripts 🤔
okay, no prob ! thanks
i'll keep poking at stuff but i might need some more advanced help
for the time being i'll revert those plants to the generic groups
but was any script removed?
😦 then im not sure what is happening
@lofty lark it is somehow related to new tree cutting
It is failing on GetRemoveTreeStrategy
so there is an interfeca IRemoveYieldStrategy that need to be on prefab 
I'm on mobile so hard to check what is implementing this interface
But maybe later or tomorrow I can check
Looks like you are just missing sth
hmm yeah i just noticed that if i remove all plants from the custom group, then the custom lumberjack causes crash, so the group seems to be woking fine
my suspicion was that the missing element was linked to cuttable yielder - Cuttable group
no hurry, i'd be happy enought to have help whenever that works for you 🙂
as I said - there is a component missing that implements IRemoveYieldStrategy - but on mobile I can't check which components implements it
so compare tree prefabs
Maybe in trees there is sth? 
okay, my other custom plants work just fine though 🤔
probably they use some default implementation of that interface that is auto decorated?
But for trees must be added manually?
In which module is TreeComponent located? Forestry?
custom trees also work
yeah they have tree component
it only crashes when i change the yielder specification group from "cuttable" to "custom"
ah... now I get it
TreeRemoveYieldStrategy is for trees
But they are for Cuttables
so, when you change cuttable to custom, there is none RYS that is matching
hmm
is that difficult to do ?
or patch TRYS to work also for custom
dunno, you probably need a copy of TRYS? With one field changed
I did nothing with that system so not really aure how it works internally
any chance someone at machinistry could rework a couple of line so it works with all treecomponents no matter whether is cuttable or custom ? 🙏😇
otherwise i could ask some coding savvy people for help of course
oh sorry for the ping
nope - as that will defy the purpose of groups
i think @full acorn is not super available lately, but i'll flag him so that he can take a look when he can
wait is there also cutting strategies for cuttable- Farmhouse etc ?
to be fair having a custom cuttable group is not really vital
but the default lumberjack can store 20, which is fine for logs, but storing 20 entire sequoias... 😅
anyway, thanks for your help ! gotta go to bed soon
and by that i mean 10minutes ago
Ah, just catching up on the chat, @lofty lark let me know if I can help at all, goodnight!
[Error : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
Bindito.Core.Internal.ContainerDefinition.Install (Bindito.Core.IConfigurator configurator) (at <77aeff39aa1a4904bcb9a4557d4d140e>:0)
TimberApi.Core.BootstrapSystem.BootstrapPatcher.BootstrapperConfiguratorPatch (Bindito.Core.IContainerDefinition containerDefinition) (at <15e036bce62e4b13926bdb86cd247af2>:0)
(wrapper dynamic-method) Timberborn.Bootstrapper.BootstrapperConfigurator.DMD<Timberborn.Bootstrapper.BootstrapperConfigurator::Configure>(Timberborn.Bootstrapper.BootstrapperConfigurator,Bindito.Core.IContainerDefinition)
Bindito.Unity.ProjectConfigurator.Bindito.Core.IConfigurator.Configure (Bindito.Core.IContainerDefinition containerDefinition) (at <b6703cff75744c15a6c94fd47a3c1ca4>:0)
Bindito.Core.Internal.ConfiguratorRunner.RunConfigurators (System.Collections.Generic.IEnumerable`1[T] configurators) (at <77aeff39aa1a4904bcb9a4557d4d140e>:0)
Bindito.Core.Internal.ContainerCreator.ConfigureContainer (Bindito.Core.IContainer container, System.Collections.Generic.IEnumerable`1[T] configurators, Bindito.Core.Internal.IBinder binder, Bindito.Core.Internal.IProvisionListenerNotifier provisionListenerNotifier, Bindito.Core.Internal.IInjectionListenerNotifier injectionListenerNotifier) (at <77aeff39aa1a4904bcb9a4557d4d140e>:0)
Bindito.Core.Internal.ContainerCreator.CreateContainer (System.Collections.Generic.IEnumerable`1[T] configurators) (at <77aeff39aa1a4904bcb9a4557d4d140e>:0)
Bindito.Unity.ProjectConfigurator.Awake () (at <b6703cff75744c15a6c94fd47a3c1ca4>:0)
UnityEngine.Object:Instantiate(ProjectConfigurator)
Bindito.Unity.Internal.ProjectContainerProvider:GetProjectContainer(ProjectConfigurator)
Bindito.Unity.SceneConfigurator:CreateSceneContainer()
Bindito.Unity.SceneConfigurator:Awake()
@stone shoal , @median plinth
Can be fixed?
I don't know if it's possible to fix it on the TAPI side, I'm rather asking, but it's NPE
[Error : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
Bindito.Unity.SceneConfigurator.CreateSceneContainer () (at <b6703cff75744c15a6c94fd47a3c1ca4>:0)
Bindito.Unity.SceneConfigurator.Awake () (at <b6703cff75744c15a6c94fd47a3c1ca4>:0)
wierd error, what are you trying todo?
I need to get out the tapi version from TBMPL without loading the library into the domain. It throws NPE, so it would be enough to treat it in TAPI in
TimberApi.Core.BootstrapSystem.BootstrapPatcher.BootstrapperConfiguratorPatch
idk, sounds like you problem
in the log, you have written NPE from the TAPI source, so it can't be my problem 😉
well, i never experienced any issues with TAPI
so means something you did which makes it crash
what is NPE btw?
null pointer exception
whats that? NullReferenceException?
yep, probably configurator is null
one you are trying to add?
again, what is it you are trying todo that makes it crash?
no, it happens automatically because bepIn tries to load all the dlls and even if I load it without a domain, it calls Awake (which it shouldn't) so something falls to null

like that it works when I load it normally into the domain but this time I need it without it and this problem occurs because BepIn calls Awake on something that is not linked to other libraries
and of course I need to load the dll to find out the version, just omg situation..
What did you do to cause it
to cut it short, it loaded the tapi without game dependencies... just need to find out the version, that's all
Just check it with bepinex
I do this before loading bepinex
Decompile the DLL in runetime and read it out of the cs script
I would also need a GUID
Same answer
I can't decompile it, this option fails because I can't get the Assembly
How would you I be able to give you the version if the code may not even be loaded
There is no need to load the code for the version, I have already figured out how to solve that, I have a bigger problem with the GUID, which is only in one place and that is probably not possible without Asm
How about this: https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assemblyname.getassemblyname?view=net-8.0
no, it does something completely different than what I needed, but I already solved it, but thx
Out of curiosity, what did you need? I though, it's the assembly version.
I needed to get an Assembly instance for another plugin, but not to add it to the unity domain. The problem was that it behaves a little differently than in the case of a normal application, because here a different plugin is loaded and not the game (application) itself
Hmm. A pretty unusual usecase. Indeed, it would be tricky.
yep, that's all when patching a game that doesn't (yet) have official mod support. Nothing can be done easily
from latest patch
Wait they changed the versioning 
Cant be, they have more coders now so gonna expect more stuff to break
Ikr, and we just ask all of it to the new one 
I don't think Miami had that seriously in mind 😅

Sure is more, TAPI don't crash the game, but neither get loaded
@ebon sparrow I request a "Mechanistry devs broke modding again" stiker 😄
Well if we could drag one more dev in modding scene wouldn't be too bad I suppose, but not everyone is such a holesome workaholic
Version check is on the beginning before anything starts, so probably because of that
And, Mod Manager do not have that check ? Mod Manager is working 
Mod manager does not care about the version, like most mods don't if they would not use TimberApi
Yep, that's why mimic's mods are working ❓
¯_(ツ)_/¯
TimberApi has way more features and so more chance to break
Doubt that error will be all
U5 was 👹 for TAPI, second time it get a hard hit 😬
That will do it 😛
😄
Yeah, love it!
Now everyone can spam that sticker on a update
he doesn't use TAPI afaik
I know, and is using it's own way to check version
Application.Version still works though right? (I use this).
yes, that should be used, I don't know what Tapi uses to detect the version
my mods no use TAPI but TBMPL ^^
The games code
Why doesn't Unity use code to detect the version? 🤔 It won't break on update
It's the last thing I would need to worry about tho
Probably won't change another time 🙂
else unlucky
just that TAPI wouldn't have to break every time anything changes 🙂
I could throw away all features and it won't 
I was just thinking about finding out the version of the game
Just because it's this time because of the version won't change that it break on other stuff tho
Might even better that it broke on it, else it could have crashed on the other problem which might needed a manuall uninstall

Maybe I could add something specially for experimental that it requires the specific version else won't load
Downside it will always need to be reuploaded every update, but launchers can't crash due of it
Anyway...
TimberApi 0.6.3.1 is released, working for latest experimental version.
https://mod.io/g/timberborn/m/timberapi
- Warning: new scrolling feature of Timberborn might crash your game, unknown if this was already a problem in previous version.
- Will not be solved/checked until it hits stable.
no, I don't have any tool or none of my mods reach this panel.. i will try it with tapi only but as soon as i added tapi it disappeared
what is that, thats base game?
yes... tapi removed water tool 😭
Yea, needs to be added as tool via Tapi
yep, that's why I'm writing this here to fix it when tapi is already updated to 5.4.0 😉
I just answered your question 😉
Well, that will be fixed in the tapi 🙂
So explain one more time. I guess we don't understand each other now
Yea, needs to be added as a tool via Tapi <-- Did you mean by this that it will be fixed or?
The point is that TAPI broke the original behavior in the game so I expect them to fix it. I actually use the water tool sometimes and I really miss its absence
Yea its possible that a new tool is added
Tho its the unspoken mode, could you make a issue for it on github? Will be fixed in stable release.
Was probably already missing last update 
yep, it was already missing in the previous update, maybe since version 5, but I don't know for sure
I don't have github, so I'm writing it here for someone to look at 🙃
is timber api broken with the new update ?
crtl-scrolling thru the tools is a little bugged, but otherwise 0.6.3.1 should work
TAPI is working ... Only mods that are broken (that I was used) are Smart power and Rotating Sun 😭
ehm... what? merge bug?
0.6.3.1+25d5e6c8bea7651b095b79625414659e6b8821e2
Can you fix it? I wanted to show the TAPI version, but there is a redundant hash
how do you get it?



