TaleSpire

Created by Bouncyrock

Pre-Order the Early Access of TaleSpire and get access to the End of March Beta

Latest Updates from Our Project:

"From within the spire, the sound of many tools could be heard"
6 months ago – Mon, Dec 02, 2019 at 01:49:03 AM

Heya folks,

This week's work has been extensive but also has followed well in the rhythm that we have set in previous weeks

@Ree has been improving the asset production pipeline, working on the building tools, experimenting with game-feel and handle business.

I've been improving a lot of code handling the tiles, how they are spawn, destroyed, and synchronized. Due to being too deep in the changes I didn't write any dev logs during the week. Instead, I took this evening to write up everything in a 4 part series which you can check out here: 

On the art side work has continues on backer minis, various weapons for use in future creations and study to make sure we keep getting better at this stuff!

Weeks like this make for great progress and difficult summaries, however, we've been glad so many of you have enjoyed these little updates from across the way :)

Goodnight

Just checking in
6 months ago – Mon, Nov 25, 2019 at 11:41:35 PM

Hi folks,

This will be a quick one but there's plenty of additional reading for those who like the technical details

On the asset side of the story, we've been working on base meshes and tools to speed up the asset production workflow. This should give us a boost, especially when making Heroes and NPCs. We are aiming to do a longer update focusing on that in the coming weeks.

One the code side, there has been progress on scripting, pathfinding and a whole bunch of project organizational stuff. I'm now hammering away on the code that handles the boards so I can start making changes (add, delete, etc) using multiple cores. More details and write-ups as this all progresses.

And finally, as promised, the additional reading :)

I hope this finds you all well.

End of week update - Statefully yours
7 months ago – Wed, Nov 20, 2019 at 11:56:53 PM

Update time! Progress has been very good.

@Ree has kept on hammering away at the building tools from the last  update. He’s also been handling lots of behind-the-scenes organizational  stuff which whilst not exciting to blog about is as critical to  TaleSpire happening as anything else we do.

Jason has been chatting to loads of the backers who pledged at the  ‘Help design a ___’ levels and sculpting is in full swing. Very  exciting!

I’ve finally broken through the wall of fiddly details that was  plaguing my board sync implementation and it’s looking pretty good now.  This has freed me up to look at some other tasks that are on my todo  list so I’m gonna ramble about that for a bit in this post.

First off I went back to Fog of War. Basically, the task is this:

  1. Take a 16x16x16 grid
  2. In every cube write ‘true’ if there is meant to be fog there and ‘false’ if not
  3. Now take this info and make a 3D mesh that contains all the cells marked ‘true’

And I wanted to make sure we had step 3 worked out.

Now there are a couple of points to keep in mind:

  • The mesh we need to make needs to conform fairly closely to the grid as we don’t want to see glimpses of anything we shouldn’t
  • We don’t need to make this look like fog, we just need a mesh we  can start working with, we can do all kinds of polygonal and shader  effects on top of a simple mesh that will look much more fog-like.

As a great example check out this tweet from @Ed_dV !

Those clouds are spheres, with lots of magic on top (if you watch the whole thing it shows the spheres without the magic).

Given those two points, I decided a good source of wisdom would be  the kinds of algorithms that Minecraft-like games often use. Luckily for  me Mikola Lysenko of 0fps.net has written some amazing articles on these techniques along with WebGL demos and source code, what a star! This gave me a  huge boost and along with a few implementation tips from other sources I  was able to put together a ‘Greedy Mesher’ (the name of one of the  techniques) in Unity. Now, this next picture is not meant to be clouds, it was just a test to make sure it was working.

For the coders out there, I also made this implementation using  Unity’s job system which allows me to run the mesh generation jobs in  parallel across all cores. It’s pretty speedy considering how little  effort was required.

That is all on the subject of fog for now but we will be back with more in future.

Next on my list of concerns was interactable Tiles and modding.

We have a bunch of interactable tiles in TaleSpire and this is only  going to increase as we open up the ability for the community to make  them.

A real pain point when you make a  user-driven content game like  TaleSpire is that you have no way to know when or where someone will  just suddenly throw tonnes of extra stuff for your game to do.

For example, take that side-table in the gif above. There is nothing  to stop you dragging out a whole load of tables and the numbers get  large FAST. Remember that if you drag out a square with 32 tiles down  one side then that is over 2000 tiles that your game suddenly has to  handle. They all need to appear on all the other player’s machines  quickly and they all need to be interactable immediately.

That means all 2000 of them are running their own little scripts. How do you ensure that they don’t start crippling your game?

Now we naturally knew this was coming and previously we had been  making small fast components that would then be wired up using a LUA  script (that’s another programming language for those not into this  stuff :] ).

It worked but I was still concerned about how it would scale.

