Merge branch 'main' of github.com:liquidev/treehouse
This commit is contained in:
commit
f25a168714
|
@ -22,10 +22,24 @@
|
||||||
% id = "01H969NN1BQX07505EM3093W47"
|
% id = "01H969NN1BQX07505EM3093W47"
|
||||||
- or use your favorite streaming service's search engine, but I'd prefer if you supported the artist by buying their music :ralsei_love:
|
- or use your favorite streaming service's search engine, but I'd prefer if you supported the artist by buying their music :ralsei_love:
|
||||||
|
|
||||||
|
% id = "music/album/aphex-twin/drukqs"
|
||||||
|
content.link = "music/reviews/aphex-twin/drukqs"
|
||||||
|
+ ### album: Aphex Twin - drukQs
|
||||||
|
|
||||||
|
% id = "01H9JB094GTG1TJ029CQ4PNMS0"
|
||||||
|
- buy: [Bandcamp](https://aphextwin.bandcamp.com/album/drukqs)
|
||||||
|
|
||||||
|
% id = "01H9JB094GS63ZP0Y22W6F5A27"
|
||||||
|
- (no review yet, section only for permalinking purposes)
|
||||||
|
|
||||||
% id = "music/album/aphex-twin/syro"
|
% id = "music/album/aphex-twin/syro"
|
||||||
content.link = "music/reviews/aphex-twin/syro"
|
content.link = "music/reviews/aphex-twin/syro"
|
||||||
+ ### album: Aphex Twin - Syro
|
+ ### album: Aphex Twin - Syro
|
||||||
|
|
||||||
|
% id = "music/album/radiohead/a-moon-shaped-pool"
|
||||||
|
content.link = "music/reviews/radiohead/a-moon-shaped-pool"
|
||||||
|
+ ### album: Radiohead - A Moon Shaped Pool
|
||||||
|
|
||||||
% id = "music/album/radiohead/hail-to-the-thief"
|
% id = "music/album/radiohead/hail-to-the-thief"
|
||||||
+ ### album: Radiohead - Hail to the Thief
|
+ ### album: Radiohead - Hail to the Thief
|
||||||
|
|
||||||
|
@ -39,3 +53,11 @@
|
||||||
content.link = "music/reviews/radiohead/ok-computer"
|
content.link = "music/reviews/radiohead/ok-computer"
|
||||||
+ ### album: Radiohead - OK Computer
|
+ ### album: Radiohead - OK Computer
|
||||||
|
|
||||||
|
% id = "music/album/radiohead/the-king-of-limbs"
|
||||||
|
+ ### album: Radiohead - The King of Limbs
|
||||||
|
|
||||||
|
% id = "01H9JB094HBXF1G48ZME4WV2JA"
|
||||||
|
- buy: [Bandcamp](https://radiohead.bandcamp.com/album/the-king-of-limbs)
|
||||||
|
|
||||||
|
% id = "01H9JB094HGCA0D7EGR39FC509"
|
||||||
|
- (no review yet, section only for permalinking purposes)
|
||||||
|
|
97
content/music/reviews/radiohead/a-moon-shaped-pool.tree
Normal file
97
content/music/reviews/radiohead/a-moon-shaped-pool.tree
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
% id = "01H9JB094C60Q6DR1E7SME7Y0N"
|
||||||
|
- buy: [Bandcamp](https://radiohead.bandcamp.com/album/a-moon-shaped-pool)
|
||||||
|
|
||||||
|
% id = "01H9JB094C7QNWZNYQDKPX7CVA"
|
||||||
|
- a really chill album compared to most of their previous work
|
||||||
|
|
||||||
|
% id = "01H9JB094C7S8K58DCCRCA22AG"
|
||||||
|
- takes on some of the chillness of [The King of Limbs][branch:music/album/radiohead/the-king-of-limbs], but it's much more acoustic
|
||||||
|
|
||||||
|
% id = "01H9JB094CX3APT8AFQHKE23Z5"
|
||||||
|
- favorite tracks
|
||||||
|
|
||||||
|
% id = "01H9JB094CE84FR36P97W43J07"
|
||||||
|
- while I usually try to rank these tracks by how much I like them (from top to bottom), it's really hard to do it with this album, so just know I like these equally.
|
||||||
|
|
||||||
|
% id = "music/track/radiohead/present-tense"
|
||||||
|
+ #### Present Tense
|
||||||
|
|
||||||
|
% id = "01H9JB094CYBC0QRFV8D0H8CGB"
|
||||||
|
- *this dance, this dance*\
|
||||||
|
*is like a weapon, is like a weapon*\
|
||||||
|
*of self-defense, of self-defense*\
|
||||||
|
*against the present*\
|
||||||
|
*the present tense*
|
||||||
|
|
||||||
|
% id = "01H9JB094CPV3N30272TKSMQNC"
|
||||||
|
- going crazy, going nuts. a dance of self-defense. against the present... the present tense.
|
||||||
|
|
||||||
|
% id = "01H9JB094CAVH2H79B32V0AKXY"
|
||||||
|
+ you cannot stop the passage of time, but at least you're here right _now_. your time will be up one day, so while you're losing your mind...
|
||||||
|
why not freak out a little too?
|
||||||
|
|
||||||
|
% id = "01H9JB094CA5KG5H1VDSRVT3RB"
|
||||||
|
+ why not assert dominance by assaulting your friends with `uwu`s and `owo`s when they least expect it?
|
||||||
|
|
||||||
|
% id = "01H9JB094CHP56MFNT73AWQP6D"
|
||||||
|
- send (fluffy) Internet hugs while you're at it?
|
||||||
|
|
||||||
|
% id = "01H9JB094CZ53VNV0K1HA7VY6B"
|
||||||
|
+ why not wear a horned headband to work for a few weeks; have some fun in your life for once?
|
||||||
|
|
||||||
|
% id = "01H9JB094CWFR3NJMV933EVK7D"
|
||||||
|
- (I'm actually doing this btw.)
|
||||||
|
|
||||||
|
% id = "01H9JB094CDQZ8T1Q278B269M6"
|
||||||
|
+ why not just stop giving a shit about what other people think for a moment. they probably don't give a shit either.
|
||||||
|
|
||||||
|
% id = "01H9JB094CH7JFBKQF6QZ6KPEB"
|
||||||
|
- or if they do, tell them what *you* think. tell them why you're freaking out like that. and be honest :)
|
||||||
|
|
||||||
|
% id = "music/track/radiohead/daydreaming"
|
||||||
|
+ #### Daydreaming
|
||||||
|
|
||||||
|
% id = "01H9JB094C0R4Y4ZS2MZFRZV1Q"
|
||||||
|
- it's so soft it feels like you're floating on the surface of an endless lake, with nothing but clear water, you, and the endless blue sky.
|
||||||
|
|
||||||
|
% id = "01H9JB094CRX525PM9G07ES9R7"
|
||||||
|
- daydreaming, daydreaming, daydreaming...
|
||||||
|
|
||||||
|
% id = "01H9JB094CN53APVVHTJ0JGF98"
|
||||||
|
- lost in an endless stream of thoughts
|
||||||
|
|
||||||
|
% id = "01H9JB094CY0F7XKG40MRSKQQD"
|
||||||
|
- lost on the surface of the lake, looking at the sky
|
||||||
|
|
||||||
|
% id = "01H9JB094CPT875M6C5AWM4YCM"
|
||||||
|
+ and daydream you will, forever
|
||||||
|
|
||||||
|
% id = "01H9JB094CTN4XHRKFXDTG4WQ2"
|
||||||
|
+ always
|
||||||
|
|
||||||
|
% id = "01H9JB094C0MKJ0NJ5EEWPC5TX"
|
||||||
|
+ if not right now, a time will come
|
||||||
|
|
||||||
|
% id = "01H9JB094CRA07WTF2FT2ZAD1N"
|
||||||
|
+ and by the moment you realize...
|
||||||
|
|
||||||
|
% id = "01H9JB094C3JEKHJ098QBBPACD"
|
||||||
|
- the daydream is over, but it'll never be out.
|
||||||
|
|
||||||
|
% id = "01H9JB094CXN4FWC6N2RZKWFDA"
|
||||||
|
+ try getting lost in your mind every once in a while.
|
||||||
|
|
||||||
|
% id = "01H9JB094CPPZGX217BR6BAT4J"
|
||||||
|
- get your headphones, sit down comfortably, play this song, and close your eyes.
|
||||||
|
|
||||||
|
% id = "01H9JB094CXXHF5E6ABRAQF7GT"
|
||||||
|
- and let yourself drift... across the endless blue lake.
|
||||||
|
|
||||||
|
% id = "music/track/radiohead/ful-stop"
|
||||||
|
+ #### Ful Stop
|
||||||
|
|
||||||
|
% id = "01H9JB094CPCV921YGVXNJGPHK"
|
||||||
|
- I don't really have an interpretation of the lyrics, or the composition... but I really love the tension buildup.
|
||||||
|
|
||||||
|
% id = "01H9JB094CT9KW5KYF9BEK3ER4"
|
||||||
|
- I love buildups in general. and this one is balanced very well; it's the kind of rock track I like. full of amplified guitars, but not too loud.
|
|
@ -8,6 +8,13 @@
|
||||||
content.link = "programming/projects"
|
content.link = "programming/projects"
|
||||||
+ ## projects
|
+ ## projects
|
||||||
|
|
||||||
|
% id = "01H9R1NKBQ9PEQT49XJZ6PB1KH"
|
||||||
|
- (actually nothing here yet lol, I was about to write something here but forgot but now don't wanna delete a branch I'm gonna bring back again anyways)
|
||||||
|
|
||||||
|
% content.link = "programming/cxx"
|
||||||
|
id = "programming/cxx"
|
||||||
|
+ ## C++
|
||||||
|
|
||||||
% content.link = "programming/unreal-engine"
|
% content.link = "programming/unreal-engine"
|
||||||
id = "programming/unreal-engine"
|
id = "programming/unreal-engine"
|
||||||
+ ## Unreal Engine
|
+ ## Unreal Engine
|
||||||
|
|
60
content/programming/cxx.tree
Normal file
60
content/programming/cxx.tree
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
% id = "01H9R1KJESR2F420HE67HW4AVR"
|
||||||
|
- design lessons from the best programming language of all time that everyone loves (not really)
|
||||||
|
|
||||||
|
% id = "programming/cxx/access-modifiers-as-labels"
|
||||||
|
+ access modifiers as labels (`private:`, `protected:`, and `public:`)
|
||||||
|
|
||||||
|
% id = "01H9R1KJES39Z6RBCKY4E71PYD"
|
||||||
|
- although Java and C#'s approach to symbol privacy may be verbose, it has one great advantage: it is stateless.
|
||||||
|
|
||||||
|
% id = "01H9R1KJES17626QXYEGM7XBC7"
|
||||||
|
- the way they're implemented in C++, it's essentially a bit more parsing state you have to keep track of
|
||||||
|
|
||||||
|
% id = "01H9R1KJESG4K8T1K1G36T7HBP"
|
||||||
|
- and you know what other parsing state you have to keep track of in C++? - that's right, the preprocessor.\
|
||||||
|
access modifiers, like all tokens, are affected by the preprocessor, and you have to take that into account.
|
||||||
|
|
||||||
|
% id = "01H9R1KJESJ0G0VQAW994ZHR0S"
|
||||||
|
- take the following example:
|
||||||
|
```cpp
|
||||||
|
class ComfyZone
|
||||||
|
{
|
||||||
|
std::vector<SoftBed> _soft_beds;
|
||||||
|
|
||||||
|
#if ENABLE_HUGS
|
||||||
|
|
||||||
|
public:
|
||||||
|
void hug(Person& person);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int _remaining_hugs = 10;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
% id = "01H9R1KJESDDX4089WVHVV8N3H"
|
||||||
|
+ although quite contrived, it illustrates the problem pretty well
|
||||||
|
|
||||||
|
% id = "01H9R1KJESD2KED5TAFBY426A6"
|
||||||
|
- (before you ask, `_remaining_hugs` needs to be always present because it has to be (de)serialized no matter if hugging functionality is compiled in. otherwise we'd get data loss.)
|
||||||
|
|
||||||
|
% id = "01H9R1KJESES27VKVW4A0ZVM11"
|
||||||
|
- we intended for `_remaining_hugs` to be private, but if hugs are enabled, it becomes public.
|
||||||
|
|
||||||
|
% id = "01H9R1KJESTKW90R788SSPMNC6"
|
||||||
|
- this can be _very_ hard to spot if you have a big class with lots of declarations inside.
|
||||||
|
|
||||||
|
% id = "01H9R1KJESCJ3VC8ATPYFDCPSP"
|
||||||
|
- this can be worked around by banning access modifiers from appearing in `#ifdef`s, but you have to *realize* that this might happen
|
||||||
|
|
||||||
|
% id = "01H9R1KJES4ZYHVADDF80WAXH6"
|
||||||
|
- and I've seen instances of this exact thing occurring in the Unreal Engine codebase, which is *full* of long lists of declarations (made even longer by the prevalence of `UPROPERTY()` specifiers)
|
||||||
|
|
||||||
|
% id = "01H9R1KJES182MCV2V0A4VHKKX"
|
||||||
|
- even if we didn't have the preprocessor, that access modifier is state _you_ have to keep track of
|
||||||
|
|
||||||
|
% id = "01H9R1KJESH7PWNKCKW3H0WJHW"
|
||||||
|
- I very often find myself needing to scroll upward after <kbd>Ctrl</kbd>-clicking on a field or function declaration, just to find out if I can use it
|
||||||
|
|
||||||
|
% id = "01H9R1KJESFE6F1D4J5PA5Q381"
|
||||||
|
- (thankfully IDEs are helpful here and Rider shows you a symbol's visibility in the tooltip on hover, but I don't have Rider on code reviews)
|
|
@ -36,81 +36,80 @@
|
||||||
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][branch:hello]!)
|
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][branch:hello]!)
|
||||||
|
|
||||||
% id = "01H8Y0CKD1G06CG62XWZ02JREC"
|
% id = "01H8Y0CKD1G06CG62XWZ02JREC"
|
||||||
+ writing Blueprints is actually pretty darn nice and there's a lot to learn from the editor UX
|
+ writing Blueprints is actually pretty darn nice and there's a lot to learn from the editor UX and basic refactoring tools
|
||||||
|
|
||||||
% id = "01H8Y0CKD1G86TY8AF6Z2SQ85P"
|
% id = "01H8Y0CKD1G86TY8AF6Z2SQ85P"
|
||||||
- I say this mainly with regards to writing new nodes. it's as simple as dragging your mouse out of a pin, and a window will pop up giving you suggestions on what could be connected there
|
+ when you drag your mouse out of a pin, and a window will pop up giving you suggestions on what could be connected there
|
||||||
|
|
||||||
% id = "01H8Y0CKD1P9SNK3TV967M705C"
|
% id = "01H8Y0CKD1P9SNK3TV967M705C"
|
||||||
- then you select from the list and it creates the node, autoconnecting stuff as necessary
|
+ then you select from the list and it creates the node, autoconnecting stuff as necessary
|
||||||
|
|
||||||
% id = "01H8Y0CKD1PQS2J2WB22ASZY17"
|
% id = "01H8Y0CKD1PQS2J2WB22ASZY17"
|
||||||
- one of the nicer autoconnections it can do is when you want to call a function on an actor component
|
- one of the nicer autoconnections it can do is when you want to call a function on an actor component
|
||||||
|
|
||||||
% id = "01H8Y0CKD16PFNWJ6EAARHA7BD"
|
% id = "01H8Y0CKD16PFNWJ6EAARHA7BD"
|
||||||
- instance functions require you to pass in a `self` to call the function on
|
- instance functions require you to pass in a `self` to call the function on
|
||||||
|
|
||||||
% id = "01H8Y0CKD1FVPCA5NBY5KK1F5X"
|
% id = "01H8Y0CKD1FVPCA5NBY5KK1F5X"
|
||||||
- so what it does is it suggests functions to call on all the _concrete components
|
- 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)`,
|
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
|
it'll not only create a function call node, but also hook up `DefaultSceneRoot` as its `self` parameter
|
||||||
|
|
||||||
% id = "01H8Y0CKD1KM42PKVSGB4QASG3"
|
% id = "01H8Y0CKD1KM42PKVSGB4QASG3"
|
||||||
+ another cool thing that happens with nodes (or pins rather) is when you try to connect two pins of incompatible types
|
+ when you try to connect two pins of incompatible types, it'll automatically insert a conversion node for you
|
||||||
|
|
||||||
% id = "01H8Y0CKD1NES5RBGVTPRH3F0Q"
|
% id = "01H8Y0CKD1NES5RBGVTPRH3F0Q"
|
||||||
- Blueprint is strongly typed so you can't just pass in a `Float` where a `String` is expected
|
- 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
|
||||||
|
|
||||||
% id = "01H8Y0CKD1VVMB8RVECVGZP0V2"
|
% id = "01H8Y0CKD10GQBNNP0RBJEWKW4"
|
||||||
- but instead of having you explicitly type out "o dear Blueprint I would like to convert this `Float` to a `String`", you can just join the two pins together and it'll insert a
|
- 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.
|
||||||
conversion node for you automatically
|
|
||||||
|
|
||||||
% id = "01H8Y0CKD10GQBNNP0RBJEWKW4"
|
% id = "01H987QXFE445XNN5YDS2FYR5F"
|
||||||
- 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. perhaps a bug I could fix one day?
|
+ perhaps a bug I could fix one day?
|
||||||
|
|
||||||
% id = "01H8Y0CKD1G3PV1NMWV590H6Y3"
|
% id = "01H987QXFEYSE260S996BE84DV"
|
||||||
+ in the end most of the time writing Blueprints is very ergonomic
|
- from [Oskar Kogut](https://github.com/kretoskar): if you change a `BlueprintCallable` function to `const` (or otherwise make it pure,) the editor will automatically correct the `Exec` pin flow for you
|
||||||
|
|
||||||
% id = "01H8Y0CKD1C5TJXXD40B99WQ3C"
|
% id = "01H8Y0CKD1C5TJXXD40B99WQ3C"
|
||||||
+ except when it isn't because Blueprint is still an imperative language and has a concept similar to statements (`Exec` pins), which breaks the entire idea of pure data flow and
|
+ 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
|
||||||
introduces control flow into the mix
|
flow and introduces control flow into the mix
|
||||||
|
|
||||||
% id = "01H8Y0CKD1J2P2HZ507YBSNVKK"
|
% id = "01H8Y0CKD1J2P2HZ507YBSNVKK"
|
||||||
- this split is called _pure_ and _impure_ nodes, where impure nodes are those that perform control flow (ie. those with `Exec` pins)
|
- this split is called _pure_ and _impure_ nodes, where impure nodes are those that perform control flow (ie. those with `Exec` pins)
|
||||||
|
|
||||||
% id = "01H8Y0CKD1P5JQCGHEY405KKPH"
|
% id = "01H8Y0CKD1P5JQCGHEY405KKPH"
|
||||||
- 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`)
|
+ 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`)
|
||||||
|
|
||||||
% id = "01H8Y0CKD1EGWTQYHT2WYQSZY5"
|
% id = "01H8Y0CKD1EGWTQYHT2WYQSZY5"
|
||||||
- `Branch` is used to shuttle control flow between two `Exec` lines, based on a `Bool`. you get a `True` branch and a `False` branch
|
- `Branch` is used to shuttle control flow between two `Exec` lines, based on a `Bool`. you get a `True` branch and a `False` branch
|
||||||
|
|
||||||
% id = "01H8Y0CKD1WFEWNYPZWGCH3N7X"
|
% id = "01H8Y0CKD1WFEWNYPZWGCH3N7X"
|
||||||
- and `Select` is used to choose a value based on another value, kind of like a ternary in C++
|
+ and `Select` is used to choose a value based on another value, kind of like a ternary in C++
|
||||||
|
|
||||||
% id = "01H8Y0CKD156C0ZAXK7JS9W81D"
|
% id = "01H8Y0CKD156C0ZAXK7JS9W81D"
|
||||||
- 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
|
- 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
|
||||||
|
|
||||||
% id = "01H8Y0CKD1YP7Q3HVJJZNJAJKG"
|
% id = "01H8Y0CKD1YP7Q3HVJJZNJAJKG"
|
||||||
- this would be fine if not for the existence of Gameplay Tags, which precisely _do not_ have a finite set of values
|
+ this would be fine if not for the existence of Gameplay Tags, which precisely _do not_ have a finite set of values
|
||||||
|
|
||||||
% id = "01H8Y0CKD1P7D9QMPVQYWSDFT5"
|
% id = "01H8Y0CKD1P7D9QMPVQYWSDFT5"
|
||||||
- there is a `Switch on Gameplay Tag` node, but that is for control flow and not data flow!
|
- there is a `Switch on Gameplay Tag` node, but that is for control flow and not data flow!
|
||||||
|
|
||||||
% id = "01H8Y0CKD126918N282MNBXD2C"
|
% id = "01H8Y0CKD126918N282MNBXD2C"
|
||||||
- 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
|
- 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
|
a version without an `Exec` pin
|
||||||
|
|
||||||
% id = "01H8Y0CKD1N37WTCY66CM7R198"
|
% id = "01H8Y0CKD1N37WTCY66CM7R198"
|
||||||
+ in fact I'm seeing a bit of a semblance to the classic [function coloring problem][def:article/function_coloring]
|
+ I'm seeing a bit of a semblance to the classic [function coloring problem][def:article/function_coloring]
|
||||||
|
|
||||||
% id = "01H8Y0CKD19JMY87YY50M3RCQF"
|
% id = "01H8Y0CKD19JMY87YY50M3RCQF"
|
||||||
+ 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
|
+ 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
|
||||||
|
|
||||||
% id = "01H8Y0CKD1Q8RXXK3KE4F4XAFF"
|
% id = "01H8Y0CKD1Q8RXXK3KE4F4XAFF"
|
||||||
- and speaking of `async`, [Blueprint handles the classic `async` problem very gracefully][branch:01H8Y0CKD106HXQAJK87XV0H93]!
|
- and speaking of `async`, [Blueprint handles the classic `async` problem very gracefully][branch:01H8Y0CKD106HXQAJK87XV0H93]!
|
||||||
|
|
||||||
% id = "01H8Y0CKD106HXQAJK87XV0H93"
|
% id = "01H8Y0CKD106HXQAJK87XV0H93"
|
||||||
+ did I mention how well Blueprints handle latent tasks?
|
+ despite its flaws, one of Blueprint's strengths is asynchronous and latent tasks
|
||||||
|
|
||||||
% id = "01H8Y427B03JNPTWW025ES176K"
|
% id = "01H8Y427B03JNPTWW025ES176K"
|
||||||
- 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
|
- 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
|
||||||
|
@ -128,7 +127,7 @@
|
||||||
- which is annoying but not terrible, since most of that latent, high level gameplay logic happens inside the main event graph anyways
|
- which is annoying but not terrible, since most of that latent, high level gameplay logic happens inside the main event graph anyways
|
||||||
|
|
||||||
% id = "01H8Y96DGCWWTAP5X8ZYPCJZQC"
|
% id = "01H8Y96DGCWWTAP5X8ZYPCJZQC"
|
||||||
+ that isn't to say the editor UI is perfect
|
+ the editor UI, despite [being helpful as it is][branch:01H8Y0CKD1G06CG62XWZ02JREC], is far from perfect
|
||||||
|
|
||||||
% id = "01H8Y96DGCRP0W6YWJ3PYJ2GES"
|
% id = "01H8Y96DGCRP0W6YWJ3PYJ2GES"
|
||||||
- it's actually quite janky and there tend to be brief flashes of content falling into place
|
- it's actually quite janky and there tend to be brief flashes of content falling into place
|
||||||
|
@ -137,16 +136,16 @@
|
||||||
- this is true of other parts of the Unreal editor UI but I'll focus on Blueprint here
|
- this is true of other parts of the Unreal editor UI but I'll focus on Blueprint here
|
||||||
|
|
||||||
% id = "01H8Y96DGDDRA8DD6PRGDCF8GP"
|
% id = "01H8Y96DGDDRA8DD6PRGDCF8GP"
|
||||||
+ the annoying thing is that node UIs are laid out lazily, by default using an algorithm that does not produce precise results for pin locations
|
+ node UIs are laid out lazily, by default using an algorithm that does not produce precise results for pin locations
|
||||||
|
|
||||||
% id = "01H8Y96DGDT0Y23G86HEKNWF4H"
|
% id = "01H8Y96DGDT0Y23G86HEKNWF4H"
|
||||||
- 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
|
- 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
|
||||||
|
|
||||||
% id = "01H8Y96DGDCEF6FEQWGX2BQ6AH"
|
% id = "01H8Y96DGDCEF6FEQWGX2BQ6AH"
|
||||||
- the effect looks quite janky and really upsets my inner perfectionist
|
- the effect looks quite janky and really upsets my inner perfectionist
|
||||||
|
|
||||||
% id = "01H8Y96DGDJG41P3XTFE8F4Y1M"
|
% id = "01H8Y96DGDJG41P3XTFE8F4Y1M"
|
||||||
+ another annoyance I have is that as you zoom out, the nodes start looking just a little bit differently due to font sizes being snapped to integers.
|
+ as you zoom out, the nodes start looking just a little bit different due to font sizes being snapped to integers
|
||||||
|
|
||||||
% id = "01H8Y96DGDRCBKWBXC7AXZV43E"
|
% id = "01H8Y96DGDRCBKWBXC7AXZV43E"
|
||||||
- at very low zoom levels, nodes stop rendering their text altogether, which makes their layout shift even more.
|
- at very low zoom levels, nodes stop rendering their text altogether, which makes their layout shift even more.
|
||||||
|
@ -164,7 +163,7 @@
|
||||||
- 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
|
- 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
|
||||||
|
|
||||||
% id = "01H8Y0CKD1103FHF332M2Q4MG7"
|
% id = "01H8Y0CKD1103FHF332M2Q4MG7"
|
||||||
+ maintaining Blueprints in a large project though could be a lot better
|
+ maintaining Blueprints in a large project could be a lot better
|
||||||
|
|
||||||
% id = "01H8Y0CKD1PPEPX8EEFRAM2VE1"
|
% id = "01H8Y0CKD1PPEPX8EEFRAM2VE1"
|
||||||
+ with regards to your graphs becoming really large
|
+ with regards to your graphs becoming really large
|
||||||
|
@ -173,10 +172,10 @@
|
||||||
- everybody kinda sorta just formats nodes however they see fit, and there is no unified autoformatter
|
- everybody kinda sorta just formats nodes however they see fit, and there is no unified autoformatter
|
||||||
|
|
||||||
% id = "01H8Y0CKD1VRVNMZ827RF7XBCA"
|
% id = "01H8Y0CKD1VRVNMZ827RF7XBCA"
|
||||||
- there's a reason people say Go's tooling is frickin' amazing, you know
|
- there's a reason people say Go's tooling is frickin' amazing, you know. it keeps codebases consistent!
|
||||||
|
|
||||||
% id = "01H8Y0CKD1980VGHFBYGM8PN3E"
|
% id = "01H8Y0CKD1980VGHFBYGM8PN3E"
|
||||||
+ this results in what we Hat in Time modders used to call _Kismetti_ in the Unreal Engine 3 days but now we'd call _Blueprintti_
|
+ 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_
|
||||||
|
|
||||||
% id = "01H8Y0CKD179SBZ58F5JMDC5F3"
|
% id = "01H8Y0CKD179SBZ58F5JMDC5F3"
|
||||||
+ which is a portmanteau of Blueprint and spaghetti.
|
+ which is a portmanteau of Blueprint and spaghetti.
|
||||||
|
@ -203,7 +202,7 @@
|
||||||
- and not asynchronously in the background, you will have to _wait_ for it to finish loading. which is pretty annoying
|
- and not asynchronously in the background, you will have to _wait_ for it to finish loading. which is pretty annoying
|
||||||
|
|
||||||
% id = "01H8Y0CKD16HEQKQX1NJG9GG42"
|
% id = "01H8Y0CKD16HEQKQX1NJG9GG42"
|
||||||
+ and the runtime performance isn't the best for a few reasons
|
+ the runtime performance isn't the best for a few reasons
|
||||||
|
|
||||||
% id = "01H8Y427B1ZKJA16V17NG80QHS"
|
% id = "01H8Y427B1ZKJA16V17NG80QHS"
|
||||||
- the VM isn't implemented in the most optimal way
|
- the VM isn't implemented in the most optimal way
|
||||||
|
@ -221,7 +220,7 @@
|
||||||
- and it's not hard to extract the performance sensitive parts to C++ because Blueprint offers tools for refactoring your code
|
- and it's not hard to extract the performance sensitive parts to C++ because Blueprint offers tools for refactoring your code
|
||||||
|
|
||||||
% id = "01H8YT7R15MFW3RRQAF8CM4EP6"
|
% id = "01H8YT7R15MFW3RRQAF8CM4EP6"
|
||||||
- but that doesn't prevent me from liking it!
|
- but all that doesn't prevent me from liking it!
|
||||||
|
|
||||||
% id = "01H8YT7R15ZJWBY0TN6F6HN95Y"
|
% id = "01H8YT7R15ZJWBY0TN6F6HN95Y"
|
||||||
- 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.
|
- 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.
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl Generator {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let tree_path = tree_path.with_extension("").to_string_lossy().into_owned();
|
let tree_path = tree_path.with_extension("").to_string_lossy().replace('\\', "/");
|
||||||
let file_id =
|
let file_id =
|
||||||
treehouse.add_file(utf8_filename.into_owned(), Some(tree_path.clone()), source);
|
treehouse.add_file(utf8_filename.into_owned(), Some(tree_path.clone()), source);
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,8 @@ body::selection {
|
||||||
|
|
||||||
body,
|
body,
|
||||||
pre,
|
pre,
|
||||||
code {
|
code,
|
||||||
|
kbd {
|
||||||
font-family: 'RecVar', sans-serif;
|
font-family: 'RecVar', sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
@ -133,7 +134,8 @@ h4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pre,
|
pre,
|
||||||
code {
|
code,
|
||||||
|
kbd {
|
||||||
--recursive-mono: 1.0;
|
--recursive-mono: 1.0;
|
||||||
--recursive-casl: 0.0;
|
--recursive-casl: 0.0;
|
||||||
--recursive-slnt: 0.0;
|
--recursive-slnt: 0.0;
|
||||||
|
@ -179,6 +181,12 @@ code {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
padding: 3px 6px;
|
||||||
|
border: 1px solid var(--border-1);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
margin: 12px 0;
|
margin: 12px 0;
|
||||||
|
@ -187,7 +195,9 @@ pre {
|
||||||
}
|
}
|
||||||
|
|
||||||
pre>code {
|
pre>code {
|
||||||
|
padding: 0;
|
||||||
background: none;
|
background: none;
|
||||||
|
border-radius: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And don't let code examples fly off and overflow the window */
|
/* And don't let code examples fly off and overflow the window */
|
||||||
|
|
|
@ -125,12 +125,15 @@ function expandDetailsRecursively(element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigateToPage(page) {
|
function navigateToPage(page) {
|
||||||
window.location.href = `${TREEHOUSE_SITE}/${page}.html`
|
console.log(page);
|
||||||
|
window.location.pathname = `${TREEHOUSE_SITE}/${page}.html`
|
||||||
}
|
}
|
||||||
|
|
||||||
async function navigateToBranch(fragment) {
|
async function navigateToBranch(fragment) {
|
||||||
if (fragment.length == 0) return;
|
if (fragment.length == 0) return;
|
||||||
|
|
||||||
|
console.log(`nagivating to branch: ${fragment}`);
|
||||||
|
|
||||||
let element = document.getElementById(fragment);
|
let element = document.getElementById(fragment);
|
||||||
if (element !== null) {
|
if (element !== null) {
|
||||||
// If the element is already loaded on the page, we're good.
|
// If the element is already loaded on the page, we're good.
|
||||||
|
@ -138,6 +141,7 @@ async function navigateToBranch(fragment) {
|
||||||
rehash();
|
rehash();
|
||||||
} else {
|
} else {
|
||||||
// The element is not loaded, we need to load the tree that has it.
|
// The element is not loaded, we need to load the tree that has it.
|
||||||
|
console.log("element is not loaded");
|
||||||
let parts = fragment.split(':');
|
let parts = fragment.split(':');
|
||||||
if (parts.length >= 2) {
|
if (parts.length >= 2) {
|
||||||
let [page, _id] = parts;
|
let [page, _id] = parts;
|
||||||
|
@ -147,8 +151,12 @@ async function navigateToBranch(fragment) {
|
||||||
// navigation maps with roots other than index. Currently though only index is
|
// navigation maps with roots other than index. Currently though only index is
|
||||||
// generated so that doesn't matter.
|
// generated so that doesn't matter.
|
||||||
let [_root, ...path] = fullPath;
|
let [_root, ...path] = fullPath;
|
||||||
|
console.log(`_root: ${_root}, path: ${path}`)
|
||||||
if (path !== undefined) {
|
if (path !== undefined) {
|
||||||
let isNotAtIndexHtml = window.location.pathname != "/index.html";
|
let isNotAtIndexHtml =
|
||||||
|
window.location.pathname != "" &&
|
||||||
|
window.location.pathname != "/" &&
|
||||||
|
window.location.pathname != "/index.html";
|
||||||
let lastBranch = null;
|
let lastBranch = null;
|
||||||
for (let linked of path) {
|
for (let linked of path) {
|
||||||
let branch = LinkedBranch.byLink.get(linked);
|
let branch = LinkedBranch.byLink.get(linked);
|
||||||
|
|
Loading…
Reference in a new issue