#TimberAPI

1 messages ยท Page 2 of 1

lofty lark
#

it's twice the same icon, the conflict waht between my house waterpump, and the normal one. but mine used the normal icon so kaboom

#

i just made a copy

#

and that works

#

now i'm trying to see if the waterpumping animation can be saved

vast otter
#

so add a sufix LM_ ๐Ÿ˜›

lofty lark
#

when i need new names i just give my keyboard a spanking ๐Ÿ™‚

north hatch
#

you could append the modid, wouldn't solve the issue for having multiple of the same name on the same mod but would solve it for different mods at least

north hatch
#

well then all you can do is cope PepeHands

stone shoal
#

Random gen YA_Yuri_Boba_Sip

#

tbh, that would work since it's not ment to be used in the specifications for choosing another building image

#

You can just use the full path for that

vast otter
#

๐Ÿ™‚ Hidden worked

#

even if its then always hidden ThinkingIT

stone shoal
#

can you try lower case

#

and "Type": "PlaceableObjectTool" isn't required since it's already that

vast otter
stone shoal
#

ok ?

vast otter
#

next info about Type ๐Ÿ˜›

stone shoal
#

Defines what tool will be created, check out TimberApi Tools to find the identifiers or check out the mod creator

vast otter
#

was needed before with the first alpha ๐Ÿ˜›

stone shoal
#

also not thonkeyes, I think

vast otter
#

who know will try remove it later

#

nope this did not work ๐Ÿ˜ฆ

"Devmode":true
"devmode": true
"DevMode": true
stone shoal
#

I mean the file name ๐Ÿ™‚

#

mb

#

Not sure if properties are capital sensetive, I do believe so

vast otter
#

hmm well if Hidden works then i dont see a reason why it should be the file name ThinkingIT

stone shoal
#

hmm tryu

#

Believe I found a bug in the generator tho

#

but should not matter for the manual setting it

vast otter
#

so try "DevModeTool":true?

stone shoal
#

Oh

#

whoops

#

objectLoader.GetValueOrDefault(new PropertyKey<bool>("DevModeTool"), false),

#

Didn't change it

#

I believe DevMode is better tho

#

So it will become dev mode

vast otter
#

will keep it hidden for now

stone shoal
#

isn't hidden in your case even the better choice ?

#

why would you want it enabled in dev mode ThinkingIT

vast otter
#

true, and if they want it they can remove the Spec

stone shoal
#

okay so you cannot fix the fallbackgroup error

#

It's live again

vast otter
stone shoal
#

@vast otter mentOutOfRangeException: Property not found: 'FallbackGroup'

#

ye nvm im dum

#

I removed 1 FallbackGroup too much goddang

stone shoal
#

@vast otter 3rd time a charm, should work