There was another thing. Like I said we were using LUA in a weird  way, as a way of setting stuff up. I started thinking that that might be  the worst of all worlds for users as, for those who like LUA, there are  lots of things they would be told not to do and for those who hate LUA,  well they hate it :p

Were there other problems? You’re damn right there were!

As mentioned before, we need to keep all of these tiles in sync on  everyone’s machines and so the idea of scripts just being able to fire  off messages whenever they liked was a nightmare, it could really make  the game unstable if done wrong.

Now, this sounds tautological but there are two kinds of state for a  tile: State that matters to the story and state that doesn’t. For  example, whether a fire is lit or not matters, the exact positions of  every smoke particle does not. As long as it roughly conforms all is  well.

So it would be good if we can separate these kinds of scripts out  from each other so we have a shot at being able to enforce sensible  behavior over the network.

So after pages and pages of notes and a lot of coffee, I decided it  would almost be worth making our own compiler that suited our needs but  we needed

Now, this bit gets technical so feel free to skip to the row of asterisks!

+++++++++++++++++++++++++++++++++++++++++++++++++++

I wanted something that

  • has a simple execution model.
  • was focused on only the tasks we need.
  • run on multiple cores
  • used no GC
  • was reasonably fast

Here’s the approach I went for:

0. I decided to start with only 4 data types: int, float, int3, and float3

1. I use a node graph as the code representation. I’m currently using the excellent XNode but if/when Unity’s new graph UI stabilizes I will probably move to that.

I added code to detect cycles and compute the correct types at each node

2. Walk the graph and generate a tree of IR nodes. This is mainly for convenience but in the conversion, we also pick correctly typed IR nodes in a few specific places.

3. Walk the IR nodes to compute the layout for the stack

4. Walk it again and generate a bytecode that represents the program

5. Do a little cleanup pass and kick the result out as a NativeArray<byte>

6. Write a Job that takes the instruction array, an array of private state and a few other bits and run our little bytecode in parallel.

7. Marvel at the power of coffee

***********************************************************

It took 18 hours to get the first version up and running and the results were promising.

Here is a picture of some nonsense ‘code’

The graph above (whilst being gibberish) can be run for 10000 tiles  in around 2ms, which is way slower than it will be but it’s acceptable  for a first pass. It told me the approach was worth more work so I took  Friday to flesh it out a bit.

Oh, and the language is called Spaghet!

With that we have the kind of script that can be used for the ‘not  story critical stuff’ but we still need the other scripts too.

To that end, I’m now working on how to script the state machines that will run the important stuff. Here is a little picture of the prototype I’m currently working on:

Naturally, the look of the graph and the nodes available will be improved too.

Soooo yup, it’s been a good, busy week. I’m going to be working on  this and all the code that holds it together all this week. I’m hoping to have the major plumbing done by Wednesday though.

Seeya! Have a great week

More gifs? More gifs.
7 months ago – Wed, Nov 20, 2019 at 12:19:27 AM

First off a little clip of some of the cutaway work we are doing.

This is a WIP of the effect from the other day, re-implemented in to Unity. As you can see we haven't made this play nicely with shadows yet but it's fun to see that we will have the level of control we need for the effect.

Next Jason has another great mini in the works.

More of this fellow when it lands in-game :)

That's all for tonight.

Seeya

It's not heights that frighten me, it is the rapidly ascending floor.
7 months ago – Wed, Nov 20, 2019 at 12:17:56 AM

(Paraphrasing Rincewind the Wizzard)

Greetings!

Baggers is continuing his amazing work on the new backend and Dwarf has started exciting work on the Kickstarter "Help design a" rewards! So this week I'm going to be rambling on about stuff. Stay awhile, and listen. I mean, if you've got some time...

Everything in this update is still work in progress, UI, etc will evolve, so will the features themselves.

Let's talk about the floors.

This past couple of weeks, I've been working on building mechanics, and more specifically, how they should work with floors. We're technically obliterating the floor concept as it existed in the Early-Alpha. That doesn't mean we're removing verticality, of course, it just means that we're trying to embrace it fully by allowing GMs to stack blocks onto each other, not worrying about what is a "floor" and what isn't.

This new solution doesn't come without its share of challenges, however, as there are certain things associated with the previous system that I'd like to maintain. There was also clarity in the last implementation, and everyone could refer to the floor by number, which quickly translated across. Also, this adds a bunch of complexity. Not only in systems written, but a lot when it comes to the (UX)User Experience. What are the" points of interest" on the vertical space?

How do we communicate that with other players? Where should we cut to make this area visible without hiding relevant information?

I'm trying to move backward through my thought process on these experiments, to talk a little bit about why I went down specific routes.

