From the Burrow

TaleSpire Dev Log 222

2020-09-07 02:02:20 +0000

Heya folks.

Ree has been working full steam on the flying mechanic, and it’s looking pretty damn nice. You should get your hands on it very-soon™ if all goes well.

Work on assets has been going well too. We have some good stuff we hope to show there soon-ish also.

Before the weekend, I tried to get more dice working. However, the D12 was spinning relentlessly, so I just put that down for a bit. I feel like we are past the big hurdles with that part of the physics integration, so it should be a case of just hunting down those issues.

I also started on porting the animated fire to the new system. This requires some relatively simple changes to the batcher but also means we need to recreate some scripts in spaghet. Here is the noodly goodness as it stands now.

noodles

This will definitely be cleaner when we support collapsing subgraphs into function-nodes, but it’s not too bad even now. We are sampling a few curves in order to:

  • pick the active mesh
  • rotate the object which holds the light
  • adjust the light’s intensity

For the curious, this compiles down to a short sequence of operations.

ops

I still need to switch from local time to global time and add a random-number node to add some timing variation between each fire instance. I believe I still need to do a little work to handle some cross-frame state, but this hopefully won’t throw any spanners in the works.

Tomorrow I’ll pick up where I left off and try to get this lot running in TaleSpire. Except for lights, which are their own can of worms.

Seeya then.

TaleSpire Dev Log 221

2020-09-01 14:00:30 +0000

Hi everyone,

Integrating the new physics engine is going well. I wrote a component that converts old-style colliders and rigid-bodies into the new style.

conversion

Sorry about the weird colors here. Unity today decided that I last renewed my license tomorrow (yup), and so right now, it thinks I’m unlicensed and gave me the light editor theme[0]. The blue tint on the righthand-side lets me know when I’m in play mode, which is super helpful. It looks a lot less baby-blue when used with the dark theme :P

I’ll pretty the UI up in time. For now, seeing everything is helpful.

It took me a while to work out where to get some mass related values right, so the dice rolled strangely, but now it’s a little better.

dice roll

Behind the scenes, a lot is going on, not least of which is that the physics is running with a fixed-timestep. This shouldn’t be a big deal as a fixed-timestep is mandatory for stable physics across framerates. However, this is not fully supported in Unity’s ECS, so I was concerned that it would be difficult.

Luckily for us, it was not[1]. The physics engine is pretty great at giving you control, so I loop running the simulation for the required number of steps. If you have read about fixed-timestep before[2] you’ll know that you need to interpolate the results as the final step. The physics engine doesn’t have that support for that out of the box, so we added a job to collect that information and apply it as we write the transforms back to the GameObjects.

With that done, I need to replicate the parts of the old physics API that we use. If I can get dice rolls working again then I should have replaced most of what we need.

Have a good one folks, Peace.

[0] yup I do know about the latest version making the dark theme free, but upgrading is risky and we are on a tight schedule right now.

[1] The interpolation is not hard, but the Unity folks have a lot more to support that we do, so we get to only handle the simpler case.

[2] The best known fixed-timestep explanation can be found over here. It’s a good one.

TaleSpire Dev Log 220

2020-08-29 16:05:37 +0000

Phew, a few days away from the dev-log there. I got really caught up in some changes that were a real grind.

I’ve been working on the behavior of uncommitted changes. This work is taxing as you have a matrix of different states tiles might be in. Let’s take redo of delete for an example.

  • You might be redoing an undo which has been committed
  • You might be redoing an undo which has not yet been committed but the delete action it undoes has been committed
  • You might be redoing an undo where neither the undo nor redo have been committed yet

And that’s one action in isolation. What about the delete of assets which were made by undoing a separate delete. The matrix of possibilities applies to all the actions involved in that sentence too. In short, making sure you get a reasonable result takes a lot of concentration (and bizarre diagrams :D ).

