From the Burrow
TaleSpire Dev Log 446
Hi folks!
I’ve started work on my next big feature, the dice engine!
This is a complete rewrite not just of the networking code but also (and more excitingly) the system that handles the automation of different kinds of dice rolls.
Until now, we’ve supported very basic dice syntax. For example, you can type !farble:2d20-2/garble:3d6+2d4
into the chat bar and get a combined roll with 2d20, 3d6, and 2d4. Once you’ve rolled, it will do the math and show the results with the titles “fable” and “garble” above the respective results.
This is very limited, though; we don’t yet support exploding dice, re-rolls, fate dice, or many other useful constructions.
My task is to fix that limitation.
I’m gonna talk about work-in-progress techno hoo-hah for a bit, so a warning:
GMs, Players, and even implementors of rule systems will not have to deal with the things I’m talking about below. The code gubbins I’ll be showing is for the under-the-hood implementation that will make the nice, user-friendly stuff work.
Alrighty! With that out of the way, let’s get nerdy.
Many VTTs have a nice, terse dice syntax language that supports a range of useful kinds of rolls.
I want us to have something similar, of course, but eventually, I’d like to be able to support dice rolls written in other systems’ syntax, too. This is nice for people who have experience with other VTTs and don’t want to learn a new system each time they move.
I see most dice languages like regular expressions, a (nice?) compact way to express a specific class of problem.
However, there is usually a trade-off for that terseness, and it’s a loss of generality. For example, if a new game comes out with a new style of roll, you’d have to wait for new syntax to be added. However, with a richer language, the community could implement the new rule and start using it immediately.
Alright, so I want dice languages to be available to the users, but behind the scenes, I want something more flexible.
I also don’t want to have to make a whole new backend for each dice language we support. So it’s time for compilers \o/
The first step is transforming these strings into an AST. The AST is a data structure that describes a dice roll. It’s much more verbose than but much more general. It supports variables, function definition, recursion, etc.
Here is a contrived example where we roll 6d6, re-roll the two lowest results, and add up the final score[0]
(let ((rolled (roll (dice d6 6))))
(+ (take-top 4 rolled)
(roll (take-bottom 2 rolled))))
Phew, you wouldn’t want to have to write that every time! And, of course, you wouldn’t, as this representation would be used by TaleSpire behind the scenes.
Next up, to run it. We could write an eval function that simply walks the AST and executes it. That’s what I’ve done in my experiments so far, as it was a quick way to get something working.
For release, I think I’d like to take the AST and compile it into byte-code instead. We will then have a small byte-code evaluator to run that code. There are some advantages to this:
- The evaluator is simpler: For example, with tail-call elimination, we should be able to flatten the recursion to jumps.
- Easier to port to other languages: I’d like to port the evaluator to different languages. Having the code be a flat array makes working with it trivial, whether from C++ or Python.
- Trivial to encode for sending as a URL and embedding in rules documents: We have talespire:// URLs and a rule system coming in the future. I like the idea of making it very to interface with those things.
I’m currently experimenting with this system in common-lisp, as that’s just a nice place to noodle with ideas. I have an AST and working eval, so I’m able to make dice rolls in the REPL and check the behavior.
The language needs plenty of work, but to guide that, I will implement a bunch of common rolls from various rule systems. When I’m happy that this covers what we need, I’ll start on cleanup and then on the byte-code compilation.
This all may sound a bit complicated, but it’s actually straightforward to make. The code is way less involved than most things in making games. I recommend playing with toy compilers if you are curious. Once you get past parsing the text, it’s a lot of fun.
Okay, that’s enough nattering for now. I’ll see you in the next one.
p.s. I’d like to open-source the language and compiler once it’s been in production for a while. I couldn’t find a good place to stick this in the text above, so it’s chilling out down here.
[0] Again, this is very much not it’s final form. We will be using s-expressions for the textual representation of the AST, but take-top and take-bottom feel like they could easily be reworked as a take
function that itself would take a predicate function to tell it what to take.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
TaleSpire Dev Log 444
I’m back! Having ten days to get a proper mental reset was very nice. I’ve barely been online (except to download things to read), so I’m definitely out of the loop, but I’ll get caught up to speed this week.
To give myself something fun to jump back into, I looked at a performance problem that has been on the list for a while.
The problem
Picking in TaleSpire is pixel-perfect. This is critical for moving in crowded spaces. We don’t pick based on physics colliders as a good collider doesn’t necessarily match the shape of the object exactly (if you are curious, do check out this dev log).
Instead, we render pickable things from the scene in a specific way and read back the thing the mouse is over the very next frame. That “very next frame” bit is important as we don’t want things to feel sluggish. However, reading back data so soon is generally not how the GPU would prefer to work. If you try to read data back from somewhere the GPU was using, it wants to wait until it’s done everything it was doing, and this causes a huge delay. Luckily, MJP’s post over here explained a feature in DirectX that we can use to read data back the next frame without stalling the rendering. We’ve used this for ages, and it’s been great, but there are cases where it has not worked.
My laptop is a Thinkpad with an integrated GPU (Intel UHD Graphics 620), and it runs terribly on an empty board in TaleSpire. I got out the profiler and saw this:
Jumpin’ Jesus, what is going on with PixelPicker.FetchSingleResult
?
The theory
If I recall correctly, Unity will try to overlap the rendering of frames (this is a good thing), so my theory is that something is touching the buffer that holds the picking results too soon, causing a stall.
Mitigating this could be really simple. We can just add a second buffer and switch between them each frame. That way, we don’t get any accidental prodding of the resources.
The result, and what next
Let’s not beat around the bush.
Yeah, that’s much better. The time to fetch the result is insignificant now (from 22ms down to 0.003ms or something in that area).
Of course, the frame rate is still far too low. There are a lot of things that need to be done to make it run well. But a win is a win, and this needed to be fixed so we could see the other issues. I’m happy with this.
We will be shipping this fix in the next couple of days.
So what next? I’m not exactly sure. I’ve got to get back to some partners now I’m back, and I need to get caught up with community happenings. However, I will do some more profiling and start thinking about what I want to tackle next on the performance front.
I’ll also look into the next big feature I’ll be starting work on. But more on that another day.
Until next time.
Peace.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
TaleSpire Dev Log 442
Hi again folks,
In yesterday’s dev-log, I talked about us working with TitanCraft to help you bring your creations into TaleSpire.
The first thing they would like to do is allow their users to export their miniatures in the TaleSpire creature format. To that end, I’ve been working on a command-line tool they can use in their export pipeline.
Today, I fixed a bug in the handling of thumbnails, and suddenly, we had TitanCraft creations in TaleSpire.
These are looking very much at home! [0]
The rest of the day was spent on tweaks and fixes as we tried more minis.
Tomorrow, I’ll be looking at scale. TaleSpire has some limits on scaling due to our current movement code not being enjoyable once things get really big. As with our HeroForge support, we will need to massage the input to work well with our system. It’s something we’ve done before, though, so it shouldn’t be too hard.
That’s all for now,
Peace
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
[0] Please note that these visuals are not final, we will likely tweak the shader before this feature ships.
TaleSpire Dev Log 441
Heya folks,
Today, I’ve been working on something different. A feature, for sure. But not one that goes directly into TaleSpire.
Today, I was making a program that can fit into TitanCraft’s pipeline so that, sometime in the future, you’ll be able to download TaleSpire-compatible assets right from their creator!
For those who don’t know, TitanCraft is an excellent way to create miniatures online, both for downloading and also 3D printing. If you haven’t checked them out before, I’d recommend it. Their approach to asset packs is really neat.
We’ve been chatting for a while about working together, so getting started on this is a lot of fun. My main task for today was taking TaleWeaverLite and reshaping it into something that could run headlessly. The goal being that they can then use this as part of the export process. I haven’t tried to share the codebase with TaleWeaverLite yet as I’m not sure how this project will evolve, but I expect we might do that once we know what shape this will be in the longer term.
I got the basics working. We have a command-line tool that takes a digital miniature, and repacks it for TaleSpire. They result opens in TaleWeaverLite, but I’ve got a few bugs in-game that I’ll fix up tomorrow.
Oh, and just in case anyone was worrying, no, we aren’t moving away from HeroForge or anything like that. We love what they do, and we’d like to work with more folks in the space, not fewer! So, if you have a favorite way to bring characters and content into your adventures, why not let us know at https://feedback.talespire.com. If it’s been suggested already, please upvote it. We keep an eye on the vote to help prioritize what we are up to.
Anyhoo, that’s all for tonight.
Have a good one!
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team
TaleSpire Find Region Fix
This patch fixes an issue that you may have been bitten by. Starting fairly recently, creating a campaign could take a very long time. The reason was that it was taking a long time to find the correct region in which to host the campaign.
We have rewritten the code, and it’s significantly faster now. However, if you do experience new issues around making campaigns, please let us know, as we are very eager to squash these bugs. You can report at https://feedback.talespire.com, and you can chat about all things TaleSpire over on our discord server.
Hope you’re having a good weekend folks.
BUILD-ID: 14881453 - Download Size: Win / Linux 5 MB / Mac OS 7.3 MB
TaleSpire Feature Release - Builder Presence
With this release, we start showing GMs what other GMs are building. This increased ‘presence’ helps you know who is working where and on what. It brings a little of the naturalness of building together that can be lost when moving to a digital space.
As always, let us know what you think. This is not the last iteration of this tool, and your stories help us find what we need to build.
See you in the next release!
BUILD-ID: 14438443 - Download Size: Win / Linux 2.8 MB / Mac OS 8.8 MB
TaleSpire Dev Log 440
Hi folks,
Just a quick log for today. I’ve tweaked the visuals of the build preview we will show for other GMs. I added a new shader and UI to show the dimensions of any region of tiles the GM is dragging out.
I’ve also started working on a tool for a 3rd party to take their assets and produce tsMod files. We’ll chat more about that and who it’s for another day :)
Alright, I best be off,
Have a good one folks!
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the teamdidnt
TaleSpire - Attachments Patch Release
Heya folks,
Today, we’re adding attachment points to a slew of modern props. Props such as:
- Fire escape ladders
- Fences
- Deco Strips
- Flag Strand
- Assorted Furniture & Shelving
- Industrial conveyor belts and ladders
- Some kitchen cabinets and sinks.
- Office desks
- SciFi consoles
May your props be aligned this fine weekend.
See you in the next release!
BUILD-ID: 14796269 - Download Size: Win / Linux 13.4 MB / Mac OS 16.7 MB
TaleSpire Dev Log 439
Hi folks,
Today, I’ve been tinkering with improving the sense of presence of other builders in the game.
Communal building is a foundational part of TaleSpire. Even though we are far from finished, the fact that large groups of people can build together socially is something we are very proud of. However, one area that has been lacking is communicating what you are doing to other builders before you place something.
When building with legos, it’s easy to gesture or show each other what you are up to. To that end, I’ve begun working on showing the tile or prop you are holding to other builders.
We still need to make it more obvious that the item is being held by another person (probably with a visual effect) and maybe even which person is holding it. However, along with voice chat, it’s already easier to ask questions about positions and orientations while also getting motivation from seeing others at work.
Naturally, this will be for GMs only, as you wouldn’t want the players to see what devilry you are secretly constructing up ahead!
That said, we will start experimenting with a “ping” system in the not-too-distant future, allowing for more visual communication between both GMs and players.
That’s all for tonight,
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 438
Hi folks,
Bug month may be over, but the bugs certainly aren’t. Today, I’ve been working on some server-side bugs. I didn’t want to tackle these last week while @borodust was away due to the risk of causing a problem that would send him alerts during his vacation!
All the fixes are minor, mainly cases where we weren’t sending messages to the clients in response to events like boards being imported.
I will test these fixes shortly, and then tomorrow, we’ll look into pushing them to staging.
That’s all from me tonight. Hope you are doing well.
Disclaimer: This DevLog is from the perspective of one developer. It doesn’t reflect everything going on with the team