Navigation

 Moving around vertically is the first issue to solve. As we now require somewhat free movement on the vertical axis a couple of things has been added. [SHIFT] will be repurposed to move vertically, while a lot of the building tools will be associated with [CTRL] (delete, copy, sample). (The new input system will allow for easier remapping of these, mapping them to separate buttons should also work). I Added double-click to move to a location, working across all 3 axes. There is also a new marker indicator bar that has a slider to move the camera plane up and down. So far this does feel pretty good and answers our question about basic navigation in vertical space. It will require more actual game testing to settle on though.

"Floors" and Indicators

 Looking at the above example, it sort of feels like floors are very much still there. But in reality, the markers clicked on to the right are clusters of creatures. That was mainly done to test the system as creatures are not a great way to calculate where markers should be placed. Although players and Game Masters would be seeing the same markers at the same locations, they also reveal quite a lot about the tower to our players. One could have the ones shrouded in fog, hide, but that would be another piece of data for the Game Master to keep track of. A different approach is to analyze the space with clusters of walkable spaces and try to guess what "a floor" should be. Or maybe more appropriately make it easy for the GM to create bookmarks/markers, both permanent and temporary, which could allow for a bit more control. The answer likely lives with multiple of these options. 

All of this also makes me want to ask the question of, should players even be able to move between floors which the GM doesn't deem a point of interest. This is a question for another time, however. 

Before moving onto the next topic, this solution maintains the nice juicy feeling of moving between floors, but it doesn't fully solve the problem of clarity between Game Masters and players, which is something we'll have to dig into soon.

Visibility, Colliders, and Building

One of the greatest features of the new system, and quite frankly why we needed to get rid of floors, to begin with. Building.  Now you're able to stack blocks on top of each other, not worrying if it lines up with our preset "floor" height.  We could have kept the floor system, and enabled each floor level height to be defined by the Game Masters. That would make sense if you have a single structure, but if you're at the ground floor of a tavern, you don't necessarily want to flatten the rest of the city. As a result, we've centered the visibility around the Camera target. It is currently set to be a square, which can be moved up and down by using the sliders to the right (might change). Zooming out also reveal all hidden tiles (might also change). This along with our cutout shader we can get pretty good visibility within structures which multiple floors. 

I started talking about this great building feature, and then suddenly shifted to visibility. The reason for that is I wanted to talk a little bit about some challenges associated with implementing building with this new system.  

(I might on occasion accidentally use the phrase "floor", but what I really mean is a vertical marker, which indicates a vertical point of interest.)

 (If you know what raycasting in games is, I'd skim through  this next part) I mean, stacking tiles on top of tiles is great! nothing wrong with that, but what happens if you want to furnish a room way down in your tower, or replace a wall inside. The way the Early Alpha building system works is that we just RayCast down the camera, and interact with the first surface we hit or the plane of the currently selected floor. Raycasting is like pointing a laser at something and seeing where the red dot appears, and from that, we can ask for all sorts of information, including the tile/model hit. It should work perfectly still, but the way we hide tiles is actually more of an optical illusion. The laser still believes they're all there. The red dot would still appear on the outside of the wall, unable to see inside. One solution is to remove the optical illusion, and just actually remove the tiles, temporarily. But there are certain benefits to leaving them in place. One is performance. Disabling\Enabling them (or removing them as per my analogy) is costly, but the main reason is. How would we stop you from building/placing tiles through other tiles? Let's say you forget there is another "floor" above yours. It would be good for us to be able to warn you. This is why we went with another feature of RayCasting. Let's call it XRay mode. Instead of hitting the first thing you see. You can turn on x-ray, and ask it to return ALL the tiles it passes through. Now we get a list of all the Tiles they laser passes through, and we can ignore all results with the illusion applied. 

(if you do know what Raycasting is and happen to be using Unity. Remember that Physics.RaycastAll & RaycastNonAlloc doesn't guarantee being ordered by distance. This took me a while to discover, despite it being clear in the documentation)

With this approach, we should be able to create a visual indicator when something you're building is intersecting with something hidden. How that should be represented visually is still a work in progress. All of this does enable pretty free building, without having to worry about floors, which has been our goal.

Oh, we've also got a separate, moveable, Build plane, which gives you the option to place "floating" things. As hinted at below.

 This is still rather clunky, but it's next on the list. Will post more actual building in my next update.

Final thoughts: I think this covers a lot of our requirements. It is currently feeling pretty good! The main thing which hasn't been answered is clarity across players and GameMasters. Making sure there is a consistent language that can be used for communicating where and what. 

Thank you very much for getting this far through the rambles. I apologize for the low resolution on those gifs, I'll fix that for the next update I write. 

Till next time, have fun!

TLDR: We got rid of floors in favor of a marker system. This allows free building being able to cut into areas dynamically, and locally. You can now also build things inside of enclosed rooms, replace walls, etc. Still, a lot of work to be done.