severe solar
#
[Error  : Unity Log] ArgumentException: An item with the same key has already been added. Key: TrackIntersectionTIcon-v6
Stack trace:
System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <27586baf39bf4babbfd8a2caabe8e228>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) (at <27586baf39bf4babbfd8a2caabe8e228>:0)
TimberApi.ToolSystem.ToolIconService.AddIcon (UnityEngine.Sprite sprite) (at <4cae64c9bbf24b2ca603f90bbb316330>:0)
TimberApi.ToolSystem.Tools.PlaceableObject.PlaceableObjectToolGenerator+<Generate>d__2.MoveNext () (at <4cae64c9bbf24b2ca603f90bbb316330>:0)
System.Linq.Lookup`2[TKey,TElement].Create (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] keySelector, System.Collections.Generic.IEqualityComparer`1[T] comparer) (at <40b481cb584843bbbf4c840095ac6811>:0)
System.Linq.GroupedEnumerable`2[TSource,TKey].GetEnumerator () (at <40b481cb584843bbbf4c840095ac6811>:0)
TimberApi.SpecificationSystem.SpecificationRepository.AddRange (System.Collections.Generic.IEnumerable`1[T] specifications) (at <4cae64c9bbf24b2ca603f90bbb316330>:0)
TimberApi.SpecificationSystem.ObjectSpecificationGenerator.Load () (at <4cae64c9bbf24b2ca603f90bbb316330>: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 <ba22fff6ef524e90a1e90e690a52e955>:0) (at <778bc0c07d524335aa2b9ad24f3a2144>:0)```?
#

@vast otter did you get this? Sorry to bother you the whole time SadIT

#

just ignore me otherwise

vast otter
#

Have not tested latest version i am still on 0.5.5.1

severe solar
#

Same

#

I have no clue whats the problem here

#

I downloaded all your updated mods

#

but i dont see anything different from you and what im doing

vast otter
#

Hmm then im not sure why, have had problem with icon having the same name as base game item but that had a different error

#

Eq not file name but name of icon

severe solar
#

I feel like its trying to load both IronTeeth and Folktails

#

no clue why it would be doing that though

#

Oke, taking a break, getting really frustrated

vast otter
#

think i know what it is its just as i said 2 icons have the same name in the icon (not file name)
Note that in this example the file name hase V2 in it but the name ingame/in assetbundle does not
so it will crash with that error you could try 0.5.5.3 and see if it works right away that is what .2+ is trying to fix

#

send me a message later if your still stuck and we can look at it ๐Ÿ™‚

severe solar
vast otter
#

No its old info in the meta file what the icon is called that is the problem๐Ÿ˜œ

severe solar
#

Latest seems to work

stone shoal
#

So everything is ok now ?

severe solar
#

for me, yea

#

except for when im crying that CategoryButton is useless ๐Ÿ˜ข

stone shoal
#

You can reform it into a left screen side bar ๐Ÿ™‚

#

or like a recent used section

#

or maybe somehow make quick open categories

severe solar
#

cannot wait till i need to create a special tool for pipette

#

then i will prbably need help again

stone shoal
#

๐Ÿ“ƒ Docs KEKW

severe solar
#

who reads those?

stone shoal
#

You ThinkingIT

severe solar
#

๐Ÿค“ ?

stone shoal
vast otter
vast otter
#

Have set order for ladder in my staircase mod but it does not move it ๐Ÿค” will send config used later

stone shoal
#

objectLoader.Get(new PropertyKey<int>("Order")),

#

Seems to be used somewhat

#

idk ThinkingIT, well see if you sent the rest

vast otter
stone shoal
#

I hope you are just testing it

#

Because order and groupId should just be configured in the placeableObject monobehaviour

#

But yes this seems right, maybe try it on another mod

#

Doubt but maybe you cannot change your own ThinkingIT

vast otter
#

its not myown its tobberts (other mod that i have as dep)
and i do can change where it is just not what order it has ThinkingIT

stone shoal
#

And know I do a Order * 10

#

for each building

vast otter
#

hmm but is there a max order that im hitting maybe ThinkingIT

stone shoal
#

dont think so

stone shoal
#

zippi ?

vast otter
#

have tried now without "Type" and it works ๐Ÿ‘

stone shoal
#

Maybe a typo in the type?

#

but then it should give an error

vast otter
#

No change in how "order" work

stone shoal
#

Oh

#

can you give zip

vast otter
stone shoal
austere tangle
#

Download version 1.4.3 from ModIO !

stone shoal
#

@vast otter [Error : Unity Log] StaircaseLeft: 20200

#

staircaseleft is set on order 20200

#

but even than I cannot get it to work thonkeyes

vast otter
#

๐Ÿค”๐Ÿ˜ณi see so order in unity is not 10x only specs

stone shoal
#

I should make it +10 though

#

my math brain was off

vast otter
#

Hmm +10 i think will be even more bad. Not sure how to do it in a good way

stone shoal
#

I just wanted to give a 10 spacing between buildings

#

for groups

#

idk why it does weird things

#

reee

#

ah no okay yeah * 10 is better

#

but also confusing

#

WoodenStairs.Folktails: 2.010.000

#

sheesh

vast otter
#

Only 10x if base game object? Not mod?
Basegame WoodenStairs.Folktails is 201 becomes 2010
Mod setting StaircaseLeft to 2011
I expect it to be placed right after woodenstairs and befor anything at 202 in basegame
I do understand and like the use case to increase the value for base game tho

#

Cut how to know that its a modded buildingThinkingIT

stone shoal
#

It is specially done for modded buildings

#

not for the game

#

The game uses spacings between order (at least for the buildings not dev stuff or map stuff always)

#

But if you made your own group why would you set the orders to something like 2000

vast otter
#

I did not move the woodenstaircase pos just where it is and you said you did 10x to numbers so basegame it is 201 and i want it after so i set it to 2020ThinkingIT

Have to try 202 and see how it behave

#

But if ladder is then placed in the back thats not great because then it does not help for placing mod buildings between base game items just toolgroups

stone shoal
#

What if someone wants to place a group between them

#

And for replacing them with jsons it also helps

#

But if the base game is 201 I find it very weird why it ends up being WoodenStairs.Folktails: 2010000

#

Which would be order 201.000 and that sounds like an odd number for Timberborn to fill in thonkeyes

austere tangle
#

In 0.5.5.3, only specifications like BonusTypeSpecification, WellbeingTierSpecification, NeedSpecification and RecipeSpecification works ! BuildingSpecification, don't ! Something is changed in the mod that affect how it works ?

vast otter
#

Note also the shader fix for dirt has stopped working on U4 ๐Ÿ˜ฎ

austere tangle
#

Well, if dev's didn't broke anything in the latest update, looks like TimberAPI managed ๐Ÿ˜„

stone shoal
austere tangle
#

Cannot add a recipe to a building. No problem to modify a recipe ....

stone shoal
#

I blieve that was never possible

ebon sparrow
#

but now it is a bug :P

lofty lark
#

I think I would need the building specifications to work for some mod compatibility. I made some custom resources in my mod and it would be nice if I could make building from other mods use them ๐Ÿ˜Š

Typically I'm likely going to add a "scaffolding" manufactured resource for platform and all sorts of things, but I might want to edit the ladder cost to need some.

north hatch
stone shoal
#

But it cabnot make a generator or making it bake bread from a ladder

severe solar
#

Hey, a new idea

#

btw, did you add that specification service?

#

or did i have to do that myself?

#

i forgot

stone shoal
#

Both incorrect

severe solar
stone shoal
#

You could implementat it yourself if it takes to long bit you had other problems and league ThinkingIT and me being sick

severe solar
#

trueeee xD

#

and school

stone shoal
#

Bit it was internal so you cant ThinkingIT

severe solar
#

yea, but i wasnt sure who should do what

stone shoal
#

You making a pr or me fixing it

severe solar
stone shoal
median plinth
stone shoal
median plinth
#

yup that would be possible if someone was willing to add logic that adds the required components to buildings if trying to add recipes to it

#

but I won't have that time sadly

severe solar
#

I was thinking more about indexing what components are on a gameobject and just make spec that adds or removes them

#

based on the decration system ofcrouse

median plinth
#

good idea, now make it and do a PR for TimberAPI HappyF

stone shoal
severe solar
#

Then he says, no not gonna add that OMEGALUL

#

are you gonna add my Dynamic specifications?

#

hype ?

stone shoal
#

Yes if you can add it cleanly instead mvp and maintain it

severe solar
#

there is nothing to maintain, thats why its called dynamic

#

Dynamic

stone shoal
#

Oh ye it will never break

#

Stupid of me

severe solar
#

if its in TimberAPI, ofcourse not

#

TAPI is always correct

austere tangle
median plinth
#

Did it work before?

austere tangle
#

Dirt mod, or Coffee time mod .... Sure it works !

stone shoal
#

You cannot add recipes to a building that does not have any recipes to begin with

austere tangle
stone shoal
austere tangle
stone shoal
austere tangle
stone shoal
#

strange

#

It is still applied at the ILoadableSingleton and it sees the DirtMine Recipe, but it won't shown in the dropdown as if it's earlier initialized

austere tangle
#

Strange is that is no errors or warnings in game log, looks like is ignored.

stone shoal
#

It is initialized in the IDedicatedDecoratorInitializer

austere tangle
stone shoal
#

I made that a long time ago

austere tangle
#

Until now, was working, based only on specifications ...

stone shoal
#

Let's see if older timberapi works else the game changed something this patch

#

I am very confused

#

How do they add the icon tho thonkeyes

#

Is that something new in localization ?

#

Beaver doesn't have a MetalStaircaseNeed found in save, ignoring it. ThinkingIT

#

What did I break RemiCry

austere tangle
#

You did not break anything, staircase mod is missing

stone shoal
#

For that okay, but I broke something that the dirt recipe won't work anymore

austere tangle
#

or coffee recipe for Coffee Time ๐Ÿ˜„

stone shoal
#

But it just doesn't care

austere tangle
#

Hmm, with game latest update, not working even with version 0.5.4.2 of TimberAPI... pmduda strikes again ? ๐Ÿ˜ฎ

stone shoal
#

More like we just were lucky with th eloading order before or something

#

changed something so it would work for modded buildings and now its ded

#

Okay this is pretty bad ๐Ÿ™‚

#

I cannot fix this any time soon at least since i'm feeling too sick to really investegate

#

Not sure if it's a problem with the small change I did, or another not specificly related change

austere tangle
#

guess is the second, AssetRipper is RIP for the latest version, too ๐Ÿ˜„

stone shoal
#

again ?

#

it was fixed before

austere tangle
stone shoal
#

but didn't give any problems right ?

austere tangle
#

I've started exporting. Wait to finish, to see what is it

vast otter
#

what version of asset ripper are you trying alpha version or 0.3.10 or newer?

austere tangle
#

0.3.1, seems to be OK, still

vast otter
#

well it has problems if you want to open in unity

austere tangle
#

But, for codeless , it's enough

crude shuttle
stone shoal
crude shuttle
#

Oof, well I'd be okay probably on the science sideSingerFTAHHH

stone shoal
#

Tobbert trying to add 1 single tool

#

instantly breaks the feature at core level

severe solar
#
[Error  : Unity Log] KeyNotFoundException: The given ToolId (recoveredgoodstack) cannot be found.
Stack trace:
TimberApi.ToolSystem.ToolService.GetTool (System.String id) (at <24bfd2b63dc048179e128b15aa9b2e38>:0)
PipetteTool.PipetteTool.OnSelectableObjectSelected (Timberborn.BaseComponentSystem.BaseComponent hitObject) (at C:/Users/jordy/SynologyDrive/Unity Projecten/TimberbornModsUnity Update 4/Assets/PipetteTool/Scripts/PipetteTool.cs:137)
PipetteTool.SelectionManagerPatch.Postfix (Timberborn.SelectionSystem.SelectableObject target) (at C:/Users/jordy/SynologyDrive/Unity Projecten/TimberbornModsUnity Update 4/Assets/PipetteTool/Scripts/Plugin.cs:90)
(wrapper dynamic-method) Timberborn.SelectionSystem.EntitySelectionService.DMD<Timberborn.SelectionSystem.EntitySelectionService::SelectSelectable>(Timberborn.SelectionSystem.EntitySelectionService,Timberborn.SelectionSystem.SelectableObject)
Timberborn.SelectionSystem.EntitySelectionService.Select (Timberborn.BaseComponentSystem.BaseComponent target) (at <80beb876bbd844b89421a0615bd517d1>:0)
Timberborn.CursorToolSystem.CursorTool.ProcessSelectObject () (at <971a99570b2440e0b093796d887b91f7>:0)
Timberborn.CursorToolSystem.CursorTool.ProcessInput () (at <971a99570b2440e0b093796d887b91f7>:0)
Timberborn.InputSystem.InputService.CallInputProcessors () (at <3deba2729fdf4909903ff6b90269e488>:0)
Timberborn.InputSystem.InputService.Update () (at <3deba2729fdf4909903ff6b90269e488>:0)

[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
Timberborn.CoreUI.PanelStack.Awake () (at <17ba2d2ed15e44878b307f80be58abba>:0)``` ![OMEGALUL](https://cdn.discordapp.com/emojis/588032489595863061.webp?size=128 "OMEGALUL")
#

@stone shoal

stone shoal
#

What even is that

#

recoveredgoodstack

severe solar
#

Piles after destroying a building

#

is a fysical block object

stone shoal
#

sounds about right

severe solar
#

but not buildiang

#

buildable

stone shoal
#

I guess you should only do it on certain types

#

or just try catch it ๐Ÿ™‚

severe solar
#
      Tool tool;
      try
      {
        tool = _toolService.GetTool(selectableObjectName);
      }
      catch (Exception e)
      {
        return;
      }```
vast otter
#

Seen this report?
#๐Ÿš€mod-users message

stone shoal
#

@ebon sparrow Do you maybe know when the Resources and object collection are completely reset?

#

I believe objectCollection is on every load, but the values are still set in the Resources prefab on second load ThinkingIT

ebon sparrow
#

Resources like objects in unitys Resources folder?

stone shoal
#

Yes

ebon sparrow
#

those reset on game quit

#

if you change those assets in unity editor, it persistseven across sessions

#

changed values are saved on disk

stone shoal
#

๐Ÿ‘€ It can even be made persistance on quitting the game sheesh

#

Let's not do it, ThinkingIT ever KEKW

severe solar
#

Serialized fields are reset. I think he means the changed values if in the editor

full acorn
#

To add a tool group in the latest release, is it just a case of adding the required specification file or do I need a script to register it?

full acorn
#

Ah thanks, In which case there's something I'm doing wrong - 'tis toubleshooting time! HappyF

stone shoal
#

Else post the problem here ๐Ÿ™‚

#

Did you read the docs ?

full acorn
#

I did, but not sure if I've misinterpreted something

#

So the goal is to add a group inside the 'Power' tool group:

  "Id": "Flywheels",
  "GroupId": "Power",
  "Order": "180",
  "Type": "PlaceableObjectTool",
  "Section": "BottomBar",
  "NameLocKey": "ToolGroups.Flywheels",
  "Icon": "Sprites/ToolgroupIcons/BasicCategory"
}```
stone shoal
#

"Type": "PlaceableObjectTool",should not exist in groups

full acorn
#

Ah!

stone shoal
#

you sure you used the Group docs instead of the Tool docs ThinkingIT

#

okay type exists thonkeyes

#

I think I made an oopsie

full acorn
#

I ended up flipping back and forth between Tools and ToolGroups docs trying different things. Not getting an error message at all, just failing to load

stone shoal
#

failing to load ?

#

Doubt that should be caused by the spec, specially without an error

full acorn
#

The docs did suggest that you need to use a script to register the group, but I assume that's for a custom tool or functionality?

#

rather than just building placement

stone shoal
#

yeah that is for creating custom types of groups

#

ConstructionModeToolGroup is a valid type

#

to show construction mode when clicking on it

full acorn
#

so in the example above, the Prefab's Tool Group ID would be "Flywheels" right?

stone shoal
#

Yes

full acorn
#

Just gave that a try and getting a The given ToolGroupId (flywheels) cannot be found

#

With the same spec posted before, but with the Type changed to ConstructionModeToolGroup

stone shoal
#

Do you have the specifications in the specification folder

#

with an mod.json ?

full acorn
#

Yep - the mod.json is in the mod's root folder, but they're all specified in the ThunderKit manifest

stone shoal
#

What is the filename called ?

full acorn
stone shoal
#

they don't have .json ThinkingIT or it doesn;t show it ?

full acorn
#

It's ToolGroupSpecification.Flywheels.json

#

it just doesn't show it

stone shoal
#

hmmm

#

Maybe @vast otter knows. He has added groups already so should work

#

Are you btw sure you using the latest TimberApi ? obviously else you would not get that message

full acorn
#

Pretty sure, though now you say that I'm going to check

vast otter
#

Check staircase mods specifications as reference

full acorn
#

Well, turns out that the actual game's version is correct, but the Unity version is not

#

damnit

vast otter
#

Note add icon to asset bundle and set toolorder to Flywheels

#

Do ping me if you get stuck and i try to get time and help๐Ÿ˜Ž

full acorn
#

Sorry about that, thought I'd changed it across but I've obviously only changed the Game's version and not done Unity's

full acorn
#

Hmm, same error, think there's something I'm not doing right

stone shoal
#

Do other specifications work ?

full acorn
#

The Faction Specs work, but I'm having a look at Staircases to make sure it's all correct

#

Ah, different error now, FallbackGroup isn't documented but It's in Staircases so I'm just going to mirror it and see if that works

#

Ayyyy that's done the trick

#

Final spec:

  "Id": "Flywheels",
  "GroupId": "Power",
  "Order": "181",
  "Icon": "battery.flywheels/battery_flywheels/BasicCategory",
  "NameLocKey": "ToolGroups.Flywheels.DisplayName",
  "FallbackGroup": false
}```
stone shoal
#

Ah ye, I see i didn't add that in docs.

#

But should throw an error ThinkingIT

full acorn
#

it did, I think it was the Icon path - I was using the absolute path rather than the asset bundle's path

stone shoal
#

absolute path ThinkingIT

#

Like C:\image\image.jpg ?

stone shoal
#

in like bullet points

full acorn
#

Added!

#

More than happy to contribute to the docs, but will need to brush up on Git, been a while ๐Ÿ˜…

north hatch
full acorn
#

I'm assuming the Docs can only use plain markdown since they get shown on the wiki page? Or can I use mermaid for diagrams?

north hatch
#

just markdown iirc

stone shoal
north hatch
#

yeah true and pr too

#

but you can do that through gh ui

full acorn
#

Also I feel like I'd want to do a PR rather than a push

stone shoal
full acorn
stone shoal
#

@vast otter, @median plinth, @severe solar

Part of @calm copper request is to add under the ToolGroupSpecification example.

_NOTE:_ The specification must be stored in a file with the specific name to be recognized properly. E.g. the file name can be `ToolGroupSpecification.foo.bar.original.json`, where prefix `ToolGroupSpecification`, suffix `original`, and extension `json`
are **required**. You can put arbitrary text between _prefix_ and _suffix_. See more in [specification naming](../specifications/index.md#specification-naming).

I kinda understand why to add, but also feels wrong. Reason original.json doesn't have to be required if you overwriting an existing one.

Maybe just a note to link to the naming of specifications would be enough and fit better?

vast otter
#

Ya a link to how to name specifications feels better and more centreralized place if stuff change down the road

calm copper
#

I'll spend some time tonight to suggest more updates to the docs.

calm copper
#

What's the recommended way of creating tools in runtime? Let's say I have a logic that decides how many and which tools should be present in the bottom bar. The file based specification approach doesn't fit well here.

severe solar
#

Depends on what it is, i have updated Pipette Tool, which is an instance. Therefore you load it using the dependencycontainer. Object tools are created with a constructor

stone shoal
calm copper
#

No, at the start of the game, but I want to decide which tools to add programatically.

stone shoal
#

Csn you give an example of why/when? Could not quite recommend it since it would remove the customability

calm copper
#

E.g. I maintain my own config file. There I can setup rules to show particular tools. A rule can look like "advanced settings = true", which results in creating a dozen of new tools that are not visible otherwise. Or, even a more complicated example, there can be some custom script-kind config that defines actions, and I want to make tools for them.

#

Tbh, I don't fully understand the current approach. Why keeping tool specification in file if it won't work without code support anyway? Why not just configuring the tool in runtime?

stone shoal
#

The feature is not made for code modders, but it isn't made harder

#

It's there to have full control over the tools and behaviour as a third party (user, modpacks, dependent mods) to change them

#

The implementation of the systems also fixes some small thing like the game crash when same order is used

calm copper
#

At some point I thought it's possible to create multiple specifications with the same Type, just passing different arguments. But it didn't work.

#

This would make sense. I crate one type, and many people can create their own tools.

stone shoal
#

ISpecificationGenerator isn't documented though since it was more like an internal feature before

#

Its heavily used in the ToolSystem code

calm copper
stone shoal
#

But if your tool would place platforms in an area and have like a 3x3, 4x4, 5x5 tool you could make 1 type for that with an ToolInformation property AreaSize or something

#

Can also be used for custom ability say you use colors for highlighting

calm copper
#

How about range selection? Let's say I have a common code that decides what to do with the selected objects, but the selection criteria is configurable, and I want a separate tool for every criteria.

#

Like, I can provide 2 criterias initially, and users may want to add a dozen more lately.

stone shoal
#

If you think it would be the same Tool behaviour just with some other settings sure

#

But I cannot decide that for you ๐Ÿ˜› in the end I cannot block if it would be misused

calm copper
calm copper
#

One sec, I'll reproduce it pretty quick.

calm copper
#

Lol. Now it works fine. I think, last time I made a copy of the specification and didn't update the Id.

stone shoal
#

probably

calm copper
#

With the same type and different ToolInformation I get exactly what I need.

#

Well, kind of. Ideally I'd prefer to fully control it from the code ๐Ÿ™‚

stone shoal
#

Well it was like that before but just isn't handy whenever more modders would join, and even now it already had limitations

#

Because someone wanted to make a overhaul on the bottombar which wasn't possible

calm copper
#

Yeah, I remember the order ID problem. It was the first thing I learned. I was surpised the conflicts are not maintained in the stock code.

stone shoal
#

stock code ?

calm copper
#

The Timberborn game core. The bottom bar is their functionality, after all.

ebon sparrow
calm copper
ebon sparrow
#

we have a tie break algo. If there is a tie, exception is thrown and you have to resolve the tie :P

stone shoal
ebon sparrow
#

I agree it is not the best, nor mod friendly, but this is a really old code, so it is as it is ๐Ÿคทโ€โ™‚๏ธ

calm copper
#

Trust me, I know what does "old code" term mean AngryIT Half of my working time I'm fighting with the legacy.

ebon sparrow
#

well, it is not that way - it is not legacy code

#

it is code written with different priorities in mind

stone shoal
# calm copper Let's say I created a mod with tool "remove dynomites" (just a silly example). I...

Lets go back here for a bit.

Icon, background color, position, order, visibility can be easily modified by just editing the specification file.
They obviously cannot change it's behaviour.

Depending on you it can also could be customizable with the description/name.
If it's done like this: https://github.com/Timberborn-Modding-Central/TimberAPI/blob/main/Core/TimberApi/ToolSystem/Tools/BotGenerator/BotGeneratorToolFactory.cs
It would not be possible since the loc key would be fixed, I didn't want to add more to maintain for the default tools.

calm copper
#

In my world it's called "legacy", but it's essentially the same. Something that was made long time ago, and that time back it did make sense.

stone shoal
ebon sparrow
calm copper
ebon sparrow
stone shoal
ebon sparrow
#

yes, you could have aqueducts from the beginning

#

the point is, you need to find manpower to do it ;)

stone shoal
calm copper
#

"An aqueduct is a watercourse constructed to carry water from a source to a distribution point far away". I disagree that we have it!

ebon sparrow
#

I said "you could have it"

calm copper
#

Ah, my bad.

stone shoal
#

@calm copper for the Tools also a more recommended way to create compared to what Tobbert said.
Recommended: https://github.com/Timberborn-Modding-Central/TimberAPI/blob/main/Core/TimberApi/ToolSystem/Tools/BuilderPriority/BuilderPriorityToolFactory.cs

Lazy: https://github.com/Timberborn-Modding-Central/TimberAPI/blob/main/Core/TimberApi/ToolSystem/Tools/BotGenerator/BotGeneratorToolFactory.cs

Creating an instance from the dependency container is just a lazy way to do it because this way people aren't able to create the same exact ToolType in different locations since it's a singleton.

calm copper
stone shoal
# calm copper I'll spend some time tonight to suggest more updates to the docs.

As said by knatte, and myself, prefferable to just have links to the detailed information instead of writing it down.

If you want to make such big changes prefer to keep these things in mind:

  • Keep it as much single responsible so no duplicated information over different pages occur (the redirect links)

  • Make things not too long or for one specific use case only. (Like this has indeed something to do with creating tools but not with registering https://github.com/Timberborn-Modding-Central/TimberAPI_Docs/pull/21/files#:~:text=public override ToolDescription Description() If you could find a way to descripe those 2 different thing seperately would be great. Maybe a full Tool guide on a different sub page?)

  • Might be annoying, but maybe could be handy to make a seperated PR if you change different pages? if some are good they can already be implementd but that's up to you.

  • The rest you will see in a review, it's my first doc so just trying things out. In general I'll like to keep the information only on the feature needs and not exampling the reasons why something is usefull because of the game.

#

If you did something because of some other docs, just link the docs so I can see their examples

calm copper
# stone shoal As said by knatte, and myself, prefferable to just have links to the detailed in...

I'm totally OK if the entire PR will be rejected ๐Ÿ™‚ It's more like "guesses" at this point since I don't feel confident about the logic and the design if the API. If you find any line in this PR useful, then the goal is already achieved and the spent time was not wasted.

In a company where I work, we have a concept of "codelab". I.e. for any topic, regardless how complex it is, there is a walkthrough that you pass step by step and end up with working basic application. Those, who need advanced things, can read deeper, and for this purpose there are links to "special cases" during the codelab. Like, "you could make it more flexible, but more complex - see here how". I guess, I tried to walk on your docs from this perspective. I was literally making my first mod from the scratch (before, I got someone's mod and patched it with my code to play with things).

severe solar
#

Whats a mdo?

calm copper
#

"mod" ๐Ÿ™‚

#

"plugin" fwiw

severe solar
#

Oh, ups ๐Ÿ˜…

#

I only learned by coping water triggers from hytone

stone shoal
#

Not sure if code lab would work very well since its all. Very seperated concept and could require all for all examples. But well see what you make from it HappyIT

#

Maybe on a sub page make your first X guide

#

Or the other way around

calm copper
stone shoal
#

I remember vagely when I made mods as well pepesad

calm copper
#

And for the PR, feel free to consider it as just my personal notebook which I shared just in case ๐Ÿ™‚

severe solar
#

Oooh, reminds me i need to update the animation guide

#

Something for ehen im back

calm copper
#

After working for some time in enterprise dev, I ended up with a conclusion, that the good docs are the most useful to myself. You make something, it works for couple of years, and then out of nowhere people come and ask you do add a feature to the long forgotten code. This is the moment when the docs and following the good practices pay off.

stone shoal
calm copper
#

I did. Read thru all the examples... and understood not that much ๐Ÿ™‚ Then, I forked from KyP-timberborn-mods and there the journey started.

stone shoal
#

The examples should the only things that could be understood thonkeyes

#

That is your coddelab pretty much

calm copper
#

In the big companies there is a position of technical writer. This person intentionally has not programming background. It helps to be unbiased. The main mistake of any programmer who makes a doc is that we assume the reader knows "the basic stuff". And who decides what's "basic"?

#

FWIW, my employer company is big, but we don't have tech writers ๐Ÿ™‚

stone shoal
#

We don't have any docs, but yeah I just finished college anyway

calm copper
#

But we do have a rule: "code is the doc". Which means, your code must be written so that it either doesn't require documentation, or the documentation is already in the method comments.

stone shoal
#

Comments YA_Yuri_Boba_Sip @ebon sparrow

calm copper
#

C# has a very good documentary system. If you keep them in good shape, there are tools that can make cute doc sites for you. Like Sandcastle.

stone shoal
#

ยฏ_(ใƒ„)_/ยฏ

#

Ehh

#

Not my cup a tea

#

Also find that as confusing as just readon code thoug xD

calm copper
#

In the today's world of intelligent IDE's, the dedicated help sites becomes less useful. However, the role of the comments in the code only increases. I'd not be surprised that one day an AI will be presented that uses the comments for deep learning.

#

AI driven code completion is already a very powerefull feature that saves a ton of time.

stone shoal
#

code pilot was pretty bad I heard

calm copper
#

At work I use a proprietary AI system. It rocks! Sometimes it's enough to type just two characters in ktor to have the whole class implemented.

#

It applies to the common cases, of course. AI cannot invent the code for you.

ebon sparrow
#

we are using Github Copilot and it is also quite good

#

sometimes it can really impress :)

calm copper
ebon sparrow
#

yep

calm copper
#

I need to try the copilot then. I use RD too.

stone shoal
# ebon sparrow yep

Did you have any problems with it connecting tho? I saw some reviews that it keeps forgetting and working pretty slow

#

Not yet the time to test it out

severe solar
#

Ooh, then i will also give it a try

calm copper
#

Btw, in case someone didn't know it, RD subscription can be given for free if you write mods/plugins.

stone shoal
#

I know, I have it HappyIT

#

It's a full all pack subscription though

ebon sparrow
#

it usually has a bit of a lag, like 0.2-0.4 sec to which you need to get used to

#

but I had no connection problems

severe solar
#

Ive been using the school subscribtion. Will be able to use that for another few years

calm copper
#

The free "modders" one is pretty good. It has a lot of stuff (most of which I never used or going to use).

stone shoal
#

The free subscription is kinda making me not yet paying for a personal one ohlsippyn

calm copper
#

Which language version is recommended for Timebreborn? I usually use 9.0.

calm copper
#

That's not the language version ๐Ÿ™‚

stone shoal
#

.NET Standard 2.1 C# 8.0

calm copper
#

Now it is.

severe solar
#

Dafuq is lagnuage version?

stone shoal
#

But pretty sure 9 and some 10 feature versions work just fine

#

I believe bepinex also causes some things to work more than should

#

like file based namespace works fine

calm copper
#

Many things in 9.0 are just syntax sugar. They work fine in any runtime.

#

But there are edge cases.

#

I'm writing my mod in .NETFramework v4.8, C# 9.0. It works fine with the latest game version. However, it's not a reliable sign of compatibility.

stone shoal
#

TimberApi also uses C# 9 it seems

#
        <TargetFramework>netstandard2.1</TargetFramework>
        <Nullable>enable</Nullable>
        <LangVersion>9</LangVersion>
lofty lark
#

ah, i found a new, very minor thing :
if a group description is written on two lines, the screen location will be based on the first (top) line and not the last one, making the text clip with the icons.

stone shoal
lofty lark
stone shoal
#

Make a custom groupvisualization or fix it with a remake of the original one ๐Ÿ˜›

calm copper
#

I'm implementing IPersistentEntity on my component and adding it to a block object. On save the IPersistentEntity.Save is called just fine. However, on load my component doesn't get restored. Why? Where should I register it?

severe solar
#

What you mean? It should be called hust fine

#

Did you save it in the first place?

calm copper
#

Ha! That was my first idea.

severe solar
#

You need initializing in 2 places

calm copper
#

TWO palces? I know only one.

severe solar
#

So if its not saved, then in start or awake. If its saved, after the load

#

Maybe intialize is not the correct word

calm copper
#

No, it's a basic component added to a constructible object.

#

I add a component like this:

BaseInstantiator.AddComponent<IFTTTAutomationTestRule>(selectedObject.GameObjectFast)

The added component implements IPersistentEntity, which I can see behaving as expected on save. However, on load the component doesn't get restored on the object.

severe solar
#

Does it have serialized fields?

calm copper
#

It doesn't as of now, but I tried a case with a serialized int field. This is how I save:

  public void Save(IEntitySaver entitySaver) {
    TestValue = 123;
    DebugEx.Warning("*** state saved: {0}", TestValue);
    var saver = entitySaver.GetComponent(savableKey);
    saver.Set(TestValueKey, TestValue);
  }
severe solar
#

Its always good to check both component and the field if they exist

#

Can cause crash on runtime

#

Furthermore, its better to use the decorator system to add that component

#

As i dont see a reason why you cannot

calm copper
#

I'd love to know more about the decorator stuff. How do I do it?

severe solar
#

Oh, give me a sec

#

Oh, not really TAPI related

calm copper
#

Heh. No worries. I know at least one mod that does it - SimpleFloodgateTriggers. I'm goign to check their code.

severe solar
#

I send in modders chat

north hatch
#

is there any tutorial on how to actually get your prefabs in game? All i see in mods are a bunch of seeming random files

#

my guess is that i need specifications but thats about it

#
//FactionSpecification.Folktails.json
{
  "CommonBuildings": [
    "me.darkeyedragon.steamworks/steamworks/PipeStraight.Folktails"
  ]
}
#

thats what i figured out so far

vast otter
#

We do have my minimal mod setup #1042573456732082206 that can be used as a base but in a nut shell its:
1 add model to a prefab that has the components needed for the typ of building see base game for examples(asset ripper)
2. Set prefabname to uniq name
3. Add building to manifest(R)
3 add path to specification

north hatch
#

manifest?

vast otter
#

Thunderkit is the king

#

If doing stuff with models

#

To build the asset bundle and move stuff to right place

Even has a video how to verify that minimal mod setup works

north hatch
vast otter
#

Do you have a mod.json file?

north hatch
#

yeah

#
{
  "Name": "SteamWorks",
  "Version": "1.0.0",
  "UniqueId": "me.darkeyedragon.steamworks",
  "MinimumApiVersion": "0.5.3",
  "MinimumGameVersion": "0.3.5.2",
  "EntryDll": "SteamWorks.dll",
  "Assets": [
    {
      "Prefix": "me.darkeyedragon.steamworks",
      "Scenes": [
        "InGame"
      ]
    }
  ]
}
vast otter
#

Can you send it and what name does the assetbundel have

#

๐Ÿ˜ฏno asset bundel declared

north hatch
#

steamworks is the asset bundle

#

oh right

vast otter
#

So spec is "uniqid/assetbundle name/prefabname"

north hatch
#

lets see if this boots at all

vast otter
#

else see you in beaver-noices? ๐Ÿ˜‰

north hatch
#

sure

calm copper
#

Are there any tricks with injections in the BaseComponent descendants?

I have the following (simplified) code:

MyClass : BaseComponent {
  [Inject]
  MyClass(BaseInstantiator baseInstantiator) {}
}

The ktor is not called at all. Moreover, it breaks the normal class initialization.

severe solar
#

Basecomponent has nothing todo with that. Basecomponent is just a Timberborn version of mono behavrio which is used to have caches when getting components to increase performance. Injections is bindito and is just to get acces to singletons before the awake

calm copper
#

It still doesn't give the answer why it's not working.

severe solar
#

Sorry, i didnt understand what is not working? Gonna google ktor

#

Aaah, inject InjectDependencies replaces the constructor

calm copper
#

ktor = constructor

ebon sparrow
#

you can't have a ktor in MonoBehavior

#

Unity thing

calm copper
#

Yeah, usually I cannot. But with inject it compiles and "kind of" working (not). But it explains what's happenning.

#

Not very intuitive, though.

#

One more side effect I found is that local fields doesn't get initialized if there is an inject attributed ktor. Is it an expected behavior?

ebon sparrow
#

inject is not for ktors

severe solar
#

I never had a constructor in a monobehavior

ebon sparrow
#

if you can have ktors, then you should inject via them - singletons

#

if your class is mono behavior, then having a ktor is a mistake

#

you should use inject attribute for a inject method

calm copper
#

Ah, so the [inject] thing is for an arbitrary method that should "replace" ktor?

ebon sparrow
#

yes, becouse in MB you can't have ktors

calm copper
#

Got it. It makes sense. Thank you.

ebon sparrow
#

if MB would allow ktors, then inject attribute would be removed

#

as not needed

calm copper
#

Btw, do you have any statistics on injecting "many arguments" vs "one argument"? I.e. will it be faster if my component injects just one argument instead of a dozen? Given the component is created for a considerable number of game objects.

severe solar
#

If you need them you need them

ebon sparrow
#

tho we believe that more then ~5 is too many

calm copper
calm copper
#

I just noticed that game freezes on save game load, and assumed it's Bindito doing all the deps resolution work. Thus, assumed less complexity may improve the timing.

north hatch
#

more so the fact everything has to be loaded from disk more so than binding i think

severe solar
#

I believe it mostly actually loading the assets, not the associated code

north hatch
#

ig you could check disk read/write to confirm

ebon sparrow
#

afaik it is template system in works

north hatch
#

i wonder how much of that time is parsing json

ebon sparrow
#

dozen max

north hatch
#

depends on mapsize and buildings i imagine

severe solar
#

Parsing json might be intensive, for my mod that loads 3000 specifications its only 10 secs to 14 secs

calm copper
#

My system is mostly idle during the load. The only growing paremeter is RAM. CPU is below 25% and disk is idle (fast nvme drive).

ebon sparrow
#

keep in ming that unity mostly uses 1 core

#

so CPU below 25% might mean that 1 core is at 100% and rest is idle

#

well, this is for sure area for improvement, but, well...

#

people got used to it ๐Ÿ™Š

north hatch
#

multithreading is a slippery slope kek

calm copper
#

Not much to do if it's Bindito thread. However, if it's the asset loading, this can be parallelized. Not sure about the template module, probably not.

ebon sparrow
#

it's connected to instantiating and calling awakes - and unity requires it to be done from main thread

north hatch
#

I find it funny how easy unity makes game development, but the moment you need any kind of performance gain you gotta start altering the engine itself

calm copper
#

...and this is how we endup with the custom prefab formats ๐Ÿ™‚

#

I wonder if they (makers of Unity) are trying to do anythign with it. I get the problem of multi-threaded 3d engine. But at least the scene loading could be improved.

ebon sparrow
#

good at everything, best at nothing

ebon sparrow
#

I was blown away by Dyson Sphere Program - no idea how they do it, never bothered to check

#

but they also use Unity and they load a game in mere seconds

north hatch
#

oh they basically ripped out the entire engine at this point

ebon sparrow
#

probably we will end there too soon xD

north hatch
#

they have some interesting blog posts regarding the development

calm copper
#

Learning one more engie for making mods woudl be too much for me.

north hatch
#

i dont think much would change on our end tbh

#

well not more than now

#

the endpoints would still be the same

severe solar
#

Bindito does most of the heavy lifting

calm copper
#

Btw, is Bindito a home brewed system? I tried to google, but didn't find any useful docs.

severe solar
#

Yea, timberborn devs created it

calm copper
vast otter
#

A note then adding subgroups or groups you have to set assets to apply to all

severe solar
#

Timberborn is calling Resource.Load directly

Resources.Load<BinaryData>(meshyDescription.ModelName);```
Could this result in TimberAPI not updating the path to a assetbundle?
stone shoal
#

