From the Burrow
Bug Month Patch 4
Fresh out of the national holidays, we have another patch. This one tackles the following:
- Entries in the unique-creature panel should be ordered alphabetically. Previous they would go out of order in certain situations
- Minor performance improvement: avoid re-sorting the unique-creature panel on every change to a unique (such as changing position)
- Fixed an issue where the first use of the ‘sample’ tool did not properly focus the entry in the asset browser.
The war on bugs continues next time, in bug month!
Bug Month Patch 3
Hi folks,
In this release, we are tackling a single bug.
TaleSpire would sometimes place the prop slightly lower than it should when using attachment points. This was cumulative, so over the length of a fence, each piece would be sunk slightly lower into the ground.
This patch fixes this, so subsidence is no longer on the menu!
We will keep finding and fixing more annoyances like this throughout the month.
Until next time,
Ciao.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
TaleSpire Dev Log 432 + Patch Release Notes
Heya folks,
Good news from Steam. They gave the “seats” feature the go-ahead. So now we continue setting up the production servers and getting ready for a release. I will get you the release date as soon as the team has had the next seats meeting.
So that’s great, and we also have another few bug fixes for you:
- We have fixed a case where returning to the main menu broke the build grid.
- We’ve fixed a potential issue with the “cut region” toggle not working right after returning to the main menu
- Updating a unique-creature’s position or values no longer collapses its entry in the unique-creature panel.
Have a great day!
BUILD-ID: 14359448 - Download Size: Win / Linux 2.8 MB / Mac OS 5.9 MB
TaleSpire Dev Log 431 + Patch Release Note
Heya folks, After much gnashing of teeth, the seat feature is in for review with Steam. Now we wait and fix anything they decide needs tweaking. We’ll let you know as soon as it’s through review and ready for release.
In the meantime, I want to get stuck in our long-awaited “Month of Bugs,” where I just try and fix as much random stuff as I can.
I can’t guarantee it’ll be the specific bugs that you most want to be squashed, but there will (finally) be some visible work from me after a few months of quiet grumbling.
We are kicking off with a little patch courtesy of @chairmander, who fixed these while administering the public bug-reporting site.
- Fixed a couple of cases where “Waiting on GM” was not updating to reflect changes in the player’s rights
- Fix a case where clicking on client-portrait was not focusing the active creature
- fix a couple of typos in an alert message and a tutorial
- fix a log message
Alrighty, I’ll get back to work. I hope you’re all having a successful 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 430 - April Bi-monthly banter available on youtube
Yup, just a quick one to drop the recording of Friday’s stream. I hope you are all doing well.
p.s. As we mentioned the possibility of an additional dog on the next stream, here is a down payment on that:
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 426
Heya folks, I hope the first week of the year is treating you well.
Things are going well over here. I feel well back into the swing of things now, so it is a good time for an update on what I’m doing.
Before Christmas, I had been pushing hard to get creature modding shipped, but clearly, I didn’t succeed. I thought I could hack around some of the tricky cases and get something made to see us through the holidays. If that had worked, my January would have been rewriting all the hacks into reasonable code.
As I failed to hit that target, I felt I had a couple of options.
- Continue the crunch and try and get the hacks to work. And then immediately rewrite them all.
- Just bite the bullet and do it more correctly, with the downside being that it would take more of January to do it.
I chose option two.
I chose that as my personal goal this year is to get better balance and organization in my life, something I have always struggled with. If I’m in doubt[0], I always find it easier just to work as I know what I’m doing with code as opposed to… well, everything else. But you can only do that for so long before cracks appear elsewhere.
This choice is feeling good for me so far.
That’s quite enough of the human meat issues; let’s talk technical stuff instead!
Content Addresses
Until now, most of the content you interact with in TaleSpire has been identified by a UUID. This gives us a (hopefully) globally unique identifier (name) for each creature, tile, prop, etc.
When you copy a slab, those IDs are included in the weird string that TaleSpire produces, and when you paste it back in, we use the IDs to find the data for the tiles/props/etc that you are pasting.
Now imagine how it will be with mods. A person may copy a slab with tiles or props made by the community or (soon) may be hosted on a repository that Bouncyrock does not control. How can TaleSpire find the data it needs only using the UUID from before?
There are a bunch of possibilities. One is that we could host a central address book that lets TaleSpire look up an ID and find the content pack and repository that contains it. This, however, means registering all content and IDs with use, centralizing information, and giving us too much power over creators. Instead, we are borrowing from the web and moving to URIs.
With the new scheme, every piece of content has a content-address:
Here is an example one: :46be6663d03843b6bb320a97716e5ace#72fbaa19-806d-4816-8d7f-91f17a459b93
Without the scheme, this identifies a piece of content named 72fbaa19-806d-4816-8d7f-91f17a459b93
in the internal content-pack 46be6663d03843b6bb320a97716e5ace
(An internal content-pack is one that is shipped as part of the game)
The #
is the start of a fragment, often used in URLs to point to some content within whatever thing the main part of the URL was pointing to. That’s precisely what we are doing, too.
Here is a different one: repo://talesbazaar.com/api/7d745de08e494e7ea7dce871519c09f0#d0bd95b7-0ef3-4144-a1ee-63aeedc93707
This doesn’t work yet, as we haven’t yet published the community repository REST API specification. But, once we do, a site like talestavern.com or talesbazaar could implement it, and then TaleSpire would be able to fetch content from places that are entirely out of our hands (We think this is critical for the longevity of TaleSpire).
- The
repo:
scheme tells us it is a public repository. - The
talesbazaar.com/api/
portion tells us the location of the endpoint (https
is always used, so that doesn’t need to be specified in our URI). - The
7d745de08e494e7ea7dce871519c09f0
is a hex-encoded content-pack ID. It’s not globally unique, but it will uniquely identify a pack in the repository - Once again, the fragment
d0bd95b7-0ef3-4144-a1ee-63aeedc93707
is the UUID of the content inside the pack we are fetching.
We have other schemes for mod.io, HeroForge, and we are even tinkering with fetching content from arbitrary web addresses. This is proving useful for icons that are hosted separately from the content itself.
This is just example syntax, but I’m experimenting with URIs like this: web://some-site.com/some-place/some-image.png#64,64,32,32
In this case, the “content-pack” is an image at https://some-site.com/some-place/some-image.png
, and the fragment identifies a region of the image that is then used as an icon.
Async everywhere
TaleSpire grew out of a simple, single-floor, dungeon-building, TTRPG-esque game. Initially, all of its content was built in, and there is still code that assumes some resources are immediately available. Over the years, we’ve been moving away from that as we tackled HeroForge and the community mod browser, but there is plenty of old code around.
As you can imagine, modding breaks all of that!
I won’t be able to fix all these old assumptions this time. I will leave some for when we add modding for Tiles and Props, but still, it’s a lot of work.
Each time I finish a feature like the mod browser, I think, “Ah, yeah, now we’ve got all the bits we need to make the real solution,” and each time, something else comes up. I’m sure there will be something else I need to handle. I’ll be sure to let you know when it happens!
Progress
All in all, though, it’s going well. In a game that is so much about displaying and navigating content, it’s no surprise that changing the fundamentals of how content is addressed, obtained, and loaded touches a significant portion of the project.
I’m working through hundreds of files and tens of thousands of lines of code and doing so carefully, as I never want to break anything you’ve been building.
I think I’ll be through the first wave of TaleSpire refactorings in a few days, and then I’ll move on to TaleWeaver, where there is a TON of work to do as the internal content-pack formats have completely changed.
I’m very optimistic, though, and I’ll keep you posted as it all quickly gets closer to release.
Man, this got so long, and I haven’t even talked about the ways we intern the URIs to make them fast to work with at runtime or any of the other stuff we are doing, but that will have to keep for another day.
Have a great night folks,
Peace.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
[0] and I’m always in doubt :P
TaleSpire Dev Log 422
Heya folks,
Today was a tedious one.
I finished up last week by moving a whole bunch of code out of our Unity project and into a separate C# project that referenced the Unity DLLs. We are doing this as we want to ship TaleWeaver as compiled code[0].
I finished that task, and the TaleSpire project compiled, but when I ran it, it crashed immediately. The reason is that by moving all the code to a separate project, all of the references from prefabs and scenes to that code broke.
To understand why, we have to know that Unity wants developers to be able to rename and move things without breaking all those references. So, rather than referring to the classes by name[1], they create a GUID for everything in the project. As they can’t push those GUIDs into the files they are identifying, they instead make a separate file called a meta
file, which stores the ID and any other metadata for that thing[2].
As meta files are a Unity concept, I can’t include them in our new C# library. So, by moving the code, I broke all the references!
Of course, Unity does need a way to identify types inside a C# library, and I found this unofficial info talking about how it works: https://www.robinryf.com/blog/2017/10/30/unity-behaviour-in-dlls.html
I now have the tools I need to fix this issue.
- First, I will check out a build from before I moved the code out to the separate library.
- Then, I will write a script to collect the GUID for every script in the project[3]. I will make a lookup table between the GUIDs and the fully-qualified type names.
- I can then check out the most recent code (the one with all the broken references), scan the project for any use broken references, and use the GUID to find the fully qualified type name.
- With the type and the sample code from the link above, I can calculate the new reference information and replace the broken reference.
If I’m correct, I can automate the entire repair, which is a relief as I have done fixes for issues like this before, and they SUCKED.
In the future, I might even be able to use this knowledge to make tools to help fix issues that occur during merges sometimes.
Well, wish me luck for tomorrow. We’ll see how this all turns out.
Peace.
p.s. The MD4 hashing code from the linked blog post was helpful but performed a bunch of unnecessary heap allocations. I ended up procrastinating earlier today by tweaking it to be more efficient. You can find that here: https://gist.github.com/baggers-br/48bba51a9e0b1c5a0632c57537f84534 It is almost entirely untested, so please beware.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
[0] I know, I know. Byte-code. But still, you know what I mean. [1] Fully-qualified or otherwise [2] If you are very curious, you can find some info about this here: https://unityatscale.com/unity-meta-file-guide [3] In fact I’m only including subclasses of MonoBehaviour
TaleSpire Dev Log 421
Heya folks!
After a few weeks of public activity, it feels weird to be quiet again, but things are progressing well.
My big task is restructuring our projects so we can ship the creature modding tools as DLLs.
This task involves some decoupling from Unity, so I’ve been removing the dependency on Unity.Entities. We didn’t use the ECS they provided at all, but they had a zero-copy data format, which was pretty handy.
I wrote our own format the other day, so for the last couple of days, I have been updating all the code to use that. I’ll admit that a lot of that time was me trying to find what I thought were bugs but turned out to be me screwing up.
My task for today is to work out how I will handle conditional compilation (e.g. ConditionalAttribute and #if) with this library. We’ll see how that goes.
Catch ya soon.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team
TaleSpire Dev Log 420
‘Allo folks.
Today went well. I’ve got a texture format I think we can work with, and I’ve made a de/serializer for it. Here is a quick pic.
There isn’t really a way to tell it’s from our format, but I guess that’s the point :P
I need to put this all together into a file format, but that is easy with the work from the other day.
The next unknown I need to tackle is building dlls from Unity projects. This is required for the project we will ship to let you make creature mods.
We’ll keep you posted on the progress.
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 419
Hi again folks,
Today, I continued working on our custom mesh format. The image below shows some of the progress.
This is the first mesh I’ve taken from Unity to our format and back again.
With that working, my next task for creature modding is to work on how we will store textures on disk. I should be able to work on that tomorrow, although there may be other Bouncyrock work that will take precedence. We shall see :)
That’s all for today,
Ciao.
Disclaimer: This DevLog is from the perspective of one developer. So it doesn’t reflect everything going on with the team