When I finally got it running locally well, I connected up a second client and immediately disaster. The result was very wrong. I’ll admit I started panic sweating at that point. Last time this happened, we had to delay the Beta. Luckily this time, the system is much simpler, and I have an extensive test suite to lean on.

I dusted off the tests (I may have neglected them for a while) and started digging into issues. The great news was that, whilst the tests did find a couple of bugs in the new code, the underlying board code was still working fine.

This helped me relax and focused my attention back into the code that handles the batching of uncommitted tiles. After some time in the debugger, I finally spotted a case where tiles were not removed from the uncommitted state when committed. This amounted to a constant being 1 instead of -1. With that typo fixed, it started behaving rather well.

With that terrifying detour done, I needed to get back into physics. I have had to write a lot of the physics code fairly reactively rather than with a solid plan, and so I hit the point where I needed to clean things up. This sucked. It was a painful combination of being very tedious but also critical to get right. Some days are just like this.

These last weeks I’ve really been feeling the pain of not being able to just rely on the game-engine in the ways we usually do. Because of our bad estimate of when Unity’s new ECS would be ready, we are having to make a lot of systems ourselves. This is fine in theory (I love making stuff), but it’s meant losing at least a month of dev time that we did not expect. That’s always difficult, but our timeline was already tight. It’s pretty stressful.

Anyway, panic/rant aside, things are progressing. The thing on my plate now is hooking regular Unity GameObjects into our physics setup. We need something that takes current-gen Unity Physics components and makes equivalents in a format suitable for their new physics engine. We can then write some code to manage copying the values to and from the new physics engine to keep it all in sync.

If all that goes well then hopefully I’ll be rolling dice again soon!

Thanks for stopping by folks,

Seeya in the next dev-log

TaleSpire Dev Log 219

2020-08-27 02:06:31 +0000

Today has been spent working on the behavior of uncommitted action.

Whenever you add or delete tiles, we need to perform the action on the other players’ boards. To get the right result, the actions need to be applied in the correct order. This is done by sending all of these actions to a player, which was automatically designated as the ‘host’. They then relay the action to everyone, which gives us an order. We call an action which has been given an order a ‘committed action’.

Given that we can only apply the actions once they have been committed, we are in this annoying position where we need to wait for that roundtrip before we see a change from our keyboard/mouse click. That feels bad[0], so we needed to do something about it. By the time of the beta, we had made a system that could update the board’s visuals for our uncommitted changes so that the change looked immediate. It was complicated, but it was made much more so by the fact that we had to spread some changes over many frames due to Unity not being able to keep up with spawning without impacting frame-rate.

Now that we have taken control of batching, we can happily spawn thousands of tiles a frame with no issues, and this lets us drop the performance workarounds. I’m now rewriting the code that handles applying visual changes for uncommitted actions.

It’s going pretty well. I have uncommitted actions working for adding tiles and undo/redo of the same. I have made good progress on delete and, although it’s significantly more complicated, I’m pretty confident I’ll have it working tomorrow. If I can get this done in two days, that’ll be pretty great as the last version took months to get right. [1]

As soon as this is behaving, I will be switching back to physics. The first task is to make the ground a physics object again, and then I will be looking at dice. I hope to have some familiar dice rolling gifs by Monday :)

Hope this finds you well folks.

Peace

[0] It might seem like not a big deal, but we had complaints about the responsiveness of undo/redo in the alpha, and back then, that delay was mostly due to performing the action on key-up rather than key-down. Input latency really matters.

[1] Of course, it’s not an apples-to-apples comparison as the codebase is already structured in a way where this would be possible. However, it definitely feels much simpler.

TaleSpire Dev Log 218

2020-08-25 17:53:43 +0000

Heya folks,

Today I started out looking at the slab code again. The slab is the way we refer to a section fo tiles that have been copied. When you paste a slab string, that slab appears in your ‘hand’ in-game, and you can place it like a tile.

