obsidian is awesome

the logo of obsidian with a single sparkle on it, ontop of a background of a black/grey radial background with cocentric circles

I’ve started using Obsidian about a week ago, and I basically have new relationship energy with it. I’ve never used a note-taking application which had so much emphasis on simplicity and an ability to link my notes together in such a powerful way. With it, I finally feel that taking notes is making me more productive and effective. It’s made me so excited to… work on things and research stuff? ᵒʰ ᵍᵒᵈ ʷʰᵃᵗ ʰᵃᵛᵉ ᶦ ᵇᵉᶜᵒᵐᵉ

I just wanted to take some time today to shout from the rooftops one thing about it that I really love and what it has empowered me to do.


Each person has their own unique version of how they use Obsidian. For me, my notes serve the purpose of being a knowledge base. I want to use it to reduce the context switching cost of remembering what it is I want to do, make it easier for me to deal with problems similar to ones I’ve encountered in the past, and keep track of information that I would otherwise immediately forget.

I accomplish this task by doing a combination of keeping a dev journal and writing notes using strategies similar to Zettelkasten. As a short aside, if you are not familiar with Zettelkasten and you want to take notes, I highly recommend reading this article as I’ve found it to be very useful.

Journaling

Here’s a concrete example. Recently, I was working live at twitch.tv on my game when I ran into a bug:

# 20:50-0500
Trying to solve a [[Camera Flickering|camera issue]] where it shows the player
in the wrong position for a single frame. Unfortunately, the following
approaches did not work:
 
* Using `_enter_tree`, because the spawn point doesn't exist yet.
* Loading the scene without switching to it with `load`, making the change, and
  then switching to the scene, because the spawn point doesn't exist yet
  (`_enter_tree` and `_ready` have not been called yet when you instantiate a
  scene this way)
* Calling a function to set the camera position from `_ready`, in case the
  camera's position was being updated before the player. This did seem to
  improve the situation (since the camera is always before the player in the
  scene view, so I'm guessing we're now 1 frame behind instead of 2), but it
  doesn't fix it.
 
Maybe the problem is that I'm conflating node existence with registration of the
position, and i should change my dictionary to be a map of keys strings to
positions instead of strings to nodes. This would at least free me of my
dependence on the Node lifecycle.

…and every time I would try a new strategy to fix the issue I would write what I was trying, why it didn’t work, and what my gap in knowledge might be. When I didn’t find an answer by the end of the day, I even wrote a note on what I might try next time I try to figure out this problem. Eventually I found the answer, and wrote an explanation of what the problem was.

# 22:15-0500
 
<omitted>
 
Inspecting the code, it appears that `align()` takes the global position into
account when updating its internal representation before calling
`update_scroll()` which updates the viewport. Adding a debugging print for the
`update_scroll` function also reveals that it is called before the frame is
rendered, but since it doesn't take the global position into account, the
viewport is not updated correctly.
 
Calling `align()` fixes the problem. Consider the following code:
 
<omitted>

Linking

So now I have a full timeline of the problem I encountered, the things I tried to fix it, and what the ultimate solution turned out to be. Well, great! That can be a note too:

# Camera Flickering
 
> My camera is rendering the incorrect position for a frame even though I've
> put in a debugging statement showing that the position is correct!
 
The Camera contains a mutable state which needs to be communicated to a
Viewport in the [[RenderingServer]]. This problem could be fixed by calling
`align()` to force the state in the rendering server to be synced.
 
# History
 
## 2023-05-15
![[2023-05-15#2050-0500|20:50-0500]]
![[2023-05-15#2103-0500|21:03-0500]]
 
## 2023-05-16
![[2023-05-16#1941-0500|19:41-0500]]
![[2023-05-16#1951-0500|19:51-0500]]
![[2023-05-16#1956-0500|19:56-0500]]
![[2023-05-16#2021-0500|20:21-0500]]
![[2023-05-16#2118-0500|21:18-0500]]
![[2023-05-16#2215-0500|22:15-0500]]

Here, I’m summarizing the problem and solution and I’m also linking to each journal entry where I wrote about my attempt to fix the issue. the ![[]] syntax embeds the content of the linked note and the # allows me to embed just a specific section, which is pretty great because I don’t always work on the same problem continuously in one entry.

It looks boring in edit mode, but when you switch into read mode, it magically turns into this:

# Camera Flickering
 
> My camera is rendering the incorrect position for a frame even though I've
> put in a debugging statement showing that the position is correct!
 
The Camera contains a mutable state which needs to be communicated to a
Viewport in the [[RenderingServer]]. This problem could be fixed by calling
`align()` to force the state in the rendering server to be synced.
 
# History
 
## 2023-05-15
 
> # 20:50-0500
>
> Trying to solve a [[Camera Flickering|camera issue]] where it shows the player
> in the wrong position for a single frame. Unfortunately, the following
> approaches did not work:
>
> <omitted>
 
> # 21:03-0500
>
> Changed the code to set the position on `_enter_tree` and using
> `process_priority` to make sure all of the steps are done in the correct
> order, but this still doesn't produce the expected behavior. It's not clear to
> me when Godot renders the scene when you swap to it, because it seems
> nonsensical to say that Godot will render a scene before `_enter_tree` has
> been called for all of the nodes, because saying so would mean that Godot is
> rendering a scene that hasn't finished loading yet.
>
> <omitted>
 
<omitted>

This means that I also have a focused timeline right under the solution explaining how I solved the problem and I don’t have to wade through all of my notes trying to sort out which parts of my journal entry are relevant or not. If I have a problem with camera flickering again, I know exactly where to go. And if the solution doesn’t work, I can look at what I’ve tried before to see if I already had other ideas on possible fixes or if there are certain things I’ve already tried that don’t work.

Moreover, I can create summary posts for related subjects, like the camera. Am I having a weird camera issue, but I don’t know how to word it? Well, I can look at my camera note:

# Camera2D
 
The [Camera2D](https://docs.godotengine.org/en/4.0/classes/class_camera2d.html)
class is a generic, general purpose 2D camera. If more specific needs are
required, a custom camera class can be implemented instead.
 
By default, Godot always [[2D rendering in Godot|renders the canvas]] of the
2D world at `(0, 0)`. The Camera2D node changes the transform of the canvas by
setting `Viewport.canvas_transform` in the nearest [[Viewport|`Viewport`]] node
in an ascending search, allowing arbitrary portions of the 2D world to be
rendered.
 
## Troubleshooting
 
![[Camera Flickering#camera-flickering|Camera Flickering]]
 
![[Cannot move past Camera bounds#cannot-move-past-camera-bounds|Cannot move past Camera bounds]]

This contains my current (probably incomplete or incorrect) understanding of the Camera2D API written in a way that I understand. And, when rendered, the Troubleshooting section contains a bunch of short snippets containing problems and solutions, which are also hyperlinked to the note if I need a longer explanation:

## Troubleshooting
 
> # Camera Flickering
> > My camera is rendering the incorrect position for a frame even though I've
> > put in a debugging statement showing that the position is correct!
>
> The Camera contains a mutable state which needs to be communicated to a
> Viewport in the [[RenderingServer]]. This problem could be fixed by calling
> `align()` to force the state in the rendering server to be synced.
 
> # Cannot move past Camera bounds
>
> > I cannot seem to move past the bounds of my Camera even though the bounds
> > appear to be calculated correctly and there is obviously more map that I can
> > traverse.
>
> Make sure that the camera limits, which are in global space, and the position
> you are clamping are both in the same space.

Isn’t that awesome?! I fucking love it.