Wish I can use my new vacuum cleaner to suck up all the spam emails I’m getting about my new vacuum cleaner. ๐
This week’s earworm: The Wind Chimes by Mike Oldfield. ๐ต
This one’s a bit surprising since it’s not a new addition to my collection. Maybe because I haven’t been listening to it all that often.
I didn’t record narration for the previous post. It featured a dialog and I needed a scene partner. So I tried recording one with AWS’s text-to-speech engine last night, and ahโฆ yeah, it didn’t sound as good as I was hoping. I mean, the tech is getting better, but there’s still a way to go: that uncanny valley hasn’t been bridged yet.
This is probably the best version of what I was able to make. This was using AWS’s new-ish “Generative” voice model. There are only three voices available of this kind in AWS so far. I chose the US English male voice, since it spoke at a rate which, to my ears, is about as close to a speaking rate that I’d consider natural:
I also tried the same exchange out with the “Neural” engine, which has been around for several years:
The Generative voice model is decent. Still not good enough to fool anyone that I’m speaking with a real person, yet it’s a lot better than the Neural engine. There’s no mistake with that one that I’m speaking with a computer.
So, no recorded dialogue, but it was still an interesting exercise. And it’s always a little fun playing around with AWS’s text-to-speech engine.
Rubber-ducking: Of Config And Databases
It’s been a while since my last rubber-ducking session. Not that I’m in the habit of seeking them out: I mainly haven’t been in a situation when I needed to do one. Well that chance came by yesterday, when I was wondering whether to put queue configuration either in the database as data, or in the environment as configuration.
This one’s relatively short, as I was leaning towards one method of the other before I started. But doubts remained, so having the session was still useful.
So without further ado, let’s dive in. Begin scene.
L: Hello
๐ฆ: Oh, you’re back. It’s been a while. How did that thing with the authorisation go?
L: Yeah, good. Turns out doing that was a good idea.
๐ฆ: Ah, glad to hear it. Anyway, how can I help you today?
L: Ok, so I’m working on this queue system that works with a database. I’ve got a single queue working quite well, but I want to extend it to something that works across multiple queues.
๐ฆ: Okay
L: So I’m wondering where I could store the configuration to these queues. I’m thinking either in the database as data, or in the configuration. I’m thinking the database as: A) a reference to the queue needs to be stored alongside each item anyway, and B) if we wanted to add more queues, we can almost do so by simply adding rows.
๐ฆ: “almost do so?”
L: Yeah, so this is where I’m a little unsure. See, I don’t want to spend a lot of effort building out the logic to deal with relaunching the queue dispatcher when the rows change. I rather the dispatcher just read how the queues are configured during startup and stick with that until the application is restarted.
๐ฆ: Okay
L: And such an approach is closer to configuration. In fact, it could be argued that having the queues defined as configuration would be better, as adding additional queues could be an activity that is considered “intentional”, with a proper deployment and release process.
I wonder if a good middle-ground might be to have the queues defined in the database as rows, yet managed via the migration script. That way, we can have the best of both worlds.
๐ฆ: Why not just go with configuration?
L: The main reason is that I don’t want to add something like string representations of the queue to each queue item. I’m okay if it was just a UUID, since I’d imagine PostgreSQL could handle such fields relatively efficiently. But adding queue names like “default” or “test” as a string on each queue item seems like a bit of a waste.
๐ฆ: Do they need to be strings? Could the be like an enum?
L: I rather they’re strings, as I want this arrangement to be relatively flexible. You know, “policy vs. mechanism” and all that.
๐ฆ: So how would this look in the database?
L: Well, each row for a queue would have a string, say like a queue name. But each individual queue item would reference the queue via it’s ID.
๐ฆ: Okay, so it sounds like adding it to the database yet managing it with the migration script is the way to go.
L: Yeah, that is probably the best approach.
๐ฆ: Good. I’m glad you can come away with thinking this.
L: Yeah, honestly that was the way I was leaning anyway. But I’m glad that I can completely dismiss the configuration approach now.
๐ฆ: Okay, good. So I’m guessing my job is done here.
L: Yeah, thanks again.
๐ฆ: No worries.
If all I was taught came from old DOS games, I’d probably come away thinking that archeology is the coolest job in the world. ๐
Have to remind myself that it’s better to build for the state of the world now, rather than for some future state that may never happen. That probably means you’ll need to change it later, when the future inevitably reveals itself. Just be prepared to do so, and don’t be so hard on your past self when you do.
Oof, left the house without my wallet. Good thing I set up Google Pay on my phone or I wouldn’t have been able to pay for my coffee.
Project Updates
Well, it’s been three weeks since my last post here, and as hard as it was to write this update, not writing it would’ve been harder. So let’s just skip the preamble and go straight to the update.
Cyber Burger (That Pico-8 Game)
I’m terrible at being coy, I’ll just spill the beens. That game I’ve been working on is call Cyber Burger. It’s based on a DOS game I saw on YouTube, and it seemed like a fun project to try and work on, with some tweaks to the gameplay that I think would make it more forgiving.
In the weeks since my last update, I finished with the prototypes and started working on the game itself. The initial set of art is done and a very simple “Game A” mode has been implemented. In this mode, you are shown a burger you’ll need to make in your basket. You do so by shooting down the items flying across the screen and catching them in order. When you do, you get a “tip”, which basically amounts to points. If you make a mistake, you’re given a demerit. There are five rounds in total, and once the round is complete, you move on to the next one, with maybe slightly different items, or different item speeds, etc.
I managed to make a HTML version of this which plays through round 1. I gave it to someone at work to play test and the results wereโฆ well, they weren’t bad but it didn’t set the world on fire.
I think I’m okay with that, but I do need to keep working on it. I think one thing that would help is adding sound. And I think it might help me deliver this earlier if I abandoned Mode A and start working on Mode B, which is closer to an arcade style of game that would allow for continuous play. These two things, I’ll aim to work on this next week.
Oh, and I’ll need to fix the item spawner. Waiting ages for an item you need is no good.
If you’re interested in giving it a try, you can do so by following this link (it runs in the browser). Feel free to send any feedback you may have.
UCL
The other thing I’ve been spending some time on over the last week or
so was UCL. I’ve been using that work tool which has this language
quite often recently and I’ve been running against a number of bugs and
areas where quality of life changes could be made. Just small things,
such as allowing the foreach
command to be called with a proc name
instead of requiring a block, much like the map
function. Those have
been addressed.
But the biggest thing I’ve been worked on was building out the core library. I added the following functions:
- The `seq` function, used for generating a sequence of integers. I like how I built this: it’s effectively a virtual list โ that can be indexed, iterated over, or calculated the length of โ but does not take up linear space.
- Comparator functions, like `eq`, `ne`, `gt`, etc. plus settling on a type system much like Python, where values are strongly type (can’t compare ints to strings) but are also dynamic.
- Arithmetic functions, like `add`, `sub`, etc. which operate on integers, and the `cat` function use to concatenate strings (these functions do try to cohere values to the correct type)
- Logical functions, like `and`, `or`, and `not`.
Along with this, I’ve started working through the strings package, which would add the various string functions you see, like trimming whitespace, splitting, joining, etc. I’ve got trimming and converting to upper and lower case, and my goal for next week is to add splitting to and joining from string lists. Once that’s done I’ll probably put this on the back-burner again so I can finish off Cyber Burger or work on something else.
Just a reminder that there’s also a playground for this too, although I apologise for the lack of documentation. I’ll need to get onto that as well.
Finished reading: Hell Yeah Or No by Derek Sivers.
A good book. I resisted reading it for a while (Iโm not sure I was ready to hear what it had to say) but I bought this Friday, hoping that it would help me work through an important decision, and I think it did. ๐
My regular cafe no longer opens on Sunday. Most of the other cafes close to me open at 8:00. There’s one that opens at 7:00 but it takes a 30 minute walk to get there. I went to that one today, and despite the walk, I arrived home earlier than I would have if I waited for the other ones to open.
More DOS game nostalgia watching on YouTube over the last few days. This time on Commander Keen, an absolute favourite of mine growing up. For all the other Keen fans out there, this one’s for you.
And yes, making this is how I spent my evening. ๐
It’s a pint sort of evening today. Balter XPA. Cheers. ๐ป
It might be that the first day where everything’s working smoothly, nothing’s on fire, and there’s nothing for me to fix would also be the first day that I’m out of a job. Even so, a day like that would be nice. ๐ฎโ๐จ
Oh, so those flashes of blue light was not arcing from the overhead catenary. โ๏ธ
Had to deal with an API written in JavaScript where a field could have zero or more string items. Two or more items, the field is an array. If it’s one item, the field is set to a single string. Zero items, the field is not set at all.
๐คฆโโ๏ธ
I don’t blame the language, I blame the API designer.
Helped my barista arrange some stock that tipped over in her display fridge, and she didn’t charge for my coffee. I absolutely appreciate the sentiment and free coffee. I also like you to stay in business, so please let me pay in the future.
Some follow-up from my post about 1Password this morning. Turns out it’s not 1Password picking the wrong suggested password, it’s Vivaldi. Not sure why at this stage. I may have chosen not to save the password for the subdomain and it was picking up something else. Or it’s just broken. ๐คท May need to investigate further (or not).
I also realised that there’s no such thing as an Android 1Password extension for Vivaldi, or if there is I’m not using it. 1Password does have something which uses the accessibility settings to pre-fill passwords in “supported browsers.” Not sure Vivaldi is such a supported browser because when I turned on that feature, nothing happened (it did show up when I tried Chrome).
Also, shout-out to yatal who suggested clicking on the extended options for the domain, and selecting “Only fill on this exact domain”. Found this option on 1Password for 8.10.40 and managed to turn it on for all the subdomains that I have.
As to how I can get it working on Android? Not sure at this stage. Maybe I need an updated version of the Android app.
I wish 1Password’s browser extensions recognised subdomains better. I have around 6 services hanging off a single apex domain, each with a different password, and whenever I visit the login page for one of them, 1Password always suggests the Linkding one. It’s not like it doesn’t know the site URLs.
Since bringing home the ukulele, all I’ve been wanting to play on it is tracks from Mike Oldfield’s The Voyager. Here’s a test recording of my attempt at playing She Moves Through the Fair, which I think is actually an Irish folk song. Also wanted to hear how well my webcam mic performs with music.
I’ve been listening to Marco talk about his user’s response to the Overcast rewrite with interest. I have no comment to make about the rewrite itself โ I don’t use Overcast since I don’t use an iPhone โ but listening to Marco on the latest episode of Under The Radar come to realisation that Overcast is now at a stage where he cannot only consider it his own is admirable. To have created something that has grown to be bigger than yourself, where the best thing you can do for it is to say “I may have started this, but this is no longer mine”, is a testament to how large and successful Overcast has been. If only we all could say we had that chance to do likewise in our own careers.