DnD 04 Feb 2024 18:04:27

D&D One Shot: Aid the Elderly

Single session one-shot for one or more characters.
No combat expected.

Adventure Hook

A little old lady who needs help with a spring cleaning ritual and feeding her cats.

DM Hook

The role of the DM is to make it ambiguous whether the players should help the little old lady, Elara, or the demon. There are plenty of hints to make the players distrust Elara. On one hand, there is a little old lady who could answer all the questions but doesn’t want to, and is in a bit of a rush to have a ritual completed, and on the other hand there is a demon that wants to break free but can’t communicate properly.


Hundreds of years ago during a great war in a battle going poorly, Archmage Lady Elara Timell made a desperate bargain with one of the primordial demons she had enslaved to fight at her side. She would live a full, long, and healthy life in exchange for her soul upon death. This let her overload her magic without fear of dying, thus winning the battle and eventually the war.

And then she noticed a loophole in the contract: If she imprisoned the demon so that it could not claim her soul, she could live forever, in good health. She promptly did so. But the seal only lasts about a decade per casting, becoming weakest around the time where the stars align a certain way.

Elara has long since become a quiet force for good. She mostly keeps to herself, and her studies of the skies and other planes.

A few renewal cycles back, the seal got so weak that the demon managed to curse Elara. From that point on, the seal can only be fully renewed by someone who doesn’t know they are doing it. The more the person knows, the weaker the seal will be, meaning Elara herself cannot renew it at all. Thus, she enlists aid from taverns and passersby, in the guise of an old lady who needs help with a spring cleaning ritual and feeding her cats.

This time, the seal is weak enough that the demon can communicate a little, and play some simple tricks on Elara.


Code &JavaScript 19 Sep 2023 15:51:13

Ordbogit App Mid-Mortem

I am currently in the process of developing an offline cross-platform version of Oqaasileriffik’s Greenlandic Dictionaries, ideally as an app. The concept is really simple: Take the existing 150 MiB SQLite database and bundle that as an app.

A year ago, I tried to use .NET MAUI, but that quickly proved feature anemic and buggy. I also looked at React Native and a few others. But in all of those frameworks, I ran into the same limitation: There is no way to just use a bundled read-only SQLite database. It has to be copied from the bundled resources into the app storage space, meaning it would exist on the device twice, and that was unacceptable to me.

Three weeks ago I was reminded of the project, and this time I started from scratch and tried working at it from the Progressive Web App (PWA) angle. I figured it was worth a shot to take the existing website and just let users run that offline. But again there was the quirk of how to get that 150 MiB of data to the user and persist it once and only once, ideally in a way that’s not in RAM all the time.

First I tried Dexie.js, an IndexedDB wrapper. Unfortunately this proved much too slow. Preloading files and inserting all the data into the database took 6 minutes on a beefy desktop computer. Turns out inserting into IndexedDB is really slow, even when doing bulk inserts, and when you’re inserting 3.3 million rows there is no way to overcome that. Could I reorganize the data so it’s fewer rows and differently indexed? Maybe, but that’s an absolutely last resort.

Next I tried Roy Hashimoto’s wa-sqlite. This was much faster, bringing insertion time down to 2m30s, despite still using IndexedDB as storage. But 2m30s on desktop translated to over 10 minutes on a fast mobile device, and that’s not acceptable.

I finally relented and tried caching the raw SQLite database and loading that with sql.js. I really didn’t want to do this as it requires keeping the whole 150 MiB database in RAM. Well, the result is that the PWA preloads and initializes in under 20 seconds from localhost. Naturally this will be slower over the internet, but this makes it network-bound instead of CPU-bound. It’s the same amount of data to transfer either way, and I guess 150 MiB isn’t much in this day and age.

Cooking 02 Oct 2021 21:53:22

Spicy Crispy Chicken

I made an incidental chili bread roll.

What I actually cooked tonight was spicy crispy chicken. We are all rather fond of the KFC-style spicy crispy chicken, but we also don’t actually go to KFC or similar fast food places more than about once every half year. So I figured I’d try making it myself, because surely it couldn’t be that hard. The recipe that I found for it called for brining and an egg mixture and a way of preparing that would take way too long, so I took shortcuts.

The chicken strips that we buy in Denmark comes pre-brined, so that cut away the 3 hour brining step. The recipe also calls for putting the seasoning blend on the chicken, then doing the whole egg and flour thing. I skipped straight to the egg.

Ingredients that I used:

  • 375 g pre-brined chicken strips
  • 1 egg
  • 160 g flour
  • 2 teaspoons baking powder
  • 1 heaping teaspoon garlic powder
  • random amounts of black pepper powder, paprika powder, cayenne pepper powder, and chili powder

And fats for frying:

  • salted butter
  • salted easy spread “butter”
  • olive oil

