#TimberAPI
1 messages ยท Page 7 of 1
Well yeah that works, but that kinda ugly ๐
but yea a "base class" (or interface) that defines public static T Default (or public static T GetDefault() may work)
maybe?
interface WithDefault<T> {
public static T Default;
};
public record BuilderPriorityToolSpec : ComponentSpec, WithDefault<BuilderPriorityToolSpec>
{
}
and then constrain the type passed to GetSpecOrDefault to implement WithDefault<T>
Test your C# code online with .NET Fiddle code editor.
Yeah just did that
the T is a bit unfortunate but already better
Then just have an extension method which will return the default prop if it extends my component otherwise throw error.
Downside, you can't do it with anything that doesn't have the abstract class
that should have failed to compile,
Foo doesn't define DefaultValue, it defines Value

oh
kek
what
Ohh
Forgot to default defaulty
Test your C# code online with .NET Fiddle code editor.
but then is Bar<T> even needed,
couldn't you just call new T() if the spec is missing?
(except for caching the singleton)
Totally, the only plus side of this is. It being static so only 1 exists instead of creating new ones when you use it./
yea
The downside, you need to have this extended version
But maybe that's a plusside as well
. So you only retrieve defaulted specs when a developer wants it to be that way
do you care about making the Default readonly?
How you mean ?
in the fiddle, I can change the value of Test with Foo.Default.Test = 2;