Their resource loader is just a small wrapper why use this ThinkingIT

severe solar
#

@ebon sparrow Would it be possible to change?

stone shoal
#

The only thing i can imagen is it being required before bindito

severe solar
#

no, called ingame

ebon sparrow
#

Change what?

severe solar
#

Instead of calling Resources.Load directly, to use IAssetLoader

#

sorry, IResourceAssetLoader*

ebon sparrow
#

I'm pretty sure its impossible, since it is used also in editor

stone shoal
#

In editor ?

severe solar
#

But the code is ran at runtime, no?

ebon sparrow
#

It might be used to load models for editor preview

#

I will check tomorrow

stone shoal
#

Sounds hacky, because of meshy thonkeyes ?

ebon sparrow
#

why hacky? Using Unity API is now hacky?

severe solar
#

using unity is hacky, yes

severe solar
#

MeshyPrefabOptimier i beli8eve

ebon sparrow
#

yeah, it looks like in MeshyPrefabOptimizer it is a mistake and IResourceAssetLoader should be loaded

#

how big of a pain it is @severe solar ?

severe solar
stone shoal
#

I believe the other way around, it's a mistake and can be fixed. How much does it suck so he'll take a prioritythonkeyes

ebon sparrow
#

yep

severe solar
#

We cannot use meshy as modders

