From the Burrow

2025-09-02 16:17:06 +0000

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 480

2025-09-01 19:44:49 +0000

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

2025-08-29 18:53:17 +0000

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

2025-08-28 10:41:00 +0000

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

TaleSpire Dev Log 475

2025-05-27 19:52:50 +0000

Howdy all,

Lot’s in flight right now.

Chairmander has been working on the tags and part of that has been upgrading the creature format to support those. Yesterday I helped a little by updating the pack loading code in TaleSpire to work with the latest version of the format. I got to spend a little time helping get the vision limit feature closer to merging, and testing some backend fixes which will (when complete) allow some more features to progress.

However the main thing I’ve been spending my time on the last couple of days has been the particle system. Like many other particle systems the behaviour is scripted via a noodle graph[0]. We’ve had issues in the past with libraries for making these graphs so over a year ago, Ree made one for us. I’ve finally been able to get stuck in and it’s been ace.

I’ve just finished making the serialization code and hooking it into Unity’s save prompting system.

Next up I’ll be working out how I want the type and error checking to work, and then I’ll sketch out the basics of the compiler. From there I can hand all this over to Alex so he can add it to his work on the particle system.

If all goes well I should be back on the dice networking rewrite late next week. Early in the week I may be involved in a little hackaton, but I’m not sure what on yet.

All fun stuff, looking forward to telling you more.

Peace

Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team

[0] Or node graph, whichever you prefer

TaleSpire Dev Log 474

2025-05-21 20:04:51 +0000

Heya folks.

Here’s a smattering of stuff I’ve been up to recently.

I’m getting ready to take this fix to slab placement out of Beta. It’s had good testing from folks in the community, so I’m happy we’ll finally be shipping it. I’ve got the build on our pre-production branch, and I’ll do the final release testing tomorrow.

I’ve been helping out a bit with the WIP particle system. My role is writing the spec, stubbing out the API, and then setting Alex loose on it! Things are taking shape well there. Alex has been refactoring his particle experiments into more reusable code. He’s also been researching what core operations are needed for us to build the rest of the standard library. We are slowly cornering the design, and it’s a lot of fun.

Yesterday afternoon, however, I simply couldn’t get my brain to focus on particles, so I read about the network sync of physics objects. This meant I was in the perfect place to start a VERY overdue task: rewriting how our dice are synchronized.

The code that manages the dice has been around since before TaleSpire was called TaleSpire, and has been frankensteined over the years as we have added more features on top of it. Due to this, it has some very long-standing bugs. It is way past time it got some love. Until now, every die was its own synchronized entity in Photon, so it was often tricky to treat them as a group. In the new version, the “roll” is the synchronized object, and we handle the data packing ourselves. The result should be greater stability and hopefully less traffic used.

Until now, we have limited the number of dice in a single roll to 40. There have, however, been mods that hack around this. In the new version, the protocol will have a fixed limit of 64 dice per roll[0]. It will not be possible to change this without replacing the sync code.

You can still have many hundreds of dice on the board, but each roll will have that hard limit. This limit also won’t affect multi-part rolls (which will come with the improved dice macro system later).

We are aware that it’s possible, in games like 40K, to have some utterly mad rolls, but we think we can tackle mega rolls as their own feature in the future when it becomes an issue.

We do not foresee this being an issue for general play, but we didn’t want it to seem like we were sneaking this change past you. So now you know!

I’ll definitely write more about this as it gets closer to shipping. With the roll code rewrite, it’s going to be even easier to add the dice automation later this year.

That’s all from me today.

Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team

[0] The UI may limit to less (e.g. 60) as a round number and will feel more natural to most folks.

TaleSpire Dev Log 474

2025-05-14 09:54:31 +0000

Morning all,

Amongst the vision limiting and bug fixes, I’ve been working on a feature that lets you store dice rolls in your inventory.

dice in inventory

The visuals are all 100% work in progress, but it feels good to get something working on this. The feature has been on my mind for a long time.

This feature is one that starts small, but as we make this behavior more universal, it will become more important. Early on the list is being able to drag things to chat messages to send them to other players, and to be able to drop them into symbiotes so others can build upon it. In time this also will include per-creature inventories and gm-containers (chests maybe) that have inventories that can store goodies.

