From the Burrow
Heya folks!
In preparation for creature modding feature shipping, we are making the tool available so you can try it out, and we can fix any egregious bugs you find.
You can find a guide on how to get the tool and how to use it over here:
https://talespire.com/taleweaverlite-guide
NOTE: You cannot load the mods into TaleSpire today. This is simply a build of the tooling used to make the mods.
What is this (and what is it not)
TaleSpire is going to have a couple of ways for you to add new creatures to the game:
- In-game creature creator: A way of building creatures out of a palette of configurable parts
- Mods: mod-files are composed of pre-made assets outside of TaleSpire
TaleWeaverLite is for the second approach. It is a very minimal tool for composing pre-made assets into a creature mod that is ready to be used by TaleSpire.
It is not a modeling or posing tool. It expects content in specific formats and with specific layouts.
The expected usage is that the mesh and textures are prepared in other tools, such as Blender, and using TaleWeaverLite is the final step in making a mod.
The good
Once you are producing meshes and textures in the correct format, it’s trivial to turn them into a mod. Simply drag them into the Unity project, set the fields in the creature panel, and save.
The meh
We’ve been using Unity for our asset tools for a long time. It handled processing assets for us and gave us a UI we could use to make tools.
This means that to use TaleWeaverLite, you need to install the free version of Unity.
We have mixed feelings about this, as packaging this stuff for public use has not been as easy as we had hoped. Your feedback will help us decide whether to stick with this in the long term or to start moving to a more standalone tool.
The future
We are busy working on the backend changes needed to support the new creatures. Once we have that done, we’ll wrap up the needed changes in TaleSpire and get ready to ship. We are pushing hard for this and hope we can get this in your hands very soon.
By getting TaleWeaverLite out now, there might even be some new creature mods ready to ship the moment that TaleSpire gets the feature!
Until then, thanks for stopping by.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 494
Allo folks,
This dev-log is for the last two days
I’m working on the code that runs an “effect” as defined in our particle system. This code is currently called the “effect-driver” which may change, but will do for this log.
The effect-driver is a MonoBehaviour (a component that lives on Unity’s GameObjects and gives them behaviour) that holds a reference to an effect made in our system. It then does three main things:
-
Dispatches the various compute-shaders that updates the particles, and then the code that draws them
-
Notices any changes to the definition of the effect and updates or recreates the buffers used for the effect
-
Provides a Unity-friendly UX to the folks configuring the effects. This means both that it’s associated with a GameObject and that it provides UI in the inspector to configure the values used by the effect.
This is already a bunch of work, but there are also other concerns. Unlike normal game code, we need the effect to run in edit-mode rather than just play-mode. This is the norm for tools like these, it would suck to have to run the game every time you wanted to tweak how a particle effect would behave.
There is a tool for this, ExecuteAlways. I’m getting used to how this works. Along with disabling domain-reload (which I mentioned in the last log), this does make fairly major changes to the normal flow of a MonoBehaviour’s lifecycle, so I’m having to read a lot to make sure I have actually understood what it’s doing.
Progress is steady though. I am currently working on the code that works out what parts of an effect have changes and reconfigures the driver.
Until next time.
Peace.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 493
Heya folks,
Today I worked on updating a bunch of our libraries to support a feature in Unity: Disabled domain reload
You can find out the official details here. It does a good job at explaining it actually, so I’ll quote it here:
Domain Reloading resets your scripting state, and is enabled by default. It provides you with a completely fresh scripting state, and resets all static fields and registered handlers each time you enter Play Mode. This means each time you enter Play Mode in the Unity Editor, your Project begins playing in a very similar way to when it first starts up in a build.
Domain Reloading takes time, and this time increases with the number and complexity of the scripts in your Project. When it takes a long time to enter Play Mode, it becomes harder to rapidly iterate on your Project. This is the reason Unity provides the option to turn off Domain Reloading.
It doesn’t affect you folks directly, as it’s purely a Unity Editor thing, BUT being able to iterate faster will be huge for us, so it’s worth the investment.
It took all day, but in the project where I am developing the particle system, the time to enter play-mode went from over six seconds to under one! I’ll take it.
Learning this has been very useful so now I can dive into writing code to run the effects in edit-mode with more certainty.
Until tomorrow,
Peace.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 492
Friday went well enough. I was preparing to rewrite the editor code that runs the effects, as I need to make it work outside of play-mode.
This was a good time to restructure the project, so I was doing that and experimenting with what Unity allows it terms of spreading the definitions of scriptable objects over multiple assemblies. The answer is, in short, it doesn’t. The C# compiler is happy enough with it, but Unity’s runtime is not. It’s fine though, it was simply an effort to keep the codebase cleaner by separating the code that is needed at runtime from the parts that are not.
Tomorrow I’ll be getting stuck into getting particles back on screen, and exploring ExecuteAlways, which is something I’ve only used for very simple systems before now.
Seeya in the next dev-log
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 491
Hey all,
Decent progress yesterday .
- Fixed cases where curves connecting nodes were laid out incorrectly during certain inputs
- Dedicated types for various internal IDs
- Added the ability to drag/drop resources from the Unity project directly into the canvas.
- Improved debugger integration
- Users can now replace connections without removing the old ones first.
- Added a way to specify default values for connectors
- Got user-defined functions to compile correctly when used in other effects.
The drag/drop one is simple but it’s nice to be able to drop a texture into the graph and get a texture node immediately. The same is true when dropping in a user-defined function asset.