#

Or @stone shoal needs to make a small patch workaround

#

Or i need to

#

I'm currently on the way so I cannot look at the code look at the code but I believe I believe it's not possible to patch that function directly function directly so the work around would be a little bit bigger

north hatch
#

tobbert lagging

severe solar
#

Using speech recognition in my car it's the my car it's the best

stone shoal
#

Tobbert can speak english that can be recognized thonkeyes

#

C1 for sure

nova gale
#

@stone shoal Im updating my power trigger mod to U4 and the linking objects inside TimberAPI works in a game saved but when I try to start the linking process I get an error

#

[Error : Unity Log] ArgumentException: An item with the same key has already been added. Key: GravityBattery.Folktails(Clone) (UnityEngine.GameObject)
Stack trace:
System.Collections.Generic.Dictionary2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <cbc72d4a9767498db39486e941a498e3>:0) System.Collections.Generic.Dictionary2[TKey,TValue].Add (TKey key, TValue value) (at <cbc72d4a9767498db39486e941a498e3>:0)
TimberApi.ObjectSelectionSystem.PickObjectTool.StartPicking[T] (System.String title, System.String description, System.Func2[T,TResult] validateCandidate, System.Action1[T] callback) (at <24bfd2b63dc048179e128b15aa9b2e38>:0)
TANSTAAFL.TIMBERBORN.PowerGenerationTriggers.UI.StartLinkingButton.StartLinkEntities[T] (TimberApi.EntityLinkerSystem.EntityLinker linker, System.Action createdLinkCallback)