This has been on my wishlist for a long time, so I’m glad to see some movement. It’s also got me working on the dice rewrite again, which has been parked for ages (for dumb reasons I’ll go into another day :/)

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 462

2025-02-17 09:12:03 +0000

Howdy folks. My posting is erratic, but I am still working away. Recently, my focus has been on localization and more 3rd-party mini support.

Localization

I’ve been on a translation kick again in the last few days. I’ve been fixing bugs and going through the main menu and settings panel, slowly making all the text elements translatable. This is tedious work, but it’s got to be done.

One tip I picked up from a GDC talk (I can’t recall which one[0]) was to make a “translation,” which is just the English text backwards. This helps as, even if you aren’t skilled in other languages, you can see what UI elements have not been translated at a glance. It’s easy enough to read the text, too, so you can keep testing the game.

My next task here is to make dropdown menus localizable. Let’s hope that is as easy as it sounds.

Once we have something I’m happier with, I’ll enable the translation tools in the settings panel, at which point some of the adventurous of you can kick the proverbial tires.

Additional third-party mini support

You have all made the community creation support a huge success. While we at Bouncyrock still have a lot of work to do (for example, tagging, improved search, and tile/prop support), we are delighted and amazed with how much you have all built. Naturally, not everyone is a 3d artist, and there are folks online who have created great options for making and exporting miniatures. Eldritch Foundry and TitanCraft are two who have reached out to see if we could make the process of bringing creations to TaleSpire as smooth as it is for the community and HeroForge.

As usual, we are not taking any money or kickbacks from EF or TC for doing this, and we won’t be taking a cut of their sales [1]. We just want to make sure the community is strong, and part of that means giving you all options.

We still have our creature creator on our roadmap, but we are a tiny team, so it takes us a long time to get big stuff done. Luckily, we aren’t going anywhere, so we’ll keep building, and the rest will work itself out.

I’ve been using this feature as an opportunity to do the work to merge the 3rd party providers into the community creations panel. Currently, HeroForge is in a separate tab, but the community browser has always been meant to support many providers. Having HF separate has been grand, but it will get a little unwieldy once we have three mini-providers. This work is also helping with the future community-run-repository support as it’s forcing me to fix a lot of places where I had hardcoded things for Mod.io support[3].

More stuff

Here is a grab-bag of other stuff that I’ve been involved in.

We had a report of a weird performance bug where player mode was running slower than GM mode. That kind of bug is catnip to me, so I dove into fixing that. When that was done, I used Unity’s PlayerLoop API to add a new callback later in the frame that they usually let us run code. The goal here was to run some tasks while waiting for rendering to complete. This worked, but it didnt give the performance boost I was hoping for[2]. However, it was fun for an hour’s work and something I will definitely be revisiting when I return to performance work. I’d love for TaleSpire to get faster as we add more features, rather than how it too often feels in much of software we all use day to day.

Chairmander has been working on tagging, so I’ve been in meetings with him as we hammer out details.

Among the many things Borodust has been working on, he made a nicer view of our internal error tracker, and with it, I found a load of bugs in TaleSpire that would be difficult for users to report due to how they manifest. I fixed about 8 bugs that afternoon. That was great fun.

The creature-vision-limit feature has been parked for a few weeks as it needs some play testing, and we’ve all been busy. The play sessions are to determine what else we want to do with the UI for the feature. The sooner we get that done, the better. I’m dying to get that in your hands. Today, I’m probably going to be wiring up some excellent work by Ree, which makes the range limit hide the floor plain in addition to hiding tiles/props/creatures.

Well, that’s what’s popping into my mind right now. I’m sure I’m forgetting a slew of other things, but that’s what dev log 463 is for!

Peace.

Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team

[0] It might have been this one [1] The same is true with HeroForge [2] Unity’s frame interleaving was already doing a semi-decent job and so we didn’t get a benefit from just pushing things around. [3] This happened as I was rushing to try and get the package managed shipped before the heat death of the universe :D

TaleSpire Dev Log 456

2024-09-12 08:49:08 +0000

Allo folks,

Yesterday, I exported the Norwegian translations into the new format. This went well. I’m now looking at the developer’s experience of using the system.