Recently we have been writing batching code, something that used to be handled by Unity. It got to the point where I needed something similar for the slabs, which I started yesterday. There are a couple of differences from the standard code batching code:

  • We don’t want physics to be set up for the tiles/props
  • We don’t want scripts to start running
  • We need to update the position of every object in the slab every frame (as the player moves it)

This mainly involved taking the existing code, taking a chainsaw to the parts we didn’t need, and stitching together the remains. It’s still very rough, but I was able to try pasting in the slabs from the community… which of course crashed the game :P It was obviously not the fault of the community content, it was that it was a much more complete test that I had run up until then and it found a few bugs. One was a case where we had assets in TaleWeaver with a MeshFilter with no mesh specified. Another was that I hadn’t written the code to handle missing assets.

I got the code to the point that I could paste a slab. However, it feels pretty rough as the ground plane in the game doesn’t exist in the new physics system yet. I’ll be back working on the physics code soon, and then I can take another crack at this.

The rest of today has been spent looking into building code. I need to re-implement the stuff that handles things that have been affected by changes that have not yet been committed (confirmed by the host). It’s pretty hard going, but I’m hopeful I can make some decent progress this week.

I’ll leave ya with a view from the cabin one of our friends were kind enough to invite us along to over the weekend,

Ciao

the hills

TaleSpire Dev Log 217

2020-08-25 03:40:31 +0000

After a lovely couple of days out of town, I’ve got back to business, and it’s been a busy one.

I spent the first half the day on dynamic colliders. For now, these are the colliders that are attached to tiles (and props) and are moved by scripts. This was a somewhat painful process as I ended up bouncing back and forth between TaleWeaver and TaleSpire as I needed to make some tweaks to the code that dealt with the object hierarchies.

dynamic collider 0

dynamic collider 1

With that behaving, I stubbed out the code for computing the motion data required by the physics engine. Finally, I tweaked the per-frame code so that the physics engine knows when it doesn’t need to be rebuilding all the internal data for static objects. This should, in normal cases, give decent performance.

For the rest of the day, I switched to slabs. I really wanted to be able to paste large objects from the community and see them appear immediately. Annoyingly they have managed to avoid working yet. The majority of the work is done. I’m just chasing down smaller bugs and mistakes, but it’s late, and I need to sleep.

I expect to write up a bit more on this once it’s working.

Seeya tomorrow.

p.s. I’ll show a pic from the weekend to those curious when I get them from my partner. I’m using a dumbphone currently, and photos are not it’s strong suit :D

TaleSpire Dev Log 216

2020-08-21 17:10:11 +0000

chest

This looks like nothing. If you used TaleSpire, you’ve seen this a thousand times. For me however, this is great. The fact it looks the same means the following:

  • Spaghet’s realtime scripts are being controlled correctly by the state-machine scripts
  • The custom animation system is working
  • The new batching system is working
  • All the work from the last week to replace the old physics engine has paid off. If you can pick a tile (which we are), then the raycasts are working.

This has been a slog. Any time you have multiple days without being able to start the game, it’s mentally draining, and these last weeks have been tough. There are piles of issues still[0], but I think I might be through the worst part.

Have a great weekend everyone

[0] To name just one, mesh colliders aren’t properly oriented

p.s. I’ll be offline for the next few days as I’ll be off recharging in the country somewhere :)

TaleSpire Dev Log 215

2020-08-17 09:19:38 +0000

Progress feels slow but is steady.

The batcher now produces the data the physics engine needs for static colliders. Thanks to that, I’ve started writing some helper methods that mirror the parts of the older physics API we use. This should make the porting of the existing code noticeably easier. I’ll find out how that goes today as I’m planning to start porting that now.

You’ll notice I specifically mentioned static colliders above. I haven’t worried about the colliders attached to objects moved by scripts yet. The reason is that they are, for the most part, just a slightly more complicated version of the thing I’ve already done, whereas the board tools and dice are still unknown quantities.

