-
Evidence that I didn’t sleep well last night: for a split second I thought this was actually a note I made. I even remarked as to how neat I made it.
The neatness is what eventually tipped me off. None of my notes look as good.
-
A lot of track work going on this weekend. I enjoy seeing these trucks that can go both on roads and rails. You don’t want to be waiting for them to transition, though. It’s usually done at level crossings and they don’t rush it.
-
Here’s a bit of a blast from the past. I managed to get ccedit working again. This was the original level editor for workingset.net/2022/12/2… my Chips Challenge “fan game” I’ve been working on.
I’ve been designing a few levels for it recently, but since moving to a new Mac, the level editor I was using was going to be difficult to port. It’s QT application and the QT bindings were a pain to setup, and I rather not go through that again. I was using a Mac at the time I started working on it, but I wasn’t yet ready to go all in on MacOS. So to hedge my bets, I decided to go with QT as the UI toolkit.
This was 5 years ago and I’m unlikely to go back to Linux, so choosing QT was a bit of a bad decision. I think if I had my time again, I’d go with something like AppKit.
Anyway, the level editor still works but I have to log into a screen share to use it. I’d like to be able to edit levels on the machine I’m using now.
The code for the original level editor was still around but it hasn’t been touched in ages. It’s basically an SDL application β the same graphics library I’m using for the actual game itself β and the SDL v2 bindings I’m using are still maintained, so updating those were quite easy1.
One thing I did have to pull out was the Lua VM2. The editor was using old C Lua bindings. Better Lua VMs written in pure Go are now available, so I didn’t want to keep using these old bindings anymore. In fact, I didn’t want to use Lua at all. Lua was originally used for the level scripts, but I replaced this in favour of another language (which is no longer maintained π, but I’m not changing it again).
The original CCLM Editor So far the editor boots up, but that’s about it. I can move the cursor around but I can’t add new tiles or load existing levels. There seems to be some weird things going on with the image name lookup. I originally thought image name were case insensitive, but after looking at the image name lookup logic in the game itself, I’m not so sure.
How much time I’d like to spend on this is still a bit of a question. It all depends whether I’d like to release the game itself in some fashion. There are still questions about whether I’m allowed to, given that the graphics are not my own. Still need to think about that.
But in any case, good to see the old editor again.
-
To Wordpress Or Not To Wordpress
I’m facing a bit of a dilemma. I’ve been asked to setup a new website for someone who wants to stand up a new business. In therory this is something that I can do quite easily. I know HTML and CSS. I’ve made a living building backends for web-apps. I do have an undeveloped eye for design, but I like to think I have an idea of the principal of good website usability; and as long as I’m not too ambitious, and aim for a minimal usable site, I can probably put together a simple static website. Continue reading β
-
Ok, I now understand why everyone is going on about the Wordpress block editor. I’ve installed Wordpress this morning to play around with it in preparation of a new project, and wow is there a lerning curve associated with it. Definitely not your dad’s Wordpress instance.
-
Here’s something I’d never would have imagined: Jaycar does same day delivery. I experienced this once before but I dismissed it as just a fluke. But it happened again today. I bought something from them at 1:14 this afternoon and it arrived at my house at 3:26. Incredible.
-
It sometimes sucks being a listener of Apple tech podcasts when you’ve got an Android phone. I love the shows where an indie dev talks about an app they’ve worked on. But I can never try them out because I don’t have an iPhone.
I know there are fixes to this. Just not ready to apply them yet.
-
Foldables and rollables are so 2022. Where are the scrunchables? When I’m done with my phone, I want to be able to scrunch it up into a little ball and stuff it in my pocket. Why can’t I do that? Where is the R&D money going?
(Honestly, the whole foldable phone thing seems kinda ridiculous to me).
-
I was listening to an episode of Sharp Tech the other day. When the conversation moved on to AI and Ben Thompson’s experience with Sydney, an idea for a game came to me.
It’ll essentially be a text adventure, but the goal is to try to get a GPT AI to play it. The AI would give you a description of what it “sees” on their screen, and you have to tell it how to proceed. You can’t enter the commands yourself. Except, you have to use natural language to guide the AI through the game.
Maybe in the harder difficulty levels the AI could disagree with you and you’ll need to convince it to do what you say. Or maybe it’ll give you partial information about what it “sees”. It can say that it sees a castle, but doesn’t explain that there’s a gate-house as well, and you have to tease this information out of it in order to move forward.
This sort of harkens back to the time when you’re playing a game for the first time with someone that’s experienced, and they’re telling you what to do1. Here, you’re that experienced player giving assistance, even though you’ve never played the game yourself.
Anyway, free idea for anyone who wants it.
-
Or maybe those times when you’re trying to give tech support over the phone. Those are fun, right? Well, what better way to spend your downtime than playing a simulation of that. π ↩︎
-
-
For anyone working with YAML Cloud Formation, if you were to see this error message:
E0001 Error transforming template: 'NoneType' object has no attribute 'get' cloudformation.yaml:1:1it might be because one of your resources is not properly indented. That is, the
TypeandPropertieskeyword is at the same indentation level as the resource name:Resources: # Broken DeadLetterQueue: Type: AWS::SQS::Queue Properties: # ... # Fixed DeadLetterQueue: Type: AWS::SQS::Queue Properties: # ...Another problem is that you’re trying to use
!GetAttwith a string parameter:Parameters: DynamoDBStream: Type: String Resources: LambdaDynamoStream: Type: AWS::Lambda::EventSourceMapping Properties: # This is the source of your woes EventSourceArn: !GetAtt DynamoDBStream.StreamArnTook a while for me to find the cause of these. Had to comment out all the resources and uncomment them back one by one. In retrospect, a quick glance at the entire file would’ve found it as well; although the slow act of going through the file, commenting and uncommenting things, was still a useful act in and of itself.
Naturally the error message is cryptic, probably because it falls within the gap of a well-formed YAML file but a badly formed object model. Some better error reporting would be preferred though.
And yeah, there’s going to be commentary about error reporting in these posts. π
-
Quotes Around Names In Error Messages
I saw this error a few minutes ago: failed to process input: RUNTIME ERROR: function has no parameter stack This threw me for a minute as I was trying to work out which parameter stack went missing, what I did to cause it to go missing, and what the heck a parameter stack actually is anyway. But it had nothing to do with any sort of stack. The error message was showing up because a function call was expecting a parameter with name “stack” which was missing from the function definition. Continue reading β
-
Interesting feeling I had just now. I was drafting a reply in Micro.blog which I chose not to post. And yet, it feels like I’ve posted it. Wonder if that falls into the same sort of fallacy as the one where talking about what you’ll do feels like you’ve actually done it. π€
-
A park I frequently go to once had a non-directional beacon transmitter built there. Being somewhat interested in things like this, I always enjoyed looking at it as I walked by. It was decommissioned in early 2020 and now there’s no trace of it ever being there. I kinda wish I had a photo of it.
-
Web Search Works With Blogs Too
Here’s one more reason to write (or syndicate) to your blog instead of post directly to social media: you can use web search engines to find what you need. I hear a lot of people complain about the crappy search in Twitter or the lack of search in Mastodon, but this won’t be a problem if you post to your site and let public search engines crawl it. They’re incentivised to make sure their search is good, so you’re more likely to get better results more quickly. Continue reading β
-
Some acorns fell to the ground while I was passing under an oak tree this afternoon. I looked up and saw a few female king parrot perched there, feeding on the acorns.
It was difficult making them out: their green plumage provided good camouflage.
-
TIL that long-clicking some toolbar icons in desktop Safari will bring up a menu. I would’ve though a right-mouse click would suffice for that, but I guess touchpads and traditional Mac mice only have a single button. I just wish I could make the long-click delay a bit longer.
-
Setting up Yarn on a new machine to manage some JS packages. As usual, everything about how the tool works is completely different from the last time I installed it. So, once again, what was expected to take 5 minutes is now taking 30 as I learn the new way of doing things. π©
-
Close encounter with a kookaburra.
Taken a few days ago while on a walk.
-
I donβt understand people β adults who are by themselves β who go to a cafe just to watch something on their phone with the load speaker. A bit discourteous in my opinion. Please use headphones if you got them. Otherwise, watch it at home. That way you wonβt distracting others.
-
Reading something about workplace memos this morning got me thinking: are workplace memos still a thing? As in printed memos pinned onto bulletin boards? Iβve never worked anywhere that did this. Iβd think most places would use email for this now, especially after 2020.
-
Looking at the core gRPC status codes this morning. There are 17 status codes in all, and most of them β like
NOT_FOUNDorPERMISSION_DENIEDβ are what you expect. I can see why those codes are listed there. They’re pretty common error conditions seen in most systems.But the code
DATA_LOSSappears there as well:DATA_LOSS (15): Unrecoverable data loss or corruption.
I’m a little curious as to why that error case was considered worthy enough to be given a code here. Hopefully not because it was frequent enough to warrant one.
-
Looking through my drafts last night to see if I could use one of them for my daily post. Found one that I wished I actually published at the time. Not because it was insightful or anything. It was just a record of what I did that day. But that’s sort of what this blog’s about in the end (as I need to keep reminding myself).
P.S. I ended up publishing it with the original timestamp using Micro.blog’s scheduling feature. It’s super useful for publishing things with date-stamps in the past as well as the future. I use it all the time.
-
Spent some time closing off the Dynamo-Browse shortlist. I think I’ve got most of the big ticket items addressed. Here’s a brief update on each one:
Fix the activity indicator that is sometimes not clearing when a long running task is finished.
How long running tasks are dealt with has been completely overhauled. The previous implementation had many opportunities for race conditions, which was probably the cause of the activity indicator showing up when nothing was happening. I rewrote this using a dedicated goroutine for handling these tasks, and the event bus for sending events to the other areas of the app, including the UI layer. Updates and status changes are handled with mutexes and channels, and it just feels like better code as well.
It will need some further testing, especially in real world use against a real DynamoDB database. We’ll see if this bug rears its unpleasant head once more.
Fix a bug in which executing a query expression with just the sort key does nothing. I suspect this has something to do with the query planner somehow getting confused if the sort key is used but the partition key is not.
Turns out that this was actually a problem with the “has prefix” operator. It was incorrectly determining that an expression of the form
sort_key ^= "string"with no partition key could be executed as a query instead of a scan. Adding a check to see if the partition key also existed in the expression fixed the problem.Also made a number of other changes to the query expression. Added the ability to use indexed references, like
this[1]orthat["thing"]. This has been a long time coming so it’s good to see it implemented. Unfortuntly this only works reliably when a single level is used, sothis[1][2]will result in an error. The cause of this is a bug in the Go SDK I’m using to produce the query expressions that are run against the database. If this becomes a problem I look at this again.I also realised that
trueandfalsewere not treated as boolean literals, so I fixed that as well.Finally, the query planner now consider GSIs when it’s working out how to run a query expression. If the expression can be a query over a GSI, it will be executed as one. Given the types of queries I need to run, I’ll be finding this feature useful.
Fix a bug where
set default-limitsreturns a bad value.This was a pretty simple string conversion bug.
Add a way to describe the table, i.e. show keys, indices, etc. This should also be made available to scripts. Add a way to “goto” a particular row, that is select rows just by entering the value of the partition and optionally the sort key.
These I did not do. The reason is that they’ll make good candidates for scripts and it would be a good test to see if they can be written as one. I think the “goto” feature would be easy enough. I added the ability to get information about the current table in the script, and also for scripts to add new key bindings, so I don’t force any issues here.
The table description would be trickier. There’s currently no real way to display a large block of text (except the status bar, but even there it’s a little awkward). So a full featured description might be difficult. But the information is there, at least to a degree, so maybe something showing the basics would work.
Anyway, the plan now is to use this version for a while to test it out. Then cut a release and update the documentation. That’s a large enough task in and of itself, but I’d really like to get this finished so I can move onto something else.
-
With all the designs I’ve made for systems using the Stripe API that blew up in my face because of some undocumented edge-case, you would’ve though I’d internalise this by now, and remembered that the only real strategy for knowing that a design is viable is to actually test it.
But no.
And so here I am once again, trying to contort my design so that it’ll work with the Stripe API while trying to avoid making any dramatic changes. π€¦
So, for next time: build a prototype, and use it to validate your hypothesis. Honestly, just do it. Spending those few hours of work now will save you the many hours of work down the line, when you find that you’ve hit some edge-case and you’ll have to go back to the drawing board.
Just frickin’ prototype!
-
It’s Tuesday, I don’t shutdown my laptop during the week, and I only just now launched a terminal and IDE. Guess how much programming I did yesterday.