The connection replacement, too, is a nice quality-of-life improvement. Previously, connectors could be turned into value slots with a right-click action. However, based on feedback, we’ve moved to showing the value slot whenever a connection is not made. It doesn’t always make sense to have a slot though, for instance, you wouldn’t want to type a texture!

Today I’m going to focus on improving resource handling. In the graph, resource-nodes are nodes where the value comes from the CPU, rather than being computed on the GPU.
Seeya you then.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 490
Heya folks,
As promised, the minimally viable dev log!
I’ve continued work on the fixes post my major refactor of the particle tooling. Today has involved
- A bug in node deletion
- Fixing deserialize as it wasn’t preserving node-inputs with fixed values (as opposed to a connection to another node)
- Improvements to the user api
- And assorted small fixes and improvements
Next up, I’m making it so removing a connection from an input automatically turns it into a value input (I’ll show a gif tomorrow).
Then hopefully I’ll probably be back to the runtime code.
Seeya tomorrow.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 481
Howdy all,
Today, I’ve been back working on our GPU particle system, which will eventually be used for our weather effects.
Our artists will need to be able to script the particles’ behavior, so we’ve gone down the very tried-and-true route of having them make these scripts via a node graph.
WIP version of the node graph. Not final
A while back I wrote a good chunk of the compiler and, although I’ve got more to add, it’s already producing decent compute shaders. Since then we’ve been working on making the user exerience for the artists nicer.
The current task I have for this is adding support for allowing the artists to make their own nodes (essentially functions), which themselves are defined as node graphs.
Hopefully, this’ll only take a few days. After that, I think I’ll be back on dice. We’ll see how it goes.
Until next time folks.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 480
A quick one today.
I put in some basic code for handling language in fuzzy name search. I’m 80% sure I’m going to have to tweak how it works when we work out the UX, so I’m not stressing about it being perfect right now.
After that, I did a little work on the Discord and got set up to work on particles again. Next up, I want to add support for user-defined functions.
Back soon with another dev-log.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 479
Heya folks.
Today I’ve continued working on tags. The big remaining task on my todo list is adding language support to the fuzzy name search. So, of course, I distracted myself working on search performance.
First off, a quick overview. In TaleSpire today, you can search for creatures using tags. In an upcoming version, you’ll be able to search not only by tag but also by the creature’s name. We also intend to make search results update live as you type, rather than having to hit return before it starts the search.
The code to do this is fairly straightforward. We take the text you typed in the search field and loop over all the creatures names computing a score which indicates roughly how different your text is from the name we are checking. If the score is low enough we include the creature in the result.
The score is a not based on real research, it’s mostly a couple of levenshtein distances with some tweaks that got us good results back when I wrote the search last time. For now I’m sticking with this approach so I just wanted to make it faster.
I first wrote the search as a Burst compiled job. Along with some common sense tweaks to avoid lots of allocations, the time to search for a tile (fuzzily comparing against the name of every tile) was ~3ms [0].
This seemed slow, so I turned to the Levenshtein distance function, where the meat of the processing is happening.
The implementation was very nieve, it filled out the entire table of scores before extracting the result (see the linked article above for pictures of these tables). A very simple optimization comes from looking at how the table is filled and realizing that you only ever need two rows in memory, the current one and the previous one. For a long asset name of 50 characters that means only needing 100 elements rather than 2500.
Next up, I decided to cap the portion of the name we would compare to 254 characters. This mean that the highest number ever stored in the table was 255, so we could use a byte. This means 1/4 of the entire row can fit in one cache line. It also means that we only need 512 bytes of data for the two rows.
Lastly, I looked at the fact that I computed two scores. One comparing the search term to the whole name[1], and one comparing the search term to a subset of the name. You might notice that this is duplicate work, so we extract the score for the substring partway through computing the score for the whole name.
These simple changes, which as usual amount to “not doing the dumb thing”, make a big difference. The time for searching all the tiles went from 3ms, to 0.5ms, and searching all the creatures takes 0.05ms.
There is definitely more we can do, but this plenty good enough for a first version.
On Monday I’ll get back to what I was meant to be doing and add the language support :P
Hope you have a great weekend,
Ciao.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
[0] This is a very informal dev-log. We aren’t aiming to be a robust education resource here, and so the timings are adhoc, and only from my specific pc. I’m including them mainly so we can get a feel for the speedup from the changes.
[1] Actually, I split the names into chunks at specific characters, but that doesn’t affect the implementation of this bit.
TaleSpire Dev Log 478
Hi folks,
Yesterday, I wrote the code that performs fuzzy search over the names of assets.
I’m now taking another quick look at tag search, as I need to be able to filter the tags by what kind of asset is currently of interest (e.g. creatures, tiles, or props).
This should be straightforward, and so by the end of today, I hope to have the behind-the-scenes of the tag search finished.
However. I do need to spend some time considering how language plays into search. For example:
- How do we handle translations of the asset’s name?
- When we do, what do we search for? If the name isn’t available in your language, which language/s do we fall back to?
This will be fine. I just need a good mug of coffee and a chat with @Chairmander, and we’ll work it out.
That’s all for now. Hope you have a great day.
Ciao
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team