I’m hoping the tool side goes smoothly today as I really want to start looking into things like dice and creature, which will have a hybrid setup in this system. By hybrid, in this case, we mean that we will be using Unity’s GameObjects, but we will write custom components to hook them into our physics setup [0].

Speaking of the physics setup, we’ve always had two sets of colliders we keep in different layers in Unity. We have the ‘explorer’ layer, whos colliders we use when placing tiles, and the ‘tile’ layer[1], which is the version used during play by dice/creatures etc. The split allows us (and modders) to provide a better building experience by tuning the explorer colliders. As I’ve been working with the new physics engine, I’ve started to think that it might be worth using two totally separate physics-worlds, rather than layers.

The reason is one of performance. When querying the colliders, we usually care about either the explorer layer, or the tile one and the physics engine has to skip the ones we don’t care about. It does this via a layer mask, so it’s a quick check, but not doing something is always faster than doing something. I’m also musing about if this allows us to do less work per frame by having different update frequencies for the two worlds. We will be trying to keep things fast by, per-frame, only giving the physics engine data for the zones[2], which contain the player’s cursor or dynamic objects like dice. However, there is a tradeoff between changing data (which requires more frequent rebuilds of internal data-structures[3]), and the number of things being tracked by the physics engine (which affects query times).

This is something that can be tuned over time, so I may just set up the code so that swapping and changing will be less painful in the future.

Alright, that’s all that I need to ramble about for now. Hope to see you in the next one.

Ciao.

[0] In contrast, all tiles/props are managed/batched by us. It’s a tradeoff between having Unity help us with lots of things and performance.

[1] Yeah, not great naming :P

[2] 16x16x16 regions of world space

[3] BVH https://en.wikipedia.org/wiki/Bounding_volume_hierarchy

p.s. oh yeah I’ve also started on tools to visualize colliders in our new system

raycast

TaleSpire Dev Log 213

2020-08-14 08:45:48 +0000

Morning all,

Yesterday I got the new collider data loaded into TaleSpire and started writing the code that would lay out all the static colliders.

I originally planned to store the colliders per asset[0], but after writing a significant amount of code, I remembered that Unity.Physics’ colliders don’t support scaling. This means I need to store scald versions of the asset’s collider for each Tile/Prop[1] that uses it.

I realized this fairly late in the day, and it was a bit of a bummer to have to start rewriting then, so I stopped for the evening and relaxed instead.

Today I’ve got to detour into some other code, but I’ll get back to this asap.

We do learn from this however, that we won’t be able to animate the scale of the parts of assets that have colliders. I’m not sure if this means we’ll just disallow animating scale or only give warnings if you do it to something with scale. I’ll chat with Ree about this in our next daily.

Alright folks, hope you are doing well.

Seeya

[0] In TaleSpire, Tiles, Props, and Creatures are made of assets arranged in different ways. Assets themselves are made of objects, but you don’t address those sub-assets directly.

[1] Each kind of tile, not one for every instance of the tile.

TaleSpire Dev Log 212

2020-08-12 00:47:53 +0000

Today was pretty simple. I spent the day reading into the Unity.Physics package and trying to work out more of the nitty-gritty of how we will work with it. Tomorrow I’ll start implementing things.

The first thing to do will be to work out the serialization for colliders on assets. I’ll be slightly changing the data stored per object inside assets to avoid additional processing on the TaleSpire side. I’ll then be looking at the colliders that live on tiles and are used by the building tool.

It’ll then be over to Unity to look at loading this stuff and how to asynchronously create the mesh-colliders. I’ll need to ensure that the other systems aren’t notified that the asset is loaded until this processing is complete.

I’m sure I’ll run into some other little complications on the way, but that’s fine.

I expect this will take most of tomorrow, and so on Thursday, I’ll start updating the batcher to handle the physics data. Colliders attached to animated objects will likely require some attention to get right.

With all that in place, it will hopefully be time to write a little helper API and to start updating all the existing code to use this new system.

We’ll keep you posted on how this goes.

Seeya

Mastodon