Another week of quarantined
programming, video games, and hitting f5 on economic news.
Investments
The
recent peak was a chance to sell most of my "is this a dip?" stock and ETF holdings for a modest profit. The glaring exception is oil, which is now both a headline and a punchline.
Oh well, it'll be back. This is what I get for not being a conscientious investor. Speaking of long term investments, bonds are fun and low maintenance. For the uninitiated,
here's everything I know about bonds, using etrade's terrible ui as a visual guide:
At least with etrade as a broker, you're looking at $1000-ish increments of investment. The
bonds themselves have a market value independent from their face value against which interest/coupon is paid. It seems like selling bonds requires advertising that you're willing to sell and letting the broker match you up with a buyer. I put out a sell feeler to see if I could make a tidy 10% on one investment and never heard back.
So scrolling up, for whatever reason people want to buy a 6.75% Centurylink bond but not so much a 7.10% Dell bond. I presume this is come combination of return (coupon/maturity) and risk - I stuck with companies I expected to remain in business (or acquired) through these troubling times. Anyway, they're better than 0.0000000001% interest or (in my opinion) even cash. That said, if the bond market were to tank you could be stuck with each holding until maturity. So interleaving maturity and having other investments is important.
Options
I'm squeamish about calls in this weird pumped market. I haven't dedicated the hours to work out some actual options trading strategies; without a copilot I'm convinced I'm going to do something wrong as soon as I add a leg. Still,
a few puts here and there gives me something to f5:
- DOW 09/18 $25p - SPY premiums are high right now and the bailouts seem directed at S&P companies, so I wanted to avoid those anyway. I should have gone with DIA or something more actively traded. Barcharts was a pretty good guide.
- IYR 09/18 $61p - based on the simple idea that the normal real estate cycle combined with unemployment combined with other economic impacts will hit real estate to an extent that isn't yet priced in.
- XHB 09/18 $24p - same deal but with homebuilding, including the fallout of idle time during quarantine.
If nothing else, the unlinked interplay between indexes and headlines has been funny to watch. But the 2020 news just keeps coming:
Axis & Allies, World War... 1(?)
In addition to a few concurrent
Wargear matches,
Jon is
remotely hosting Axis and Allies: 1914. The game is well-suited to tele-wargaming; it's long and deliberate and requires very little interaction from anyone but the attacker and dice roller.
The game itself is an interesting departure from the WWII editions, but maintains most of the core elements.
Same:
- Dice mechanics
- Turn stages/purchases
- Movement, for the most part
- Submerging submarines, battleship bombardment, reduced-range fighters
Different:
- Board, obviously, the territory is very different from the standard WWII layout
- To simulate trench warfare, attackers/defenders only roll once, so countries end up 'contested'
- Fighters claim air superiority and promote artillery
- Tanks and the United States only come into play round four, attacking tanks soak a point of damage for free
The combat was different enough that I had to modify my Anniversary Edition simulator to do tench warfare.
Memes and more
The Zoom era is upon us, I've been in chats, movie nights, and even played a revival of the 90s classic You Don't Know Jack. Other chat media is still around, of course.
I finally gave in and watched Rise of the Skywalker. I guess the good part was all the nostalgia and tearjerkers for movies that weren't this one - deceased characters, Luke's X-Wing, even Liam Neeson('s voice). The bad parts were - well - the plot is just a ho-hum scavenger hunt, the finale was written on the wall from the start, and it really didn't need a heavy-handed "
well the moral of the story is that friendships win wars against impossible odds". Oh and some time bending on par with GoT season seven.
Keras
Site meta
So I've steadily
built a code base for a variety of things to include this site. The project has included things like auto-thumbnailing and tag generation. My post-to-post workflow has been:
1. Dump media into a directory
2. Run a script that autogenerates a starter markdown file based on those images
3. Run a COTS tool to resize and compress graphics, once for screenshots and once for photos
4. Author the post
5. Run the markdown parser/page generator
Combining 2 and 3 wasn't too difficult once I
went through the legwork of looking up how to set jpg compression level. I took the opportunity to implement a border crop feature that was useful for removing some black bars from recent SotC screenshots. The final piece was automating the image resize policy. For the moment, it's based on hard-coded known sizes (e.g. 1920x1080 or a D700 sensor).
Classifying images as photos (resize) or screenshots (resize if > 1920x1080) seemed like a pretty standard application of Keras.
A brief sidetrack: Python and Keras suck
Well, not exactly. They're awesome and the best tool for the job, but
it's agonizing that no one in the Python community can make interoperability work. This is mostly a Keras/Tensorflow/PyTorch experience, and those admittedly are a more recent thing (but not *that* recent). In a more general sense, you need look no farther than the global agony of moving to Python 3 to see the impact of undercooked technologies.
Back to machine learning, after many, many hours of searching on every new warning or error, I found my golden combination of ML-related software:
imageio 2.6.1
Keras 2.3.1
Keras-Applications 1.0.8
Keras-Preprocessing 1.1.0
numpy 1.18.1
nvidia-ml-py3 7.352.0
opencv-python 4.1.2.30
pandas 1.0.3
Pillow 7.0.0
scikit-image 0.16.2
scikit-learn 0.22.1
scikit-umfpack 0.3.2
scipy 1.4.1
tensorboard 2.1.1
tensorflow 2.1.0
tensorflow-addons 0.8.3
tensorflow-datasets 2.1.0
tensorflow-estimator 2.1.0
tensorflow-gpu 2.1.0
tensorflow-gpu-estimator 2.1.0
tensorflow-metadata 0.21.1
tensorlayer 2.2.1
tf-slim 1.0
torch 1.4.0
torchvision 0.5.0
... all using Cuda 10.1 (not 10.2, that does not work). This worked for my existing code base and is reasonably up to date, so, lock it in.
With that settled, I downloaded about two dozen Keras/TF/Torch projects from Github, hoping to just run their example code. Ticking them off one-by-one, they all fell to one or more of the following:
- Python 2.x
- Linux only (okay, that's on me)
- Keras 1.x, sometimes even more restrictive
- Tensorflow 1.x, "
- Something wrong with the project itself, because they're mostly grad students mashing together a poorly-written adaptation of some published algorithm
I've spent hours upon hours slowly creeping toward a setup that works with my hardware and software,
reverting to a previous version is not something I want to do because everything else is going to have to change. A lot of these issues came back to Keras removing certain features that everyone used for 1.x projects. They're not superficial changes and the project authors have largely left their projects to be abandonware.
But
what about Docker?!? Nope, nope, nope. Not even considering this in a Windows environment trying to hook a web of interdependent machine learning libraries into a Nvidia/.NET framework that provides graphics acceleration.
So what was this rant?
I don't know, think harder about your API. Deprecated stuff can still function, so leave it in. When you shuffle stuff to supporting libraries, they shouldn't only be available on someone's personal web site. Build software for version x or newer.
About that classifier
Ah yes, so I'd been working with a 256x256 classifier on sizeable /photo and /screenshots libraries. It does some
convolutions and maxpools down to a reasonable 32x32 before flattening for classification to conceptually two classes (photo/screencap). It trained quickly and learned the training data with high accuracy.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv_256w_8sz_x16 (Conv2D) (None, 256, 256, 16) 3088
_________________________________________________________________
conv_256w_8sz_x12 (Conv2D) (None, 256, 256, 12) 12300
_________________________________________________________________
conv_256w_4sz_x12 (Conv2D) (None, 256, 256, 12) 2316
_________________________________________________________________
dropout_256w_0.1 (Dropout) (None, 256, 256, 12) 0
_________________________________________________________________
maxpool_256w_x2 (MaxPooling2 (None, 128, 128, 12) 0
_________________________________________________________________
conv_128.0w_4sz_x12 (Conv2D) (None, 128, 128, 12) 2316
_________________________________________________________________
conv_128.0w_2sz_x12 (Conv2D) (None, 128, 128, 12) 588
_________________________________________________________________
dropout_128.0w_0.1 (Dropout) (None, 128, 128, 12) 0
_________________________________________________________________
maxpool_128.0w_x2 (MaxPoolin (None, 64, 64, 12) 0
_________________________________________________________________
conv_64.0w_4sz_x12 (Conv2D) (None, 64, 64, 12) 2316
_________________________________________________________________
conv_64.0w_2sz_x12 (Conv2D) (None, 64, 64, 12) 588
_________________________________________________________________
dropout_64.0w_0.1 (Dropout) (None, 64, 64, 12) 0
_________________________________________________________________
maxpool_64.0w_x2 (MaxPooling (None, 32, 32, 12) 0
_________________________________________________________________
flatten (Flatten) (None, 12288) 0
_________________________________________________________________
output_x4 (Dense) (None, 4) 49156
=================================================================
Total params: 72,668
Trainable params: 72,668
Non-trainable params: 0
_________________________________________________________________
Validation accuracy
flattened around 60-70% though. I turned some knobs:
- Removed and re-added higher dropout rates.
- Randomly scaled inputs to some reasonable factor between 256 and the original size, then sampled patches of them.
- The normal translation/mirroring/noise stuff.
I was going to dig into hyperparameters and retry with batchnorm, but diverted to a new model based on the idea that a
seven convolutional layers is getting toward the feature recognition domain, and this isn't really what I want. I'm looking to characterize input based, perhaps, more on gradients than edges (maxpool bad?). I don't want the model to learn that human faces are generally photos and zombie faces are generally video games. I want it to see the grit of a photo, the depth of field of an SLR photo, the smooth rendering of a screenshot, or even its pixelation for older games.
Maybe a deep network does that anyway, just throw training at it. But it was worth
experimenting with a shallower network.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv_256w_8sz_x16 (Conv2D) (None, 86, 86, 128) 3584
_________________________________________________________________
batch_normalization (BatchNo (None, 86, 86, 128) 512
_________________________________________________________________
gaussian_noise (GaussianNois (None, 86, 86, 128) 0
_________________________________________________________________
conv2d (Conv2D) (None, 86, 86, 32) 4128
_________________________________________________________________
batch_normalization_1 (Batch (None, 86, 86, 32) 128
_________________________________________________________________
dropout (Dropout) (None, 86, 86, 32) 0
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 21, 21, 32) 0
_________________________________________________________________
flatten (Flatten) (None, 14112) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 14112) 0
_________________________________________________________________
dense (Dense) (None, 64) 903232
_________________________________________________________________
batch_normalization_2 (Batch (None, 64) 256
_________________________________________________________________
dropout_2 (Dropout) (None, 64) 0
_________________________________________________________________
output_x4 (Dense) (None, 4) 260
=================================================================
Total params: 912,100
Trainable params: 911,652
Non-trainable params: 448
_________________________________________________________________
Of course I turned a bunch of knobs (because wheeeeeee!). Strided input and a 4x max pool to get the many convolutional kernels down to a reasonable dense layer. Results: 60-70% accuracy. Blast.
Divinity
Mine and J's Divinity 2 characters finally departed Fort Joy. Fane has a neat shapeshifter helmet so he can blend in with all the lizardfolk.
The Red Prince does the tanking...
...
I mostly just cast blood rain whenever it's up. Particularly out of combat.
Anyway, the game is really good.
Guns, Love, and Tentacles mop up
Before jumping back into Divinity, we
finished up all of the GL&T side quests.
Could have used a raid boss, but I'll settle for the Nibblenomicon.
Here's a little
gallery/writeup on Shadow of the Colossus, the PS+ free update on the PS2 classic. In case anyone's considering a playthrough, I start with a short summary of the gameplay then - with callouts - progress to show each colossus (gameplay spoilers) and finally wrap up with the ending (plot spoilers).
SotC has a
fairly short playtime, which is mostly why I decided I could squeeze it in my scarce solo gaming time. There's replay value with time attack and possibly some secrets, however as we'll see that really isn't for me.
As I mentioned, it's an
update on a 20-year old title. SotC is what I'd call a 'tight' game - it doesn't sprawl in size or depth like Skyrim or Divinity - it gives the player a simple, direct experience. It's sort of like
The Last of Us but replaces character development and shooting with silent mystery and a sword. Both can be completed in under ten hours, both are on rails but don't feel like it.
Intro
The plot arrives lightly in the beginning and heavily after you fell the last colossus. The intro sequence shows our hero racing to a forbidden land to
ask a higher power to save his girl. That's it. It's a tale as old as Atari.
The diety promises to bring her back if the hero defeats sixteen colossi. From here until the end, it's all gameplay.
Mechanics
The gameplay is pretty straightfoward, but not easy. Foreach(colossus):
Your sword reflects sunlight (if present) toward the next colossus. This mechanic is pretty good; it's more atmospheric than a map marker, but
makes finding most colossi reasonably straightforward (pun intended).
Using your sword-compass, you ride Agro across a beautiful open world whose diameter is probably 10-15 minutes of continuous riding.
Agro is a well-animated, reliable steed who always answers your whistle and sticks around when things get dangerous. He does, however, like slowing down when you gently nudge the reigns to turn him. This isn't great on a map that is very open but has small obstacles scattered everywhere.
SotC only has bosses. The ride between colossi is just to let a little air out of the tires between battles.
Eventually you enter a colossus's domain. After a short intro sequence,
you must devise a way to fell the creature. That intro scene is actually quite important; if you fall off of something before you actually get to the colossus you're returned to the temple at the center of the map.
Each colossus must be stabbed a few times in one or more achilles heels. Since these heels are typically around their head, you must use
the game's main mechanic: climbing. In games that followed the original SotC release, climbing has been both a neat way to add map verticality and a horrible mechanic that slows gameplay and brings many, many insta-deaths. Climbing sequences in SotC are generally brief and rarely lethal, but they are somewhat clumsy. The clumisness is is derived from a few things:
- The controls are somewhat awkward (not very awkard, just somewhat).
- As you might imagine, you sometimes need to jump between moving objects (colossus limbs) using hold-then-leap. Combine that with a moving colossus and moving camera, I was clocking in at maybe 25% success rate.
- You have a grip meter (as you should) that the colossus will deplete by trying to buck you off. While the game thankfully never requires you to take the meter to its limit to accomplish something, you'll run it out simply by trying to ride the colossus long enough to get the maximum number of stabs in.
So what's the bottom line here?
Execution of the climbing mechanic is maybe a 7/10, even when gauged against modern games like Assassin's Creed and
Far Cry. The mechicanic enables the unique playstyle that SotC offers. It is, however, sometimes frustrating and not overwhelmingly gratifying.
Climbing the colossus is more than a matter of walking up to it and pressing X.
Each boss is unique and must be conquered in a different way using some combination of climbing, your weapons, the terrain, and its behavior. The strategy for each colossus can be subtle and require a gamefaq.
Each plunge of your sword takes the colossus's health down. He may toss you off or change the location of his weak spot. Eventually, he falls.
The colossi (gameplay spoilers)
Colossus 1
Colossus 2
Colossus 3
The third colossus was my first stumble. Either it hadn't been explained or I ignored the fact that holding X to vault was a thing. Tapping it put me in the water under the left stairway until I looked it up online.
Colossus 4
Colossus 5
The first winged colossus was a fun ride. Wind resistance came into play but wasn't OP.
Colossus 6
Colossus 7
A water colossus, whaaa?
Colossus 8
The first AoE attack colossus got me a couple times.
Colossus 9
Turtle colossus really didn't like walking over the geysers. This wasn't a short battle.
Colossus 10
The
sandworm battle felt like it could have been frustrating but actually went very well. Agro did a good job keeping pace and letting me aim.
Colossus 11
Colossus eleven had me close to ragequitting. I got the dude to charge the fire pedestals, pretty sure I was on the right track.
The faq told me I needed to pick up a torch and wave it at him. This was weird, I'd never picked anything up. I walked over what looked like the torch and mashed various possible buttons. I put away my sword. Nothing. The faq assured me circle would execute the pick up.
I eventually cycled through the control scheme and found that
the 'classic' controls had an action button not present in the default 'modern' mappings. Wow.
With that worked out, I scared the colossus off the cliff and exposed his weak point...
... he promptly rammed me through a hole in the map.
Colossus 12
Twelve had some difficult jumps but wasn't nearly as frustrating.
Colossus 13
Colossus 14
Colossus 15
Fifteen's unique mechanic of stomping a ramp into the terrain eluded me until I looked it up.
Colossus 16
I hoped for a challenge with sixteen and I got it.
Dodging fireballs wasn't too bad, my own impatience had me not timing them well.
The climb to his head took me at least a dozen frustrating attempts. The grab-lunges and camera angles made it very tough. Luckily once I had reached his head I didn't fall off and get fireballed.
Scenery
While mechanically it's just filler, the scenery of SotC makes the journey to each colossus rather pleasant. The redwoods, especially.
Ending (plot spoilers)
Something seemed a little off about the
black smoke that overtakes you after defeating each colossus. Black smoke is rarely good.
In a rare camera cut to other people, some knights seem to have taken notice.
I was more fond of Agro than the girl based on screen time and utility. This was the most heartbreaking moment of the game.
Eventually things come to a head as the knight dudes arrive in the forbidden land.
Oh yeah, I guess the diety was playing me...
... to create a colossus voltron. But
the knights prevail and seal our hero to the temple lake thing.
Leaving the reanimation wish to, for some reason, still be fulfilled and a limping Agro to happily return.
Quarantine
The uncertainity of
two weeks ago has given way to
various stages of compulsory home isolation.
Our March
GBES event was bookended with the staff telling us that breweries and dine-in would be shut down statewide starting the following day.
Still, for the scale of the change, everyone's seemed to carry on in a reasonably professional manner.
Friend groups have organized
video chat kickbacks, including a screening of
Velocipastor.
The meta
The national consciousness has been pretty well conveyed in the memes.
In the early days, the question on everyone's mind was,
"is this going to actually affect me?"
Then there was brief period where companies large and small would use covid as an excuse to send marketing emails.
Everone works from home now.
The timeline looks more dubious every day. Still, I'm not sure anyone's missed sports *that* much.
Acceptance is one of the stages, right?
Guns, Love, and Tentacles
In a couple sessions, me and J finished a playthrough of the core content of
the new BL3 DLC. Even managed to do it on Mayhem 4 without too much trouble.
It's a huge homage to Lovecraft, from the story to the dialogue to the locations (and their names).
So this is one of the more moody and atmospheric BL experiences. It's
a nice contrast to the comedic casino heist and the obnoxious main game antagnoists. It's still Borderlands, though, so there's ample humor and over-the-top characters.
Unfortunately
I have a hard time killing Kritchies.
My Fl4k build is focused on critical damage (duh) with Dominate as the other top tier. With Leave No Trace (Critical hits may refund one round to the magazine) and new(?) ARs that have the same effect, I have
a few weapon options that behave almost like Infinity Pistols.
One of the Gaige quest rewards is a class mod that buffs damage with hit stacks, this works really well with the rest of the build.
Divinity: Original Sin 2
While waiting for the BL3 DLC to drop, J and I
started a Divinity 2 playthrough.
Luckily there are tentacles in this one, too.
A few hours in, the game feels quite a bit like the first one:
very deep and detailed with tons of story and lore.
The combat is still very cerebral. I felt that positioning was practically meaningless in the last game, not a ton has changed. Still, attacks and specials and elements make for a great combat system. Characters have
physical and magic armor that seems to significantly reduce the possibility of status effects, meaning basic attacks are back in style, at least til their armor has been depleted.
I went Fane, J went Red Prince. The motliest of crews.
Escape from Tarkov
The lolbaters/pubg squad is giving the indie Russian shooter Escape from Tarkov a go.
The gameplay is like this (with squads up to five):
- There is a collection of maps that you can select to play on.
- You play as either a Scav(enger) or a PMC (Private Military Corporation) unit, you can select either role each time you launch a raid.
- Scavs start with basic equipment and need to reach an extract point, optionally killing and looting along the way. If you die, nbd, but there is a ~20 minute cooldown between scav runs.
- PMCs start with equipment your persistent character owns. If you die, you lose it (and another scav or PMC might pick it up) and suffer injuries that cost money to heal. PMCs can theoretically go into scenarios with a huge advantage (scopes and suppressors and nades), but new players sometimes have to roll with a pistol and scavenge. So it's basically the time-tested cat and mouse formula thats like an inverse battle royale.
- Maps have AI-controlled scavs that are friendly to player scavs (unless you attack them) and hostile to PMCs. They are potential loot sources for either player class, but aren't easy kills when you have a pistol and no armor. As a scav, I haven't tried using them for a tactical advantage, but their firefights with PMCs are good for finding/avoiding trouble as you traverse the map.
It's a realism-oriented shooter. Without armor you can be dropped in a shot or two and injuries like limb damage and bleeding out are a thing. There are magical heals, but they don't work if you're severely injured. The inventory system is extensive and not intuitive - well,
it makes sense that the reload button doesn't work if the next mag is in your backpack, it's just not something you normally think about.
When I first played pubg I found the lack of creature comforts challenging. In EFT you don't have ally callouts or a map or really any standard video game training wheels.
The try-hard element can be punishing during the action, at least in
inventory management you have all the time in the world to figure out which mods work with which guns. Could it be color coded or sorted? Yes. Would that make you feel less like a badass? I guess.
As you can see from the lower grid in the screencap above, weapons are very customizable. Having looted a few fully-kitted PMC loadouts (great feeling, btw), I can say that
the difference in a optics and recoil afforded by mods is a massive advantage - the cat's claws, as it were.
Iron sights are usable on the Mosin, but other than that, scavs and destitute PMCs are at a huge disadvantage in ranged combat. Also, not having body armor, scavs and destitute PMCs are at a huge disadvantage in close quarter combat.
Asymmetry is awesome, but the game is unbalanced. Sometimes you'll get lucky, drop a PMC, and have good gear until you are next killed. You can also bring a squad and hope to find solo opponents.
Combat engagements are very short; it feels like the first time I played Rainbow 6 after years of Goldeneye, Perfect Dark, Turok, etc.
Gear can be obtained in raids, but
there are also a few vendors with neat, criminal underground identities. I think there are three currencies in the game - rubles, dollars, and bitcoin - only one of which can be exchanged for a particular item. Dealers also provide quests (kill/find x of y), which is a lightweight way to have sustaining, orthongal objectives/rewards.
In addition to the independent currencies, many items can only be traded for using the random junk you find when inspecting containers scattered around each map. This can be pretty frustrating, e.g. I had my eyes on
a grenade build in an attempt to overcome my optics/armor disadvantage. With nades I could choose to fight in buildings and hope for a more even playing field. Turns out grenades must be bartered for with zippos or batteries. Once I do collect enough of these items, I hope it's an unlock-for-purchase mechanic because there's no way I'll collect zippos and batteries at the rate I expend or lose grenades.
You have a hideout that provides the
passive rewards for grinding - healing of your injured PMC, a workbench, bitcoin mining, etc. Twenty minutes to produce toilet paper at the lav?!? Okay one: too soon. Second: that doesn't even make sense. And third: this game mechanic should only be used in free-to-play games as away to get people to buy speedboosters.
The verdict is still out.
Strengths:
- It's new
- Lots of gear, customizability, and unlockables
- Grittiness makes for a rewarding experience
- NPCs don't feel like cheap kills, but are essential to giving new players a chance
Weaknesses:
- Matchmaking times
- Matchmaking
- Combat could become frustrating
- The grind may be too much
- I have a sinking suspicion that there's an aimbot problem
Three Houses/Crimson Flower/madness (midgame spoilers)
When last we spoke,
Byleth had accompanied Edelgard to the imperial capital because the Church of Seiros doesn't set boundaries for their faculty.
Now he's protected her and pissed off the church.
I expected a difficult playthrough, with a
steep xp climb and every unit susceptible to double attack. I got that, but I also got different plotline with new battle scenarios (on the same map set).
A few notes:
Impregnable Wall (units only deal/recieve 1 dmg for a turn) has been critical. Last playthrough it was a way to defeat the Dark Knight early on, now
having two units (Batallion carry-over) able to put up a wall is irreplaceable. The frequency of enemies that can overcome this with Pass has lessened in the mid-game.
Lysithea is a monster. In fact, for whatever reason
physical attacks seem massively nerfed in this playthrough.
I'm sticking to
the plan and
making flyers out of everyone except tanks and mages. The class-based speed gains, high movement unaffected by terrain, and canto aspects of these characters has been necessary to keep them out of harm's way - that is, most of my units are susceptible to being one-shotted since there's no way to do main quest battles at anything better than enemy level-6. If the level disparity decreases, I may flex my flyers into other classes.