=^.^=

Low spoons way to make Sauce Hollandaise

May 13, 2020

Hardware needed:

  • a stick blender
  • a tall container with an inner diameter not much bigger than the stick blender head
  • (recommended) a tool to press out the lemon juice
  • (recommended if you're unexperienced with seperating eggs using their shells) a tool to seperate eggs
  • a way to melt the butter (but not heat it up too much)

You will need:

  • 250g butter
  • 3 - 4 fresh eggs. Important: They must be less than a week old, the fresher the better
  • a lemon
  • a teaspoon of mustard
  • salt & pepper

Melt butter

You start by melting the butter. I use a small covered pot on lowest heat. You want it to be liquid without any solid blocks. I start the process when the butter has turned opaque without any solid pieces visible. It's important to keep the butter below ~56 °C because we're not cooking the egg.

Prepare eggs and lemon juice

While melting the butter you can work on juicing the lemon and seperating the eggs. We only need the egg yolks (I keep the leftover egg white for later and add it to my solution when I make scrambled eggs for example).

Note: It's important that you separate the egg yolk nicely so that no egg white gets into the mixture as it will hinder the emulsification.

The magic

Add egg yolk and lemon juice to the tall container. When the butter is liquid, put the stick blender into it, start and slowly add all the butter to it. It will emulsify nicely.

Then to taste add salt and pepper. I also like to add a bit of mustard and some sichuan pepper.

Storage: Keep in the fridge, use up quickly.

Random Minecraft Rocket Generator

January 02, 2020

Minecraft fireworks

I played a bit of vanilla minecraft in survival with a friend and crafted a bunch of fireworks rockets. They are quite expensive, so I cheated in some resources. I wasn't satisfied with the selection and the effort it takes to create a lot of rockets with different colors and shapes by hand. I decided to cheat some in.

I searched online if there's a way to generate random rockets and came across a generator. You have to select a bunch of options and click "generate" to get a string. But I wanted about 100 different rockets.

So I looked into the output, the generator gave me

/give @p firework_rocket{Fireworks:{Flight:2,Explosions:[{Type:1,Flicker:0,Trail:0,Colors:[I;14188952,6719955]},{Type:1,Flicker:0,Trail:1,Colors:[I;11743532,2437522,14188952],FadeColors:[I;14188952]}]}} 1

I quickly decided I am going to write a little ruby script to generate random rockets, because I have a lot of experience in ruby and I can do it with a very little overhead.

I started to cut out the important sections and replaced it with variables

puts "/give @p firework_rocket{Fireworks:{Flight:#{flight},Explosions:#{gen_explosion}}} #{count}"

flight is the equivalent of 1 to 3 gunpowder you add so I defined it as

flight = rand(1..3)

to get a random range between 1 and 3.

I wrote this code to generate the explosion string:

def gen_explosion
    type = rand(0..4)
    flicker = rand(0..1)
    trail = rand(0..1)

    res = ["Type:#{type}","Flicker:#{flicker}","Trail:#{trail}","Colors:#{random_colors(rand(1..3))}"]
    if trail == 1
        res << "FadeColor:#{random_colors(1)}"
    end

    return "{#{res.join(",")}}"
end

A rocket can have multiple explosions and they need to be in square brackets. So I added a method to call gen_explosion 1 to 5 times

def gen_explosions
    res = []
    rand(1..5).times do
        res << gen_explosion
    end
    "[#{res.join(',')}]"
end

I also needed to generate the color. Looking at the string, I figured that the color is a decimal representation of RGB, so we have 255 * 255 * 255 colors that will work. I ended up making a method that generates n colors (similar to what the methods above do, combined it in one) method:

def random_colors(n)
    colors = []
    n.times do
        colors << rand(0..255*255*255)
    end
    return "[I;"+colors.join(",")+"]"
end

This could be a lot fancier. For example I could want to avoid having dark colors. I was okay with random values for now though and I wanted to get it working.

Strings too long

At first in the development process, I messed up having forgotten the square brackets in gen_explosions. After debugging it by comparing it to a good string, I found another issue: When I pasted the output into the chat line in the game, it would cut off the string if it was longer than 255 characters and fail to generate the rocket. I reduced the amount of explosions a rocket has to 3, as well as limit the colors to 3 and one color for the fade effect. It sometimes still generated strings that were too long.

Quick workaround

As a quick workaround I am not particularily proud of; I ended up generating the strings so often until I have a string that is lower or equal 255 characters in size.

def gen_rocket_to_copy
    size = 256
    while size > 255
        res = gen_rocket
        size = res.size
    end
    res
end

Let's count

I was dissatisfied with it and I decided to count the characters. I split a few things into parts and copied it into irb (the interactive ruby shell):

"/give @p firework_rocket{Fireworks:{Flight:1,Explosions:[]}} 64".size
=> 63

So the base command takes 61 characters of space already. I then noticed that there's room for optimization in the gen_explosion method: I can omit values of Flicker and Trail if the random value is 0. So I ended up changing gen_explosion to

def gen_explosion
    type = rand(0..4)
    res = ["Type:#{type}"]

    res << "Flicker:1" if rand(0..1) == 1
    if rand(0..1) == 1
     res << "Trail:1"
     res << "FadeColors:#{random_colors(1)}"
    end
    res << "Colors:#{random_colors(rand(1..3))}"

    return "{#{res.join(",")}}"
end

Back to counting. I limited the color generation to 3 colors. The maximum size it can be can be quickly determined using irb:

"[I;16581375]".size
=> 12
"[I;16581375;16581375]".size
=> 21
"[I;16581375,16581375,16581375]".size
=> 30

And the string per explosion minus the colors:

"{Type:1,Flicker:1,Trail:1,Colors:,FadeColors:}".size
=> 46

Since I set FadeColors to be just one color, the maximum lenght it can have is 46 + 12 (1 fade color) + 30 (3 main colors) + 1 (comma) = 89

I changed the code in gen_explosions to check for if it can fit the remaining length:

def gen_explosions
    res = []
    rand(1..3).times do
        if res.join(",").size <= 255 - 63 - 89
            res << gen_explosion
        end
    end
    "[#{res.join(',')}]"
end

But what if the gen_explosion it generates in this iteration can actually fit in the string? I made it to generate the explsion string first, then compared it if it fits within the boundaries of 255 - 63 - 1 (adding a comma)

def gen_explosions
    res = []
    rand(1..3).times do
        e = gen_explosion
        if e.size + res.join(",").size <= 255 - 63 - 1
            res << e
        end
    end
    "[#{res.join(',')}]"
end

Copying it to clipboard

So instead of having to copy+paste the output from my terminal, I wanted to copy it to my clipboard. I use CopyQ as my clipboard manager, in order to copy it to my clipboard I can easily do it with a call:

system("copyq copy \"#{gen_rocket}\"")

In my first attempt do automatically get more rockets I put it in an endless loop and generating a new rocket every half second

while true
    system("copyq copy \"#{gen_rocket}\"")
    sleep 0.5
end

Auto-Paste

I could have stopped there, but I wanted to not press "t", my paste key combinaton and enter every time. I installed autokey and looked into its documentation. First, i changed my script to output the give command instead of copying it to my clipboard (and removed the endless loop):

puts gen_rocket

In autohotkey I wrote a script that activates on a keypress. I bound it to "z".

res = system.exec_command("~/src/minecraft_fireworks/fireworks.rb", getOutput=True)

keyboard.fake_keypress("t")
time.sleep(0.2)
keyboard.send_keys(res)
time.sleep(0.2)
keyboard.fake_keypress("<enter>")

I couldn't get it it working at first but then I looked up the documentatoin and figured that I needed to add getOutput=True to the system call. I had (and still have) some timing issues. Adding 0.2s delays between they key presses seem to fix most of the issues.

Sources

It has been a fun little project! If you liked liked this little adventure and you're able to, you can sponsor me on github or buy me a coffee.

I pushed the source code to my repository on github: https://github.com/jglauche/mc_fireworks

Rails gotchas #1: credentials

December 31, 2019

To store credentials, Rails offers a command line tool to store credentials

$ rails credentials:edit

So, at some later point, you might want to setup or edit a credentials file for development:

$ rails credentials:edit -e development

And then you want to check the credentials file for production

$ rails credentials:edit -e production

and then think wait... it's empty. So next you exit the editor. If you then happen to restart the production webserver you get a wall of text displayed and at the end you see the error message:

Missing secret_key_base for 'production' environment, set this string with rails credentials:edit (ArgumentError)

The next part of the gotcha is if you actually look into your credential file again as the error message stated:

$ rails credentials:edit

There's your secret_key_base that Rails has set up for you. So what the heck is going on? When you run this command, it will edit your master credentials, they are:

config/master.key

config/credentials.yml

Master credentials vs. production credentials

So, when you execute

$ rails credentials:edit -e production

it will create 2 files:

config/credentials/production.key

config/credentials/production.yml.enc

Important Notes:

  • It will even write those files if you exit your editor without saving!
  • If Rails finds those two files for production in config/credentials/, it will look no further and will not use the master credentials.

My solution

I deleted the 2 files:

$ rm config/credentials/production.key
$ rm config/credentials/production.yml.enc

As alternative you could port over all credentials into the other file; but I had difficulties doing so because I couldn't copy+paste the buffer from vim (using the decryption wrapper) as I couldn't open the other credential files as buffer directly.

Ableist sponsorship tiers

December 14, 2019

When I first set up my github sponsor page, I thought I needed different sponsorship tiers. I felt having a creative block coming up with anything that's doable for me and easily automated.

I've payed some attention to other people, mostly content creators, that collect money via crowdsponsoring. What their offer usually falls into one or multiple of those categories:

  1. you can watch their content earlier than other people
  2. you can get your name listed somewhere
  3. you can get content that nobody else can see
  4. you can influence the content in some way.

I'm pretty much okay with the first two things. I do not gain much by being the beta-tester for some content I will see 2 days later and I can surely get my name on things if I help in other ways as well.

Number 3 and 4 on the other hand are ableist and require you to have the ability to spend the asked amount of money in order to participate.

For me, as I am not a content creator but want to work on open source, it doesn't make much sense for me to have any kind of custom content locked away, nor do I want to actually sell my product.

I decided to make all sponsorship tiers have the equal reward of an optional listing on a contributors file. At this point I want to mention, that money is not the only way you can get your name on it (feel free to ask nicely!).