Home Artists Posts Import Register

Content

Hello I am still alive! Thank you everyone for bearing with me as I am still going through this gruelling refactoring period. I am still dividing my time between Blockhead and contract work but mostly I have been working on Blockhead since my last post. I have been quiet but that is just because there is little to talk about when refactoring.

Sorry v0.28.3 is so buggy. My priority is still bug fixing and stability but some of the issues are so deep that they require these large changes to the codebase so it is what it is. There will be more refactoring to do in the future but once I am done with this particular stretch I will be in a good spot to focus on fixing the last remaining bugs and getting a nice solid stable build. I know I said something similar a few builds back but this time it feels more real.

Curved envelope segments

Refactoring gets so mentally draining so a while ago I did decide to add curved segment editing to the envelope editor. This was probably a bad idea because obviously adding more things can just introduce more bugs but it's done now and can't foresee any major issues with it.

The curved envelope segments are actually approximated under the hood using a bunch of invisible linear envelope points, with more points generated on the curvier parts. It seems to be working well.

Fixing an old performance problem

In v0.28.3, every block instance that exists in the project has a "block control" associated with it. The block control is the rectangular thing on screen with all the buttons and controls on it that the user interacts with. (If you understand Godot-ese, a block control is basically a subscene.) The control that we interact with is not the same thing as the "block instance", which is more of a conceptual thing which exists within the system.

So in v0.28.3, if you scroll the workspace and a block instance disappears off the edge of the screen, the block instance still exists, and the block control associated with it still exists. It's just not visible.

This is how I designed things early on because it was the most obvious way of doing things. It ended up being a massive mistake but to be fair it was difficult to see the mistake at the time.

The main issue is that a Blockhead project could end up with thousands of block instances, and Godot subscenes are not particularly cheap to instantiate. You can remedy this a little bit using a Godot feature called "instance placeholders", and by releasing old controls to a pool and reusing them, but these techniques are a bit painful and don't actually help all that much.

At some point I also added macros, which was a feature I never even though about when I first started writing Blockhead. If you have a macro with 1000 block instances inside it, which I don't consider unreasonable, then each one of those block instances has a block control created for it, even if the user never opens up the macro to edit the block instances inside. And if you copy and paste the macro, another 1000 block controls will have to be created.

In v0.29.0 (upcoming), none of this will be an issue anymore. Blockhead should never create more block controls than those that are actually visible on-screen at any one time. When you scroll the workspace and a block instance disappears off the edge of the screen, the block control will be released back to a pool, and when you scroll the block back onto the screen, a new block control is acquired from the pool and restored back to the state that the old one was in when it disappeared.

When you copy paste a macro block, only one block control needs to be instantiated - the front-end of the new macro block which is visible on-screen.

And when you zoom all the way out so that everything goes into low-detail mode, all those block controls will be released to the pool and restored when you zoom back in.

So visibly everything will look exactly the same as it did, but we no longer have to keep a pool of thousands of block controls, and we are no longer instantiating loads of unneeded block controls for block instances which aren't even visible.

Instead of completely deleting them I do still release the block controls to a pool so they can be reused, but now the pool will never grow particularly big. I don't think the pool is really necessary at all anymore but it's a hangover from the old code and it shouldn't hurt at all.

The main complication here is what I said about the state of the block control being "restored". If you open the envelope editor for a parameter on a block, scroll the workspace so that the block is no longer visible and then scroll back to bring it back into view, the envelope parameter will still be open. And if you selected an envelope point then the point will still be selected.

With the old design this was easy because all that state was stored inside the block control itself. When the block control disappeared the information about what parameter was open and which point was selected was still there. The block control was just hidden, not deleted. So I didn't have to do anything.

But now every time the block control goes out of view it is effectively deleted (or returned to the pool), so that information has to be stored in the block instance instead, so that it can be used to restore the block control back to where it should be when it next comes back into view.

If you are an object-oriented programmer you might be thinking to yourself "MVC" but while the Godot c++ bindings layer does tend to push you into the object-oriented world with a heavy hand, the Godot scene tree doesn't actually lend itself very well to this clean separation of model and view in my opinion.

I spent quite a while figuring out a nicer way of working with Godot scenes and ended up with something which I think is pretty good and allows me to effectively separate out the block control "view" from the "model" in a clean way. But it does mean that almost every part of the existing block controls had to be rewritten in this new style.

So I've been working on refactoring all these buttons, toggles, sliders and editors which already existed inside the block controls, slowly getting everything back to where it was before, but this time without the performance issue.

Current plan

  • Finish this block control refactor
  • Do a bunch of testing and fix as many known bugs as I can
  • Release v0.29.0 alpha
  • Keep testing and fixing bugs
  • v0.29.x alpha (stable?)
  • Once we have a nice stable version of Blockhead, proceed to actual fun stuff. The next actual feature I would like to work on is saving and loading blocks to files.

In general everything is going fine with development (apart from not quite being able to work on Blockhead full-time right now due to finances.) I'm not hitting any major issues with the refactoring work anymore so it's just a case of grinding it out. I do expect to have to do a bit more refactoring in the future (some problems with the baking system and the plugin system come to mind) but I don't see those taking quite as long.

Comments

Anonymous

Take your time man, I wouldn't worry. I have faith it'll turn out to be something special.