#

must be
_allCandidates.Add(item.GameObjectFast, item);
the line thworing the error

stone shoal
#

@severe solar said it worked fine without any changes, I have no idea how to use that code

#

It's just a copy paste from the base game to this, so it can still be used

nova gale
#

Im gonna try in a new game instead of the save from U3

#

In a new game I get the same error

#

@severe solar do you have a sample using it?

severe solar
nova gale
#

I didnt find why it would work on U3 but not on TAPI, Im gonna build TAPI tomorrow with a TryAdd instead and see if it works
_allCandidates.TryAdd(item.GameObjectFast, item);

stone shoal
#

I believe before it wasnt using a dictionary ThinkingIT

#

But you are somehow adding the object twice now

#

What do you do to make it crash

north hatch
#

[Error :SteamWorks] Failed to deserialize: version string does not match regex
Might be nice to show the actual regex requirements in the error message

stone shoal
#

What are regex requirements

#

But it's semver with an additional numver

north hatch
#

the pattern

stone shoal
#

so instead of 3 4

north hatch
#
{
  "Name": "SteamWorks",
  "Version": "1.0.0",
  "UniqueId": "darkeyedragon.steamworks",
  "MinimumApiVersion": "0.5.5",
  "MinimumGameVersion": "4.0",
  "EntryDll": "SteamWorks.dll",
  "Assets": [
    {
      "Prefix": "darkeyedragon.steamworks",
      "Scenes": [
        "InGame"
      ]
    }
  ]
}

