From the Burrow

TaleSpire Dev Daily 58

2019-01-16 23:35:06 +0000

Evening all, only a quick one tonight as I’m super tired. However I can let you know that we just had a pretty exciting planning session where we went through a bunch of designs of ways to improve the building system. From walls to thin corridors and from floors to props, the next iteration of the building system could be very interesting.

Not everything will be solved in the way that seems most obvious but when we have finished some prototype and have something to back up our ramblings we’ll put out a video (maybe a stream) where we talk about the design issue, our findings and where we are taking it.

Probably a month out but we’ll certainly keep you posted. Also don’t worry this wont delay the next batch of people admitted to the alpha, we’ll be letting more of you in before the new system lands.

Until tomorrow,


TaleSpire Dev Daily 57

2019-01-16 00:36:24 +0000

Quick rundown of client-side from today:

  • Fix a bug that occurred in battle mode when clicking next with an empty creature list
  • Made the ? button hide the help if already open
  • Made the atmosphere music loop with a configurable delay between each loop.
  • Fixed drag-select so that it would work properly when you let go over a UI element
  • Atmosphere block are now drag-selectable
  • Try to ensure that steam definitely knows that the game has shutdown [0]
  • Don’t sync board if you are leaving due to the board being deleted.

I also started on the following

  • Can’t stand on dirt (Tilled)
  • Unique creature panel is not updated on creature rename.

The dirt one I though would be a doddle and it was missing some required information, however after adding that it still doesn’t work. It’ll be something stupid I’m overlooking but that’s where it is now

The unique creature ticket is the start of a few issues I’ll be working on in this area. For some reason the ui is not updating when the rename is applied and I have to close the panel and open it again.

After that I’ve got to look into some issues with creature ownership. Those are annoying as I don’t know what triggers them so it’s gonna be a lot of logging, testing and code review. We’ve already seen this mess with people’s streams so it’s a high priority one for me right now

I also took a couple of hours to look at some work I need to do on the backend. One of the pressing tickets is that, currently, there is no limit to the number of older versions of your boards we store. We obviously need this as storing more that we need increases our costs and thus limits how far each sale of TS can take us. It’s not a hard task but having some time to muse over the best way to structure the queries was nice. The second backend task was to design a basic stats collecting module so we can start getting better info on how many people are active at different times of day and, on average, what kinds of requests they make. This is important so we can make some better guesses at how load etc will increase as we move from hundreds to thousands of users and beyond.

One last thing, when I went to bed last night I realized that the line of sight technique is pretty simple if we limit the number of creatures involved. It goes roughly like this (for this example we will use 256 as the max number of creatures):

  • make an ssbo which contains an array of 256 bools
  • find all creatures in range and give each an id between 0 & 256
  • clear the ssbo so all entries are false
  • render the scene from the selected creatures position, in the 6 cardinal directions, into a cubemap
  • render the occluders as black and creatures with their red color component based on their id. e.g. vec4(id/255)
  • draw a quad and use the fragment stage to read a single texel from each face. Write true into the array using the red component of the texel as the index into the ssbo array e.g. result[(int)(sample.r * 256)] = true
  • pull the data back to the cpu side.

The slots that are true state that the respective creature is in line of sight. We can use a 512x512 texture to trade off accuracy for speed but given that we only need this once per time something moves it should be no problem to have something a little higher res.

I haven’t thought of a way to do it without an ssbo (or writable image) yet though.

I might make a prototype of this in lisp as a stream next week. Sounds pretty achievable in 2 hours.

Goodnight folks, back tomorrow with more.

[0] We can the Steamworks shutdown call in an OnDestroy which should have been triggered on all normal terminations. However sometimes it still didnt work, so we’ve added another call to it from a method that is explicitly called on shutdown. !

TaleSpire Dev Daily 56

2019-01-15 00:59:34 +0000

Hey again folks, these dailies had to be put to the side during the crunch to get the alpha out of the door, but now a few days have passed I’m ready to get them started again.

Today has been a slow day as I guess my sleep schedule is still somewhat recovering, however I worked on a couple of bugs.

The first was ‘Ambient lighting stacks rather than replaces prior atmospheric lighting’. This turned out to have a simple mistake which took me a while to find as I was sure it was an error in the LUT post-process. Instead it was that some atmospheres don’t specify new values for the lighting and, instead of the defaults being used, the previous value just remained.

The next were ‘Line of sight is behaving oddly’ & ‘Line of sight indicators show for creatures on all floors’. These ones have a number of components to it that make it fiddly so currently I’m working on some tweaks (hacks?) to what we have so that the result is more acceptable whilst we come up with a better approach to replace it in future.

Previous, in order to see if one creature could see another we just had a simple sphere cast between the two.


Issues included not taking creature eye position into account and that if the ray clipped some scenery, as in the case above, the creature would disappear even though most of it was in view.

To mitigate this I’m now taking multiple raycasts between an approximation of the head positions of the two creatures. We take one ray from the center of the head, one from slightly to the left and again from slightly to the right. On the destination creature we aim a bit wider in order to take the model size into account.