but it can't inherit
I think this is fine, at least for the first version
ahh public int Test {get; } = 4; fixes that
Fixes what
If you add {get; } or {get; init; } then the value is readonly
Yeah
It is
because most (all?) existing specs have {get; init; } on their fields
all
specs should not change after cached
At least, for their code 
Anyway, fixed the generated specs, I think
Still not ingame something about missing required Type for ToolGroupSpec. 
But no more complains from the SpecService
That's logged by SpecTypeCache.GetType
I wonder when SpecTypeCache.Create is called
oh, field default value in BlueprintDeserializer
yea, that's going to be called before mods are loaded
you could overwrite it in your modstarter
I don't think anything fancy needs to be done, just call Create again
Neet you don't have to do [Serialize(true, null)] anymore
Wait whut 
If you use sourceName, you need both
I expected it to be just a name difference
One of the latest exception. Probably:
[Error : Unity Log] InvalidCastException: Invalid cast from 'System.Int32' to 'Timberborn.SerializationSystem.ObjectSave'.
Stack trace:
System.Convert.DefaultToType (System.IConvertible value, System.Type targetType, System.IFormatProvider provider) (at <ed969b0e627d471da4848289f9c322df>:0)
System.Int32.System.IConvertible.ToType (System.Type type, System.IFormatProvider provider) (at <ed969b0e627d471da4848289f9c322df>:0)
System.Convert.ChangeType (System.Object value, System.Type conversionType, System.IFormatProvider provider) (at <ed969b0e627d471da4848289f9c322df>:0)
System.Convert.ChangeType (System.Object value, System.Type conversionType) (at <ed969b0e627d471da4848289f9c322df>:0)
Timberborn.SerializationSystem.PrimitiveTypeSerialization.Deserialize (System.Object value, System.Type type) (at <0aed9953773e4367a91cc8c16fd4e08d>:0)
Rethrow as ArgumentException: Exception while deserializing 0 to Timberborn.SerializationSystem.ObjectSave
Timberborn.SerializationSystem.PrimitiveTypeSerialization.Deserialize (System.Object value, System.Type type) (at <0aed9953773e4367a91cc8c16fd4e08d>:0)
Timberborn.SerializationSystem.ObjectSave.TryGet (System.String name, System.Type type, System.Object& value) (at <0aed9953773e4367a91cc8c16fd4e08d>:0)
Timberborn.SerializationSystem.ObjectSave.Get[T] (System.String name) (at <0aed9953773e4367a91cc8c16fd4e08d>:0)
Timberborn.BlueprintSystem.BasicDeserializer.DeserializeSingle (Timberborn.SerializationSystem.ObjectSave objectSave, System.Reflection.PropertyInfo serializedProperty) (at <45ba439b519648d3a2fd00386db8f8d6>:0)
Timberborn.BlueprintSystem.BasicDeserializer.GetValue (Timberborn.SerializationSystem.ObjectSave objectSave, System.Reflection.PropertyInfo serializedProperty) (at <45ba439b519648d3a2fd00386db8f8d6>:0)
Timberborn.BlueprintSystem.BasicDeserializer.Deserialize (Timberborn.SerializationSystem.ObjectSave objectSave, System.Type type) (at <45ba439b519648d3a2fd00386db8f8d6>:0)
Timberborn.BlueprintSystem.BlueprintDeserializer.DeserializeSpec (System.String specProperty, Timberborn.SerializationSystem.ObjectSave specObject) (at <45ba439b519648d3a2fd00386db8f8d6>:0)
Timberborn.BlueprintSystem.BlueprintDeserializer+<Deserialize>d__5.MoveNext () (at <45ba439b519648d3a2fd00386db8f8d6>:0)
Timberborn.BlueprintSystem.Blueprint.Create (System.Collections.Generic.IEnumerable`1[T] specs) (at <45ba439b519648d3a2fd00386db8f8d6>:0)
Timberborn.BlueprintSystem.SpecService+CachedBlueprint.get_Value () (at <45ba439b519648d3a2fd00386db8f8d6>:0)
Timberborn.BlueprintSystem.SpecService+<GetSpecs>d__9`1[T].MoveNext () (at <45ba439b519648d3a2fd00386db8f8d6>:0)
System.Linq.Enumerable.Count[TSource] (System.Collections.Generic.IEnumerable`1[T] source) (at <df4e462ab02c4b6493ccedf77f247b33>:0)
TimberApi.Tools.ToolSystem.ToolSpecService.Load () (at <bafac25fee814d9185c941259a8e075a>: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.SingletonLifecycleUnityAdapter.Start () (at <4d4c9d6b82054

Why is my immutable array like
not there
@quiet delta I think this is a bug.
[Serialize(true)]
public string[] Scenes { get; init; } = new string[] { "Game" };
It seems to become null, and not my default one. Also tried with immutableArray, same problem.
Anyway, I have all Tools running except prioritizing tools. IDK, idc for now
Error on the ToolGroupSpec. But that's probably fixed fast with the fix of this morning
sounds like nice progress
So many errors lmao
There were ~1k, so any less than that is a win
although most of those are from warning about duplicate dlls that I can't figure out and don't seem to actually be causing any issue
This ain't going to work....
You can't call T.Default on generic item even though you say it should be of that class type
Is implemented in .net 7 though...
So would need to resort in reflections and I think just creating a new one than is as fast 
you'd have to define a new abstract class with two generics,
public abstract record OptionalComponentSpec<T> : ComponentSpec where T : new()
{
public static T Default { get; } = new T();
}
public static T GetSpecOrDefault<T>(this Blueprint blueprint) where T : OptionalComponentSpec<T>, new()
{
var result = blueprint.GetSpec<T>();
if (result != null)
{
return result;
}
T.Default <-- not working
}
what about:
public abstract record OptionalComponentSpec<S, T> : ComponentSpec where T : new()
{
public static T<S> Default { get; } = new T<S>();
}
or something like that
how would that change something ?
I can't get the method/prop Default when using generics
But gotta eat, probably just going for a static dictionary, that caches the requested types. And clears it in unload.
isn't that code missing a final return?
Yeah it was just for showing what cannot be done
Cannot do non-virtual member lookup in 'T' because it is a type parameter, blegh
T.StaticProp is a .net 7 feature
and (new T()).Default doesn't seem to work either
cannot be accessed with an instance reference; qualify it with a type name instead
Well if you do new T. You already have it so it would not require a default prop anymore
yea
return (T)typeof(T).GetProperty("Default", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy).GetValue(null);
๐คฎ
Yeah defests the speed of the static. But its still same instance across which would be good
yea, and if you're going to cache the PropertyInfo, then might as well just cache the default instance
only if you know the items at construction time, (which in this case is easy)
what

Debug.LogWarning(toolGroupExtensionSpec.Layout);
Debug.LogWarning(new ToolGroupExtensionSpec().Layout);
First log is null, second gives a value
The return of the first is return new T();
I hitnk
Why am I ordering on a layout
Okay so I guess setting a default value after the getter and setter does not work.
Don't know for sure, since it's not a clean test area
I tried
I need to think this over
Blueprints have more limitations for customizability compared the old specs which breaks the bottombar
not duplicates, but it can't decide if System.Collections.Immutable should be version 8 or 9, so it prints 20k lines of warnings
and they're all from TimberApi.DebugTool.csproj
ignoring all of those, there's only 6 warnings, and 11 errors when trying to build the solution,
0.7.9.1 has everything I need though, so all good ๐
looks like we are not using user defined default values at all. But I think we should ๐ค at least I think prefab components are using these a lot
Yeah in the end it wasn't just the hasmap. That doesn't work in general ๐
Oh sweet TimberAPI is fixed
Noticed it because the people started asking about updates in my steam mods lmao
Updated ish
.
The most user required feature is not implemented ๐
you referring to the tool spec? agreed, I already tried modifying more groups to use blueprints and the new headers, no such luck getting the tools to actually move though :(
Ya exacly bottombar is not yet fixed so its base game atm
Ps take it easy @stone shoal its fine๐ i atleast has alot of work to do anyway๐
I have an issue with the UIBuilder. As you can see, the bars are offset on the GameMinMaxSlider. Can you reproduce?
currently creating it like that:
visualElementBuilder.AddComponent(UIBuilder.Create<GameMinMaxSlider>()
.Small()
.SetName("in_stock")
.SetLocKey("Ximsa.EmploymentAutomation.None")
.SetLowLimit(0)
.SetHighLimit(1)
.Build());
This is actually been an issue for some time, but I thought someone said it was not fixed 
Are you on U7 or U6
both actually ๐ but i won't be sad if it isnt fixed for u6
I might take a look in the weekend
Is it possible to add some property like tapi_deferto to the component instead and just assign it a new default component to fob off everything to?
maybe that will get round the inability to use T.Default?
or maybe it's like c++ where you gotta use friend or something prior to your callback's header?
or maybe you just gotta return null/nil/whatever to indicate to try the next function?
That problem is annoying but it is actually mostly only a problem due an earlier problem:
#1064983064020799498 message
But even if that's fixed this is an even bigger issue which is atm just a hard limitation (haven't tried with constructor so might try that)
#1064983064020799498 message
ah, the old inheritance gotcha. The bane of flexible programming
Privously I could just use my own deserializer https://github.com/Timberborn-Modding-Central/TimberAPI/blob/main/Src/TimberApi.Tools/ToolGroupSystem/ToolGroupSpecificationDeserializer.cs
For my own ToolGroupSpecification while still using the original files of ToolGroupSpecification.XXX.json
Because I could just say. Don't use the type as the name of the file you are looking for. Here is a string the the specification I want to have and give the deserializer to convert it.
Hmm, how about something like: { "TapiToolGroupSpec": { "ToolGroupSpec": { ... }, ... }? You could fob off the ToolGroupSpec to the original initially then apply the extras afterwords. By making it a subspec you prevent the spec handler from not passing you the info/object you need

No don't think so. This way you still cannot reuse the existing files of the ToolGroupSpec.
I am going to solve this problem with just generating my own TimberApiToolGroupSpec with all data I need. And then use the spec generator to generate them at runtime.
I'm assuming the reason you didn't just go with "ToolGroupSpec" : {...}, "ToolGroupExtensionSpec" {...} is because the spec handler doesn't pass on previous spec's object or something?
I am doing this now.
Problem is I need to have the extension spec in all other specs to retrieve them with GetSpec. Therefore was the .Default workaround. And it did work. but still not quite handy
So I got everything to work that way, but <#1064983064020799498 message> made it hard to continue
Well if you do it the TapiSpec: { TBSpec: {} } way you can get that default group state to pass on.. I assume
It's not about passing on. It's about reusing the existing specs
as in files
The one Timberborn has created to be a ToolGroup
Not the reuse of the code
well either way if tapi is the one launching the spec handler for the regular group then you can grab the object it passes back to reuse right?
What about on initialisation of tapi you just create a new Timberborn.ToolSystem.ToolGroupSpec object inside your TimberApiToolGroupSpec and then fob off the toolgroupspec subgroup to it before continuing to handle the rest?
๐ค
https://timberapi.com/
I added the navigation, and made the UIBuilder info what I had live so far.
It has not much, if anyone would want to add the old relevant information to the new format I would be very pleased. Unfortunatly I cannot do it soon myself in a short notice: https://github.com/Timberborn-Modding-Central/TimberAPI_Docs/tree/main/documentation old documentation
Default dark mode? chefs kiss
If you set it once I suppose it is ๐
I never touched it in this phone before so idk
But anyway, the site looks nice thanks for doing this
@quiet delta Comming back at the default values for optional props. I read this method
[OriginalAttributes(MethodAttributes.Private)]
public static object GetDefault(PropertyInfo serializedProperty)
{
string name = serializedProperty.Name;
Type propertyType = serializedProperty.PropertyType;
if (!serializedProperty.GetCustomAttribute<SerializeAttribute>().IsOptional)
throw new ArgumentException("Missing required specification field: " + name, name);
return !propertyType.IsValueType ? (object) null : Activator.CreateInstance(propertyType);
}
Maybe I am just wrong but it actually already should have given back the default but just is not yet working, or was it not yet tried to implement?
for ValueTypes only though?
@stone shoal Is v0.7.9.1 supposed to run with u7? Or is it "the partially compatible" version?
It's supposed to work with U7, but it's only partially there,
The U7 compatible bits are present, the incompatible bits are missing,
Ok, then, I'll live with my local solution for now. The only thing I needed from TAPI was dependency container.
It works and it returns the default value, but not the one that is assigned to the property in the record definition
But the c# default, so 0 for numbers etc
yea, that's what the function is being asked to do -- return the default of the properties type
if you want support for non-"type-default" values, then SerializeAttribute would need to gain a way to specify the default value you want
facinating, ILSpy and AssetRipper decompile the same method slightly differently:
private static object GetDefault(PropertyInfo serializedProperty)
{
string name = serializedProperty.Name;
Type propertyType = serializedProperty.PropertyType;
if (serializedProperty.GetCustomAttribute<SerializeAttribute>().IsOptional)
{
if (!propertyType.IsValueType)
{
return null;
}
return Activator.CreateInstance(propertyType);
}
throw new ArgumentException("Missing required specification field: " + name, name);
}
Ah yeah that kind of default.
What part do you need?
Oh found it
Dependency container should exist
I ran the game with the updated mod, and got errors. Only then, I realized they were on my side ๐
However, I saw some "test" error messages in the logs.
Like what. Could be possible
Alas, the logs are gone now. I only keep logs from the last 10 sessions (launching the game).
But I can try to replay it.
They don't seem the real errors, though.
Yeah they are logs
Foe when the scene changed in the scene manager
Which now is the context manager
For me, if anything is "red" - it's the problem ๐ It's why I was so fast to come back and asking if the mod is compatible.
My "traces" are always "yellow" (warnings).
Yeah I use error and warning to see easily where my log is when debugging
@vast otter have you ever been able to set the position of a group 
It should be right
You mean the order right then yes
Yeah
Both a tool group and a existing tool
There is like no usage of the Order... like how as well as devmode doesn't work
Not sure 100% sure what you mean?
No usage of being able to tell the order of sub groups and main groups?
like i add decoration cubes in the middle and tunnels i want at the end๐ค
As far I can usee the Order in a toolgroup is not used. But might be looking in wrong place
Its used i am able to place decoration in the middle ๐ค
Alright
something goes wrong when I generate 2 specs of the same
yeah okay that's a bug, was always there just never had to use it before.
Won't be too much problem for now
I see, it's not used from the class which is just there for information if someone wanted to know it.
Order is done by the spec directly
@vast otter and idk who else used the ToolSystem. Should be working now.
Usage info:
Want to change a ToolGroupSpec?
Use the following, it's inside ToolGroups folder, File name = TimberApiToolGroup.[name_of_group].json
{
"TimberApiToolGroupSpec": {
Id
Order
NameLocKey
Icon
FallbackGroup
Type
GroupId
Layout
Section
DevMode
Hidden
}
}
Most things are not required , if it's an existing ToolGroup. You can only use the parts you want to change like with any other spec.
!! Modifying toolgroups with the ToolGroupSpec might lead to things not working.
You should be able to make a normal ToolGroupSpec, but having 2 files with same ToolGroup isn't recommended at this point.
ToolGroupSpec
ToolGroupInformation has been removed, use the GetSpec<> to retrieve alternate information for your group information.
ToolSpec
ToolSpecificationis changed toToolSpec.BaseToolFactoryhas been removed, not more needed due blueprint mechanicIToolFactoryneeds to be used for everything now.ToolInformationhas been removed, use theGetSpec<>ontoolSpecfor retrieve alternate information for your tool.- Generated specs are located in
Tools, with following name schemeTool.[PrefabName].json - If you want to change the bottombar section (spaces in between) you need to add a
BottomBarSpecto the blueprint, with a propertySectionwhich is a number.
Spec:
{
"ToolSpec": {
Id
GroupId // Optional, null
Scenes // Optional, ["Game"]
Section // Optional, "BottomBar"
Type
Layout // optional, "Default"
Order
Icon
NameLocKey
DescriptionLocKey
Hidden// optional, false
DevMode // optional, false
}
}
Known problems
- It logs a few missing keys in dictionary (localization), don't know where they comming from atm.
ToolGroupSpecshould not be used to modify existing toolgroups.- SpecGeneration can't have multiple same specs, was already a bug since creation just wasn't done before.
If anyone is able to test it a bit out before I upload it ๐
Unluckily donโt have much spare time at the moment, but Iโll give it a go as soon as I can!
me 2 maybe @quasi igloo , @austere tangle, @lofty lark or @primal wind is interested and give it a go
With only Harmony and TimberApi in the mods folder, version 0.7.10.0 crashes for me loading in existing saves and starting a new game.
Looks like he forgot to include a blank definition for Timberborn.ToolSystem.ToolButtonService.GetToolButton[TTool]
That's the problem with the new blueprint system.
You MUST have at least 1 entry for it. Which means if you're making an API like this, you have to include a blank example for every blueprint spec.
maybe, either way, there's an empty array there.
Should not give problem if it's just TimberApi since I get in ust fine
But it's about the tutorial stuff maybe I had other faction
Creating a new save on folktails give the same error
testing ironteeth now
Weird, it doesn't crash on my existing folktails but does If I start a new one
Ironteeth works (or is it secound launch?)
Maybe it's possible to skip the tutorial nowadays in a save and it will skip that part of the code 
Removed tutorial agian.
New zip should get you in
which one of these things is it that lets me move things from 1 group to another, ToolSpec?
I'll have my bath, start my food and while I'm waiting on the food I'll finishing updating my copy of more groups since I only did roughly a 3rd of the toolspecs so I expect a crash if I don't
Loaded all 3 faction savegames (3rd being Emberpelts), and started a Folktails, no crashes.
Yes, but new buildings can be done directly without the spec
Everything is the same as before, except for the ToolInformation
what am I doing... I'm doing it all wrong.
I don't know, what are you doing ?
I'm translating my U6 version to U7... when I'm doing things differently in U7.
So I need to not do that, but make new things
Not sure if I follow
I think you only need to do what you did with other specs is, Change name, and add a wrapper around the existing json with the current spec name
It's entirely a me problem.
Since I want to do something different than I did in U6
Though, I'm going to end up with an issue where my mod moves the things, but then more groups also moves the same things. Is there a way to account for that?
@vast otter this about right for the paths2 subgroup? getting a crash while trying the tool spec and this was the 1st issue I found, "subgroup_paths2 not found"
how is the assetbundle your using setup? looks to point to assetbundle for staircase mod
Well I assume this is a result of one of your mods referencing a group it expects tapi to create with one of it's own tool specs but I saw no sign of the blueprint. I forgot which mod actually uses that group to begin with but I remember you mentioning that one of your mods just that for the time being while tapi was working on toolspec. I just copied the staircase group and edited every mention of staircase in the group to paths2
but do you have staircase active else the asset will not be found for the icon
yeah I have it, had it the moment the mod manager realised it should be updated
and yes I do have it enabled XD
no idea then and have other things to focus on
well which mod was supposed to use the group so I know where to look for it
this should be from staircase mod and its not really done for tapi as the mod is updated before
oh, I assumed you just encased everything in the assumed specname to have at least half support for it when it's implemented
but the souce #1064983064020799498 message tell you to use TimberApiToolGroupSpec for TAPI
well starting with the original toolgroups and fixing them after I finish fixing the tool specs, at least TB recognises the originals without issue
or is it that tapi is only looking at it's custom ones, not the native ones?
if so that's a pain but at least fixable
Yeah this resolved it, added it to your blueprint folder along side the original and got past the issue so it's fine to have both cases without the .optional
Original ToolGroups are convert to TimberApiToolGroups, but with the current specification generation you cannot have the same file twice. So modifications to an ToolGroup will not work and might lead to a crash if that's the one loaded earlier.
If it's a **new **ToolGroup, you can make it like a normal one if you want to. If it's a modification to a ToolGroup you should use the TimberApiToolGroup
What do you call this situation then? This is what got me past the paths2 error
Also besides a rando crash from steam side 1st time I tried, the 2nd try (no edits) worked just fine
And just for clarity
hadn't even finished fixing the tool spec files XD
still gotta try the building spec next. I'll finish with tool spec file fixes 1st then see if my bentos are being loaded
Idk what this setup should mean, the content matters for blueprint system as well
Is not fixed
darn :|
Might be hard to fix even
mega darn :|
I can't set these spec files....
because of the init;. And doesn't publicize it for some reason
๐ฎ
Then just go with "TimberApiBuildingSpec", I'll adapt
Thats not really the problem
They use the spec to set the values which I cannot change anymore
before it was a on a scriptable object with just a normal prop
Serialized field
Oh, you mean you had to replace the bottombar altogether?
Is that not what you meant?
The feature that you can change recipes etc is broken because I cannot set the new values
I'm extrapalating from the info you've given me
recipes can still be changed normally, it's just the list that's the issue
if you can just figure out how to access the RecipeListSpec component or whatever it was called (I think it was that) then should be able to edit the spec
I was just looking at the wrong BuildingSpec, looked at my own
face palm moment? I do it all the time XD
Just being tired the last 5 moths (4 years up down)
Anyway, will check it out next weekend
fair enough, as long as you have a lead now :)
Don't think it would be too hard
g2n, for now I'm happy to have my groups back :D
If I have some feedback that the Bottombar is working everything should be fixed next weekend probably
yeah just finishing off the tool spec fixes then I'll post to moregroups channel (if there's one), may end up having to stop midway to attend gospel though
welp there DOES appear to be an issue, mighta shown in previous screenshot but I didn't notice until this try when I had finished fixing the tool spec files. It seems the "GroupId" of the groups is not being honoured well. I had my tanks group out in the open while the warehouse and pile groups were in the storage group like they were supposed to be. the dynamites was likewise out in the open instead of being in the landscaping group. Not sure if it's tapi or just the way I had set the groups. I'll upload a zip of my copy of more groups now then get ready for gospel
Here you so now I gotta go :)
Why do you have the same group twice ?
One as ToolGroup and one as TimberApiToolGroup
I'm just thinking how to have maximum compatability with More Groups as possible, and the only way of doing that I can think of is basically just to define the same thing they do, again.
but that means that you end up with 2 identicle TimberApiToolGroup definitions.
The alternative is to do an IF this group exists, move it, but nothing about Timberborn is really built that way.
why not add those file to more group so if its installed it moves them 
I don't mind doing that, but I also need a default that doesn't completely destroy the paths group.
ya 
One for TB to recognise and one for tapi :) Anyways I'm about to try with the TB variants set to .optional to see if that fixes the issue
Nope, no change :|
hmm
Having looked at the previous screenshot I gave, yeah it did show the issue there too, I just didn't notice as I tunnel visioned into checking the paths group for subgroups
But sometimes it works ?
Not from my experience
An you just want to put a group in a group ?
I just want the groups to go where they're declared to go in the spec files
Works fine for me. Pictures taken with an moregroups version converted from 2.2.4.
It's great that the tools go where they're supposed to but strange that the tool groups don't go where they're supposed to despite being given the same property
weird
I'll take a look at my log
Nope, can't find the source issue. Did notice some things @vast otter should look at though, also noticed why my BotBats weren't even showing in the warehouse item lists
hmm, maybe it's an incompatibility with toolfinder? I'll try without, only installed it as a substitute for MG
nope that wasn't it, had to fix an issue with my botbats mod before I could check that but done with that now. Was just missing an icon for the botbats. The one I scaled down for it was the power icon from the bottom bar. realised after that would be confusing with the gear icon so gonna change it for the science icon XD
not that the bats showed though :|
not sure what your doing wrong but these are the files Juf0816 prepared
yeah that seems to work (was fixing more issues with my bot batteries mod, all I need now is to insert the recipe into the grease factory)
noticed an issue that has been overlooked so far, missing the priority group
it's in both of the recent screen shots, mine and juf's
Got at least one of my tools to load. Not that it is fully functional, but the parts I expected from TAPI seem to work so far.
Sounds great ๐
I was pretty sure I had somethinbg commented out but didn't see it
Guess it was the priority :)(
How is "Scenes" in the ToolSpec supposed to be used. That "Game" is default is fine for me. I just considered adding the optional ones, and I can't get Scene to work quickly.
"Scenes": ["Game"],
"Scenes": [Game],
"Scenes": "Game",
I assumed as much due to the [ ]. But an array can have a single entry...?
But what you're essentially saying is that it isn't supported yet?
Yes
And single entry still require array format
Good enough for me. The reason for asking was mainly to ensure it wasn't a bug. ๐
@quiet delta Bluerpint is now a lazy list does that mean I can just add to it at another time and should be fine 
And the IObjectSerializer hmmm will check that out in the weekend if I feel better
It always has been (but much more complicated), you just need to add your changes before first GetSpecs call, that will deserialize it
wasn't it an immutableDictionary before ?
Well at least the _cacheedBlueprints
The rest I am not quite sure of
it was something like Dictionary<Type, List<CachedBlueprint>> so we basically simplified CachedBlueprint into Lazy<Blueprint>
and also there is the IBlueprintModifierProvider interface now, which may help you with dynamic blueprint overwriting
Maybe I just completely overlooked that one than
. That would mean I could just added to it with my generator later on all along
it was changed into IValueSerializer, with some tweaks
Can check it out, although I don't change jsons much. But maybe it's another way to reuse the ToolGroup problem I have.
Ill split the UIBuilder from TimberApi for now. So that one can work standalone, and do the rest another time ๐
Thanks for the info, i'm sure I could do it myself normally. But I'm not sure if I could have updated without all the help so far!
no worries
Hello today's experimental patch crashes this
yes
In Goodfellas, the next scene they burn down the restaurant from the laughing scene

Is the UIBuilder split a long term plan, or will it be folded back into the main mod?
I'm wondering if I should bother to update the Steam Update Buttons manifest
Then it still fits, devs laughing 1 moment, tapi breaks next moment upon patching XD
Its long term
Since it probably does not require any updates besides presets. Which even if i wasnt updating it anyone could remake it
And it also does not require harmony so thats a plus
I tried to fix this last night and searched Timber APT, talked my way into the DMs of someone named ROSร who said she'd get right on it, also that I'm an idiot...got a good feeling
I have no idea what the meaning of this sentence should be 
its a joke, there is a song APT by ROSร, I'm playing the comedic role of the idiot who misspelled API
I see
@stone shoal would you be open to me making a pipeline to fetch updated DLLs for TimberAPI and hosting them on GitHub so I can install them as a package in Unity?
Then Ideally someone could add the mod as a package in Unity and then it's just always updated
Doesn't it need to become a unity mod thanb ?
Because the stuff of emka isn't a dll either ?
Yeah Mod Settigns isn't hosted as DLLs on GitHub yet, though harmony is
I was looking into how to subscribe to the mod update webhook on mod.io and then I could make an automation to fetch the files and update a github repo
@vast otter What was it you used for that discord server?
What is C#
There is aye, but I was hoping I could just YOINK the code to figure out what it's doing

Wait @severe solar your old plugin for thunderkit could that be of use?
so, how'd things go today with regard to updating?
To that I say "why can't everything be written in C?" :P
Atleast the standard is USBC PD now. Enforced by EU law.
For charging.
On portable devices, like phones.
@quiet delta Do you have an example of a enum used in a spec ?
public record BuilderPriorityToolSpec : ComponentSpec
{
[Serialize]
public Priority Priority { get; init; }
}
Seems like mine is crashing
GoodSpec has VisibleContainer
hhmm
[Serializable] this should fix it probably, but the enum is a timberborn enum so can't really change that
I'm 99% sure it is not that - we don't care about that attribute in our system
it is for Unity, so it can be used in prefabs
Ah I see
Timberborn.SerializationSystem.PrimitiveTypeSerialization.DeserializeEnum (System.Object value, System.Type type) (at <256ed191de6344a691466c98964a1715>:0)
Timberborn.SerializationSystem.PrimitiveTypeSerialization.Deserialize (System.Object value, System.Type type) (at <256ed191de6344a691466c98964a1715>:0)
Well almost done with the test can at least test it I suppose
yep, I removed Serializable from VisibleContainer, since it is not needed leftover - and everything starts just fine
yeah didn't work ๐
The new fad language that's going to fix everything wrong with C we swear
Funny
I created another spec with the same name even without knowing
BuilderPriorityToolSpec
Didn't crash with same class error as before
maybe something changed
Altough something doesnt work either way
Its fixed as far i csn do right now
All important stuff is working. In a not clean way 
Same format as alpha version?
Yes
is there such thing as clean when it comes to real code? I doubt it, while it's nice to try for but shouldn't ever make that the mark of good code
K
you both disable and update EntityLinkerSystem? ๐
ps do tell if you want access to the server thats generating posts for mod updates
No thanks ๐
fixed it
time to debug some mods and work on more groups ๐
Some people on steam say it does not work
But I cannot start the game anymore, becaues it's not downloading the mod
try unsub and sub or verify game files
It's stuck on validating
It won't download anything
Steam kinda works wonky on my pc for some reason
Just in general
๐ฎ
Hmm i have some mods that add Toolgroups for base game but they are not auto generated with timberapi
Mods installed:
Modded: true, official
- Harmony (v2.3.3)
- KnatteMaterials (v2.0.0)
- Staircase (v3.0.2)
- TimberApi (v0.7.11.0)
meaning it did not convert Base game Toolgroup Blueprint to TimberapiToolgroup
even if i can fix this as i want to support timberapi i think it can be a problem for other mods 
They need yo be in toolgroups folder i think
and here i had them in the folder Toolgroup ๐ฎ but if i created TimberApiToolGroupSpec files with the same content it works in the same folder
but have released a "hotfix"
but will do a test if renamed the folder if they work
i have v0.7.11.0 updated. timber api loaded alone will allow the game to load. simple flood gate triggers (v7.0.0) or steam update button (v0.1.2) checked off causes a crash. do we know if its timber or the mods causing the crash, or do you need logs?
Try load timberapi ui builder
Its split of to seperate mod and not all mods has updated req
do i run both timber builder and api?
Depends if mods need it
ok, i'll try
Did the "dynamic" properties feature make it into the release? I know it has been shown off a bit, I was wondering if it was available or not.
Dynamic properties?
You mean the @mod stuff?
yea
With respect to a request (#1264533154983710800 message) to not move the staircase into a group on its own.
I was wondering if there was an easy way to only move it into a group if other mods that installed things into the Staircase subgroup.
I guess the easiest would be to put the "set subgroup of stairs" to the various mods that install additional staircases (and remove it from More Groups)
Assuming that multiple mods installing the same override would be compatible.
so if more group is installed move them to its folder? 
The alternate would be to conditionally move the stairs if a mod (or mods) are installed,
initially I thought to make it conditional in More Groups (based on other mods installed),
but yea, putting it in other mods (conditional on More Groups) would probably be better.
and can confirm that it works if Toolgroup is placed inside Blueprints/Toolgroups (base game format)
The most complex way (and simplest for mod authors) would be for Timber API to "collapse" subgroups if they only have a single item.
or maybe it's an adjustable setting, because I could imagine someone asking that subgroups with 2 items should also be collapsed -- it depends on how much space you have on your screen
I don't like this, it would not make sens. And if I have to guess would also be really hard to make
Why just with 1, why are 2 allowed ?
player preferance,
Even harder to make xD, and the mod owner groups it so 
Automatic flattening doesn't seem like a good option imo
but it then do crash if there is both a:
- TimberApiToolGroupSpec
- ToolGroup
for the same ID
Yeah you should not do that :).
yea
I think 
Is that only if the value is different?
but how do i then allow them to be in the toolgroup if tapi is not installed but in the subgroup if it is
It actually should work I think, not sure why not
Ah
Your naming is wrong
??
TimberApiToolGroupSpec -> TimberApiToolGroup in the file name
i see
The normal ones are tranfered to those and how you did it. It just created 2 toolgroups
yepp that was the problem ๐
ToolGroupSpec doesn't have a GroupId field, should it even be included?
no ๐
shouldn't it be on TimberApiToolGroupSpec only?
It does nothing in that matter so 
It won't hurt
Until you think it should do something
Maybe later on I can fix some things and have the workings like before so it can be reused
kiss
meaning copy paste with just rename of prefix ๐
it'll cause warnings to be printed into the Player.log won't it?
I was also thinking that if the "automatic" conversion of ToolGroupSpec to TimberApiToolGroupSpec was hard to get working (but I think you fixed it now right?) then you could just convert them offline and include the new specs with the mod.
it would mean having to manually update them when the game introduces new specs. Mod authors would also have to provide both (but they'll need to do that anyways if they want TimberAPI to be an optional dep)
Well converting wasnt hard. But I prefered it not to be converted just like before
And @spring radish i could check in weekend maybe for that feature. It was implemented but not sure how far
yea, no rush. I have nowhere I can think of where it would be used.
except as a workaround for this "only one item in a subgroup" issue
Sorry if I sparked a headache for you all
which is easy to work around by just deleting the spec for that tool
@stone shoal Yo! Just to clarify. The specification system is no more. And so far, there is no ETA to have a working replacement.
I'm not going to ask a dumb question "when will we have the working version!!!". Just need to understand how to shift my priorities in terms of the mods updates ("Automation" is on a hard block for the TAPI tools system).
I d9nt get your question.
What does not work?
What has tapi to do with specification system?
And the tool system is already been implemented with last update
Pardon me, but it sounds like the thing I need is not working.
This isnt the latest version
Specifications have always been a Timberborn feature.
Pre update 6. TimberApi made it possible to make you load them with just files.
After update 6 its done by Timberborn itself.
Update 7 is now called blueprints.
You checked at the wrong place
Newest verion isnt stated at "other version"
Unless a newer version isnt the active version...
Yeah... Mod.io, 
My "yesterday" was 02/26. I would not say for the rest of the world.
Here, where?
California. 02/28 started 3 hours ago.
Im youe future

But somewhere in the chat here is talked how the new toolspec works
I created a whole info thingy when giving the pre release few days ago.
I saw it, but didn't have a chance to read deeply. Just checked the MOD.io to sync.
I will do tests with 7.11.
Oki
Emka or knatte can help you with blueprint stuff in general
I csn help if its specific to TimberApi blueprint otherwise i dont have the mental cpacity
All I need, is the tools customization. Does it sound like TAPI thing?
Anyway, I have ILSpy and Harmony ๐คฃ
Yeah thats tapi and the new Toolspec blueprints. Knatte uses it to create his more groups
Not sure if he already set it live
do you have any ideas for getting the building blueprint system to work? if not you could create new objects that you have control over to replace the originals, in which case I would start by making a function that takes the original and copies over all properties to a new object. You could then fob off duplication duties to that as and when you encounter a buildings blueprint
If you need to change the name of the resulting object you could silently recognise the tool blueprints for the originals as being for the new copies too. Could do a try { get("tapi_" + tool.name) } else { get(tool.name) } in tool blueprint implementation
I'm sorry to interrupt any work being done, but if all the mods I'm using are updated (TAPI, More Groups, Bob's Platforms) and the game crashes still when I load a map from last week, is it that the save will never work again due to the updates being so much different?
It's depends on what mods you were using and what's broken. Sometimes if you get the crash log and post it someone can look at it and see what happened. My crashes have been simple u6-u7 fixes or waiting on U7 updates. I haven't logged in to older builds since I know certain mods are broken so it won't load
Request:
InvalidOperationException: Sequence contains more than one matching element
at System.Linq.Enumerable.Single[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] predicate) [0x0004a] in <41d1bd92f95542f4aa33290b7e44d57e>:0
at TimberApi.Tools.ToolSystem.Tools.PlaceableObject.PlaceableObjectToolFactory.Create (TimberApi.Tools.ToolSystem.ToolSpec toolSpec, Timberborn.ToolSystem.ToolGroup toolGroup) [0x0001e] in <226f21d0a2bf409595632106f280afb2>:0
at TimberApi.Tools.ToolSystem.ToolService.Load () [0x00064] in <226f21d0a2bf409595632106f280afb2>:0
Please could PlaceableObjectToolFactory.Create catch the InvalidOperationException and add context if which PrefabName is being looked for. It would help significantly when debugging.
potentially it may be better to do in ToolService.Load
that way it doesn't need to be done in each and every factory
Another request: For ToolSpec could you make Order a float/double/decimal type. It would make it easier to insert items between existing items that 1 order different
Mostly it's the new zipline and tubeway buildings in GreedyBuilders that are annoying me. Instead of Z1, Z2, Z3, T1, T2, T3, they're showing up as Z1, T1, Z2, T2, Z3, T3.
ohhh, that wouldn't actually be very hard to fix with the way it is atm,
their Orders are 40, 41, 42 and bridges only start at 50
So Tubeways could just be moved to say 45, 46, 47
@primal wind Could you override the Order for Tubeway buildings to make them appear after all the Zipline buildings?
I guess the only issue would be what's the order for mod buildings like tiny tubeway extra ziplines
I guess that's up to theapologist316 and Bobingabout
I see the new ToolSpec doesn't have ToolInformation. What's the suggested way to pass a custom data now?
Define your own extension?
some discussion back here, I don't know if the new style ended up being used or not
It looks like yes,
see example of how PlaceableObjectToolSpec is used
Well, defining own spec is only a half of the task. The other half is loading the data from the specification file.
In IToolFactory.Create I only have the group and toll specs, and they don;t seem to have anything that would let me getting the file.
Hmm, and the loading will happen behind the scene?
I think the loading has already happened,
I think when the json file is deserialized all of it is consumed
ohhh, I see these specs are not loaded from json files,
try it anyway,
ohhh, SpecService.Load
different Specs in the same Blueprint are treated and completely separate?
and TAPI has a GeneratedSpec which works slightly differently
so maybe you can only do it via ISpecGenerator
and not via .json files
Like, having two different files: one to define a tool and another to provide data for it?
no, I don't think it matters if the Specs are in 2 blueprints, or 1, they're not loaded together
i.e. 2 blueprints each with 1 spec, or 1 blueprint with 2 specs, both result in two completely separately loaded specs.
Hmm. The group doesn't get created.
{
"TimberApiToolGroupSpec": {
"Id": "AutomationToolGroupId",
"Layout": "Blue",
"Order": 10000,
"Icon": "Sprites/IgorZ/automation-group",
"NameLocKey": "IgorZ.Automation.ToolGroup.Main.DisplayName",
"FallbackGroup": false,
}
}
What do I do wrong?
TimberApiToolGroup.Subgroup_Automation.json
The group is empty until a tool is in it try place some building for now joink a toolspec from more group๐
So, an empty group is not shown?
@vast otter with More Group, how are the 2nd group buttons work? Since the ToolGroupButton only defines List<ToolButton>? My mod wants to scan for all tools but I think I will miss them for those using MoreGroup.
It uses timberapis rewrite of bottombar to allow creation of subgroups and move items with toolspecs
(all done with jsons and timberapi)
oh so it totally "disappears" the game's ToolGroupButton?
Eventually, I managed to create a group and a tool programmatically. This is even better. For long time I was thinking about creating automation tools in runtime (you create a script, then you assign it to a tool), but never had enough courage to get into details of the tools creation.
I stopped before because I thought I needed Unity/Asset Bundle ๐ turned out I could just leave the Sprites out
How did you do this, creating a building with dame prefab name?
Snd only crashes when load instead at creation?
The SpecGenerator had one problem, which was always there but never an issue before.
And that is that you cannot generate the same file twice.
The .GetSpec. is the new feature of blueprints.
Its the same idea as like unity object where you set nultiple scripts on. Timberborn uses it for a need that can be deadly.
And now you csn use it for your custom data in a simpler way than before
Honestly, I failed to understand how it works. Can it give me a deserialized object? Like we had with the ToolSpecification in the old TAPI.
#1064983064020799498 message
I understand that you have a lot of much more important stuff to do, but eventually it would help to have it here: https://timberapi.com/timber-api/tool-and-toolgroups/tools.html ๐
Timberborn modding documentation
Blueprints are deserialized autlmaticly.
- Create a spec, look up anything that has
ComponentSpec - Create a file with a toolspec & add your custom spec in the SAME file.
- In your tool factory you can do now .GetSpec on the ToolSpec.
Thanks, I will try.
"Create a spec". Hmm. How? ๐
Like design a class in C#?
not mine, it comes from #๐mod-users message
Yes checkout how the game does it with componentspec. Its not hard at all
That might be an issue yea
Yeah, I saw this code. And I got lost at:
var genericToolSpec = toolSpec.GetSpec<GenericToolSpec>();
Looks like magic to me. How does it know what I need?!?! ๐คฃ
Although i thought you cannot have multiple same prefabs name anyway. Pretty sure would conflict
Short answer magic. Long answer look at BlueprintDeserializer. But this is all just Timberborn. Emka probably knows more about it.... Since he made it
Now, I figured out, I can add tools in runtime. Probably not the groups, but adding tools is already a big step. Dynamic tools is a feature that I need badly.
Why not the groups?
I can add groups in runtime, but only during the configure stage. I need to add stuff during the game. I bet I can use Harmony to fix it, but for now I'm fine with adding only tools ๐
Ahh, okay goodluck
Yeah, I check the code already. It's not a trivial task. To say the least.
That's fine, I didn't notice myself as I just focus on playing
I might just make a separate mod that GreedyBuilders and MoreGroups can optionally depend on to correct the tool item order. I think I would do it so the order is added onto some form of the tool group's order and/or faction order multiplied by maybe 1000 to allow room for many tools
You know what I will make that mod, I'll call it "Re-order Vanilla Tools" with the id "ReorderVanillaTools", just so @vast otter is aware of what to add as an optional dependency I'll ping him :)
What would be nice is if the tool order become something like an IP address where it would be <faction>.<group>.<mod>.<tool>
Just making sure you are aware that there is a crash when opening the map editor with TimberAPI (U7) enabled.
The only mods enabled when it happened were Harmony, TimberAPI, and KnatteMaterials. Disabling TimberAPI fixed the crash.
oof
Making the tools refactoring, I also stumbled upon the custom cursors. Now, they are specs too 
I almost believed, I can get away from the specs ๐คฃ
@stone shoal Do I understand it correctly that the tool groups at the second level and up, is the TAPI feature? Trying to add a group button to another group button... and cannot see how ๐
@stone shoal I found something strange. I implement a class like this
sealed class AutomationButtons : IBottomBarElementProvider {
}
It's bound to Bindito. On the vanilla game, this component gets executed as expected and IBottomBarElementProvider.GetElement gets called. However, with TAPI, this component never had a call. Is this an intended behavior?
Heh. I give up. I just cannot make this specs system working 
I believe so. The base game only allows single level groups.
Yeah. I did some research. I though TAPI only extends the stock tool system, but it in fact replaces it. That is, making any stuff for the base game functionality just doesn't make sense since with TAPI installed it won't work. And it's a bummer.
Now, I need to patch TAPI to make the tools in runtime 
Using Harmony to patch another mod is kind of a new level to me.
When (or if?) I get a working solution, then yes. For now, patching is the only working way.
just rebuild the code yourself?
from the update_7 branch of https://github.com/Timberborn-Modding-Central/TimberAPI
hmm, it miight not have the very latest code,
I would do it if the code base was the same (the stock). With two independent tool systems you have to choose exactly one. And it's TAPI, no doubts (given how popular this mod is).
yea, that's the link to the TAPI src
it's how I upgraded the Steam Update Buttons mod to the new UIBuilder code before it was released,
I spent hours to figure out how to patch the stock game code and got almost working solution. Then, I enabled TAPI ๐คฃ
heh
Btw, I got a nasty issue with the publicizer:
TestFactory.cs(36, 15): [CS0507] 'AutomationRuleSpec.EqualityContract': cannot change access modifiers when overriding 'public' inherited member 'ComponentSpec.EqualityContract'
I recall this issue was mentioned in this channel. Anyone knows how to fix it wihtout disabling publicizing?
where/what is TestFactory?
It's my own class. The actual error comes from this code:
public record AutomationRuleSpec : ComponentSpec {
[Serialize]
public string Condition { get; init; }
}
Due to the TAPI and stock code is publicized in my project, the inheritance works weird.
Publicizing of ComponentSpec makes the troubles.
buuut Condition is a new field?
Of course. It's my new field ๐
ohhh, because EqualityContract is something special?
Tbh, I have no idea what is this "EqualityContract".
But I guess it's something about the records in C#
The records are expected to handle the fields "magically". I'm not supposed to provuide any equality methods.
yea, the method is implemeted by the compiler,
it's a "bug" in the publizer, it shouldn't be making that particular method public
Any idea how to exclude a specific class from publicizing?
This is my project setup:
<ItemGroup>
<PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.2" PrivateAssets="all" />
<Reference Include="..\Dependencies\GameRoot\Timberborn_Data\Managed\Timberborn.*.dll" Publicize="true" />
<Reference Include="..\Dependencies\GameRoot\Timberborn_Data\Managed\Unity*.dll" Publicize="false"/>
<Reference Include="..\Dependencies\GameRoot\Timberborn_Data\Managed\Bindito.*.dll" Publicize="false"/>
<Reference Include="..\Dependencies\GameRoot\Timberborn_Data\Managed\UnityEngine.UIElementsModule.dll" Publicize="true"/>
</ItemGroup>
I wish there was a rule "exclude"
Lol. I just got it fixed.
<ItemGroup>
<PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.2" PrivateAssets="all" />
<Reference Include="..\Dependencies\GameRoot\Timberborn_Data\Managed\Timberborn.*.dll" Publicize="true" />
<Reference Include="..\Dependencies\GameRoot\Timberborn_Data\Managed\Timberborn.BlueprintSystem.dll" Publicize="false" />
<Reference Include="..\Dependencies\GameRoot\Timberborn_Data\Managed\Unity*.dll" Publicize="false"/>
<Reference Include="..\Dependencies\GameRoot\Timberborn_Data\Managed\Bindito.*.dll" Publicize="false"/>
</ItemGroup>
The order of the lines is important.
The last line overrides the previous lines setup. Not sure if this is an intended behavior, but it works.
yea, because the bug was created by theapologist316
You saved my day! 0.4.3 work just fine. 
niiice
so I publized all the dll's from the Managed folder,
then Windows Defender got all angry about the System.ServiceModel.dll
and System.Windows.Forms.dll
because they "can launch a binary"
At this point, I'm close to make my mod working with the specs, lol ๐คฃ
Or not.
Well, I still cannot get my custom data from the blueprint (used to be "specification"). The magic didn't work.
toolSpec.GetSpec<AutomationRuleSpec>()
Gives me NULL even though there is a relevant section:
"AutomationRuleSpec": {
"Condition": "loh!"
}
can you show the whole file
(off-topic, Firefly Blue Ghost is about to attempt landing on the moon, T-2minutes)
{
"ToolSpec": {
"Id": "Automation.Tmpl.Terrain.2LevelsDynamite",
"GroupId": "AutomationToolGroupId",
"Type": "MySpec",
"Order": 1,
"Icon": "Sprites/BottomBar/IgorZ.Automation/tool-dynamite-x2",
"NameLocKey": "IgorZ.Automation.Tool.tmpl.2LevelsDynamite.DisplayName",
"DescriptionLocKey": "IgorZ.Automation.Tool.tmpl.XLevelsDynamite.Description",
"AutomationRuleSpec": {
"Condition": "loh!"
}
},
"AutomationRuleSpec": {
"Condition": "loh!"
}
}
This is an experimental version. With teh section at below I get a default instance.
Not NULL, but still not what I'd like to have.
Should work
It does. My bad. The field was protected.
Now, I think (may be falsely) that I understand the new system ๐
And yes the old way of generation of tools is disabled 
Only generic tools can be implemented in both tapi and normal
@vast otter hi not sure if this is TimberAPI or More Groups thing but I have this code to grab all available buttons, it works for the vanilla but with More Groups, things go missing. is it easy to add support for More Groups?
void ScanAllButtons(Action<ToolGroupButton>? onGroupFound, Action<ToolButtonInfo>? onButtonFound)
{
foreach (var btn in toolButtons._rootButtons)
{
if (btn is ToolGroupButton grp)
{
onGroupFound?.Invoke(grp);
if (onButtonFound is null) { continue; }
ScanGroupButtons(grp, onButtonFound);
}
else if (btn is ToolButton toolBtn && onButtonFound is not null)
{
onButtonFound?.Invoke(new(null, toolBtn));
}
}
}
void ScanGroupButtons(ToolGroupButton grp, Action<ToolButtonInfo> onButtonFound)
{
foreach (var btn in grp._toolButtons)
{
onButtonFound.Invoke(new(grp, btn));
}
}
It's going to be part of TimberAPI,
toolButtons is ToolButtonService toolButtons btw
More Groups doesn't have any code
yeah in that case I need to know how I can scan all the buttons from the TimberApi interface I guess
yea and then make it conditional based on if TAPI is detected as loaded or not,
(which you can just do with Type.GetType())
@spring radish I did as you suggested and unloaded all mods and loaded just harmony and TAPI, it worked fine. Loading others in to see which causes the issue is a project for another weekend.
yep that part is easy, more of how to scan it ๐
Pretty sure it should still be working with tapi
Otherwise I have also a service which extends that for tools or button i think
@stone shoal It seems, the group button order behavior has changed. In my setup, I had order 1000 for the blue section. Assuming, I want to place my group button the last in the blue section. But now, I get this.
Check the very right image with "play" image. That's me.
but ToolGroupButton._toolButtons is List<ToolButton>. how do you change it to anything else?
which one should I be scanning instead?
Blue section hasnt anything to do with order. Its a different section.
The sections is the thing. We have three of them.
The ordering should be countined with the section, not globally.
What?
Section is not based on a min or max order
Look at the GitHub l. You need to add a BottomBarSe tionSpec
There are three sections. Blue, Green and "whatever". The position used to work within the section. Now, it's global.
I have no idea what you mean with that.
I need to add my group button to the "blue" section at the end of it. How I do it now?
Look at the GitHub
. Add a bottombarspec
To the file
BottomBarSpec
{
Section = 0,
}
So?
Ibn the blueprints, it's "Layout": "Blue"
๐ like this (but in the blueprint json)
"So" what? Do you get the idea of blue/green sections now or not?
I told you 3 times man. Have you tried it?
This
so something like:
{
"TimberApiToolGroupSpec": {
"Id": "AutomationToolGroupId",
"Layout": "Blue",
"Order": 10000,
"Icon": "Sprites/BottomBar/IgorZ.Automation/automation-group",
"NameLocKey": "IgorZ.Automation.ToolGroup.Main.DisplayName",
"FallbackGroup": false,
},
"BottomBarSpec": {
"Section": "0"
}
}
Tbh, I find it irrelevant to my question.
Let's start it from a new page. Where THIS group button will appear?
{
"TimberApiToolGroupSpec": {
"Id": "AutomationToolGroupId",
"Layout": "Blue",
"Order": 10000,
"Icon": "Sprites/BottomBar/IgorZ.Automation/automation-group",
"NameLocKey": "IgorZ.Automation.ToolGroup.Main.DisplayName",
"FallbackGroup": false,
}
}
...
Question: how do i add it in this section
Answer: you need to add this
Q: im not going to look 
At the end of the buildings area
And this is my point. Why? It should be the end of the BLUE (f**n) section. No? It used to be, at least.
It never did ehy would it be there
Layout != Position. Layout = visualization of the button
This magic worked.
I tried to say it from the beginning 
But seriously, folks, when you point to a sample of the code, can you give a bit more background on where to look specifically? C'mon.
needs some nice examples at https://timberapi.com/timber-api/tool-and-toolgroups/
I said you need to add Bottombarspec.
But i could have line highlighted it
If inwas on my pc i could probably fiven a better example
And I say thank you for this. But it was @spring radish who gave the answer ๐ You spend much time with TAPI code, but we don't. We're stupid in terms of how TAPI works. Sorry.
I understand but ive done litarly the same except #1064983064020799498 message
I jist could not make it as pretty as normar in full json format.
But next time ill only help when im on pc since this wasnt working out. Mb
Here, I accept my fault. Somehow, I missed this specific message.
Its fine
It works, after all. Thank you, folks!
What does this "Section" thing mean anyway? Is "Layout" now deprecated?
Or do we need both?
I think layout is the style of the button (i.e. what color and shape)
Just checked. Dropping of the "Layout": "Blue" has no effect. The button appeared in the blue section anyway.
Yeah both. It has not changed with this update
That a bug
If it is
My bad. It's now green ๐คฃ It's shown at the exact same location, but it's green. So, yes - we need both.
Maybe it could be renamed to Style? (or really add a new Style field, and load from both)
"Layout" is for the color (Style). BottomBarSpec is for the position. As @spring radish has correctly mentioned.
Is the latest code pushed to github? I think the last fixes for 0.7.11.0 are missing?
@stone shoal I just wonder. Is there a reason to have style and position of the group button decided separately? Blue/green/common concept has an idea. So, maybe just apply the style based on the section?
or the default style/layout could be based on the section.
(it's currently hard-coded to Green)
Everything in the tool system is made with seperation in mind. Instead of everything being entangled with the default bottombar.
- I named it
Layoutbecause it can be something completely different. Like a wonder is I believe structurial different and so it the settings box now. - You can create your own layout if you wanted to I just made the timberborn one possible by default. (eg. you can make a group look like a wonder).
- Making the style based on position makes it very bottombar specific again not flexible anymore.
Like you could make your own "SideBar" for your custom tools and still use the same system and have teh Section be SideBar instead of BottomBar. Than it won't be placed in the bottombar anymore.
yea, but you could add a DefaultLayout per-ToolGroup, so that it didn't need to be set on every item
blegh, I keep getting ToolGroups and Tools confused,
but is not building section default?
It is, and I would assume most groups would be made for buildings so that what's it defaults to as layout.
oh, I see the Tool / ToolGroup doesn't know anything about Section, because that's a BottomBar setting
Yah, the bottom bar sections are just spaces between inside the bottombar
You can also set it to -1 and and it goes before the blue stuf with a space between them
so, eg: FPP Camera could add a TopBar ๐
Yeah
And then you just retrieve the Tools for your section
although it shouldn't be instead of FPP Camera, but in another mod,
BottomBar in my code is purely UI.
I'm not sure what you mean with that
If another mod wanted to use it, then it shouldn't need to depend on FPP Camera,
like if the timelapse camera mod was ever updated (as a random example)
Well yeah, but that would be their choice
. If you want to add a new section specific to your mod you could do it.
If you want to make a specific section for many users to use, It would better be a different mod that just creates a section
yea
Folks, I guess, with the new spec system, we cannot load the data dynamically. Here is what I had in the old tool system:
"ToolInformation": {
"TemplateFamilyName": "Terrain.DynamiteDigging",
"Rules": [
{
"Condition": { "TypeId": "IgorZ.Automation.Conditions.ObjectFinishedCondition" },
"Action": { "TypeId": "IgorZ.Automation.Actions.DetonateDynamiteAction", "Repeat": 1 }
}
]
}
My own code was desterilizing the object, so JSON could have any data. Now, the data in JSON must match a spec to be loaded properly. Any way to overcome it? I can make a spec and pack the parameters into it in some form of serialization, but I like the old approach.
Just do something like ```
[
{ "Name": "Variable", "Content": ... },
...
]
That's what I named "pack". The down side of such approach is that I will need to add the translation code in every class that is being deserialized. It's like a dozen of classes as of now.
What you mean with dynamic?
Dynamic means the "spec" is not pre-made. I have many classes with different paremeters. They already implement deserialization logic via IObjectLoader. In the old system, this code worked for both the tool loading and the entities loading. Now, I need an alternative way to load data from the tool spec. and going over all class and making yet another branch to load from the tool is not exactly how I want to spend my time.
The cheapest way I see for now, is making a spec for something like this:
"Action": { "TypeId": "IgorZ.Automation.Actions.DetonateDynamiteAction", "Params": [{"Name": "Repeat", "Value": "1"}] }
Then, read it, translate it, and serialize via IObjectSaver.
You can do the same as me and convert those classes with deserializers to current spec system.
Then have a general spec which dictates what kind kf spec should in there like I have with the tool system. Only your tools get the spec that should have the additional spec.
Otherwise you can maybe just make the type object and do something with that?
This sounds promising. Any code hints?
Hmm. I will see, thanks.
Hi, I'm trying to modify the science cost of a vanilla building (district crossing), seems like TimberAPI can help with this, but I'm struggling to find any docs or examples. Can someone point me in the right direction? Thanks
You can use The Architect's Toolkit for a heavy-handed way to remove science costs.
Essentially, unlocking the buildings then saving the map as a custom map.
It seems like making a spec file to modify it is very straightforward, I just want to see an example so I can glean the file/folder structure necessary
Making spec/blueprint files is easy yes,
but the science cost of a building is not stored in a spec/blueprint file
If you use AssetRipper to extract the files, you can see what's in blueprints, and what's not
This ha not yet been updated sadly
no worries ๐
Or well not for update 7. It works just fine for update 6
Iimagine making a subgroup on the bottom bar would be fairly involved without TAPI, right?
I want to add a new subgroup for tubeway bridges on Emberpelts. Since I don't want to force TAPI to play Emberpelts just for toolbar neatness, I was just wondering if there's an ideal way to do things without it.
I'm thinking the best option us to just make an extra button on the bottom bar for bridges, but if TAPI is installed, move the tools to a new group for tubeway bridges.
Or have knatte anke put it in more groups.
Out of curiosity, tapi feels decently light from what I've seen, is there a reason to avoid it other than just keeping the literal list of dependencies short?
No, that's it, keep dependencies short.
I have nothing against tapi, but to a lot of people, for U6, just being able to install Emberpelts and nothing else was a big selling point.
I often see people avoid mods with lots of dependencies.
I'm not against using it, I just don't want to make it a requirement for my biggest mod.
People I play games with will often just pick random mods from the steam workshop, install them all with no regards for dependencies or incompatabilities, then wonder why nothing works.
I feel that
And as the groups modder, it's then up to me to go through the list and "Fix it", which usually requires dropping a few mods, and me writing a compatability patch specifically for the mod set, to make the ones we kept play nice together.
Seriously, our barotrauma mod pack last year had 3 mods in it that I wrote just to make mods in the pack play nice together.
But that's like, thr 2 extremes.
- Installs only the mod they want without dependencies.
- Installs lots of mods that aren't meant to work together.
The latest pack, he literally added every monster overhaul from the workshop. The most I could get to work together was 2.
Does emberpelt bit have like 10 side mods 
Like a 3rd layer? Or just a bew group where all the current groups are?
Like a 3rd layer
Only 3. 2 that modify breeding, plus ladder because that's polite to tobbert that it required his ladder. There'll also be the choo choo patch.
Timberborn does not support a 3rd layer by itself in any war or form.
Otherwise i would not have to make it ๐
Yeah, then I'll add a new button for bridges to the bottom bar, and include toolspec to move them if TAPI is installed.
Looks like I get a crash in the map editor with the most recent version of TimberAPI
I disabled a few mods that use TAPI and it crashes still. then I disabled TAPI and the crash went away
Yeah others have said that as well
Haven't checked it yet
I guess because there is nothing for a spec 
TAPI v0.7.11.0 (with game 0.7.1.1) doesn't seem to draw the toolbar button for wonders correctly.
It's also missing the game version on the settings button
Also if you click the setting button, and then dismiss the menu with Esc, then mouse input is ignored going forwards.
without TAPI on top, with TAPI on bottom
Oh thatโs what causes that? I was wondering why my game kept breaking
actually it's only if you press Esc twice, the first time it seems to do nothing.
so you get a chance to dismiss the dialog by clicking resume, and avoid it breaking
More likely that it's expecting a bottom bar but because tapi replaces it it gets null where it shouldn't
Yeah this is a long time bug. If you click on a group it should just work normally again
Well it's expecting the map editor groups and tools but as far as I know tapi only replaces the in game ones and forgets the map editor ones. The editor would be looking for those tools and maybe the groups and crashing because it doesn't find them
I tried clicking everywhere, nothing seemed to restore it. I had to exit out using Esc and then exit to menu, etc.
probably something about how it opens the dialog, because the cursor tool becomes unselected (which the base game doesn't do)
for the version on the settings button, maybe use a distinctive format (eg: v0.7.1.1), so that it's differentiable between no-mods (0.7.1.1) and modded-but-no-TAPI (-0.7.1.1-).
(I considered suggesting ~0.7.1.1~, but I don't think it's distinctive enough)
Im not sure why tapi would require to change that behavior 
if we want to know if tapi is used we look at logs anyway ๐
you do know that tapi does not toutch mapeditors bottom bar right?
or atleast should not as its done in a different way than ingame last i heard
Do you have an exact way how you can trigger it ?
It's happened to me when I click this button: But I'm not sure if I can make it happen frequently
So it's not always ?
Yeah, I just checked. I clicked this, then hit Esc twice and now the game is ignoring all mouse and keyboard inputs other than Escape
So you can't click on a group?
Nope
Why hit esc twice
. Doesn't 1 esc already cloase the dialog ?
Nope
When it's frozen like this, I can hit esc to get the menu back up and that's the only thing I can then click on
I seee
Okay that's maybe new 
It doesn't even close
Before it just kept the group open and had to click on another
Huh
Let me try something
If I open the main menu with Esc instead of clicking the button, I can hit esc again and nothing goes wrong.
If I open it with the settings button, then click resume with the mouse then same deal. It's fine.
It's only if I close the menu with esc (twice) after I open it with that button
Hmm, now the water is invisible ๐ what is happening
Oh got it back now. I clicked something to build and esc'd out of the build tool and it's back now
It's a very specific bug though
I thought it was shared? Hmm, maybe the problem is that it doesn't touch it? Maybe the existance of the tapi group spec is causing it issues?
If it's possible for you to make an issue for it on github I can check it out some time
Of course ๐
this the repo: https://github.com/Timberborn-Modding-Central/TimberAPI ?
yea
Thansk
think its more a bug that some script expect there to exist a specification and there is none but without testing with just tapi and its dep and uploading a log its hard to do anything
Something I saw in the #๐mod-users channel made me think of something that should be added to the tool & tool group blueprints since tapi is already replacing the bottom bar. "TreeId", would reference the id of both tools and tool groups alike so that "tech tree" style mods can be made. As for the UI, dunno yet, can leave that to the wayside until you're happy with the underlying implementation
Why? Why does it have to have a combined key. Snd what has it to do with TimberApi 
I cannot find a question in this paragraph. Just a add this for fun and giggles
if its just hide until unlocked tree it could be made other ways 2 with code and its own blueprint.
and just set them to devmode if not unlocked tree then groups not researched would be hidden.
ps. With the new blueprint system anyone can add any new spec to any blueprint. Even within my own system I have different specs for different information
combined id is so that the groups themselves can hide their decedents still. the reason I don't suggest a different mod for this is because of how many depend on tapi and the need to keep more groups around for stuff that's not falling into the tech tree
You have the information of both. Why would you want to add a combined one its only more work for a modder.
And its not really something for TimberApi. The mod that adds a tech tree csn use the current system to make something like that
And a mod that creates a tech tree doesnt even need to do it that way. 
No the mod that adds a tech can't use the current system. This is because they can't say Tool.GearShop... depends on Tool.Lumbermill... for example. There's only the option of saying X tool depends on Y group. The TreeId is for resolving that without breaking the existing system, meaning tool X that defines Y TreeId depends on tool/group Y
its like you describing the functionality for a completely very specific mod.
The mod that wants that can add it to the tool blueprint if thats the way they want to do it. Or a complete other way
Like a ToolTreeSpec having like the dependend spec id. Their costs. Making time or something
But it has nothing to do with TimberApi or any other mod in that matter. The Tool tree mod you want can add it.
And sinply use a tool id to identify a tool it wants to unlock.
I don't see a reason it has to be a separate mod, I'd rather you find time when you're in the mood to experiment with different ways to gel the 2 systems together and then release the result. I'm not hung up on it being in the here and now, just it being a future goal at some point to expand the tooling system to support tech trees
also the TreeId was just an example name, you can name it whatever you want if something better comes to mind
There is no point in adding support for 1 specific mod. Which is literly the job of that said mod
And the tool system can just be used for that specific mod
The only thing i hear you say is. I want s tree tool mod but dont want to make it.
It's not that I want it but others do, I was just saying that if it's made then I'd rather it be a part of tapi so I can still use building specs etc when they get implemented since I'm sure a tree mod would cause problems with that if it was done separatly
It can cause problems yes. If they dont want to use TimberApi as a dependency. But an specific implementation isnt going to fix anyone not wanting to add TimberApi as a dependency.
But im sorry to explain it. I should have said
way sooner and because I already knew it would be pointless to try and explain. My bad.
but for those who don't mind tapi as a dependency I'm sure they'd appreciate being able to use both tech trees and everything else tapi has to offer
should be easier to implement too since you can just disable buttons for the tech tree effect in whatever UI you make for that side of things
Im not going to implement a tech tree mode. Thats not an feature of an API 
not as difficult as say the building spec modifying game objects
@vast otter you understand what im saying right?
Anyone csn easily disabled buttons with the tool system of TimberApi
but it's not so easy to replace the UI right?
bottombar could switch to a panel for selections? I dunno, I was only looking for it to be an optional feature
And if you want to replace the ui. Yes its also simply done. Since the bottombar is nothing more of ordered buttons which are generated by TimberApi.
Blueprints dont even have optionals anymore 
I'll take your word for it, and I assume anyone watching this convo will too
So like I try to say. Id have to make litarly a tech tree mod for well you. To be used
While thats just a single use mod imo
I thought the tapi groups/tools were implemented with .optional as an option?
Thats not a tapi thing
Or well not anymore
And i mean a field inside a spec needs to be specified with blueprints now.
oh, you mean that's just an automatic addon from TB side of things?
Yes its since they added mod support
ya and even as i said, any tech tree mod can trigger change of devmode state of a tool and that will in reality hide it or they may even patch tapi to add any gui info they want. and as you said nothing tapi should do.
I'm still not convinced but whatever, I don't think I'm able to convince you either so we'll just agree to disagree
Try to make the mod and you will find out
I patch the Enabled property for Tool Finder. It makes the tool disappear correctly.
Specifically ToolButton.ToolEnabled
I Was looking at this it happens when no tools are installed. I installed the CuttingTool and it stopped crashing. Disabling the CuttingTool causes the crash to come back.
I'm not used to C# so this is a guess, could it be in the following code that toolSpec is set to null:
public void Load()
{
_toolSpecifications = specService.GetSpecs<ToolSpec>()
.Where(toolSpec => toolSpec.Scenes == null ? ContextManager.CurrentContext == "Game" : toolSpec.Scenes.Contains(ContextManager.CurrentContext))
.ToImmutableDictionary(specification => specification.Id.ToLower());
}
Are you talking about this mod?
https://mod.io/g/timberborn/m/cutter-tool
Because if I remember correctly, that mod enabled in u6 would cause my game to crash if I went into the map editor and if it was disabled but TAPI wasn't, the map editor worked fine
So if that's the mod you're referring to, lol?
I seem to remember something about GetSpecs won't return an empty list and will trigger a crash instead,
0.1.6: updated dependency to TimberApi 0.7.8.0, this resolves the game crashing when using the map editor
I ๐ฏ% missed this patch note so thanks mod dev for fixing that
I guess next time I restart my game I'll re-enable it lol
I just rememberd, it crashed before the CutterTool was installed. I actually installed it to test the crash
same thing happens with the forest tool. want me to create an issue on github?
I feel like the answer to that is typically always yes, make a ticket at least for tracking
but I'm not a dev on this mod so 
Correct.
I got around that with most of mine adding a dummy file.
They're as blank as possible
All the optionals missing, all strings and arrays empty.
I'm reminded (while watching someone's Youtube video), that TimerAPI doesn't show the game version ๐ฆ
ahh, that's because ShowOptionsButton isn't a Tool, but just a IBottomBarElementProvider
It is a tool. But didnt make a ui facotry for it yet
1 april i get my MRA for sleep apnea. Hopefully I get better soon after that
Good luck, hope you feel better
My wife used a CPAP for a while, now uses a MRA. Makes the world of difference.
MRA did nothing for me:( I can barely sleep without my APAP'
Yeah that would be the second option to do. MRA would be neeter if it helps enough
Lately it feels it get's worse and the test felt not 100% accurate to me. Because I only slept for like 3.5H while it said it required 6H at least
Only had 7 stops an hour though 
But how much does the APAP improve your life ๐?
I've been using it nightly for almost 10 years and I can barely sleep without it. So it's hard to remember what it was like before but if I try to sleep without it I'm constantly waking up and I'll have a sore throat in the morning from snoring too much. Plus my wife will sleep in the other room if I don't have it, so that's a big improvement to have her sleep with me
Hm yeah that's a long time
I don't wake up personally, at least not that I know it's from that. I do get awake like once or twice a night most nights.
But I just have an extreme headache, and too tired to do really anything anymore.
You might not wake up, but you're not really asleep either. That would explain the tiredness.
I have all my hope on this, because my doctor doesn't care at all an this is my only hope ๐
Funny thing is, I got a sleeping test not even by the doctor but because of jaw surgeon 
took me decades to get a diagnosis for the pain I get only while trying to sleep...decades...tis arthritis. I hope you have something treatable.
Dang that must have sucked. Lucky you were able to find something at the end.
I feel like problems caused by bad sleep is easily thrown under the rug with like oh its just autism, or inside your head.
Every little thing grows sleep deprivation and insomnia practically exponentially. Sometimes it can be a single thing, but, like a lot of things, is probably a combination of factors (to my understanding).
Snap! The latest update broke TAPI again 
It has been updated for version 0.7.2.0
@stone shoal
Only harmony and timberapi are enabled. Got this error on latest build.
Have you tried updating the mod? Which version do you have ?
Checking now
I thought that i had enabled auto update on the mod. It says on the workshop you updated it like two ish hours ago or something so i have that version?
one second i'll get it
Steam doesn't do updating when you want really well
Download the steam update mod ๐
Modded: true, official
- Harmony (v2.3.3)
- TimberApi (v0.7.11.0)
That's the old version