Steps that I took, in order:

  1. Crack the egg in a hermetically sealable container capable of holding all 2-3 times the combined ingredients. It should be the right size where shaking it would aerate and cover all the chicken.
  2. Drain the brine from the chicken.
  3. Put the chicken in the container.
  4. Seal and shake the container until there’s egg on all the chicken.
  5. In a separate open container, mix the flour, baking powder, and garlic powder.
  6. Mix in spices until the flour mix tastes good and strong enough to your liking. I found that the initial amount of garlic tasted through even when I added more of the various peppers, so I did not add more of that.
  7. Dump it all in the sealable container.
  8. Seal the container and shake until there’s mix on all the chicken.
  9. Heat frying pan to 7 of 9 and put a spoon of salted butter on it.
  10. When all the butter is melted, put all the chicken on the pan.
  11. Realize that the butter got absorbed almost instantly by the flour mix and that you’re out of butter, so add a spoon of easy spread “butter”.
  12. Realize that also got absorbed almost instantly, so give in and use oil like the recipe tells you to.
  13. Reapply oil when it dries out.
  14. Cook until done.
  15. Eat.

I had no idea what to expect from this. First time I’ve attempted something like this, so I figured it was a neat experiment, and if it didn’t taste good then it’s a learning opportunity. But oh wow, it was almost perfect. Tasted exactly like fast food spicy crispy chicken, just slightly less spicy. Was just as juicy. We ate it all, so didn’t get a picture of it.

I also realized that the leftover egg and flour mix in the container was basically bread dough, if I just added water. So I stirred (with a fork) in 250ml water, put it in a ceramic bowl, and put it in the cold oven, then turned it to 200 ℃ for 25 minutes. What came out is pictured above: A chili bread roll. Not great, but totally edible, and I look forward to having a slice with melted cheddar.

Mistakes made and corrections for future cooking:

  • Salt: The recipe calls for adding a teaspoon salt to the flour mix. I intended to do that, but I plain forgot. I figure the fact that I fried it in salted butter made up for that fact, because it all tasted great.
  • Water: I think that adding 100ml of water to the flour mix during the final shake could cause more of it to bind to the chicken. Today’s version was somewhat flat compared to fast food variants, but more batter should naturally rise more. Will try that next time.
  • Butter: Just don’t use butter. My mistake here was that I usually fry in a little bit of butter for the flavour, but actually the meat fries in its own fats. But the flour mix absorbs all the fats here, so there is nothing to fry in. I can’t recall when I last fried in oil, but this would’ve been unhealthy to keep slathering butter or “butter” on. Use oil.

So next time I make this, it will be perfect.

C++ &Rants 15 Jun 2021 22:25:00


I registered on Freenode on 2009-03-21 at 17:25:41 UTC, to participate in the Apertium channel #apertium. I also joined the C++ channel ##C++.

On 2011-06-29 at 11:06:39 UTC, I created ##C++-general with the blessing of the ##C++ operators. This quickly grew to be the 2nd largest C++ channel on Freenode, and indeed on any network at the time.

On 2015-04-15 at 13:32:10 UTC, I was granted operator status for the main ##C++ – the largest C++ channel on any IRC network at the time.

On 2021-05-19 at 07:54 UTC, this happened: ChanServ (ChanServ@services.) Quit (Killed (grumble (My fellow staff so-called 'friends' are about to hand over account data to a non-staff member. If you care about your data, drop your NickServ account NOW before that happens.)))

Immediately thereafter, I contacted my fellow Apertium PMC members so that we could prepare in case Freenode was actually taken over by non-free interests.

A few hours later, Freenode was taken over and most of the staff resigned. I got on Libera.chat as soon as it opened up and registered #Apertium, #C++, #C++-general, and #geordi.

On 2021-05-24, I applied for a Community Registration for the C++ channels on Libera.chat. However, the C++ channels’ policy was to maintain both networks and not get involved with the politics of the situation.

On 2021-05-27, Apertium officially moved from Freenode to OFTC.

On 2021-06-14 at 21:37:09 UTC, Freenode intentionally split the network in two, leaving an old Freenode with existing channels and nicks, and a new Freenode with no registered channels or nicks.

On 2021-06-15 at 07:42:07 UTC, I joined the new Freenode and kicked everyone from ##C++-general with a message to go to Libera.chat.

At 08:05:53 UTC, I kicked root and f from ##C++-general.

I was k-lined from the new Freenode on 2021-06-15 at 08:06 UTC.

At 09:13 UTC, I joined the old Freenode and kicked everyone from ##C++ and ##C++-general with a message to go to Libera.chat instead.

At 19:17 UTC, the remaining oper on old Freenode removed me from ##C++-general.

At 19:38 UTC, the old Freenode was shut down.

Danish &Rants 15 Jun 2018 14:02:41


Jeg støtter disse Borgerforslag:

Next Page »