thoughts on Blueprint

  • NOTE TO SELF: this section could really use some screenshots

    2023-08-28
    • I don’t have UE installed on my home computer yet, so you’ll have to take my word for a lot of these things

      2023-08-28
    • anyways back to your regularly scheduled bullet points, *ahem*

      2023-08-28
  • Blueprint, my arch nemesis!

    2023-08-28
    • WHAT! you don’t remember me? how rude!

      2023-08-28
  • actually I really like Blueprint

    2023-08-28
    • lots of visual languages generally feel really unpleasant to write (looking at you Scratch), but somehow Blueprint feels like exactly the opposite

      2023-08-28
      • (it’s possible Scratch got better since I last used it like 5 years ago but I remember it being pretty cumbersome to use. I had no reason to revisit it since so I simply don’t know if it’s any better now, but if it is, let’s chat!)

        2023-08-28
  • writing Blueprints is actually pretty darn nice and there’s a lot to learn from the editor UX and basic refactoring tools

    2023-08-28
    • when you drag your mouse out of a pin, and a window will pop up giving you suggestions on what could be connected there

      2023-08-28
      • then you select from the list and it creates the node, autoconnecting stuff as necessary

        2023-08-28
        • one of the nicer autoconnections it can do is when you want to call a function on an actor component

          2023-08-28
          • instance functions require you to pass in a self to call the function on

            2023-08-28
          • so what it does is it suggests functions to call on all the concrete components you already have in your actor, and when you select something like Destroy Component (DefaultSceneRoot), it’ll not only create a function call node, but also hook up DefaultSceneRoot as its self parameter

            2023-08-28
    • when you try to connect two pins of incompatible types, it’ll automatically insert a conversion node for you

      2023-08-28
      • Blueprint is strongly typed so you can’t just pass in a Float where a String is expected, but luckily this makes the system way less painful

        2023-08-28
      • I do have a gripe with this though and it’s where it places the node. it tries very hard to center it but unfortunately never succeeds.

        2023-08-28
        • perhaps a bug I could fix one day?

          2023-09-01
    • from Oskar Kogut: if you change a BlueprintCallable function to const (or otherwise make it pure), the editor will automatically correct the Exec pin flow for you

      2023-09-01
  • the design of Blueprint the Language is pretty dated - it is still an imperative language and has a concept similar to statements (Exec pins), which breaks the entire idea of pure data flow and introduces control flow into the mix

    2023-08-28
    • this split is called pure and impure nodes, where impure nodes are those that perform control flow (ie. those with Exec pins)

      2023-08-28
    • this results in weird edge cases like needing two separate node types to handle branching (one that can have side effects - Branch, and another that can’t - Select)

      2023-08-28
      • Branch is used to shuttle control flow between two Exec lines, based on a Bool. you get a True branch and a False branch

        2023-08-28
      • and Select is used to choose a value based on another value, kind of like a ternary in C++

        2023-08-28
        • however it is quite annoying because you can only switch on enums (and other stuff that has a finite set of values), whereas with Branch you can use any Bool condition you want

          2023-08-28
        • this would be fine if not for the existence of Gameplay Tags, which precisely do not have a finite set of values

          2023-08-28
          • there is a Switch on Gameplay Tag node, but that is for control flow and not data flow!

            2023-08-28
          • this isn’t an unsolvable problem but it illustrates the pure vs impure issue pretty well - you’d have to duplicate the implementation of Switch on Gameplay Tag to have a version without an Exec pin

            2023-08-28
    • I’m seeing a bit of a semblance to the classic function coloring problem

      2023-08-28
      • except where it usually applies to the async concept found in most modern programming languages, here it applies to the concept of control flow vs data flow

        2023-08-28
        • and speaking of async, Blueprint handles the classic async problem very gracefully!

          2023-08-28
    • despite its flaws, one of Blueprint’s strengths is asynchronous and latent tasks

      2023-08-28
      • since control flow is based on those Exec pins, you can easily map your classic concept of callbacks to simply firing off the appropriate Exec pin

        2023-08-28
      • for example the node for playing animations (Play AnimMontage) has a few pins coming out of it that signal playback events like On Ended, On Blend Out, On Interrupted

        2023-08-28
        • and you wouldn’t even know these are implemented as delegates in C++landia. it just feels like a first-class feature

          2023-08-28
      • the only gripe I have is that you can only have latent nodes in the main event graph (you cannot have them within functions)

        2023-08-28
        • which is annoying but not terrible, since most of that latent, high level gameplay logic happens inside the main event graph anyways

          2023-08-28
  • the editor UI, despite being helpful as it is, is far from perfect

    2023-08-28
    • it’s actually quite janky and there tend to be brief flashes of content falling into place

      2023-08-28
      • this is true of other parts of the Unreal editor UI but I’ll focus on Blueprint here

        2023-08-28
    • node UIs are laid out lazily, by default using an algorithm that does not produce precise results for pin locations

      2023-08-28
      • which means that when you first load a Blueprint, some of the wires will be bent in weird ways, and will fall into place as you zoom out and explore the graph more

        2023-08-28
        • the effect looks quite janky and really upsets my inner perfectionist

          2023-08-28
    • as you zoom out, the nodes start looking just a little bit different due to font sizes being snapped to integers

      2023-08-28
      • at very low zoom levels, nodes stop rendering their text altogether, which makes their layout shift even more.

        2023-08-28
        • the effect of this is that nodes themselves take up less space, and it appears as though there is more space between them than there actually is

          2023-08-28
          • which can make it frustrating to lay nodes out on a large scale, because you’ll only find out your nodes are overlapping when you zoom in real close

            2023-08-28
      • there’s a Straighten Connection feature, which you can use to make your graphs look more aesthetically pleasing, but it only straightens the nodes such that they look good on the current zoom level

        2023-08-28
        • so what’ll happen with it sometimes is you’ll straighten a connection, then zoom in, and the connection won’t be quite straight because of the aforementioned layout shift

          2023-08-28
  • maintaining Blueprints in a large project could be a lot better

    2023-08-28
    • with regards to your graphs becoming really large

      2023-08-28
      • everybody kinda sorta just formats nodes however they see fit, and there is no unified autoformatter

        2023-08-28
        • there’s a reason people say Go’s tooling is frickin’ amazing, you know. it keeps codebases consistent!

          2023-08-28
        • this results in what we Hat in Time modders used to call Kismetti in the Unreal Engine 3 days but nowadays we’d call Blueprintti

          2023-08-28
          • which is a portmanteau of Blueprint and spaghetti.

            2023-08-28
            • I can’t believe I remembered the spelling of that word. portmanteau.

              2023-08-28
        • there are plugins on the marketplace that solve this, but I refuse to believe Epic Games doesn’t have this problem themselves

          2023-08-28
          • I’d guess it’s just not very high up their priorities

            2023-08-28
      • refactoring your nodes is a hell of a pain. Blueprint is kind of write-only

        2023-09-12
        • say you’re calling ApplyGameplayEffectToTarget a bunch of times and you want to replace those occurrences with a custom function that wraps ApplyGameplayEffectToTarget with some extra semantic information, to make it more discoverable, searchable, and easy to use

          2023-09-12
          • well then good luck hueh

            2023-09-12
          • in a text-based language you could use a dumb search and replace to accomplish this task, but there is no such thing in Blueprint. cry

            2023-09-12
    • with regards to assets (how long this darn stuff takes to load)

      2023-08-28
      • the biggest offender here being that hard references are the default

        2023-08-28
        • thus you can add a Mesh Component to your Blueprint and it’ll load the entire mesh with all the textures and skeleton and everything when you wanna tweak a variable or some logic in the event graph

          2023-08-28
          • and not asynchronously in the background, you will have to wait for it to finish loading. which is pretty annoying

            2023-08-28
  • the runtime performance isn’t the best for a few reasons

    2023-08-28
    • the VM isn’t implemented in the most optimal way

      2023-08-28
      • I’ve analyzed this in my dispatchers repository if you wanna have a read

        2023-08-28
    • and that hard reference thing can make gameplay stutter when you’re loading in new assets, but that’s a more widespread issue than just with Blueprints

      2023-08-28
    • but in reality most of the logic you’re implementing in Blueprints (high-level gameplay stuff) shouldn’t be that performance sensitive

      2023-08-28
      • and it’s not hard to extract the performance sensitive parts to C++ because Blueprint offers tools for refactoring your code

        2023-08-28
  • but all that doesn’t prevent me from liking it!

    2023-08-28
    • since it’s way more pleasant to write game logic in than C++, given that you don’t need to wait a minute for your code to recompile.

      2023-08-28