We also cast 1 ray from the source creature’s head to close to the base of the target creature. This lets us catch cases where a creature can part of another creature on a lower floor.


As mentioned before, these are really tweaks to patch over issues with the current approach. One thing we’ve mused over is capturing a low res version of the scene into a cubemap (as in some lightprobe techniques) but naturally instead of rendering the colors of the scene we render IDs of creatures into the result. we can then see exactly what the creature would be able to see (more or less) and could accumulate the IDs into an SSBO (or similar buffer) to be used the following frame for showing/hiding the creatures in view.

The only non-trivial[0] part is the accumulation pass but it sounds like a perfect task for a simple compute shader.

I’ll write more about the new approach when I have done some more work there.

I’m gonna push my line of sight tweaks tonight so the rest of the team can have a play with them. Hopefully they’ll be out in the next update.

In non technical news it’s amazing to have the alpha out there. It’s mind blowing how quickly you see things you didn’t think of (someone playing chess in it for example :D ) and it’s intimidating how quickly the community content overpowers your ability to both keep up to date, and get work done. Some folks have already been amazing at filing really good bug reports in our issue tracker and guiding the new people as they first settle in, so it bodes very well for this as it scales.

Another thing I’ve not personally found a good avenue for is feature requests. Any game, tool, whatever.. feels a certain way due as much to what it doesn’t do as what it does. Setting good limits and excelling in your space makes for a better experience than piling it all on. Some features are non-brainers and we will definitely want to get them in, however there is larger set of perfectly reasonable features that just aren’t a good fit for this project. I guess this is part of the reason I see TS to be part of the roleplaying ecosystem rather than something that’s trying to replace anything. I’d sooner see 5 focused competitors than one bloated tool without focus.

The issue then is handling these tickets. If you’ve seen sites like the now dead Ubuntu Brainstorm you’ll know the issue. Things that are accepted get fixed but the things that don’t accumulate and can become little foci of disappointment. You can prune these but that too has to be done with care as otherwise you either get a lot of duplicate requests or you could piss off the great folks that took the time to request in the first place. I have no answer to this and I may just be over-thinking it anyway. I expect we’ll just put up a trello (or something similar) and just see how we go.

Tomorrow I’m kicking off with some work on ‘atmosphere music not looping’, some small UI bugs and then I’ll dive back into the big pool of bugs and see which can be swatted next.

Until then,


p.s. After going to be I quickly realized it’s easy to do the line of sight stuff just using fragment shaders. Trade off is fixed max number of creatures (e.g. 256) but that seems ttoally fine given the current numbers of creatures we are dealing with.

[0] non-trivial as I haven’t done much compute work and none in Unity so far.

TaleSpire Dev Daily 55

2018-12-17 23:26:33 +0000

A fairly productive day today.

  • Cleaned up client & backend code for Steam signup/signin. Feels good now
  • return validated alias from backend on signin
  • tweaks to how creature’s memories of boards are handled for serializing
  • refactored how and when unique creatures leave board and when they are name non-unique
  • tweaks to summon creature to allow specifying the location it will be summoned to.

I also had been working on the fog of war to fix a bug where doors & walls flush against a zone boundary would not be shown if the character with on in the adjacent zone. I was pretty happy with how it was behaving earlier but I must have had some spurious data as now I’m seeing some very odd cases where tiles aren’t appearing. Beats me how that happened but I’ll need to fix that up in the morning.

I’m also off to Jonny’s tomorrow so we can work a bit closer of a few bugs & features. Remote working is great but occasionally it really helps to jump on the train and yell at the same monitor :)


TaleSpire Dev Daily 54

2018-12-16 22:48:41 +0000

It’s a quick post as I’m still working for an hour or so.

Save & sync on exit is working fine now. I made a few changes on the backend to support user aliases that are separate from signin_names (for those in future who will log in without using something like steam). Aliases are allowed to clash with the aliases of others (like profile name in steam).

I’m close with the steam signin but there is something I’m missing as I’m getting an error message back from steam on the server side. I’ll get it soon but it may be tomorrow as I’m running out of hours for today :(

C’est la vie.

Back to work.

[EDIT 23:07]: It works! well, it crashes past the point where Steam has accepted the token, so yay. Login will be done real damn soon :)

TaleSpire Dev Daily 53

2018-12-16 01:41:28 +0000

I’ve enjoyed today.

We (the TaleSpire team) had a quick meeting to look at what was feasible in the days remaining. We are still going to try the closed alpha out on the 31st so it’s all hands (all 6 hands :D) in order to make that. It’s gonna be tight but it could work. Minimal viable product is the name of the game.

Campaign history is in a very basic working state and so I jumped back to looking at unique creatures. The UI had a few requirements I hadn’t met yet so I did a bunch of work getting that in shape. I finished that about half an hour ago. In short the list of data describing the unique creatures in the campaign can be used to spawn the previews we use when placing creatures. When the preview is placed we spawn the actual creature object at that spot passing in the ‘unique creature info’ this let’s us populate all the correct values (name, hp, etc) and tell the backend that the creature has moved boards.

UI is getting tighter as Jonny is hammering at it night an day. We are not going to have the final look by the 31st but we will be iterating on it pretty hard (along with everything else) in the new year.

