When linking to these pages, please use the URL:
www.iki.fi/sol/ - it's permanent.
We have a fireplace in our house, and the regulations state that there must be more fire-proof material next to it than we had, so we started looking for solutions. The classic option would be to get a metal plate (like brass or cast iron), or lay tiles, but neither of those felt nice for our living room. Then we figured we could get a nice glass panel, and found the web store nettilasi.fi where to order one from.
After the store's stated delivery time had passed, I pinged them and got a reply saying that a shipment is leaving from the factory and if our order made it to that set, it should be mailed promptly.
In a few days the glass panel did arrive. I handled it with care, considering it's glass and rather expensive. While sliding it on the floor to find its final location a piece chipped off a corner. I took a photo of this and emailed the photo to the store.
What would you expect as a response? Apology? Offer to replace? Offer to replace with discount? Refund? Partial refund? None of the above? Correct. I didn't receive a response.
After a few days I pinged the store, asking if they're planning on ignoring the complaint, and got a rather passive-aggressive reply suggesting that I must have hit the corner on something hard, braking the panel myself, because the heat shock they give to the panels at the factory would have shattered it if there was anything wrong with it.
I replied that, considering the care I took not to harm the panel (which, I remind you, is supposed to survive being walked on), something must have happened to it before shipping.
To my utter lack of surprise they never responded.
Our older dog, Jana, passed away on 6.6.2018. She had been with us for about 15 years. In the large scheme of things, it's just another dog, and her description could probably fit any number of dogs in the world, but damn it, she was our dog, and it's killing me.
She was a mix of Coton de Tulear and Lhasa Apso, so she was basically a tiny furball with an attitude. Everybody she met liked her, even those she would try to threaten, as nobody could possibly take her seriously.
She had no apparent sense of scale, and would bravely challenge dogs orders of magnitude bigger than her, especially if it came to food.
You see, the universe revolved around her tummy.
She loved food of all forms, cat food especially - the only time she actually bit me was when I took her away from some cat food that she was not supposed to access in the first place. If you were carrying food and she felt she had a chance of getting some, she'd get on her hind legs and would dance wiggling her forelegs.
She would quickly learn who's a messy eater and you'd find her under the table at attention, waiting for bits of food to fall down. We would have to keep telling our guests not to give the dogs snacks from the dinner table, because if someone did, she would start whining for more.
If you sat down somewhere, she would come around and pat you on the leg a couple of times and the roll on her back so you could rub her. She didn't mind if you rubbed her with your foot even, as long as it happened. And she was rather insistent on it.
If we had a guest who had never been to our home, she would growl at the guest when they came in, but once they sat down somewhere, it was tummy rubs time.
And she loved to take naps just about anywhere. Pillows were preferred, but a sunny spot on the floor would do just fine.
She always hated having her nails trimmed, but got more tolerant for it over time due to the inevitable snacks she would get afterwards. She was really easy to motivate - just offer snacks.
She came to our home carried in a little cardboard box, smaller than some hamsters. When we took her out for a walk, people would stop and ask if she's real. In the bus some people would wonder what that small black furball was, was it a bat?
She never learned to ask to go out (or we never learned her signals about this), so if she had to go, while she preferred to do her business outside, if nobody took her, well, carpets can be cleaned. This got worse when she got old, but we just learned to take her out often enough.
If you didn't close the door when you went to the toilet, an inquisitive snout would poke the door open, stare you for a while, and then she'd snort disapprovingly before moving on.
She loved to play with balls, even ones bigger than her. She'd play the goalie, waiting for you to kick the ball, and then charge at it.
As she grew older, one morning we found that she couldn't walk. We took her to the vet, and both her hind legs got operated on, which was a rather expensive operation. Some older relatives of ours wondered why we bothered, but this was our pet, and our decision. After the operation she gained a lot more mobility, and didn't have trouble ascending or descending stairs anymore, something we didn't even realize might have to do with her legs. We always assumed she just didn't like stairs.
In the last year or two we started to see that she didn't see as well anymore, did not hear as well anymore, and her hind legs were not as stable. We knew her time was growing short, and it was pretty clear this was going to be her last summer. I so wish she could have lived just a couple more months though.
As I was taking the dogs for a walk in the evening, she suddenly fell and started twitching on the ground with her head at an awkward angle, and I immediately realized something was wrong. I carried her home and as the seizure passed she slowly returned back to normal. After discussing our options my wife was to take her to the vet the next day.
With the public transport schedules being sucky we decided that she'd take the bicycle, and as I assembled the dog trailer (which was packed away in storage) I couldn't help the feeling I was assembling a hearse.
Morning came and she was completely herself, running down the porch stairs to pee and running back up for her treat.
The vet said that the seizure had not been an epileptic attack but instead a stroke, and that there would be more of those, they would be worse, and if the next one wouldn't outright kill her it would probably cause so much brain damage that it would be time to put her down. Being such an old dog it didn't make any sense to investigate the cause of the stroke any further, but it's likely she had been suffering from cancer for some time, which would explain some other symptoms she had.
We were devastated but glad that we still had some time. We gave her snacks and care, but generally tried to keep things normal.
After kids had gone to sleep I was spending time on my computer, and I suddenly started hearing a worrying sound from the living room. She was having another stroke. This one she didn't recover from. She would unsteadily walk in random directions, clearly confused, not knowing where she was or who we were.
It was time. It feels so unfair. We were supposed to have some time yet.
My wife took her to the vet to be put to sleep. I don't know if I could have functioned well enough to do it.
And now.. it's so damn quiet. You especially notice it at dinner time, when those little feet aren't tip-tapping around, sniffing for food scraps, sitting in attention waiting for something to drop. But you also notice it when you're sitting in the toilet. Taking just one dog out for a walk feels strange, being able to walk at a fast pace when the little furball isn't slowing down, wanting to sniff every single inch of the sidewalk, every single flower. Probably looking for something to eat.
For a long time I expected that she would die due to eating something unsuitable. That would have been so true to form for her.
She taught us a lot about keeping dogs. When I first had to open her mouth to check something I wasn't as confident as I'm now, and it didn't really work out. Confidence, as it turns out, plays a huge role in handling dogs. They can sense if you're not confident, and they will not co-operate.
If you're picking up a dog, they'll sense if you're not confident. She would always growl (especially if she was lying down somewhere) if I picked her up, but wouldn't give a fight because I was confident about it.
She was small enough to carry with one hand. On your palm.
If there's one word that I had to use to describe her, she was easy. Easy to please, hardly ever caused any problems (some soiled carpets and some gnawed audio cables she destroyed as a puppy aside). If we needed to travel somewhere, anyone could take care of her, and everyone was willing to. She didn't eat much (okay, she wanted to, but there's only so much a 4 kg dog needs). Got along with everybody, most dogs included, didn't care about cats or children, but wasn't aggressive towards them either.
I miss her so damn much.
I've been running through the games "God Eater Resurrection" and "God Eater 2 Rage Burst". These are Japanese pseudo-rpg hack & slash games with ridiculous weapons and even more ridiculous battle clothing.
The experience is kind of like a playable anime show. And they apparently made anime out of it too, and some audiences (according to Wikipedia) think the games are about the anime and not the other way around.
Game design wise they're rather interesting, in the way they took short cuts. There's a distinct "ingame" where you run around in an arena and beat up big monsters (usually around 1-5 at a time), and the ingame pretty much consists of button mashing. Mission timers generally run at around 30-40 minutes, but with enough cheating I've been able to beat the levels in under 5 minutes (each), depending on where on the arena the monsters spawn.
Sometimes new monsters are spawned during a fight, and this is most irritating when they do so on delay, so my run-through-game-cheating strategy gets a bit boring when I have to stand around waiting for three minutes for the last baddie to pop up.
You also collect random items from the arenas, which can be used for crafting, and in some cases are required to progress in the story.
The story itself is completely told through cutscenes and visual novel-like linear conversations where, if you even get an option to choose what to say (which occurs rather rarely), what you say only affects what the other person replies next (if even that) and no consequences after that. In most cases your options are literally "yes" vs "of course".
What it boils down to is that the game design feels as if the ingame was built first, and then the designers were fired and nobody touched that code anymore.
Let's say the story has a search and rescue operation. You go and beat your monsters, and then the actual search and rescue happens in a cutscene. Or the story has you field-testing some experimental hardware; you go and beat your monsters, and you don't need to actually use the hardware (assuming you even have it). When some NPCs inevitably die, they do so in a cutscene.
Some cutscenes actually show you and your companions fighting. In some cases you beat said monsters just before the cutscene.
As the story progresses you get new stuff to craft, like even more ridiculous pieces of clothing. To craft these you need items from the battlefield, so these two work as incentives to keep going; do more missions to unlock new clothing, do more missions to be able to craft them.
Between missions you can run around in your base and talk to NPCs, and every now and then you won't be able to start a new mission before doing so. Sometimes this triggers a cutscene. Sometimes you need some specific item (from the battlefield) to continue, which leads to you grinding additional missions to gather said items.
Sometimes a cutscene shows that there's a time-critical, perilous situation which needs to be addressed immediately, and then you get control and can do a dozen side missions before getting back to the main story. As you do.
"God Eater Resurrection" is actually a remake (of God Eater Burst) of a remake (of God Eater), each adding a new story arc. This was pretty weird to experience without knowing that fact, because you get end credits.. and the game keeps going. Then you get end credits.. and the game keeps going. And then you get end credits.. and the game keeps going (but without any actual plot advancement after that). The "resurrection" was actually published after "rage burst", which shows in some game mechanics being more polished.
I still haven't finished my run of God Eater 2 yet, churning through those pointless battles, waiting for the next set of clothing to unlock.. hoping the game will end soon so I can move on to something else.
Holy crap, I never ended up posting this. I wrote this on March 23rd, so it's been a while..
So.. um, okay.
Discussion with various Microsoft support organizations led me to running the windows update troubleshooter. Said troubleshooter suggested deleting the patch database and re-downloading patches, or some such. I said go ahead and left it to do its thing overnight. In the morning it was still at it, and looking at the 12 gigabyte CBS.log file I found that it kept repeating the same 1000 lines, processing one single update over and over again. I hit cancel and re-ran the troubleshooter, which told me to reboot.
Reboot, naturally, led back to the INACCESSIBLE BOOT MEDIA loop. And doing the same trick I mentioned on the previous update didn't work anymore. The next suggestion from the Microsoft reps was to do a clean install. This (luckily) doesn't mean wiping the hard drive, but it does mean that all my application installs are gone.
After the install was done, system booted, but had moved all the applications and old windows directory under "windows.old". Fine. If the alternative was to buy a new PC, I guess this was preferable. Drive letters were also changed, but that's repairable through Disk Management.
First I removed all the crap applications (such as a bunch of games) installed along with windows. Un-pinned all crap from task bar. I removed live tiles from start menu. I installed updates (which, for some odd reason, weren't installed along with windows). Rebooted. System still works.
Installed Firefox, even though Windows kept insisting that I should give Edge a chance. Installed Steam. Installed Spotify. Logged into both. Quit Steam, moved the directories under steam from windows.old to the new steam directory. Started Steam, and yes, the games are there, and my saves seem to be safe too. That means I don't need to restart my OCD run of Mafia 3.. (which I have since finished).
Photoshop: the dvd drive on this PC is broken - I could swap it with another from my PC graveyard but I'd rather not use disks if possible. Found that you can download Photoshop CS5 installer from Adobe, so I did. The CS5 installer asked for CS5 key, noted that this is an upgrade, so it asked for older Photoshop key, which I also gave (I had upgraded from CS2 to CS5) and it installed. The Photoshop license is the one I had been most worried about. I have to wonder if I had kept updating Photoshop, just how many keys it would have asked..
Affinity photo reinstalled fine. Not that I expected any problems, really, since I had just recently bought it. Why Affinity when I have Photoshop? Well, Photoshop CS5 is bound to stop working at some point, and I want to explore alternatives. And it's not very expensive (unlike Photoshop).
Ultraedit: I had bought a new version of UE right before the first system crash, so I had lost the new version install. I didn't bother installing the new version after rolling back because... UE25 is really slow compared to UE15. This time I didn't feel like digging up ancient UE installers and installed UE25. It accepted my license fine as well. Now I just have to figure out how to disable some of the annoyances that make UE25 so damn slow..
After some googling I found that the new "document map" feature, which is only really useful on large files, makes editing large files unusably slow. And this is like a 100 line file and it's unusably slow. Disabling the document map made ultraedit much faster, fast enough to be usable, but it's still blinking like crazy while I'm typing. (Since then UE has had an update that made it somewhat faster, but having word wrap on still makes it quite slow..)
Visual Studio: I guess I can just install the latest visual studio community.. the primary thing keeping me to the older visual studios has been SDL1 and I think I've mostly moved out of that by now.
After Visual Studio, I rebooted. System still works.
Cheat engine. I think I've mentioned several times that I tend to hit (single player) games with cheats if they feel like they're wasting my time. Many games have become more enjoyable after skipping the (story-wise unnecessary) grinding for money, for instance.
Sourcetree. CPPCheck. LLVM/Clang. VLC. Python.
I realized that I forgot my bookmarks in Firefox. I tried copying the whole profile over but the bookmarks didn't appear. Bummer. Then I realized that the profile exists in both AppData\Local\Mozilla\Firefox\Profiles as well as AppData\Roaming\Mozilla\Firefox\Profiles. After copying the roaming profile over, bookmarks appeared. Phew.
Audio stuff: Komplete. No worries, I'll just re-download a hundred gigs. Cough. Well, at least Native Access makes that process relatively painless. Audacity, no problems. Reaper, accepted license fine.
That set scratches the surface - there's still a lot that's missing like all of my web development pipeline (who knows when I'll get this update online..), video editing stuff, and so on and so forth.. but at least the system is usable now.
Since my web dev stuff was pretty much broken I figured I might try to do a makeover, but after looking into things for a few days I just installed PHP again just to get this update online. In longer-term I wish to change from PHP to something python based (jinja2 probably), but then again, I also want to change the site's layout at some point to something more reactive.. the problem there is that web development is a bit crazy (as it's ever been) with transpiling and sass and stuff, but for some reason I haven't been able to find a simple tutorial on setting up a decent modern web dev environment. Shouldn't be too hard, but takes time to piece things together - time I don't really have right now.
As I had feared, my system went back to the INACCESSIBLE BOOT MEDIA loop. Like the last time, my multimedia keys stopped working, and the next time I booted (which was several days later), the boot got stuck in the bluescreen boot loop.
Given the experience I had from before, I dug up the USB boot media, messed with BIOS to boot from it, went to the recovery console and ran a few commands based on twitter conversation I had after the last time this happened.
First, I found the volume that has my system files in it. The drive letters are pretty random. I went through drives starting from C:, checking for windows directory and the correct volume label. I found my system on drive H:.
Next, I checked what the latest installed package was:
Dism /Image:H:\ /Get-Packages
The latest package was a "rollupfix" package, so I presume it's a collection of patches which happens to include the one that blew up my PC a couple months ago. I removed the package with:
Dism /Image:H:\ /Remove-Package /Packagename:Package_for_RollupFix~31bf3856ad364e35~amd64~~16218.104.22.168
Package names are long. As I was in the recovery console, I don't have the exact name copied down, but it was something like that.
After the package was uninstalled, I rebooted, changed boot device back from the USB stick to the hard drive in BIOS, and... the system booted.
This doesn't fix the root problem, however, and I'm pretty sure I'll find my PC in the boot loop some morning after windows has run automated updates. Sigh. At the moment I'm pretty much dreading the next cretor's update.
I've been tinkering with SoLoud again after taking a couple years off due to being burned out on the project. Long story short, I spent all my free time on it for a few years, and then got some, erm, constructive criticism from a game developer, which hurt enough that I didn't want to have anything to do with the project for a while. The while become a couple months, then a couple more, until a couple years had gone by.
SoLoud, like any non-trivial piece of software, builds upon the work of others. I have been careful to only include libraries that do not require attribution in binary form. That means that BSD license is out, and don't get me started on GPL.
Some people feel this is unreasonable. I, on the other hand, feel requiring attribution in binary form is unreasonable.
In a few cases I've reached out to the authors of the libraries and they've changed licenses to suit my needs. In some cases the authors simply did not care about the license, and had included it because someone asked them to - or just included a license because everybody else was doing it. In some cases the authors were not available, because, you know, they were dead.
If I didn't have this limitation, building an audio library like this would be much easier, but I'd rather not to force people who use my library to have to include kilometers-long legal notes in binary form.
As an example, Steam ships with ThirdPartyLegalNotices.html - currently an approximately 200kB, 4000 line file.
Now, I'll build an exaggeration to make a point. Bear with me.
Let's say that the author of a certain Linux filesystem had gotten his way and all software required a splash screen at startup for any significant piece of software used. Let's call "significant piece" 10kLOC for the heck of it. It's industry standard, everybody's doing it, so everybody's doing it. Right? The SoLoud project, including the third party libraries it contains in source form, clocks at about 130kLOC at the moment, which would mean 13 splash screens you'd have to add to every application you wish to use SoLoud. And 13 splash screens every user would have to drag themselves through every time they launch your game.
And that's, of course, just SoLoud. The GNU C library is about 1.3MLOC - I presume other C libraries are of similar sizes - and don't get me started on the game engines out there..
I've seen code of a hundred lines that requires attribution, explicitly, in binary form.
Wouldn't it be much nicer to just include the library in your code and get on with life, without having to worry about all this? In the end, most people who release source code would rather their work is used, than that it's not used.
In the end, the end users don't care.
Some ten years ago I was walking the dogs with my wife, and commented that maybe I need a new goal, like having my code in the hands of a million people. My wife said that was megalomaniac. A year or so later Qualcomm shipped that many devices in a day with drivers that had my code in it. And unless Qualcomm's corporate culture has changed (which I find extremely unlikely), my code has likely touched a billion people by now, only through those drivers.
I'd like to stress that this does not make me unique by any means - those drivers alone have code from hundreds of people.
In any case that's just my corporate work. I've also worked on a bunch of open source, and I sometimes hear through third parties how my code is used somewhere. Some 3d chat used my (currently horribly outdated) virtual filesystem. A game where you build and battle robots used it too - I sent that company an email asking for comments on the library and they sent me a copy of the game. Most of the time I don't hear about the code use though. Is my code used in space? On another planet? I have no way of knowing.
SoLoud has officially shipped on all major consoles.
Maybe I need a new goal.
Yesterday I noticed that the media keys on my Natural Keyboard Pro stopped working, probably as a reaction to me switching from a broken mouse to a new one. I figured I'll just quickly boot to get things working again.
The boot resulted in a bluescreen saying INACCESSIBLE BOOT MEDIA. In itself it's a bit weird error message given that it's loaded from the boot media. After showing it a while the system rebooted and returned to the bluescreen. I let this go on for a few cycles and then figured it's not going to right itself.
I started googling about this and found a bunch of resources starting from a decade ago, and apparently the magic thing to do is to boot up with windows usb stick and hit boot repair, which (according to the discussions I found) is bound to fail. And it did.
The tool threw up a log file which says that an unfinished patch is stopping the boot, which sounds weird, and an error code of 0x490. Further googling gave more magic things to do, like running "bootrec /fixboot", which gave an "access denied" message. Several threads said that this is new from the latest win10 boot media, and using an earlier one worked. After trying a bunch of other things like setting the partition active and rebuilding boot records, I managed to get something done and the bluescreen was replaced with a dull message saying there's no operating system here.
I hunted down an older boot media (which is from several years ago, because the boot media build tool has "improved" since and only lets you build the very latest), booted in and got the fixboot command run without being denied access. After this the automated recovery tool managed to do something, the system booted.. back to the bluescreen.
There's a bunch of threads explaining how to fix the UEFI boot, but the thing is, this is a legacy system - there's no secure boot here. I also don't know what exactly broke it, as it's been a very long time since I last rebooted (just how long I have no idea).
Back in, I dunno, windows XP times when things were borked enough you could just reinstall windows on top of windows and it overwrote some system files but overall your system was left intact. I tried running upgrade on the media but that just said that upgrade is only allowed from a booted-up system. Shrug. I tried to roll back from the last system checkpoint but there was none, and rolling back to the earlier windows build also just failed.
A little progress, though; booting up now popped up boot options. Unfortunately, all of the options (like boot in safe mode) just ended up in the same bluescreen. Turning on boot logging didn't end up touching the log file, so the crash occurred before the filesystem was up. This probably also means that the drivers were fine.
As a funny side note, the most recently updated file in the windows directory (where the boot log resides) was windowsupdate.log which just contained a message stating the windows update logs are only accessible through powershell now. Which is, like, super helpful when trying to figure out what went wrong from a recovery console.
All integrity checks succeeded, including chkdsk, so it wasn't hardware failure. No popups asking me to pay bitcoin either, so probably not a virus.
Now, I bought myself an SSD as a xmas present, so I had done migration about a month ago. I figured that since there's nothing else to be done, I might as well (after taking last-minute backups of my source codes) re-do the migration. I'll lose about 40 days worth of changes, but I should end up with a working system. Until, in the worst case, Microsoft remotely borks my machine again. Let's hope not.
So here we are. We'll see how it goes. If things break down again, I may need to burn some money and build a new system, which isn't all bad, but there's a bunch of software licenses bound to this hardware I'd rather not lose.
My brother had an idea, pointed me at some open food nutritious data and asked (in a roundabout way) if I could make a tool that uses said data so he could get food nutritious content estimate on home cooked foods. I said I'd take a look.
It's been ages since I last did any web work, and things have definitely changed a lot. To start, I dumped all the CSV data into a SQLite database. I had to massage the data a bit because the CS Vs had some extra newlines, I had to handle umlauts somehow and decimal points were wrong (Finns for some reason use , as decimal point, which had to be changed..). I ended up html-encoding all umlauts, which meant that the C in CSV became a problem.. anyway, I got it done.
Next I made a web 1.0 version with PHP. Everything in that version is server-side, and there's no CSS or anything. While that works, it's not convenient.
Then I asked on twitter about recommendations on modern web dev frameworks. People pointed me at vue, react, elm, rolling my own, or not using a framework at all. I looked at a few of these and vue looked most friendly to me. I watched a few vue tutorial video clips which let me get rolling pretty quickly. These tutorials also pointed me at Bulma CSS framework, which solved another big piece of the puzzle. Bulma doesn't do everything I needed, but luckily there are extensions.
I decided to ajax a bunch of stuff, and opted to just use fetch() even though caniuse said some current browsers don't support it. Since the target market for this was pretty well defined (i.e, my brother) I didn't really need to care. For more complete support I could have taken in some ajax library, but why bother?
Foodsofia uses two php scripts which it uses to ajax data in; the list of food items and the nutritious values of specific food items. Both of the scripts return data based on the language code (the original data had support for Finnish, Swedish and English, so those are supported). I also made sure to sanitize all the inputs to the php script to avoid the bobby tables attack.
The primary control in FoodSofia is the select box. First I used plain select, but that's annoying (not to mention slow) to use with ~3000 items, so I changed it to v-select, which has search capability. That worked fine, except that it was really slow to start. As a test I replaced it with vue-multiselect, and that was way, way faster, so I'm happy I tried it out.
After putting the more complicated select components in, I noticed that they conflict with the bulma css, so I got to learn at least one way of trying to figure it out. Using chrome's developer tools, I found the component in the DOM, investigated it's css and one by one disabled the css items until I found the one causing the glitch. Then I wrote a one-line style to disable it by hand, and the component worked. This leads me to wonder just how many of these kinds of kludges exist in modern web sites these days..
Last missing piece was being able to share the resulting links. I encoded the food table as a hex string - one character for the "used" toggle, 4 characters for food code (slight overkill) and 6 characters for the food amount (in 1/100ths of a gram - so if you enter amounts larger than 16777.216 grams, the resulting url will not work).
The url encoding was also helpful in making the language change happen. The language buttons simply reload the whole page with the url encoding and a different language code. That way I did not need to ajax every piece of data separately. Also, there's no need for cookies.
Working with vue and bulma was fun. This site's layout was last redesigned in 2010. Maybe it's time for a revamp? I've had a few starts at a redesign, but the sheer scope of this site (some ~250 pages of content) makes it a lot of work. These frameworks might make it easier.
TMDC20 results are out. First place.
Here's one I did not finish.
My most viewed video on youtube is my "Bookworm Aimbot", where a bot I wrote plays bookworm and is pretty good at it. I figured at some point that I could make a sequel to that, which plays Bookworm Adventures instead.
First order of business was to get the dictionary the game uses. Unlike with Bookworm, the dictionary wasn't conveniently as a separate (if slightly encoded) format. I figured the dictionary needs to be in memory, so I ran the game, dumped the memory using Process Explorer, and wrote a tool that finds the dictionary words and dumps them into a text file. According to some wiki about the game, Bookworm Adventures 2 knows more words, so their dictionaries are different; if I ever go that far, I would have had to extract that dictionary too.
Next up, I needed to deal with the OCR. I took screen caps of the tiles, which are both different size and have a different font than what Bookworm used. The font is more OCR-friendly, and no particles are drawn on top of the glyph either, making the OCR way easier. After some tweaking, I got it to recognize the tiles perfectly. No preprocessing filters needed or anything.
Working somewhat smarter than last time, I used the RegisterHotKey API in windows and bound my bot to run if control-f1 was pressed, and to die if control-f2 was pressed. This way if I ever lost control of the bot, I could just kill it with the hotkey. Except when I made a bug which ended up not ever checking window messages, of course, and I had to cycle through another account to kill the process. Yay. But overall, much smarter.
I wrote routine that looks for the best possible scoring words (biased towards longer words in case of a tie), and a routine to enter the word and submit it.
And then I stopped.
The game is just annoyingly slow. After every move the bot made, the game would play a slow animation before it could continue. Couldn't even rapidly play through the dialogue, there's a speed limit there too. I guess I could have beat the world record in fastest play-through, but I didn't really feel like it. I don't think the resulting video would have been all that interesting.
On top of that there's some special stages which require different tactics (like answering riddles) which would have required a lot of code.
After that I started looking for other letter tile games I could play and/or attack, and there doesn't seem to be a lot of these out there. I did (re-)discover Bonnie's Bookstore, which is also a rather old game at this point, but since popcap was bought by EA, I couldn't re-download the game anymore (yay DRM). I did contact the original authors who sent me a new key but that didn't work, so.. dunno.
Some minor spoilers here. Game story is not discussed, some game mechanics are.
The Sexy Brutale simplifies the idea a lot, but it's still there. The location is relatively small and there are only about twenty agents in the game. On top of this, there are some characters that don't really have any agency, and could be considered interactive furniture.
The second big simplification is that the player's agent doesn't interact with the other agents directly. Interaction is indirect, you manipulate items or press a button or some such, and that changes things.
Third simplification is that the agents don't really interact with each other either (except for the obvious killer-victim interaction).
Fourth, you can only change one thing (that matters) at a time.
All that said, there's still a lot there; repeating day cycle, picked up items returning to their original locations when day restarts, a lot of actions only possible at specific times of the day, learning what's going on in order to change things. For example, if you know the key code to a door, you can open it. But you first have to find it out. Once you do, there's no need to go through the trouble of finding out again, just run to the door and go.
One idea I really like is that you can change the location from where you start the day, which reduces the frustration of having to run through the same set of rooms every time the day starts. What I really dislike is that you have to wait several seconds for your character to get up every time you re-start the day before you can move. It's a small thing, but it's annoying.
The audio design in the game is also great. Different locations in the game have different audio, different soundtrack, but key events during the day play at the same time, so you learn to intuitively know what part of the day you're in. When you spy the agents talking to each other they sometimes mention these things too, like "was that a gunshot?".
When I was thinking of this kind of game I always started from the idea that the agents would be based on some kind of generic AI which knows how to do basic things like getting from A to B using whatever is the most convenient way (i.e, take the bus), and on top of that they would have a script of events they should try for ("get to work by 7am"), with some logic ("if no car keys, don't use car"). But it doesn't need to be that complex, like The Sexy Brutale shows.
The stuff I talked about in the old blog post - social billiards - does make things a bit more complex, but with limited number of agents it should still be totally manageable. Would need a lot of planning (basically designing a graph to see what affects what), but.. doable.
To make the workload smaller, the locale could be selected so that it makes sense that only a few people are about, like they did in The Sexy Brutale, such as an off-season ski resort or maybe a cruise ship. It's also not necessary to be able to affect all agents, some might come out of buildings the player can't access and leave the same way, for instance.
I'd also make it so that the player can retry things later in the day. Kinda like with save games, but if you manage to gain knowledge or a skill, those things you could keep. When restarting the day, you could pick the time where to rewind, and the game would act as if you had played exactly the same way up to that point. Plus, of course, an option to just idle for N hours if you're waiting for something specific to happen.
The AI logic would still have to be much more complex than in The Sexy Brutale, because, let's say someone comes home and finds you standing in the middle of their living room... the agent should definitely react somehow.
I believe it would totally be possible to implement. The big question is, would it be fun to play? I guess that depends a lot on the stories the game would tell.
Let's hope 2018 ends up better than 2017 was.
Not that 2017 was all bad. But it could have been better, overall. In 2017 I dabbled with doing some consulting on the side (which my full-time work contract is fine with), which then was abruptly moved aside because, after applying for years, we became foster parents. Which naturally took all of my free time and added tons of stress, but it's not all bad.
I spent most of what was left of my free time just going through steam backlog or similar low-stress things. I did manage to get the minimal things done, though, like the new year demo:
I also entered the 20th TMDC, but the results for that are not yet out, so... expect another blog post.
Talking of blog posts, I really should blog more, even though I doubt many people read these. Maybe that'll be the thing I'll try to do more this year. We'll see..