Defold 1.10.2 BETA

Defold 1.10.2 BETA

Disclaimer

This is a BETA release, and it might have issues that could potentially be disruptive for you and your teams workflow. Use with caution. Use of source control for your projects is strongly recommended.

Access to the beta

Download the editor or bob.jar from GitHub: Release v1.10.2 - beta · defold/defold · GitHub

Summary

  • NEW: (#10547) Added support of runtime creating and updating of textures array (by ekharkunov)
  • NEW: (#10619) Make it possible to set GUI resources using gui.set() (by AGulev)
  • NEW: (#10539) Wrong include reference for dmMemory (by selimanac)
  • NEW: (#10715) Added support for hash userdata type keys in lua table (de)serialization. (by Gert-Jan)
  • NEW: (#10587) Allow getting/setting more properties using editor scripts (by vlaaad)
  • NEW: (#10635) Improve Scene View error experience (by matgis)
  • NEW: (#10651) Directories are now treated as resources in editor scripts (by vlaaad)
  • NEW: (#10644) Allow editing atlas images and animations from scripts (by vlaaad)
  • NEW: (#10701) Introduce property drag handle (by sprocketc)
  • NEW: (#10662) Expose tilesource animations and collision groups to editor scripts (by vlaaad)
  • NEW: (#10714) Edit tilemaps using editor scripts (by vlaaad)
  • NEW: (#10723) Edit particlefx emitters and modifiers using editor scripts (by vlaaad)
  • FIX: (#10592) Default to no wasm simd on HTML5 (by JCash)
  • FIX: (#10589) Copy resources from pods (by ekharkunov)
  • FIX: (#10529) Updating volume and panning handling for sound system (by thengel01)
  • FIX: (#10626) Faster atlas creation (by AGulev)
  • FIX: (#10631) Make sure that GUI components are sorted per world (by AGulev)
  • FIX: (#10653) go.exist() will now throw a Lua error if referencing another collection (by britzl)
  • FIX: (#10656) Fixes memory leak in profiler on web platforms (by AGulev)
  • FIX: (#10661) Make sure that changes in shaders are always taken into account during rebuild (by AGulev)
  • FIX: (#10663) Added function dmGameSys::ResFontSetLineHeight() to set font line height for dynamic fonts (by JCash)
  • FIX: (#10678) Added mutex to font.cpp to protect when adding and removing glyphs dynamically (by JCash)
  • FIX: (#10695) Updated to lipo 0.10 (4c7c275) to fix a Windows renaming issue (by JCash)
  • FIX: (#10713) Fixed issue where build to remote target can’t load a file more than once (by AGulev)
  • FIX: (#10654) Make sure hashes are comparable even after the game object is removed (by AGulev)
  • FIX: (#10686) Fixed data size when uploads compressed paged texture (by ekharkunov)
  • FIX: (#10712) Fixing EOS behavior of tremolo decoder when skipping data (by thengel01)
  • FIX: (#10705) Adding check to avoid zero delta values in sound mixer (by thengel01)
  • FIX: (#10727) Fix for getting win32 user directories containing unicode characters (by JCash)
  • FIX: (#10730) Improve hash management when creating objects using collectionfactory (by AGulev)
  • FIX: (#10734) Remove all dynamically created hashes (from factories) when they aren’t used anymore (by AGulev)
  • FIX: (#10624) Update camera.set_orthographic_zoom to accept numeric zoom value (by aglitchman)
  • FIX: (#10611) Add game objects, collections and components on drop (by sprocketc)
  • FIX: (#10612) Fix minimum scrollbar thumb size (by sprocketc)
  • FIX: (#10522) Render convex hull collision shape (by sprocketc)
  • FIX: (#10610) Don’t apply Model material assignments unless fully-formed (by matgis)
  • FIX: (#10696) Take page offset into account when calculating the absolute position of the pivot handle (by sprocketc)
  • FIX: (#10697) Improve performance when editing a large tilesource (by sprocketc)
  • FIX: (#10575) Added thread support to HTML5 (by JCash)

Engine

NEW: (#10547) ‘Added support of runtime creating and updating of textures array’ by ekharkunov
Texture arrays can be created and updated in the runtime. Example how it can be done:

--- create new texture array
	local new_tex = resource.create_texture("/runtime/example_array.texturec", {
		type = graphics.TEXTURE_TYPE_2D_ARRAY,
		width = 512,
		height = 512,
		page_count = 5,
		format = graphics.TEXTURE_FORMAT_RGB,
	})
--- update texture array slice
	local tex_path = "/bundle_resources/slice_02.png"
	local data = sys.load_resource(tex_path)
	local buf = image.load_buffer(data)
	resource.set_texture(new_tex, {
		type = graphics.TEXTURE_TYPE_2D_ARRAY,
		width = buf.width,
		height = buf.height,
		page = 1,
		format = graphics.TEXTURE_FORMAT_RGB
	}, buf.buffer)
	go.set("#mesh", "texture0", new_tex)

Also resource.get_texture_info() returns additional field page_count with actual slice count. For regular 2D texture value is 1, for cube map is 6.

NEW: (#10619) ‘Make it possible to set GUI resources using gui.set() by AGulev
It is now possible to set Font or Texture resources for a GUI using the gui.set() function from the GUI component itself, provided that msg.url() is used as the first argument instead of a node.

function on_message(self, message_id, message, sender)
   if message_id == hash("set_font") then
       gui.set(msg.url(), "fonts", message.font, {key = "my_font_name"})
       gui.set_font(gui.get_node("text"), "my_font_name")
   elseif message_id == hash("set_texture") then
       gui.set(msg.url(), "textures", message.texture, {key = "my_texture"})
       gui.set_texture(gui.get_node("box"), "my_texture")
       gui.play_flipbook(gui.get_node("box"), "logo_256")
   end
end

NEW: (#10539) ‘Wrong include reference for dmMemory’ by selimanac
Include reference should be <dmsdk/dlib/memory.h> not <dmsdk/dlib/dalloca.h>
Doc: https://defold.com/ref/stable/dmMemory/

NEW: (#10715) ‘Added support for hash userdata type keys in lua table (de)serialization.’ by Gert-Jan
It is now possible to use sys.save() and sys.load() to save and load tables with hashes as keys. This allows for example to (de)serialize tables that are produced and used by collectionfactory. This change also means that sys.serialize() and sys.deserialize() can serialize and deserialize tables with hashes as keys.

FIX: (#10592) ‘Default to no wasm simd on HTML5’ by JCash
This fixes a regression from 1.10.0

FIX: (#10589) ‘Copy resources from pods’ by ekharkunov
Now all resources from Pods correctly packed into .ipa.

FIX: (#10529) ‘Updating volume and panning handling for sound system’ by thengel01

  • Sound panning now configured to correctly pan stereo sound instances (basically treats them as 2 mono sources for panning).

    • NOTE: This fixes a (very old) bug where the mechanism removed ~3dB of the sounds. The fix will make the sound strength back to normal again. If this bug fix affects your game, you can lower the main sound.gain (default 1.0) in the game.project settings.
  • Added logic that can support exponential gain (as in: 0.5 perceptually is “half volume”). This is useful for a nicer fade ins/outs.

    • The functionality is enabled by setting the sound.use_linear_gain = 0 in game.project

FIX: (#10626) ‘Faster atlas creation’ by AGulev
Atlas creation is now twice as fast in bob.jar and about three times faster in the editor.

FIX: (#10631) ‘Make sure that GUI components are sorted per world’ by AGulev
Make sure that GUI components spawned in different worlds (in different collection proxies) are sorted separately, and that the later-spawned world is always rendered on top unless another behavior is specified using gui.set_render_order().

FIX: (#10653) ‘go.exist() will now throw a Lua error if referencing another collection’ by britzl
Like all other functions in the go.* namespace the go.exists(url) function will now throw a Lua error if specifying a url referencing a game object from a different collection than the one from which go.exists() was called.

FIX: (#10656) ‘Fixes memory leak in profiler on web platforms’ by AGulev

FIX: (#10661) ‘Make sure that changes in shaders are always taken into account during rebuild’ by AGulev

FIX: (#10663) ‘Added function dmGameSys::ResFontSetLineHeight() to set font line height for dynamic fonts’ by JCash
There is also the corresponding dmGameSys::ResFontGetLineHeight()

FIX: (#10678) ‘Added mutex to font.cpp to protect when adding and removing glyphs dynamically’ by JCash

FIX: (#10695) ‘Updated to lipo 0.10 (4c7c275) to fix a Windows renaming issue’ by JCash

FIX: (#10713) ‘Fixed issue where build to remote target can’t load a file more than once’ by AGulev
Fixed issue where cached resources loaded remotely from the editor return the wrong file size, resulting in a string length overflow error

FIX: (#10654) ‘Make sure hashes are comparable even after the game object is removed’ by AGulev
Fixes an issue where, after removing a game object, its ID isn’t equal to a hash with the same value.

FIX: (#10686) ‘Fixed data size when uploads compressed paged texture’ by ekharkunov
Fixed wrong data size used when updating a compressed paged texture in OpenGL.

FIX: (#10712) ‘Fixing EOS behavior of tremolo decoder when skipping data’ by thengel01
This fixes a recently introduced issue with sound instances “hanging around” forever if they are played back with group volume down to zero.

FIX: (#10705) ‘Adding check to avoid zero delta values in sound mixer’ by thengel01
This change fixes a recently introduced issue where the engine would crash if a sound was played with a very low speed.

FIX: (#10727) ‘Fix for getting win32 user directories containing unicode characters’ by JCash
This fixes an issue where the engine wouldn’t start for some users, when their app directory contained unicode characters.

FIX: (#10730) ‘Improve hash management when creating objects using collectionfactory’ by AGulev
Fix issue where hash can be removed while it’s in use

FIX: (#10734) ‘Remove all dynamically created hashes (from factories) when they aren’t used anymore’ by AGulev

FIX: (#10624) ‘Update camera.set_orthographic_zoom to accept numeric zoom value’ by aglitchman
The function camera.set_orthographic_zoom() now accepts the value as number (before it was boolean) and works the same as setting this value via go.set.

FIX: (#10575) ‘Added thread support to HTML5’ by JCash
This introduces a new web target platform wasm_pthread-web
When bundling, you can select to include supoprt for this platform.
Note that distribution sites using ADS don’t generally support threads, as it requires CORS setup.

We’ve also updated to Emscripten 4.0.6.
This also updates our minimum supported browser versions:

No Threads:

  • MIN_FIREFOX_VERSION=40
  • MIN_SAFARI_VERSION=101000
  • MIN_CHROME_VERSION=45

With pthreads:

  • MIN_FIREFOX_VERSION=79
  • MIN_SAFARI_VERSION=150000
  • MIN_CHROME_VERSION=75

Editor

NEW: (#10587) ‘Allow getting/setting more properties using editor scripts’ by vlaaad
Previously, some properties couldn’t be get/set by editor scripts. Now, it’s possible to do so! We added support for getting and setting:

  • Color properties
  • Multiline text properties
  • Choice box properties
  • Slider properties

Remaining unsettable properties are curve and curve spread (in particle fx).

NEW: (#10635) ‘Improve Scene View error experience’ by matgis

  • Render errors from Scene View objects are now presented in a more readable view and can be copied into the clipboard.
  • Most shader syntax errors will now cause render errors in the Scene View.

NEW: (#10651) ‘Directories are now treated as resources in editor scripts’ by vlaaad
Now, directories may be accessed as resources in editor scripts. The directories have 2 properties:

  • path - the path to the directory, same as with file resources
  • children - list of children resources

For example, here is how you can ensure that an atlas has all images from a directory:

local images = editor.get("/assets/images", "children")
local atlas = "/assets/main.atlas"
local txs = {editor.tx.clear(atlas, "images")}
for i = 1, #images do
    local resource_path = editor.get(images[i], "path")
    if resource_path:match(".png$") ~= nil then
        txs[#txs + 1] = editor.tx.add(atlas, "images", {image = resource_path})
    end
end
editor.transact(txs)

NEW: (#10644) ‘Allow editing atlas images and animations from scripts’ by vlaaad
Now, it’s possible to edit (add/remove) atlas images and animations using editor scripts. This is achieved using the following additions to the editor script API:

  • atlas resources now define images and animations properties, which are lists of image and animation nodes, respectively
  • atlas animations now define an images property, which is a list of image nodes
  • editor.get can be used to get the list of images and animations in an atlas, and then to look up the properties of the returned nodes
  • new transaction functions editor.tx.add, editor.tx.remove, and editor.tx.clear can be used to edit these node lists
  • editor.can_add can be used to check if a node property is a list of nodes

Some examples:

  1. Add an image to an atlas:
    editor.transact({
        editor.tx.add("/main.atlas", "images", {image="/assets/hero.png"})
    })
    
  2. Find a set of all images used in an atlas:
    local all_images = {} ---@type table<string, true>
    -- first, collect all "bare" images
    local image_nodes = editor.get("/main.atlas", "images")
    for i = 1, #image_nodes do
        all_images[editor.get(image_nodes[i], "image")] = true
    end
    -- second, collect all images used in animations
    local animation_nodes = editor.get("/main.atlas", "animations")
    for i = 1, #animation_nodes do
        local animation_image_nodes = editor.get(animation_nodes[i], "images")
        for j = 1, #animation_image_nodes do
            all_images[editor.get(animation_image_nodes[j], "image")] = true
        end
    end
    pprint(all_images)
    -- {
    --     ["/assets/hero.png"] = true,
    --     ["/assets/enemy.png"] = true,
    -- }}
    
  3. Replace all animations in an atlas:
    editor.transact({
        editor.tx.clear("/main.atlas", "animations"),
        editor.tx.add("/main.atlas", "animations", {
            id = "hero_run",
            images = {
                {image = "/assets/hero_run_1.png"},
                {image = "/assets/hero_run_2.png"},
                {image = "/assets/hero_run_3.png"},
                {image = "/assets/hero_run_4.png"}
            }
        })
    })
    

Related to Editor's scripting proposal · Issue #8504 · defold/defold · GitHub

NEW: (#10701) ‘Introduce property drag handle’ by sprocketc
drag-handle
Draggable properties now display a dedicated drag controller on mouse over input, instead of using the label as a handle.

NEW: (#10662) ‘Expose tilesource animations and collision groups to editor scripts’ by vlaaad
Now editor scripts can access and edit animations and collision groups of tilesources using these 3 new tilesource properties:

  • animations - a list of animation nodes of the tilesource
  • collision_groups - a list of collision group nodes of the tilesource
  • tile_collision_groups - a table of collision group assignments for tiles in the tilesource

For example, here is how you can setup a tilesource:

local tilesource = "/game/world.tilesource"
editor.transact({
    editor.tx.add(tilesource, "animations", {id = "idle", start_tile = 1, end_tile = 1}),
    editor.tx.add(tilesource, "animations", {id = "walk", start_tile = 2, end_tile = 6, fps = 10}),
    editor.tx.add(tilesource, "collision_groups", {id = "player"}),
    editor.tx.add(tilesource, "collision_groups", {id = "obstacle"}),
    editor.tx.set(tilesource, "tile_collision_groups", {
        [1] = "player",
        [7] = "obstacle",
        [8] = "obstacle"
    })
})

NEW: (#10714) ‘Edit tilemaps using editor scripts’ by vlaaad
Now you can edit tilemaps using editor scripts! To support this feature, we introduce the following additions to the editor script API:

  • editor.get(tilemap_layer, "tiles") to get tiles from a tilemap layer
  • editor.tx.set(tilemap_layer, "tiles", tiles) to create a transaction step that sets tiles in a tilemap layer
  • tilemap.tiles.new() to create a fresh data structure that holds an unbounded 2d tile grid (in the editor, contrary to the engine, the tilemap is unbounded, and coordinates may be negative)
  • tilemap.tiles.get_tile(tiles, x, y) to get a tile index at a specific coordinate
  • tilemap.tiles.get_info(tiles, x, y) to get full tile information at a specific coordinate (the data shape is the same as in the engine’s tilemap.get_tile_info function)
  • tilemap.tiles.iterator(tiles) to create an iterator over all tiles in the tilemap
  • tilemap.tiles.clear(tiles) to remove all tiles from the tilemap
  • tilemap.tiles.set(tiles, x, y, tile_or_info) to set a tile at a specific coordinate
  • tilemap.tiles.remove(tiles, x, y) to remove a tile at a specific coordinate

For example, here is how you can print the contents of the whole tilemap:

local layers = editor.get("/level.tilemap", "layers")
for i = 1, #layers do
    local layer = layers[i]
    local id = editor.get(layer, "id")
    local tiles = editor.get(layer, "tiles")
    print("layer " .. id .. ": {")
    for x, y, tile in tilemap.tiles.iterator(tiles) do
        print("  [" .. x .. ", " .. y .. "] = " .. tile)
    end
    print("}")
end

Here is how you can add a layer with tiles to a tilemap:

local tiles = tilemap.tiles.new()
tilemap.tiles.set(tiles, 1, 1, 2)
editor.transact({
    editor.tx.add("/level.tilemap", "layers", {
        id = "new_layer",
        tiles = tiles
    })
})

NEW: (#10723) ‘Edit particlefx emitters and modifiers using editor scripts’ by vlaaad
With this change, it’s now possible to edit particlefx emitters and modifiers using editor scripts. We added:

  • "emitters" and "modifiers" properties on particlefx component
  • "modifiers" property on particlefx emitter component
  • ability to read and write particlefx curve properties in editor scripts

New emitters and modifiers properties are node lists, where each node may be accessed using editor.get() and modified using editor.tx.set(). For example, adding a new circle emitter works like this:

editor.transact({
    editor.tx.add("/fire.particlefx", "emitters", {
        type = "emitter-type-circle"
    })
})

Curves are represented as a table with a non-empty list of points, where each point is a table with the following properties:

  • x - the x coordinate of the point, should start at 0 and end at 1
  • y - the value of the point
  • tx (0 to 1) and ty (-1 to 1) - tangents of the point. E.g., for an 80-degree angle, tx should be math.cos(math.rad(80)) and ty should be math.sin(math.rad(80)).
    Curve spreads additionally have a spread number property.

For example, setting a particle lifetime alpha curve might look like this:

editor.transact({
    editor.tx.set(emitter, "particle_key_alpha", { points = {
        {x = 0,   y = 0, tx = 0.1, ty = 1}, -- start at 0, go up quickly
        {x = 0.2, y = 1, tx = 1,   ty = 0}, -- reach 1 at 20% of a lifetime
        {x = 1,   y = 0, tx = 1,   ty = 0}  -- slowly go down to 0
    }})
})

FIX: (#10611) ‘Add game objects, collections and components on drop’ by sprocketc
Add game objects, collections and components on drop to scenes.
collection-dnd

FIX: (#10612) ‘Fix minimum scrollbar thumb size’ by sprocketc
Increased minimum scrollbar thumb size.

Before (600 nodes) → After (600 nodes)

FIX: (#10522) ‘Render convex hull collision shape’ by sprocketc
Renders the collision polygon of .convexshape files.

Screenshot From 2025-04-17 12-43-07

FIX: (#10610) ‘Don’t apply Model material assignments unless fully-formed’ by matgis
The editor will no longer try to apply Model material assignments that do not refer to a .material resource when rendering Models in the Scene View. This fixes an issue where manually deleting the path from the material resource field of a previously assigned material, that is no longer defined in the referenced Mesh, would cause an exception that locked up the editor.

FIX: (#10696) ‘Take page offset into account when calculating the absolute position of the pivot handle’ by sprocketc
Fixed pivot point handle position on paged atlases.

FIX: (#10697) ‘Improve performance when editing a large tilesource’ by sprocketc
Editing collision groups or other properties of a tilesource which do not affect the tilesource layout will no longer regenerate the texture.

20 Likes

Time to check out all your projects on the new version!

Btw, missing from the list - Update `camera.set_orthographic_zoom` to accept numeric zoom value by aglitchman · Pull Request #10624 · defold/defold · GitHub

2 Likes

Ah, the reason is that the issue wasn’t assigned to the 1.10.2 project:

I will update the release notes.

1 Like

This is a very nice feature for creating levels, but for some reason the object is assigned strange position values when dragging, even in the case of the 2d viewport camera (big Z value).

4 Likes

What a great release! Can’t wait to test all of it once home.

@sprocketc the convex hull display is a god send, huge thank you! Looking forward to when we’ll be able to edit those in the viewport :wink:

8 Likes

Only 2d? It seems from the picture that points are connected by lines in 3d (which is already great, before it was not obvious chaos at all), but triangles are not constructed by them.

1 Like

Polygons should also be rendered in 3D (not just lines). Could you please share a minimal repro case?

1 Like

repro: convex.zip (18.6 KB)

I used Using a DAE mesh for collision to create convexshape(attached to project).

1 Like

The extension-spine example crashes on Mac (M1, Macbook 2020, macOS 15.4.1):

_ZN7dmCrash7OnCrashEi + 104
_sigtramp + 56
_ZN8dmScript13DDFToLuaValueEP9lua_StatePKN5dmDDF15FieldDescriptorEPKcm + 600
_ZN8dmScript16PushDDFNoDecoderEP9lua_StatePKN5dmDDF10DescriptorEPKcb + 140
_ZN8dmScript7PushDDFEP9lua_StatePKN5dmDDF10DescriptorEPKcb + 184
_ZN7dmSpineL7SendDDFEPNS_15InternalGuiNodeEPKN5dmDDF10DescriptorEPKc + 144
_ZN7dmSpineL18SpineEventListenerEP16spAnimationState11spEventTypeP12spTrackEntryP7spEvent + 300
_Z19_spEventQueue_drainP13_spEventQueue + 416
spAnimationState_apply + 1040
_ZN7dmSpineL9GuiUpdateEPKN12dmGameSystem13CustomNodeCtxEf + 232
_ZN12dmGameSystemL24UpdateCustomNodeCallbackEPvPN5dmGui5SceneEjjS0_f + 216
_ZN5dmGui11UpdateSceneEPNS_5SceneEf + 748
_ZN12dmGameSystemL13CompGuiUpdateERKN12dmGameObject22ComponentsUpdateParamsERNS0_22ComponentsUpdateResultE + 228
_ZN12dmGameObject6UpdateEPNS_16CollectionHandleEPKNS_13UpdateContextE + 532
_ZN8dmEngine4StepEPNS_6EngineE + 1272
_Z14dmEngineUpdatePN8dmEngine6EngineE + 32
_ZN8dmEngine7RunLoopEPKNS_13RunLoopParamsE + 104
_Z11engine_mainiPPc + 104
start + 6000
1 Like

I decided to start testing the new version, but even an empty project fails to run:

INFO:DLIB: Log server started on port 52784
INFO:ENGINE: Target listening with name: ARTSIOM-MINI - fe80::9284:85ae:f076:9d04 - Windows
INFO:ENGINE: Engine service started on port 8001
INFO:GRAPHICS: Installed graphics device 'ADAPTER_FAMILY_OPENGL'
INFO:ENGINE: Defold Engine 1.10.2 (a38dee8)
WARNING:DLIB: Unable to convert 'true' to int
INFO:DLIB: Initialized Remotery (ws://127.0.0.1:17815/rmt)
Assertion failed: mutex, file ..\src\dlib\mutex_win32.cpp, line 36
Assertion failed: mutex, file ..\src\dlib\mutex_win32.cpp, line 36

Windows 10. Both from IDE and from the bundle, release and debug.

1 Like

Hmm, do you use the latest beta? Could you please share the SHA1?
Also, macOS shows a popup where you get a slightly better-looking call stack—could you please share it with me?

(I’m testing it now and can’t reproduce, that’s why I’m asking)

An observation - looks like Bullet allows us to feed it anything that forms a convex shape, and how they are connected is not important :sweat_smile:

Triangles vs Quads

.. they both work the same in the engine.

2 Likes

Thanks! We are considering rendering a simple point cloud without lines or triangles when the physics mode is 3d, to avoid making assumptions about the way the physics engine calculates the hull. The change will probably be merged into 1.10.2, so I’ll keep you posted here.

4 Likes

I noticed something possibly related yesterday in our OpenGL backend.
Could you try the Vulkan backend and see if that works for you?

EDIT: I can reproduce it here too

1 Like

Have attached the full problem report, is that what you were looking for?
SHA is a38dee87c1a751ba7187138ff974e89e1e3299e1
problem_report.txt (70.5 KB)

1 Like

Thank you!
I think I found the reason, and the fix is coming.

1 Like

FYI - the same crash on the latest beta (e025243). On Vulkan, the engine runs fine :raising_hands:

1 Like

iPhone 7, Safari 15.6, a project from the empty template, wasm target (without threads) - doesn’t run:

wasm instantiation failed! CompileError: WebAssembly.Module doesn't parse at byte 5: can't get Function local's type in group 1, in function at index 148

P.S. asm.js version runs okay.

1 Like

Thanks for the reminder. Yeah, I was working on that right before we found the Win32/OpenGL issue.
Both are surprisingly hard to track down and pinpoint :confused:
But we’ll get there!

2 Likes