I finally bit the bullet and decided to get rid of wordpress, after 16 years. There’s no benefit for my personal blog to be running a dynamic platform, I don’t have any users, or dynamic content, and comments which might be the main attraction are not something I really use.
I still need to figure out how to replace the dynamic contact form, though.
To achieve this, I initially tried to follow the Hugo tutorial, but it really only described a very incomplete set of basics. I had more luck with this other tutorial, and the theme they recommend actually has some interesting sample posts that describe how to create a hugo theme.
I also looked at this to figure out some intricacies of markdown image rendering.
I’ll continue migrating content to the new site, and running both in parallel until ready to switch.
There’s a python module called icecream which provides a nice ic() function to print an
expression and its value, but in a discussion about it I learned that a quick equivalent can
be achieved by using Python f-strings (available since Python 3.6) and appending “=” to the variable name:
It’s a visually interesting platformer/exploration game which does shine in several areas. The controls are tight and responsive, the art style is gorgeous and detailed, and the music is top-notch and really heightens the gaming experience.
It has an expansive world to explore and an incredibly interesting lore to discover along the way, and the enemies are varied and interesting for the most part.
It’s sad, though, that the developers chose to diminish the value of the positive aspects by being so hostile, unfair and disrespectful to players.
The lore (all 20k words of it if reports are to be believed) is inscrutable, hidden among disjoint dialog by (some impossible to find) NPCs, and I wonder why go through all the trouble of creating this if it’s not going to be discoverable in a way that can be pieced together within the game.
The player is never truly rewarded by honing their skill and gathering achievements – weapon and spell upgrades are few and far between and the increases in power are not all that impressive (sure the final nail upgrade is 4x more powerful than the basic one, but it still does only 21 damage against late-level enemies having more than 1000 hit points), and a lot of the charms are so limited as to be basically useless (hiveblood only restores the most-recently-lost mask, an affront to auto-regeneration in any other metroidvania -really only useful for platforming sections such as the white palace). Almost feels like the devs begrudgingly give upgrades, and some only when the plot demands it to progress.
To further this point, upgrades are somewhat pointless given some enemies and bosses that actually gain hit points according to the nail upgrade level the player has achieved. This is almost a slap in the face, why would I bother upgrading the nail if it’s only going to make enemies harder? and it kind of negates the benefit of upgrades, it’s again the developers saying “why should the player beat our game?” (which is indeed the entire point – you can produce an unbeatable game by simply killing the player at the very beginning but then nobody would ever play that).
Details like losing all your money when dying (“don’t fret it, in the late game you’ll have tons of money and nothing to spend it on”, they say – if that’s the case then why not let the player keep the money on death, if it’s not such a big deal?) or enemies re-spawning when the player rests on a bench (the reasoning is probably along the lines of “if he gets to regenerate, so should enemies”) further point to the developers coding the game to challenge themselves, and not to provide the player with a fun, rewarding experience, and rather a punishing, frustrating one.
Exploring is the most interesting part of the game but it’s hindered by ridiculously difficult bosses. “git gud” and all but they are a horrid roadblock to less-proficient players who might not have the time, devotion and reflexes to learn and beat the attack patterns. Three bosses (Hornet, Traitor Lord, Radiance) took me a full week each of trying and trying until I managed to beat them, definitely far beyond the patience of most players.
Yet I persevered and did finish the game, diligently gathering all the achievements needed for the “true ending”. My final reward? A lame 30-second cinematic which explains nothing, gives no closure and is just as inscrutable as the rest of the game’s lore. Honestly it was not worth it.
I did end up with a feeling of accomplishment, but it was more a “I finally beat this sucker, good riddance” than a more positive and satisfying one. I can finally put this piece of crap down and devote my time to games which actually respect me and want me to play and have fun, not be a grueling experience.
“git gud” indeed – I sank 90 hours of time in this game, I got proficient enough to finish it – but it should be and feel like a game and be fun, it’s not a job and should not require honing your skill that much – I found I couldn’t make a lot of progress if I played at the end of the day when I’m relatively tired – a game that requires this level of training, attention and concentration doesn’t really feel like a game, and more like a job.
I’m quitting this job and going on to easier, greener pastures – and despite how gorgeous it looks, I’m not going to buy Silksong and give these guys more of my money and time.
We added a new device which can expose a connected USB drive via DLNA, internally it uses minidlna which uses SSDP for service discovery. For some strange reason that rendered my *existing* minidlna (hosted on a raspberry pi) invisible. When researching the problem, it looks like neighbor discovery (which didn’t happen before as there were no other devices) uses a multicast 239.0.0.0/8 address which my rpi was blocking due to reasons (only allows traffic via the local network and a vpn gateway). My theory is that the new minidlna device took over as “primary” and then couldn’t find other peers and so the old server wasn’t visible anymore. The solution was to allow the specific multicast address used by SSDP.
#!/bin/bash
iptables -F
#Tunnel interface
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A OUTPUT -o tun+ -j ACCEPT
#Localhost and local networks
iptables -A INPUT -s 127.0.0.0/16 -j ACCEPT
iptables -A OUTPUT -d 127.0.0.0/16 -j ACCEPT
iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
#multicast for minidlna/SSSP
iptables -I OUTPUT -d 239.255.255.250 -j ACCEPT
iptables -I INPUT -d 239.255.255.250 -j ACCEPT
#Allow VPN establishment, this is the port in the config's #remote
iptables -A OUTPUT -p udp --dport 1198 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp --sport 1198 -m state --state ESTABLISHED,RELATED -j ACCEPT
#Drop everything else
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
As Uber’s Jump electric bike offering arrives in Montreal, a very common sight starts appearing: Orange Jump bikes parked everywhere: in parks, on sidewalks, tied to private property or public structures, sometimes blocking the way for pedestrians.
Uber’s permit stipulates that bikes have to be parked in designated spots only; a “designated spot” is a bike rack, not any random pole or fence. Of course, users park where convenient, and of course, Uber always washes their hands from any responsibility by claiming “it’s the user’s responsibility to park bikes in the appropriate spot”. Yet, for all their billions of dollars and technology, they are unwilling to enforce in any way compliance with the permit the city has granted.
I say “unwilling” because it’s entirely feasible to use technology to ensure compliance. I gave this some thought and came up with at least 3 solutions in 5 minutes. The solutions use technologies that are well within Uber’s reach and areas of expertise. They could locate and identify the allowed parking spots and areas and disallow releasing a bike unless it’s properly parked, which can be done either by analyzing Google Street View imagery (using AI, with which Uber is quite adept), sending a human to actually note locations of valid parking structures, or using AI to identify common and likely parking spots, based on density and frequency of bikes parked nearby.
Interestingly, a much smaller company (Lime, the electric scooters) has also just arrived in Montreal, with similar restrictions as to where scooters can be parked. They came up with yet another solution: upon finishing a ride, one must take a picture of the scooter, showing it is correctly parked in a designated area, and upload it.
That very simple solution is easy and cheap to implement, and it keeps users honest while ensuring everyone complies with the conditions set by the city. Honesty, however, is something that escapes Uber; it’s been shown time and time again that they will do the bare minimum necessary, and sometimes not even that if they perceive that the level of enforcement will allow them to get away with just shifting blame to users.
In my opinion, the city should mandate that Uber implement measures to curb badly-parked bicycles, seize badly-parked bikes and impose hefty fines on each one that is found, and ultimately (because these measures will NOT make Uber relent), just rescind their permit. A predatory, disrespectful company like Uber should NOT be allowed to operate in our city.
I have a second hard disk mounted under /thepool, and I want to make “virtual disks” in there and be able to mount them on any of my virsh-defined virtual machines.
The root filesystem of the VM resides on a different storage pool (uvtool) on a fast SSD, but for bulk storage I don’t want to fill out the SSD with crap.
# Create the storage pool, under "/thepool" where the big disk is mountedvirsh pool-define-as disk-pool dir - - - - "/thepool/libvirt-pool/"virsh pool-build disk-pool
virsh pool-autostart disk-pool
virsh pool-start disk-pool
# CHeck it's therevirsh pool-list
# Create a volume inside the pool, qcow2 formatvirsh vol-create-as disk-pool juju-zfs-pool.qcow2 64G --format qcow2
# Attach it to the VMvirsh attach-disk juju /thepool/libvirt-pool/juju-zfs-pool.qcow2 vdc --persistent --subdriver=qcow2
# Now inside the vm, /dev/vdc exists and can be formatted/partitioned and mounted as normal
These mkv files have h.265 hevc video which my media player can’t read, so I’d like to convert only the video stream to h.264, while leaving all other streams (2 audio tracks in aac, 2 subtitle tracks) intact.