this seems fine?

#

or is it 0.4

stone shoal
#

I believe it must have 3

#

4.0.0

#

revision is optional

ebon sparrow
#

so 0.4.0 ?

stone shoal
#

oh that as wel yea

north hatch
#

[Warning:SteamWorks] Skipped: Minimum game version required: 4.0.0.0, current game version: 0.4.7.0

stone shoal
#

but that's and error he will get next ๐Ÿ™‚, ^ that one

north hatch
#

yeah looks like it

#

patch should be optional too imo

#

as they dont break api

#

or shouldn't according to spec

stone shoal
#

It could break things in the game tho

north hatch
#

i mean technically yeah

#

but this means every time any update comes out you will need to update your mod just to update the number in case it doesnt break

#

this can cause a lot of "dead" mods over time that could potentially still work even tho the dev is MIA

stone shoal
#

Not really

#

because it's a miniumum

#

not a match

north hatch
#

oh right minimum game version facepalm

#

reading is hard

stone shoal
#

It truely is tho

stone shoal
#

Fixed orders when loading the save file again

north hatch
#
[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
TimberApi.ToolSystem.Tools.PlaceableObject.PlaceableObjectToolGenerator+<Generate>d__2.MoveNext () (at <36a8415ba25744f1935294089b9a80f3>:0)
System.Linq.Lookup`2[TKey,TElement].Create (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] keySelector, System.Collections.Generic.IEqualityComparer`1[T] comparer) (at <fa6dfabea46b4d38a92695d5d0cf891d>:0)
System.Linq.GroupedEnumerable`2[TSource,TKey].GetEnumerator () (at <fa6dfabea46b4d38a92695d5d0cf891d>:0)
TimberApi.SpecificationSystem.SpecificationRepository.AddRange (System.Collections.Generic.IEnumerable`1[T] specifications) (at <36a8415ba25744f1935294089b9a80f3>:0)
TimberApi.SpecificationSystem.ObjectSpecificationGenerator.Load () (at <36a8415ba25744f1935294089b9a80f3>: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 <ab814a1829494fd8bc5bee93ae7dd9a7>:0)

[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
Timberborn.CoreUI.PanelStack.Awake () (at <47341c47a58b4d64aabfcf4df7c26692>:0)

getting the following exception when loading into a map

#

did something change on the specification format in u4?

#

derp was missing an icon

stone shoal
nova gale
stone shoal
#

How did you trigger a crash

#

I do not know what you were doing before either

nova gale
#

it crashes when I click the button to highlight the available objects to link

#

they are gravity batteries added to a IRegisteredComponent

vast otter
#

@stone shoal have you understood yet why the ruins toolgroup is not shown in map editor?
when you get to know why maybe you can add a parameter to tell to show in map editor for other toolgroups ๐Ÿซฐ

stone shoal
#

what ?

#

ah

#

I tried to make it work for mapeditor

#

But than the 2 bottombars existed so not sure if I want to rework that one as well

#

So gonna try to make it not hidden

vast otter
#

ok

stone shoal
#

But my brain is kinda fried and tired after work, so I don't have much energy to work on TimberApi lately

vast otter
#

no problem take your time i do have alot IRL to

nova gale
#

I was indeed re-registering the gravity batteries on my mod, got it fixed for U4 now

north hatch
#

Whats the best point to add data to a component?
Essentially i want to add some data to an array on a component when a map is loaded.

#

but i'm not sure what entry point i'd use for that

#

since custom specifications don't work in unity

stone shoal
#

on a component ?

#

I guess just a Loadable?

north hatch
#

i basically want something like the right picture

#

but i cant do that with specifications cuz unity doesnt support it

#

so the alternative is to do it in code

#

i see there is an ISpecificationGenerator in tapi but i'm not sure thats what i need

#

and where to call that logic

stone shoal
#

IDK if unity scripts are also called specifications but

north hatch
stone shoal
#

specifications are not done with unity

north hatch
stone shoal
#

You just make a specifications for each building or whatever it is

#

Look at recipes

north hatch
#

will do

wintry void
#

please forgive my mesage, i was at the top thinking i was at the latest discussion. I meanto instead thank you for your tireless effort to make and mantain the mod, I could never do such work, not inclined that way. Thank you again.

lofty lark
#

i'm getting this error :

#

[Error : Unity Log] ArgumentException: An item with the same key has already been added. Key: dam2x3up
Stack trace:
System.Collections.Generic.Dictionary2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <cbc72d4a9767498db39486e941a498e3>:0) System.Collections.Generic.Dictionary2[TKey,TValue].Add (TKey key, TValue value) (at <cbc72d4a9767498db39486e941a498e3>:0)
TimberApi.ToolSystem.ToolIconService.AddIcon (UnityEngine.Sprite sprite) (at <4cae64c9bbf24b2ca603f90bbb316330>:0)
TimberApi.ToolSystem.Tools.PlaceableObject.PlaceableObjectToolGenerator+<Generate>d__2.MoveNext () (at <4cae64c9bbf24b2ca603f90bbb316330>:0)
System.Linq.Lookup2[TKey,TElement].Create (System.Collections.Generic.IEnumerable1[T] source, System.Func2[T,TResult] keySelector, System.Collections.Generic.IEqualityComparer1[T] comparer) (at <fa6dfabea46b4d38a92695d5d0cf891d>:0)
System.Linq.GroupedEnumerable2[TSource,TKey].GetEnumerator () (at <fa6dfabea46b4d38a92695d5d0cf891d>:0) TimberApi.SpecificationSystem.SpecificationRepository.AddRange (System.Collections.Generic.IEnumerable1[T] specifications) (at <4cae64c9bbf24b2ca603f90bbb316330>:0)
TimberApi.SpecificationSystem.ObjectSpecificationGenerator.Load () (at <4cae64c9bbf24b2ca603f90bbb316330>: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 <ab814a1829494fd8bc5bee93ae7dd9a7>:0)

