From the Burrow
TaleSpire Dev Log 379
Heya folks!
I’m back again with an update on what I’ve been touching this last week.
Symbiotes
Chairmander and I kicked off with a long meeting to design the manifest. We took some inspiration from other projects but ensured the file grew naturally in step with what Symbiote features are being used. This amounted to talking through user stories, though we didn’t think explicitly about that then.
After the designing, it was time to work!
I knew quickly that if a Symbiote failed to load, I wanted some UI in the panel to show that. I’ve previously mentioned that I wanted to support different kinds of Symbiote (as in, not just web-based ones), and this felt like an excellent place to use another type.
Knowing what I wanted and getting it were two different beasts, though. I spent many hours going in circles until I found an approach I liked. The details of the solution aren’t particularly exciting. Still, the upshot is that we can now support not just different user-made symbiotes, but we can technically support hot-loading the infrastructure for entirely different kinds of Symbiote. This won’t matter for a while, but I’m happy to have that worked out.
We are still improving the API Symbiotes have access to. As of today, we have calls for the following:
- fetching the initiative list and the currently active member
- sending chat messages both as players and as creatures
- putting dice into the tray
- fetching info about the currently active ruler
- fetching a slab string based on the current selection
- putting a slab into the hand (switching into build mode if necessary)
- unpacking slab strings to binary representation
- packing binary slab representation to slab string
- getting the data size of a given slab string
- sending a network message to the same Symbiote running on other clients
- fetching the ids of any parties
- fetching the ids of creatures in a given party
- fetching info about the active campaign
- fetching the board list for the active campaign
- fetching a list of the bookmarks in the active campaign
- fetching the distances units for the active campaign
- fetching the names of creature stats used in the active campaign
- fetching a list of the players in the campaign
- fetching a list of the players in the board
- fetching the id of your player
- checking if a given client-id is yours
- fetching info about a given player
- fetching a list of the connected clients
- fetching the id of your client
- checking if a given client-id is yours
- fetching info about a given client
- fetching the list of loaded asset-packs
- fetching info about the asset pack (including all tile/prop/creature info)
- fetching the list of unique creatures
- fetching a list of creatures owned by a given player
- fetching a list of currently selected creatures
We also let you subscribe to events such as:
- unique creature created/deleted
- dice roll results
- slab copy events
- asset pack loaded/unload events
- client join/left board events
- player joined/left campaign events
- player permissions changed events
- initiative list changed events
Next up, I’ll be experimenting with exposing a picker tool that sends the kind and id of the picked thing to the Symbiote.
We also will be handling documentation generation soon. With that and another big pass on the API, we will be nearing something we can ship.[0]
Community mod repository
I just put this section here to reassure you that slab sharing and mod.io integration have not been forgotten. They have had to wait a bit as pushed to find out what the Symbiote feature needed to be.
Performance
Ree is working on a cool feature that requires scanning over any tiles or props in a given area. We have some code for this that is used by the hide plane. However, it was not currently Burst compiled due to limitations on how generics work in HPC#.
I changed the logic so that a caller-defined visitor was passed chunks of data. The caller could then return jobs that processed these chunks with the help of some methods on the chunk.
The result was a significant performance improvement to the hide plane and code that could be used in more cases.
GameObject Alternative
The perf work above got me very motivated for more. So I sat with a pad of paper and started trying to design a jobified alternative to GameObjects we could use in some places.
I’m not looking to cover all the cases GameObjects do, but I want something that is more familiar than ECS (and more compatible with our setup) while being easy to integrate with jobs.
Not much to report here yet, but you’ll be hearing more about this in the future.
Physics
Next up, I worked on a bug in our physics library helpers which resulted in sphere-overlap checks not working.
My reason for the bug was that, at the time, the library we wrapped had no documentation, and the name of the field I was incorrectly using was bafflingly named[1]. That’s my excuse, and I’m sticking to it :P
macOS News
Some good news on the macOS front. The bug that has been blocking us has been fixed in Unity 2023.2 (which we don’t use) and is in review to be released in 2021.3, which is one we can upgrade to[2].
This is exciting! When that lands, we can finally get a good look at what we have and work out how to get the alpha of macOS support into your hands.
Backend
Work progresses rapidly on the backend. I was in some discussions about how we will be handling certificates and looked into our options. Nothing interesting to report, but it took some time, so it gets a spot here!
Wrapping up
More than ever, my dev-logs fail to capture the breadth of what is going on behind the scenes. Seeing so much moving from backend code stuff to community outreach is a joy.
Until next time!
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
[0] You may have noticed that no calls change the state of the game directly or require server requests. This is very intentional for the first version. We will look into state-modifying functions in future updates to symbiotes (an example of such a function would be setting the initiative list)
[1] The field is called MaxFraction
. Normally it holds a fraction of another distance. However, in some cases, this same field holds the distance directly and not a fraction. Very annoying.
[2] Those not in software development might wonder why we can’t just upgrade to 2023.2. The answer is that changes between major revisions can be substantial, so while technically we could switch, it means putting a lot of time into repairing systems broken by those changes. Also, software always has bugs, so we would be trading a known set of bugs for an unknown set, so the time it would take to get back up to speed is uncertain.
It’s very likely that we will make that jump eventually, but we will let you know when, as that will likely stop us from shipping new features for the duration of that transition.
TaleSpire Dev Log 378
‘Allo!
The latter half of the week has been 100% focused on Symbiotes.
In my last post I talked about starting to make a code generator that would take a JSON spec for the API and generate the C# and JS plumbing code required for communicating between the WebView and TaleSpire. That is now working, and it’s such a help.
It all but removes a class of user errors from the interconnect code as the boring stuff is generated. This also makes having slightly tighter but ugly encodings easier, as you don’t need to update all the plumbing code directly. Also, by generating C# structs, we get type-checking, further reducing the number of ways for me to mess up[0].
Once the generator was working, I was able to write the implementations for about a dozen of the required API functions for the first version in a couple of hours. This really reassured me that it was worth the work.
After this, I merged the slab-repository branch into the Symbiotes one. This is because one of the Symbiote API functions allows you to get the slab string for the current selection, and some of the work on the slab branch made that much easier.
We then ran into an issue we knew was coming: sometimes, the user’s JS can load in before the TaleSpire API has loaded. I added an option to the Symbiote manifest that allows the creator to specify a function that will be called on initialization and updated our setup code to support that.
With this all working, I got a build to Chairmander so he could continue his work, and I doubled back to the C# side of the Symbiotes feature. I spent a chunk of Friday cleaning up code so that all the JS and WebView-specific code lived together. As previously mentioned, I would like to see other kinds of Symbiote in the future, and the cleanup serves that potential future.
The next big todo is working on threading. I also need to get stuck back into slabs.
Anyhoo, that’s enough rambling for now.
I hope you are having a lovely weekend.
Peace.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
[0] Just as well, I’m a master at breaking code :P
TaleSpire Dev Log 377
Heya folks.
Since we last spoke, I’ve carried on with my main two tasks, slab upload, and symbiotes.
Slab Upload
Slab upload is going well. It’s always nice when something starts feeling like a feature and not a hack.
The progress isn’t exciting to show, though. It’s been things like:
- Side-load the slab data into the cache, so it doesn’t have to be redownloaded
- Show an hourglass cursor when the slab tool is waiting on a slab to download
- Tuning camera behavior so that transitioning in and out of publish mode does what is expected.
- Get tabbing between fields working as expected
- Subtle visual changes to screenshot view to improve the experience
- Add loading graphics to the entries in the community-mod browser to show that thumbnails are downloading
And so on.
I’ve still got a list of tickets to get through to get a good first version, but there don’t seem to be any show-stoppers.
The one (happy) distraction has been helping with the Symbiotes feature.
Symbiotes
Context: Symbiotes is an upcoming feature allowing community-made mods to dock on the right side of the TaleSpire window.
Our first version of this feature supports Symbiotes powered by WebViews[0].
We are providing an API that allows communication with TaleSpire. The messages between TaleSpire and the Symbiote travel over a simple interconnect provided by the WebView.
The code on either side of such a bridge needs to match and, from my experience, are places where simple user errors result in extremely annoying bugs. To deal with that, I prefer to write the API specification as a simple document, which is then used to generate the plumbing code for either side.[1]
And so that’s what I’m making. I have a JSON document specifying types, calls to TaleSpire, and the arguments and return types of those calls. I load that document, type-check it, and produce an intermediate tree of objects which describe the bridge.
Next, I’ll write code to walk over that tree to spit out the JavaScript and C# boilerplate code required.
Some of you may be asking, “why aren’t you using
Given that we are trying to ship mods quickly and that this approach doesn’t stop us from using a different serialization approach in the future, this is the way we are going for now.
Alright, enough rambling for today. Looking forward to sharing more with you soon.
Peace.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
[0] In the future, I want to explore supporting other languages/environments. [1] This is exactly what we do with our server-side API. The API is represented as an erlang data structure, and from that, we generate C# and erlang plumbing code. It’s been a huge boon.
TaleSpire Dev Log 374
Heya folks!
I’m away from my main dev machine today, so no gifs for ya, but there is some progress.
I’ve got to the point where I can select a region of the board, submit it as a slab to mod.io and bring it back into the game. So the essentials are there. It’s still janky, but I know what I need to do.
We’ve also continued working on Symbiotes (our mods that slot into the right-hand side of the game). We’ve got messages passing between mods and the game, so you can do things like send chat messages, set up dice rolls, and listen to the results.
We are busying ourselves experimenting with the API to work out what is clean and practical to get started with. We have more to show, but as that work wasn’t done by me, I’ll let that person write their own dev log about it :)
We definitely are pushing for mods to be out as soon as possible. Expect to see plenty of logs about this in the coming weeks.
Hope you’re doing well.
Peace.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
TaleSpire Dev Log 373
Heya folks!
Last week was spent on the backend. A lot is going on, but I want to save that update for when the governmental paperwork for our potential new hire is complete. It’s taking ages.
Work has continued on Symbiote, our modding feature allowing you to dock webview-based mods on the right-hand side of TaleSpire. Luis and I have been testing the web-view library under Linux (via Proton) to ensure we can provide the same experience across Windows, Linux, and Mac. So far, we’ve got it working if we disable sandboxing, which isn’t ideal but might be how we ship the beta.
Continuing with Linux, we have progressed in getting talespire:// URLs to work out of the box. Until now, we’ve been relying on a great script from community members, but in some cases, it requires user input [0]. This was because some execution flags[1] involved are system dependent.
Luckily for us, after a bunch of digging, Luis realized they were in the environment variables! So now we are pretty sure we have what we need to make this work. Hopefully, more on this soon.
From Linux to Mac we also have some good news. Unity has replied to Ree, saying that the bug he submitted (and that is blocking us from shipping mac support) has been fixed and is rumbling through whatever internal process is needed before it is released. When the fix eventually ships, we will have to upgrade our Unity version, which hopefully won’t be too painful [2].
I’m mostly done with a feature that allows you to only show the tiles/props you are currently selecting. This can be handy for precise selections, especially when working out what to upload to a slab repository. You can see it in action here:
You may also have spotted this icon:
This is the “publish slab” button. Clicking it will take you to a mode where you can frame the screenshot for your slab and provide the required information. That mode will also be used for editing the info of the slabs you’ve already uploaded. It’s looking rough right now, but we have plenty of time to improve it. For now, I want to focus on shipping this stuff as soon as possible.
I’m running a bit low on caffeine, so other things will have to wait for another dev log.
Have a good one folks.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
[0] Also because it is run by Proton, so needs to be a Windows program.
[1] ESync or FSync
[2] There is a good chance that it will also fix the long-standing bug in the input system that stops us binding e
to actions. That one is so weird!
TaleSpire Dev Log 371
It’s time for a video dev log.
While I have you here, I’m going to abuse this reach I have to pimp something non-talespire, and even non-ttrpg related.
A good friend of mine released a game last week, and I’m so stoked for him. It’s called Kandria, and it’s a 2d open world hack-n-slash platformer, with celeste’esce smoothness of control, and a story laden post-apocalyptic environment. If that sounds at all interesting please give it a look here.
And with that I’m off, Cheers 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 369
‘Allo again!
I was on the road most of today, but I have a little progress to show. Here is the first slab coming from mod.io directly into the game:
As mentioned in the last post, unlike chonkier mods like creatures and tiles, we want you to be able to spawn slabs without subscribing to them first. However, I don’t like the idea of waiting for the web request each time, so naturally, we’re doing some caching.
It works like this. When you first use a slab, it downloads it and saves it as a temporary file (that is deleted on exit). Once again though, loading a file does take a little bit of time, so we also keep the ten most recently used slabs strings in memory.
So when spawning a slab, TaleSpire can use the in-memory cache, fall back to the local file, or just download it.
In the gif above, you can just about see the timing difference between the first and second spawn of the slab.
While the code is still currently full of todos and stuff to clean up, I am going to switch to upload now as I want to start filtering by tags, and those are most easily added via the upload API. I’ll start tomorrow and see how quickly I can hack something in.
Until then, have a good one 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 368
Hey folks,
In the last dev stream, we stated that we would start our foray into mods by making an official slab repository (along with an API for user-run sites to hook in too). This gives us some experience using mod.io’s API. As of a few days ago, I had this bit working:
Since then, I’ve worked on the manager that handles downloading and caching slabs. It’s coming along well.
While I expect UX for creature, tile, and prop mods to be similar to our HeroForge integration[0], I think slabs should behave slightly differently. Rather than needing to link/subscribe to a slab to use it, I want you to be able to simply search, then click the icon to spawn the slab. If you want easy access, you can bookmark it to save the slab to your library for future use.
The way things are looking, I should have the manager working mid-week, at which point I’ll switch to working on the in-game slab uploader. Woop!
Right, that’s all from me for now.
Ciao.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
[0] And also share a lot of the same code
TaleSpire Dev Log 367
Hey again folks,
I hope you’ve had a good holiday season. I’ve finished Christmassing it up, so I am getting some work done before the close of the year.
I would have loved mac support to be wrapping up, but I’m waiting on news from Unity regarding the shader bug.
Instead, I got back to persisting initiative. I had it mostly working before Christmas, but trying to ship right before a holiday is a fool’s game, so I left it.
Today started suboptimally as the internet was down. Turns out a local distribution box[0] had frozen. Luckily the ISP was quick at getting out, so by mid-afternoon, I was back in business.
A little bug-fixing later and I have this:
Which looks pretty decent. I’ll prod it some more tomorrow and see if it’s ready to ship.
That’s all for today,
I’ll be back with more soon,
Seeya
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
[0] Or whatever they call them
Talespire Dev Log 366
Heya folks!
I’m dropping in to let you know what I’ve been up to these last few days.
Hiding board list from players
I’ve done some work on the option for hiding the board list from players. I wired up the behind-the-scenes stuff and then handed it over to Ree as I was having some trouble with the UI portion.
All went well, so we expect this to be the next feature that ships.
Mac bug
In log 364, Ree talked about a bug blocking mac support and raised a ticket with Unity. I decided to spend a couple of days looking at it in case I could make a workaround. Spoiler, I couldn’t.
To trigger the bug, you have a light (which renders its volume without writing to depth buffer), and then you have something modify the depth in that area. What is extra odd is that it requires that you forward-render something for it to show up. It’s super weird. Check out this daft shit:
Looking at the Metal frame trace in XCode, the most obviously wrong thing is that the GPU actions from later command-buffers seem to be executed in an earlier command encoder. I don’t know enough about Metal to work out why this is causing the errors, but it is feasible that it’s related.
Unity has confirmed the issue, so we are waiting to see what comes next.
Persisting initiative
Today I spent my time working on the code to allow us to persist data from board-wide systems. This is going well. It’s hard to write much about as it’s mainly me poking around to find something I like. I will need to make another pass on this sometime as patterns are emerging between the different managers that persist board data.
Once I’ve got this done (I’m thinking at least one more day of work), hooking up the initiative manager should be trivial. I’m currently expecting this feature to ship late next week.
And that’s ya lot
Despite the mac bug, it feels good to be making steady progress. I don’t foresee any issues with persisting the initiative list. I’ll get right on to the Mod.io slab integration as soon as that works!
I hope this finds you all well.
Peace.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team