Tomorrow my primary two tickets are getting the Steam signup/login finalized for the alpha and fix the ‘sync on quit’ feature. If neither of those cause any drama then I’ll probably look into a rather cute fog of war issue. Currently there is a case where if the obstruction object is on the boundary of a zone it may not show, which is terribly confusing when it’s a locked door :p

Goodnight folks!

TaleSpire Dev Daily 52

2018-12-13 23:49:47 +0000

Today has gone well. Not a whole bunch of stuff to tell but the invite panel is fine now and ui work is continuing steadily.

I found some bugs that require a tiny bit of context to explain.

Every tile in the board has an ID the game can use to address it. These IDs are how the network code specifies a tile when it wants to say something like ‘delete that tile’. Naturally IDs need to keep the same on every client and no two tiles should have the same id.

The bugs resulted in duplicate IDs. What was happening was that we synchronized the IDs when sending the board and we weren’t including the ones from things that had been deleted and were in the undo/redo history. This could result in the following sitation:

  • Player 1 places 10 tiles (ids 0 - 10)
  • Player 1 leaves
  • Player 2 deletes some of the tiles (ids 5 - 10)
  • Player 1 returns and Player 2 sends Player 1 the board (sending ids 0 - 4)
  • Player 1 places 3 tiles (starting at 5 as it thinks that is free)
  • Player 2 hits undo (restoring tiles 5-10)
  • tiles 5-8 now have duplicates.

We could either issue new IDs on undo/redo or just make sure we keep better track of ids in the undo/redo history. The latter felt like less of a band-aid so I refactored the code to handle that. It took a while to test enough to feel comfortable that it was behaving properly again but it seems ok (comforting no?).

This delayed some things but is always worth it as it’s such an ugly bug when it appears as it normal manifests differently on the different player’s clients.

Tomorrow I’m back on session history which in theory should be simple. I think after that I’ll need to tackle one of the remaining tickets which could require significant re-engineer in the worst case (most of the tickets have fairly understood scope).

Until next time!

TaleSpire Dev Daily 51

2018-12-12 23:52:24 +0000

Today we landed the new UI, we are now hooking it up and squashing bugs.

The tickets are rather specific but here are a few as the daily so far is a tad short :)

  • Start hooking up the campaign invite panel
  • Allow a lone Gm who is in player mode to perform actions that would normally require Gm approval without the request.
  • Add hooks for providing strings to the session history panel (only the lua state-machine scripts are using it right now)
  • Handle more cases where board loading can be interrupted
  • Tweaks to the radial menu to make it feel nicer (such an insightful daily)
  • Change under what circumstance we focus the camera on a creature (For some reason I had it set up to focus on the first time you selected any creature)
  • More things that are so specific to the internals that it would be meaningless

Ok. That’s enough that I’m not entirely wasting people’s time by posting this.

Tomorrow we’ll be working on more of the same. I also need to look at the code to react to a player’s rights (e.g. if they can gm) being changed during the session.


TaleSpire Dev Daily 50

2018-12-12 00:29:24 +0000

I hadn’t expected to be doing a fairly hefty refactor of the board loading today but that’s where I’ve found myself. I’m trying to nail down the behavior that occurs when the user you are syncing the board from leaves during that sync, or if the sync fails, or.. well you get the idea, we are looking at failure cases and how they behave.

The downside is having to retest a bunch of basic functionality but naturally the upside is that we are fixing issues the old one had.

The new UI hasn’t landed yet so nothing new to report there yet.

The only other important thing I’ve been working on today is adding a retry callback to our http request so that, in event of failure, you can choose if the request is retried or not. This was a pretty quick change as a bunch of the csharp code that wraps the calls to the backend is generated from a description on the erlang side. This has made it easy to make frequent changes to the backend api and know that the frontend code matches it exactly. More on that another time though.

Goodnight folks. Tomorrow is just gonna be more of this robustness work.

p.s. Reentrancy in state machines is a pain

TaleSpire Dev Daily 49

2018-12-10 23:52:19 +0000

Hey again, back after a few days without dailies.

Development is still going ok. Jonny has been working hard on getting the new UI to the point where we can merge it into master, looks like we are close there now. Once that lands we can hook things up and write the features that were waiting on that.

I mainly been working on query retries and managing the connection to the backend. I’ve merged in the branch with support for Steam login so I can get back to that soon. Board checkpointing took a little longer than planned but is working nicely now. At the start of each play session a new file for the board is created on the backend so we keep a history of those boards. For now we will just let these pile up but we’ll have to look into how many we want to keep around in future.

Another boring but necessary feature from today was adding limits to the number of campaign invite codes a person can make per minute and per day.

Tomorrow I want to look at having queries check with the connection manager to see if they should bother retrying on failure. I also need to look at the error codes from the backend queries so we can give meaning messages or take specific actions. After that it might be making the version of the steam login that we will use in the alpha.

Along with this we are squashing bugs but also finding more so the deadline is still looking very tight. I mean the worst thing that happens is the alpha is in January, but man.. I’d really love to get it out this year.

Ah well, gotta keep hammering.

Seeya tomorrow