I hope to obviate the need for a central registry of text entries that the developer has to manage[0]. TaleSpire needs to be able to export a translation template for a given language, and that file will have to include all the things that need translation. When we are in the Unity Editor we can iterate through all the objects in the game looking for translatable elements, but that isn’t something we can do once it’s shipped. That is a place where a registry helps, so I will try building this structure when we build the game.

The only fiddly part is that (unlike Godot) Unity has objects in both scenes and prefabs and working with scenes is more awkward than working with prefabs. Hopefully, it doesn’t prove to be too much of a pain.

Community creations will build their own translation tables when saved from TaleWeaverLite. That will be much easier as we control the whole format and process there.

More news coming soon.

Ciao.

Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team

[0] This desire came from our experience using the previous system.

TaleSpire Dev Log 453

2024-09-09 21:28:26 +0000

Good evening all,

On a bit of a roll with dev-logs today. Today, I’ve been working on the translation file format.

The goal is for a translator to go into TaleSpire, choose a language, and click export to produce a file that has all the strings that need translation for that language.

As usual with human stuff, it’s never that simple.

If you like a more complete and entertaining version of this, check out this Tom Scott video. https://youtu.be/0j74jcxSunY

Let’s say you want to display: “{creature-name} has {some-number of} apples.”

In the case of one apple, we’d probably want to write “{creature-name} has 1 apple”, not “1 apples” so plurality is something we will need to care about.

Let’s say the number of apples is in parameter @1. We could have some simple rules where the value is used to pick the correct text. For example:

{creature-name} has {@1=1:an apple|@1 apples}.

This syntax could mean that if @1 equals 1, use an apple. If not, use @1 apples.

Seems like a good start, but many languages have more complicated systems[0]. Luckily, the Unicode Consortium has assembled a big ol’ table of pluralizing rules. Just look at that monster! This does help, though, as translation libraries can implement these rules to provide a tool for their translators.

Most language complications are not this readily solved, though. Translation tools generally just punt and let the translator handle the issues. Which, honestly, is the right move. You want a human translation, and many texts need significant restructuring to make them feel native.

The grammatical gender of words is another thing that will come up a lot. If you, like me, were raised in a language which didn’t have grammatial genders for nouns it can feel very confusing to hear that a city is female or a door is male or whatever. This is because we conflate it with sexual gender (at least, I certainly did), which it’s not. It’s quite simply the category of the noun[1] (often called a noun class IIRC). It frequently has some overlap with sexual gender, though, which can make things extra confusing[2]. So, let’s talk about these categories.

Just gotta shout out Worrorra, which also has “terrestrial,” “celestial,” and “collective” genders. How dope is that?!

Right, so in our “apples” example above, languages will translate the text differently based on the class of both “apples” and the creature. The word “apples” is hard-coded into the string so it can be handled there, but the creature-name is passed in from the game. What we can do is support passing values (like gender) to the translation library and let the translator pattern match those parameters. Of course, in all cases, the translator also has to provide a version of the text for the “unspecified” case. In the future, we’ll need to give you various options so that, if you want (and if it makes sense), you can specify the gender of your characters.

So that’s a little ramble about some complications with translations. At the end of the day, you just gotta give the translators decent information and let them work their magic.

I’ve written a small specification for our file format. It’ll allow for pattern matching on the input arguments and a few kinds of inline formatting tools within the translation string. Those formatters include:

  • Simple list handling
  • A plural form selector (following the rules from unicode)
  • Picking the nth of some number of forms based on a parameter or conditional checks

I don’t need to implement all this tomorrow, though. My current goal is to get our (very wip) Norwegian translation working again and get this system merged into master. That translation doesn’t use any fancy features yet, so I can implement the rest another day.

Well, that’s all from me for now.

Seeya!

Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team

[0] And some languages, like Indonesian, have no differentiation! Which is awesome. This is the equivalent of “one sheep, many sheep” in English.

[1] Gender, in this case, derives from “genus,” meaning “kind,” which more clearly highlights that relation to “category.”

[2] In French, you get cases where you can end up referring to a rabbit using the masculine class, even if you know the rabbit is female.

Mastodon