[Error : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
Timberborn.CoreUI.PanelStack.Awake () (at <47341c47a58b4d64aabfcf4df7c26692>:0)

stone shoal
lofty lark
#

that is a bit puzzling, the prefab is not named like that, only the icon...
did i accidentally use it somewhere else too ?๐Ÿค”

stone shoal
#

Hmmm

#

Or I do it at 2 places and forgot to fix it

#

Or you might not have the latest version?

lofty lark
#

oh did you fix that issue where it was upset when i use the same icon multiple times ?

stone shoal
#

Yes fixed that pretty fast tho

lofty lark
#

oh, ahah

#

didn't update anythign

#

to be honest i'm too scared of breaking everything when updating ๐Ÿ˜…

#

cause i never can remember how to do it

#

oh right, TimberAPI is just a mod right ? just toss it in the right folder and here you go ?

vast otter
lofty lark
#

i think i could update it without problem ๐Ÿ™‚

#

but i have an other small problem now : empty category buttons no longer naturally disappear ๐Ÿ˜•
I made some custom category because i wanted to regroup some buildings in a different way from what the base game does, so i don't actually have anything in the "wood" category for example, yet it still displays.

#

i suppose since you remade the buttons entirely, there must be some hidden specifications such as "ToolGroupSpecification.Wood" right ? if i make a .replace that is completely empty, might that work ?

#

wait no, that would break the other factions

#

hmm...

vast otter
#

Check my water extention how i hide base game with spec and check staircase mod how i move where woodenstairs is placed

#

๐Ÿ˜ฎ ya should be able to set wood as hidden:true

vast otter
#

ThinkingIT would be great if a tab is hidden if nothing is added to it๐Ÿฅน

lofty lark
#

i'll check

#

thanks

#

hmm... i can hide individual buildings but for me that's not a problem since i have full control on the faction specification

#

i don't know if adding "hidden : true" to a toolgroup works but i guess i can try

#

oh actually that works !

stone shoal
lofty lark
#

nah it's okay. you surely have more important things to fix, and i'm probably the only troublemaker here that needs to destroy entrie categorites, so as long as i have a way that's good enough.

stone shoal
#

It seemed it was quite important in the end xd

lofty lark
#

And on that matter... i'm unable to load the custom white beaver skins somehow. ๐Ÿ˜…

Stack trace:
TimberApi.AssetSystem.AssetLoader.Load[T] (System.String prefix, System.String pathToFile, System.String name) (at <24bfd2b63dc048179e128b15aa9b2e38>:0)
TimberApi.AssetSystem.AssetLoader.Load[T] (System.String prefix, System.String path) (at <24bfd2b63dc048179e128b15aa9b2e38>:0)
TimberApi.AssetSystem.AssetLoader.Load[T] (System.String path) (at <24bfd2b63dc048179e128b15aa9b2e38>:0)
TimberApi.ResourceAssetSystem.ResourceAssetLoader.Load[T] (System.String path) (at <24bfd2b63dc048179e128b15aa9b2e38>:0)
Timberborn.Beavers.BeaverTextureSetter.Start () (at <e49ef50372814472874184010c2a1044>:0)

[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
Timberborn.CoreUI.PanelStack.Awake () (at <47341c47a58b4d64aabfcf4df7c26692>:0)```
#

and yet absolutely everything else loaded just fine ๐Ÿค”

stone shoal
#

Typo.

#

?

lofty lark
#

i actually didn't check that but have my doubts ๐Ÿ˜…

#

letmesee

stone shoal
#

This ks a different error than the meshy error tho

lofty lark
#

nope, no typo

#

i have no idea what's wrong

#

maybe i should call it with .mat ?

stone shoal
#

Also not with capital letters?

lofty lark
#

never needed that before though

#

yeah the case is correcty

stone shoal
#

It needs to be the material

#

But maybe this is a meshy problem again ThinkingIT

lofty lark
#

yeah that's what i did.

#

ah

#

well that would be problematic

#

i mean the mod can work without

stone shoal
#

@jagged python doe beaver materials also do something weird with meshy like loading the binary ?

lofty lark
#

going afk for 30 min

stone shoal
#

Its really the asset that is not found, find it kinda weird it has a other error than with the meshy buildings

lofty lark
#

let's wait for the cavalry to arrive then ShrugFT
it used to work in V3 though.

jagged python
stone shoal
#

Alright, find the error still kinda weird than. Since it complains about the resourceLoader

#

Will check it thanns

lofty lark
#

thanks !
on an unrelated note, since TimberAPI now replace categorybutton mod, would it be possible to have it also put all those bridges in a subgroup directly ? i thought about doing it in my mod, but i'm afraid mods might want to do it too resulting in incompatibilities.

if you want i can prepare the specifications for you ๐Ÿ™‚

acoustic eagle
#

@vast otter does this already in one of his mods.

severe solar
#

The best would be that its a seperate mod then

stone shoal
lofty lark
austere tangle
#

I don't think that will be funny that at every load to start searching where are located the bridges or other stuffs in menu ๐Ÿ˜ฌ

stone shoal
#

And thats more a you need to fix problem HappyIT

north hatch
#

@stone shoalSorry to bother again blobsweat
How would i load a custom specification file?
I took a look at Recipe like you said before, but it also loads the specifications from the components, which i can't do

#

essentially i think the best way to go about this is have a json specification i can load for each pipe

#

which i can then add to my FluidTransputSpecificationProvider

#

Since this cannot be done inside unity

[SerializeField]
private FluidTransputSpecification[] _transputSpecifications = new FluidTransputSpecification[0];
#
    [Serializable]
    public class FluidTransputSpecification : BaseComponent
stone shoal
#

No idea what you mean loafs from the component

north hatch
# stone shoal No idea what you mean loafs from the component

in unity you can edit fields if you mark them as serializable. Normally you can do this with classes too, but not when they're not there at compile time or something (idk exactly how it works, but apparently you cant do it when modding the game)

#

things like this

#

it works for primitive types

#

but not classes

#

normally here you'd be able to add array elements of that type and have its fields filled out and create that class behind the scenes

#

like there

stone shoal
#

But this arent specification files

north hatch
#

then why are they called specfications

stone shoal
#

Because fun

#

They kinda do the same i suppose

#

And they can do more with them

#

But it would be possible to convert all those to actual specifications

north hatch
#

yeh but this is turning out to be a giant pain in the butt

stone shoal
#

Wym

#

Tbh i dont see what the problem is but sure xd

vast otter
# north hatch things like this

@severe solar how did you do the first categorybutton when you had components to set categorybuttons ThinkingIT else maybe look at last categorybutton it reads Spec files

vast otter
severe solar
#

I loaded the json and overwrite the relevant components

vast otter
#

first verion you had so we added a component to each object(In unity) ThinkingIT github maybe have that code still there

severe solar
#

that was just to fake it to be a building

#

not really relevant here, though i dont know what the conversation is about here

north hatch
#

the thing we discussed before with the serializable classes

vast otter
#

to create components to add to a prefab if i get it correct

#

(and set parameters in it)

severe solar
#

u either use that, or use jsons

#

or use a hardcoded class

north hatch
#

i know, but i want a proper way to read the jsons

#

yeah i'll just do that then, i wanted to include thme in the asset

#

but then idk how to read it

vast otter
#

or do a patch to the game if your custom component exist do not do power transfer?
but categorybutton do read Specifications!

north hatch
#

i want to avoid patching if i can

severe solar
north hatch
#

tnx

severe solar
#
private void LoadPathSpecifications()
        {
            var list = _specificationService.GetSpecifications(_pathSpecificationObjectDeserializer).Where(specification => specification.Enabled).ToList();
            var orderedList = list.OrderBy(specification => specification.ToolOrder);
            PathsSpecifications = orderedList.ToImmutableArray();
        }
#

specificly that part

#

you dont need the ordering or anything

#

To use it, you need to create a class like PathSpecification, which is easy to understand

#

That class is used to read the json and convert it to a useable class

north hatch
#

ok thanks

#

ill take a look after my match

stone shoal
north hatch
#

not really, but would make sense

stone shoal
#

Not if its a specification ๐Ÿ‘€

north hatch
#

well the most sense would be on the prefab but guess we cant have nice things xD

stone shoal
#

But then mod users cannot easily change it ohlsippyn

north hatch
#

they dont have ot

stone shoal
#

Ye than its less nice

#

What if you make 3 lose basic lists

#

And make an editor script to use it easily thonkeyes

north hatch
#

cant

stone shoal
#

Not sure if an editor script csn go that far

stone shoal
north hatch
#

cuz idk how to xD

#

hardcoding or json will do fine then :p

stone shoal
#

Magic

north hatch
severe solar
#

i dont load them, thats all done by TAPI

#

and yes, location should be <mod folder>/Specifications/<Speification jsons>

north hatch
#

and the naming of the specification? NameSpecification.Faction.Prefab?

severe solar
#

Whatever you want, as long as the first part ends with Specification and has the same name as your class

north hatch
#

ah ok

severe solar
#

as many dots as you want and whatever in between

#

but also must end on .original

north hatch
#

hmm i see

#

is there no easy way to make objects out of the json?

#
{
  "Transputs": [
    {
      "Offset": [
        0,
        0,
        0
      ],
      "Direction": "Down"
    },
    {
      "Offset": [
        0,
        0,
        0
      ],
      "Direction": "Up"
    }
  ]
}
#

this would be the json

#

i feel like it would be easier to just use newtonsoft or whatever to parse the json at this point

severe solar
#

what?

#

everything is done for you

#

you only need to create the layout

north hatch
#

well that is the layout, but how would i get Offset?

severe solar
#

the first time i did it it was confusing, i have to admit

#

PipeSpecification.Offset

north hatch
#

uh

#

that cant work since its an array, so theres multiple offsets

severe solar
#

SadIT i just started a league game

#

you will need to give it the PrefabName aswell for example

#

call first where that is the one

north hatch
#

but these are all on the same prefab

severe solar
#

yea, its an array

#

oh, sorry

#

but that will be just the same logic as before

#

you will have an array of items

#

oooh, you mean that you have to load underlaying items

#

now i understand

north hatch
#

yeah hah

severe solar
#

sorry ๐Ÿ˜ฆ

#

uuuh, i believe you can have an objectdeserializer for that aswell

north hatch
#

finish your game, i wont go anywhere kek

severe solar
#

finished

#

wanna call about iut?

north hatch
#

sure

wintry void
#

I keep getting this and not sure how to fix it.

nova gale
#

are you trying to use a mod that is not Update 4 compatible?

vast otter
calm copper
#

In the tool specification, does the Icon field specify a Sprite? Or a texture? I created two sprites from one texture (sprite mode = multiple). The texture is recognized well in the specification, but the sprites made of it are not.

calm copper
#

So, based on my tests it seems the icon is loaded as Texture2D resource, not as a Sprite. Extrude edges on the sprite object also has no effect on the final icon in the tool.

stone shoal
#

Icon is a spritr not multiple

vast otter
calm copper
#

Nor it respects "extrude edges" setting on the sprite. The only way I found working to add padding, was modifying the texture itself and adding padding into the bitmap.

lofty lark
#

about the "toolspecification" thing we can use to modify existing buildings without modding them in and out, what does the name actually target ? typically i got the silly idea of wanting to replace the birch tree, but it is not in the factionspecifications because all factions are supposed to have birch. so can i make a toolspeficication.birch.json (of building specification) that just disables it by changing the prefab name while my custom tree (that is backward compatible with birch) highjacks the spot ?

stone shoal
#

You cannot change a prefabName

lofty lark
#

hmm

#

oh !

#

you're right

#

i never looked into this folder before, but there is one called prefabcollections

#

that list various things

#

so i can remove the brich from this list, and add it as unique ressource back in other factions

#

thanks !

stone shoal
#

probably]

nova gale
#

was it considered to make the options of mods create a file for each settlement instead of being a global one? and then giving the option of editing the config during the game?

#

when a save is loaded, look for a config file with the save name, if it exists call a method in the mod passing the new config values

#

and do the same if the user edits the config during game

stone shoal
#

That is probably not going to happen, if you want your specifications in specific faction online the specification should be made that way

#

Would to much hassle to do that in TimberApi for all specifications to maintain

#

There might come something with configs tho

nova gale
#

what do you mean something with configs

vast otter
lofty lark
#

so i just add the birch to the map editor list too, should do the trick ?

vast otter
#

you just have to try it out ๐Ÿ˜‰

lofty lark
#

hmm...if it is part of the map editor tools it seems to be added to every faction immediately

vast otter
#

probobly ya dam is and other map editor parts is set a devmode so thats why its now shown in normal play

#

wonder how they did the trees only for certen factions. but then again you cant plant those in map editor

lofty lark
#

oh that's easy, basically the IT only trees replace normal trees

#

anyway, got it to work

#

i don't know what happens if some crazy weirdo tries to make maps with my mod though

vast otter
#

but do mapeditor still work and normal faction have birch?

#

or did you manange to replace basegame item? birch and replace with yours? ThinkingIT

lofty lark
#

well they still have birch

#

but i have entire tool categories hidden in the FT and IT so to be honest playing them seems a pretty by idea with my mod installed

#

but i'll probably do a thing with the new game menu so people don't get mistaken when my mod is active

lofty lark
#

honestly it would be nice if they fixed that, what if i want my map to have wild carrots ? ๐Ÿ˜…

vast otter
#

๐Ÿ˜ฎ ๐Ÿ˜ฆ

#

ya

lofty lark
vast otter
lofty lark
#

ah, i see what you mean, no FT and IT still have regular birch

#

and loading my faction without having it installed might be troublesome ๐Ÿ˜…

vast otter
#

im talking about what happens if you have your mod installed open a map in mapeditor save and then load without your mod all pink birch will then just disappear because base game birch do not have backwardcompatible prefab

but that is what it is just place a note in description if they dont read it its there fault ๐Ÿ˜›

lofty lark
#

sorry i'm not sure i understand ๐Ÿ˜…

vast otter
#

aha ๐Ÿ˜ฎ so what then happens if you load a map with birch on it in the mapeditor do it just remove it?

lofty lark
#

i just tried... oopsie ๐Ÿ˜…

#

no birch anywhere

vast otter
#

๐Ÿ˜ฆ

lofty lark
#

but now that i think about it...i can mod it all back in !

vast otter
#

well then maybe add it to trees collection even if it is added to all factions

lofty lark
#

hmm... no that's kind of whacky

#

oh well, let's not use map editor with this mod i guess ๐Ÿ˜…

vast otter
#

what is not whacky we are modding ๐Ÿ˜›

#

some one will do it to customize to be able to play your faction and then all will break ThinkingIT

#

or get it to crash in mapeditor and see that as a feature they should not be there with the mod active ๐Ÿ˜›

#

(change mod.json Scenes : all to ingame and it will crash)

lofty lark
#

Crash is the best safety๐Ÿ˜…

vast otter
# jagged python Meshy uses materials provided by IMaterialRepository. It has only one method tha...

Is it possible to get an example image of how levee.meshy file looks like in unity on your end?(Like image 2)
to verify that we get how to import it correctly in unity.

This is because currently i can not get it to show the model in unity when i have the meshy file and it feels like im missing a step to get a prefab or something. to have multiple components one with binary data and one model metadata i only get a file that i cant read and nether can unity :S

do we need a plugin to unity 2?
because i can only suspect that you dont only see a unrecognized file in unity and not the model

1: image is how the meshy that i export look like in unity (not recognized)
2: image is how a prefab that is exported look like and they do not look the same even.(this is more what i expect to include in the mod)

calm copper
#

I figured the problem with spriets with splices: they need to be loded differently in Unity. Instead of Resources.Load it should be Resources.LoadAll. Thus, sprite slices just cannot be used as tool icons.

jagged python
# vast otter Is it possible to get an example image of how levee.meshy file looks like in uni...

Meshy files are not recognised by Unity by default, but may be deserialized by custom ScriptedImporter class. Our implementation (which allows for preview in editor) is however a strict Editor only code, so it does not get included in final build. If you'd like to create a preview, you'd need to write your own ScriptedImporter (that reads the file and uses MeshyReader and MeshyImporter classes to create preview mesh).

ebon sparrow
#

(or kindly ask devs to share theirs ๐Ÿ™Š )

vast otter
#

it would be great help to to be able to see in the editor but then again that is not the reason why we are not able to get it ingame only a visual aid. if you dont want to share that is what it is but would love it if possible

stone shoal
#

Because unity was like... let's not make the load method in asset bundles work the same as the resource folder loader

vast otter
#

๐Ÿฅน

stone shoal
#

Knatte you cannot code right ?

vast otter
#

ya ๐Ÿ˜ฆ

stone shoal
#

Well than nvm

#

Maybe I have time today, but else Ill fix that tomorrow (as far as I know how without being able to test)

#

Then the reloading error is also pushes at least

#

and people can test out meshy

#

But the unity editor script would be very much appreciated party_parrot

lofty lark
#

I finally found out what was the issue prevening me from loading the custom white beaver skins !
it was simply that it was no longer the material being called but the png. easy peasy.
also fixes a small issue we had with the kits having dark arm and legs for some reason, thanks devs ! ๐Ÿ˜Š

spiral charm
#

Lmao they do ๐Ÿ˜…

lofty lark
#

well as long as you don't say rats... they won't try to gnaw your throat while you sleep ๐Ÿ˜…

ebon sparrow
orchid sage
lofty lark
#

White rats make actually nice pets ๐Ÿ˜‰

lofty lark
ebon sparrow
#

maybe it is case sensitive? try ingame or InGame ?

lofty lark
#

ah, good point

#

what are the other possible "scenes" ?

#

i think i need the mod active in the main menu, it crashed when clicking on "new game"

ebon sparrow
#

don't knwo TAPI nomenclature, but scenes are MainMEnu, Game, MapEditor

median plinth
lofty lark
#

MainMenu and InGame seem to do the trick, thanks !

calm copper
#

I must admit, this specification approach is a powerful tool when you get used to it. With just one class that accepts tool info, I created a dozen of tools that do different things.

stone shoal
calm copper
#

Question. Let's say someone makes his own tool buttons. Can he use a type class from my mod? Or any mod fwiw. Or should it be a type from the DLL that's listed in the mod.json?

austere tangle
#

If you add a mod as dependency, you can use what is in that mod .

calm copper
#

Ah! The dependency link is needed. It makes sense.

north hatch
#

But def best practise to include it. That way mod.io can have its dependencies linked too

austere tangle
#

YA, that's to prevent a crash due to accesing something that do not exist ...

calm copper
#

So, it's nice to have, but not required? I agree, that having an explicit dep is a good practice. Just trying to clarify the case.

north hatch
#

Yeah

austere tangle
#

In fact, if dependency mod do not exist, the mod that depends on it will not be loaded .

calm copper
#

Which totally makes sense.

austere tangle
#

Best case is TimperAPI. If is not installed, what mod will be loaded ? Except ModManager, WindChanger, Fixnearplane and ...

stone shoal
#

TimberApi uses it to order everything correctly

slender hatch
nova gale
#

explosives for a 3x3 area would be cool too

austere tangle
#

You want to start a war ?

ebon sparrow
#

or maybe win one? ThinkingIT

stone shoal
#

MapTnt: lowers the whole map that doesn't have a building on it KEKW

nova gale
#

or it could blow like a + the center point and the tiles orthogonally adjacent

calm copper
# nova gale explosives for a 3x3 area would be cool too

This would be kind of a cheat. In 3x3 area, the very middle point is not reachable in case of the area is elevated or deep in the terrain. My mod simply schedules a dynamite setup, but the builders still need to come and make it as usual.

nova gale
#

its not a cheat if you make it cost the right amount

calm copper
calm copper
nova gale
#

yeah, a new explosive

calm copper
#

With a cost of, say, 9 charges and 2 planks. Indeed, it would be a good thing for terraforming.

nova gale
#

yes, it can cost more in resources than 9 explosives even, the big benefit is that you only need 1 builder trip instead of 9

calm copper
#

Why just one? In order to bring 9 charges you'd need 9 trips.

#

I don't recall the weight of the charge though.

#

But with planks cost an extra trip would be required for sure.

nova gale
#

a new explosive type Big Explosive, that to produce costs more than 9 explosives, but to build its just 1 Big Explosive

full acorn
#

Quick question on UI, looks like setting margin is only on anonymous function and setting background is only available when using CreateFragmentBuilder - am I missing something to be able to set a background and a margin?

#

I feel like I'm missing something, but a bit lost

full acorn
#

Ignore me, obviously not doing enough of the thinky-think

stone shoal
#

Seems like it