Wednesday, October 20, 2021

Minute Control Over Dynamics

My new alto recorder came in today. As stated in yesterday's entry, it is the Yamaha YRA-302BIII.

As expected, it definitely gave me much finer control over the tone, with soft dynamics working much better than my previous Yamaha YRA-28BIII. I also did my usual thing of weighing it, and it weighed in at 196.0±0.1 g, compared to the 211.1±0.1 g that is the YRA-28BIII. So, despite it having less mass, it plays much better, which suggests that for woodwind instruments, geometry plays the larger role of determining the quality of the tone that comes out of it.

That said though, I really cannot bring myself to getting a wood version of the recorder, or of any instrument that I don't play as often as my dizi. While wood and its allies are traditional woodwind instrument materials, their dimensional stability has always been something to worry greatly overr. Unlike sufficiently dense plastic and metal, wood will change its shape due to the combined effects of both heat and humidity. The geometry of woodwind instruments' air column bore is extremely sensitive to these minute changes, so they really require more care to ensure that their timbre does not get overly affected by it.

``But MT, you play the dizi---it's wood-like. Isn't that contradictory?''

Ah, but I play the dizi more often than I play some of my other alternate instruments, and so I am more aware of the changes when they occur. Also, unlike the western instruments, the dizi does not have as much ``work'' done on them that can exacerbate any of these ambient environment issues. What I mean is, dizi do not have screw holes to mount posts on (compare with piccolo, and clarinet), nor do they have mixed woods of different behaviour under the same ambient conditions (compare with the recorder where the block is often made of a different wood compared to the rest of the instrument). They do have a stopper that used to be cork and thus potentially problematic, but most modern-made dizi use a synthetic plastic-rubber one instead. The joint separating the head joint from the body is another potential source of issues, but it tends to be problematic only if is sufficiently cold and dry.

So, for instruments that I don't play as often, I'm more likely to look for something that is more consistent in its dimensions. And high density plastics tend to fit this role very well. Sure, it might lose out a little on the visual aesthetics, but come on, it's a musical instrument---how it sounds is more important than how it looks. And since these instruments aren't played as often as my dizi, cost can become a factor to consider too. The cost we are talking about is more than just the initial sunk cost of purchase---it also includes the upkeep cost as well. A hard-wearing high density plastic music instrument built with the right geometry can go pretty far without much upkeep beyond the basics, and that is usually good enough.

I'm up to p500/803 of Mathematics for Engineers (2nd Edition), and despite the author's name of Dull, is anything but. I might want to take a break from reading tomorrow and just play something, either a first person shooter like Serious Sam 3: BFE, or restarting Cthulhu Saves the World; I don't think that I have actually completed that game. I do remember that I liked the humour in it though.

Maybe I'll work a little on LED2-20 on getting that parallax background working. I am starting to think that splitting into vertical strips isn't sufficient... parallax scrolling should also include some minor up/down movements as well, which means that the far background should have dimensions that are both wider and higher than the width and height of the screen respectively. My current partial bitmap code limits the bitmaps in place to being no more than 320×200, which was why I decided to decompose the background image into vertical strips. But needing this vertical parallax as well makes me think that maybe I need to further sub-divide each vertical strip into two to ensure that I don't break anything.

Eh, we'll see.

That's all I want to write for now. Till the next update then.

Tuesday, October 19, 2021

Manual for Recorder Fingering Patterns

I find myself getting more interested in recorders. They are actually more interesting than what our school day mandatory lessons might suggest because they actually have a pretty wide range nearly 3 octaves (kinda like a concert flute), though the more standard range is closer to being 2+ octaves (2 octaves and a minor second). This is very close to that of the dizi actually---dizi has a standard range of 2 octaves and a second, with an option to go up to 2 octaves and a fourth. There are some subtle differences still of course, since in terms of correspondence of fingering patterns, the recorder's bell tone starts one major second lower than the dizi, and while the recorder does overblow in octaves, the addition of the thumb hole on the recorder means that the lower half of the second instrument octave has some funky fingering patterns to begin with.

Getting to the upper half of the second instrument octave on the recorder is super funky. They use a lot of variations from the ``standard'' simple flute fingering pattern of XXO-XXO to choose the higher harmonics accordingly to get the right pitch (see this old post for examples of the fingering). It is hard to do that on a 6-hole dizi for two reasons: the lack of a thumb hole makes selecting that higher harmonic through forcing an anti-node from pure embouchure control harder, and the holes on the dizi are much larger than that of the recorder while having a larger inner bore diameter, characteristics that make it less sensitive than the recorder in using right-hand hole covering to force different standing wave modes. But having direct embouchure control on the dizi does make up for the differences---the recorder cannot be coaxed to overblow very high harmonics due to the fixed angle set by the windway and labium.

The recorder does have a more dainty feel to it compared to the one-key flute (and it definitely is much more dainty than the dizi, though it is possible to play the dizi that way with enough training).

I spent some time today putting together an easier table to reference the fingering patterns (regular and minor/major second trills) that the woodwind fingering guide has. There's nothing wrong with that website, it's just that it is not that easy to look at the fingering patterns at a glance. I have done the same for the concert flute as well; unfortunately I cannot post them out due to various limitations listed on the main page itself since I do use the images that the site uses itself. Compare this to the one-key flute fingering chart, and the generic saxophone fingering chart.

Anyway, I raised this point because I'm expecting a delivery tomorrow for an updated alto recorder. Specifically, the YRA-302BIII. I already have the YRA-28BIII from 9 years ago, and it had been one of the old ``work horse'' recorders that I enjoy playing. Now though, amidst all the other recorders that I have, the YRA-28BIII felt a little lacklustre as compared to all the other 300-series recorders from Yamaha. It's about that windway---the other recorders that I have use a slightly curved one, and it has an appreciable effect on the amount of control that I can apply on the instrument. The YRA-28BIII just felt very flat in tone; it didn't seem to want to respond to nuances. At some point, when I was trying to play softer, the sound outright died instead of maintaining itself at the lower dynamics. I'm expecting that the YRA-302BIII will perform much better on that.

It's also a way of testing the Yamaha e-shop. Unfortunately, there really is nothing else from Yamaha that I would like to get, save for their pianica. But that involves a keyboard... and I'm a little less inclined to do so. The rest of the [woodwind] stuff, I can get them from MusicGear Singapore, and with good service as well.

------

In retro-programming land, I figured out the format that QuickBASIC stores its bitmaps in 16-colour land. The basic layout is quite messy---see this schematic to understand the actual memory-mapping used for the hardware. The abstraction here is that the 16-colour is broken down into its 4 bits, with each bit occupying one ``bit plane''. QuickBASIC stores the bitmap in row-major order, with each row comprising a byte-aligned bitmap for each plane. The bytes little-endian order, while the bits are big-endian order (as explained in the schematic). So, to write one pixel colour into the bitmap, I would have to access four different bytes and use bit-operations to set the correct bit. It's horrible, and it sucks, but it was needed because it was designed to conform to what the hardware was capable of. Figuring out the format is important because I needed some way to do pixel perfect collision---dumping it to screen and iterating through what was on-screen felt very wasteful to me. Having in-memory bitmaps that I can operate on also expands options for when I need them, like extracting sub-bitmaps from existing bitmaps/hybrid bitmaps. I think of it as a way to support things like masked bitmapped versions of fonts to allow the background to show through without having to manually create and maintain 256 separate hybrid bitmap arrays (urgh). Potentially, it can be used to handle frame-animations for individual sprites, but that will not be a high priority for now because I don't know how much memory I will end up with.

I also revamped the memory-related parts that I was using for LED2-20. The old method that I was using had an error in it---I was advancing the offsets by one [byte] each time, and when it hit 65536, I rolled it over back to 0 and incremented the segment. It was wrong because of the translation from the segment:offset to the 20-bit physical address was based on segment×16+offset. This meant that if I did what I did, I would end up going back to some previously seen memory location to recopy, which was wrong.

The correct way was to advance along the actual 20-bit physical address to make the copy. However, there was no way within QuickBASIC to walk through the memory that way---it had to be reduced back to some segment to be set by DEF SEG before the relevant PEEK/POKE can be done. And so there had to be some translation in between these two. I haven't benchmarked if this method was fast enough, but at least it would not be the part that breaks if/when I decide to use the ``huge array'' option in QuickBASIC which allowed arrays to break the 64KiB size barrier.

I also have enough machinery to start generating the background images needed for that parallax effect. For efficiency reasons, I'll probably end up storing them as vertical strips. But before I could do it though, I had to think about how the UI should be like; in LED2, the play area was about 320×176, with two lines at the top and one at the bottom used to convey game information. I was thinking that I would use the full screen, with UI elements ``floating'' on top with the background showing through. I haven't done up thumbnail sketches yet, but I do have a vague idea of what I want. Think of how (say) Bayonetta, Dark Souls and other modern action RPG's UI elements---I think I'd like to re-create that, but in QuickBASIC.

Anyway, that's about all I want to talk about for now. Till the next update, I suppose.

Monday, October 18, 2021

Machines as Masters?

Let's talk a bit about the ``recent'' craze over artificial intelligence techniques that revolve around the use of neural networks. Neural networks isn't exactly a new thing, in fact, it was one of the core ideas of artificial intelligence that were explored from the 1940s onwards. The Wikipedia article that I linked to probably can give a better summary than what I care to do here, so I'm not even going to attempt to do so. What I want to do is to disabuse the hyper-optimism that artificial intelligence based on neural networks (or other data-trained programs really) is the Final Solution of all things involving humans. This line of thought came about during one of the debates that I was having before with someone who told me in my face that I was too much of a theoretician in nature to not see the usefulness of what neural networks can bring, while I was pointing out the sheer recklessness that we are using these tools without proper understanding of its limitations in the name of Capitalism.

The idea of creating a device that can automate decision making is a consequence of our highly successful automation of physical processes as seen in the many electro-mechanical machines. In many ways, boolean logic is applied to measurement based ``features'' (to borrow from machine learning jargon) which results in particular actions stemming from fulfilling certain conditions. A crude example of such automated decision systems as used in the automation of our physical processes can be seen from ladder logic and its cousins in the form of micro-controller logic. In many ways, much of the menial decision-making has been automated already in the form of programs---the world of artificial intelligence is already here even without the use of technology like neural networks.

The key benefit of such program-based artificial intelligence is that almost all outcomes that arise from the execution of the program can eventually be back-traced as a reasoning path through the program itself, with the source code of the program acting as its own documentation of the features that it was examining, and how it chose to combine the features to arrive at a decision. This ability to trace reasoning paths through a program from its outcome is part of what ``explainability'' means. In the sense of defending decisions (or rather, actions that result from a decision) in human societies, having such a laid out sequence of antecedents makes it easier to bring about debate on the correctness/validity, since all who are interested can examine the antecedents and state if they agree with the feature, the value of the feature at the time of the evaluation, or even the correctness of the combination of the features that spark off a branch in the execution path.

Assuming no exceptions or crashes of the program, all outcomes that it produces must come from at least one execution path through its program logic. This level of certainty combined with the direct correspondence nature of feature and outcome the execution path can inspire trust in the program's correctness, as well as allowing people to decide together how to fix it if the program outcome for a specific context is not acceptable. This is a good thing, because as human societies evolve over time, their needs and requirements change, and the associated programs may need to have their reasoning checked against the updated expectations, and if that is lacking, must be fixed accordingly to fulfil the correctness of the automated decision making. More importantly, the error of a single outcome can be used to correct the program.

Now let's go back to the neural network and be extension, other computer programs that require training in order to achieve their purpose. These techniques exist for the reason that the problem space that they are used in are either:
  1. Not well understood due to too many inter-relating variables; or
  2. May be understood somewhat in abstraction, but face a steep effort wall in converting that abstraction into the boolean logic form that digital micro-processors can handle.
As humans, we tend to use consensus as a means of determining correctness, and a consensus is often obtained through structured empiricism (scientific method). So a logical extension of that reasoning process when faced with problem spaces of such nature is to try and get as much data as it is possible and ``make sense'' out of it.

There are some catches though:
  1. Data are not created equal: it's the amount of information relative to the outcome that it contains that is critical. If I want to know if tomorrow is likely to rain, knowing that there exists spotted dogs does not help me.
  2. Representation is the cornerstone of all intelligence. As humans, we cheat a little since we already have some built-in representations that we axiomatically take for granted---machines are dumb enough that we need to explicitly define it for them. It's easy to go overboard too---see the curse of dimensionality. ``Dimensionality'' here refers to each feature that we introduce to our model/program.
Much of the work [in machine learning] has been to deal with these two catches---it is important work because helps to establish the baseline correctness of the approach. So all the different neural network architectures including the number of levels, types of units, units per level, connection schemata, regularisation, ensemble learning protocols and the like are to address these two major catches. Getting these right is more art than science for now, but who knows when that will be made rigorous enough that we can predict performance before doing any training/validation.

There is a related problem from trying to solve these two big catches: I call it the surjection problem. Put simply, it is usually the case that the number of unique input to the neural network far exceeds the number of unique outcomes that we want. By the pigeonhole principle, this means that there will exist some specific outcome that will have more than one unique input that can reach it. This is usually not a problem because we assume that the input to the neural network is sufficiently biased towards ``what is possible in the real world'' that the neural network will therefore ``only be used in possible real world situations''. We gain some confidence about this through the data collection protocol that is used to train the model/program.

So, where is the disabusement?

Disabusement #1: Neural networks are fallible, and therefore we need oversight when we choose to use them as a tool.  Neural networks are fallible for the reason of the ``surjection problem'' that I raised earlier. The attack idea is like this: let's say I want a specific outcome from a decision process that is made up of the neural network. All I need to do then is to find some input that I can shove into the neural network to get that outcome. This attack can work because neural networks are surjective in nature, and more importantly, are not designed to be collision resistant because they were designed to achieve the right outcome given ``possible [in the real world]'' input and not to exclude any outcome given ``impossible [in the real world]'' input (more specifically, the behaviour of the neural network when fed with ``impossible'' input is not explicitly tested). There is a practical reason for this: the number of unique ``possible'' input is generally tractable compared with the number of unique ``impossible'' input.

Sounds impossible? Think again. These attacks are going to be more sophisticated over time as more neural networks play larger roles in decision making processes that matter. It may not be against facial recognition next time; it could be using the small hijacking of communicated data to confuse the neural network controlling infrastructure, or something more coordinated and nefarious that attacks entire economies---the possibilities for mischief are endless. In fact, it can get much worse quickly because there is a high chance that these neural networks will converge to a few trained ``super'' neural networks that everyone uses [in a service model] because training neural networks requires stupid amounts of [relevant] data and computational power that only the a few big players have, making such attacks increasingly profitable from the return of investment of effort perspective. An example of such a ``super'' neural network that can be a basis for downstream use is GPT-3.

Not terrified enough? What if we tie the human institutions of punishment to the outcome of these neural networks? What if one is automatically charged of a crime because the neural network misidentified your profile picture from the CCTV? What if the justification for the use of these automated tools with no oversight prior to taking action on final outcome is the need to deal with the increased transaction/population density/costs of deploying people to look out? Will you want to live in such a world?

Disabusement #2: Even if we have oversight, correcting the neural network so that its outcome conforms with our [society's] understanding of correctness requires a Herculean effort akin to tearing down what was already built completely and rebuild it.  The strength of the neural network is also its chief downfall when it comes to correction: since the behaviour of the neural network is largely dependent on the quality of the information from the input data, any correction that is needed from the oversight requires providing additional data that has the information relevant to the correction needed to cause the neural network to change in behaviour. One might argue that there are still various hyperparameters that can be tweaked to tune the behaviour of the neural network, but the correlation between such tweaks as compared to the oversight-determined correction is sketchy at best.

Thus, training (and validating) with new data containing information relevant to the correction required is still the better approach. Now, whether it requires a complete tear down and re-training of the neural network depends on the chosen training protocol, but my gut says that the oversight is likely to be less convinced with a ``patching'' approach using the already trained neural network as compared to a re-train ``from scratch''. Part of the reason is that there is an ontological disconnect between how the neural network works and how it is trained---it is easier to gain a peace of mind to start ``with a clean slate'' on something that is not easy understand than to worry if the new data provided has indeed corrected the behaviour of the neural network truly, or if it was just part of an overfitting phase that would immediately fail when the next instance of the input of a ``problematic type'' arrives.

Sadly, I don't think that we have the right theory now to explain any of these things. A good theory on the characteristics of how much data is required to perform certain types of correction can go a long way towards making oversight and correction of neural networks as natural as fixing a broken regular program because of a wrong antecedent.

As an added bonus somewhat tangential to the gathering of data to train such neural networks, it is apparently possible to derive a [good enough] approximation of the individual data used to train the neural network (actual paper). Still think that you have ``nothing to hide'' and therefore that little bit of information you feed into the data-dredge is safe?

So where does this leave us? Should we abandon using neural networks in Real Life then? No, I didn't claim that---I claimed that we should not be hyper-optimistic that neural networks can completely replace humans in decision making and be the Final Solution. Even in electro-mechnical automation we still see operators being present to keep an eye out on things despite those systems having decades of good performance data, what more about neural networks?

Legislation must make an effort to keep up, and we must bend neural networks to conform to human ethics, and not bend human ethics to conform to neural networks. Even if this means reduction in the efficiency in the neural network (for whatever definition of efficiency), it must be done.

Neural networks (and their allies) are powerful tools, but they should be treated as powerful tools and not as masters over us. Even the most powerful tool can cause a serious amount of damage when misused, and allowing neural networks to operate completely autonomously for ``big decisions'' that intersect with rules/norms/laws of human society is just an invitation for trouble at all levels, no matter what socio-economic class one is from.

After all (from Bill Vaughan):
To err is human, to really foul things up requires a computer.
Till the next update.

Sunday, October 17, 2021

Mending Auto-sorter & Lenna

An early-ish update for today: I managed to figure out a fix for the item auto-sorter overflow handler in Minecraft. Consider the following schematics for the redstone filter circuit I am using (reproduced from here):
Main reason for using this is the compactness in the layout, and the relatively few items that need to be stored in the filter hopper (R1C4), but that aside, look at the hopper in R2C4. When that hopper gets completely full, it transmits a signal strength of 15 through the block at R2C3, which eventually messes up the comparator signal at R1C3, leading to a shut down. That's what it means by being ``not overflow protected'', a feature tha I didn't realise until I started to have to worry about this.

My solution is to put a solid block at R1C5 with a switch, which effectively blocks the filter from working through locking it with a redstone signal. This means that when the object of the same type passes from above (the hopper chain not pictured at R0C4), it will not be pulled by the filter hopper at R1C4, and will merrily continue on to get to the other auto-sorter which filters out excess things that I want to send to the incinerator. The item generation rate of my mob farm (and bamboo farm) isn't great enough that I don't have the time to manually set that switch, and so this solution is good enough. With that implemented, I promptly demolished that branching hopper train that I built for the bamboo farm.

The next highest rate of item generation is the sugar cane farm, and the problem with that was that it fed into its storage system directly as opposed to going through the main item bus. Space in the warehouse portion of the mob farm was really tight, and I ended up building a dual-switch version of the shunt I originally implemented for the bamboo farm. It works well too. Wonderful.

------

I mentioned earlier about thinking about how to generate/handle the far parallax background, and talked about how I would use Pillow to generate it. Well, I put together a hastily written program in Python3 that generated something that could be plotted in QuickBASIC using the default colour palette. Here's a rendition of the infamous Lenna in SCREEN 7 with EGA 16 colours:
Overkill? Maybe. Remember, the idea here isn't to go full caveman mode, but to use the retro-technology to build the actual game that will be LED2-20 while applying the knowledge that I have gained over the past 20 or so years. If the assets can be generated using other more effective means, then it would be silly not to do so, since it does fall into the whole ``knowledge gained over the past 20 years'' category. I draw the line at [programming] language translation though, so I won't be doing things like writing LED2-20 in QB64 or FreeBASIC or even some flavour of C/C++ and back-translating it to QuickBASIC.

The game itself will be written in QuickBASIC, and potentially compiled to run in DOSBox as a 16-bit program. Now whether it will run well under 80286 is not part of the equation---I'm not willing to go that far, because it will mean bringing in more forbidden techniques of a bygone era (hello MASM my old friend) at which case I might as well just write it for a modern system in the first place. Any other tools that I use that fall outside of old school MS-DOS of the day are not part of the ``retro'' limitation that I am setting for myself.

That's about it for now. Till the next update.

Saturday, October 16, 2021

Mindsad

Ever heard of bacon bak kwa? Well now you have---that was dinner. I bought 300 g of it some days back to share with my parents, and I just finished the last slice for dinner today.

Well, part of dinner. The other part is a nice Jack Daniel's on the rocks. I know that I said that I had drained off the hard liquor I have, but I still had a bunch of small bottles of heavy stuff lying around, and today felt like the day to break open one of them.

I felt rotten, that's why I was in a drinking sort of mood. The reason of the rottenness feeling is that gut-punch one feels when one realises that the future is really quite bleak if one wants to stand by one's principles. Nothing remains untainted by egoism and its associated consequences. If I really wanted to stick to my principles, I would probably not work ever again.

Hmmmmmmmm... tempting.

But anyway, since the last update, I fixed an issue that I had with the FilePak that I didn't talk about---the inability to store STRING variables. I hacked a string-to-integer-array subroutine to do the save, but it had two issues: it doubled the amount of memory needed, and it made all string data be even lengthed, whether or not they were to begin with.

The solution, as it turned out, was from reading the documentation. All STRING data is stored in the DGROUP segment of the MS-DOS segment convention. And there exists a function that I've never used before, SADD(), that returns the offset of the passed string in it. With that, it was easy enough to whip up a fix to handle STRING directly.

Relatedly, there exists another function, SSEG() in Microsoft BASIC Professional Development System (or what we would call QBX from the IDE or PDS 7.1) exists that returns the segment for a STRING. If, by any chance, I decided to use the PDS 7.1 compiler, I might want to take that into account. It's not likely though---PDS 7.1 does not offer enough useful features for LED2-20 to be worth considering. The ON LOCAL ERROR GOTO ... construct is quite tempting, but ultimately insufficient to justify changing the toolchain to something that heavy. The next thing on my list might be to think about how to handle the far parallax background, or more specifically, how to generate them. The idea here is to start with some wide background image, convert it to the 16-colour EGA palette, cut them up into individual vertical strips, and then use those strips to simulate the slow parallax movement of the background. That ``convert it to the 16-colour EGA palette'' also includes scaling it to 200 px height among other things, and it might require me to break out some other modern tool to get it done---I really don't see a need to write my own damn image parser in QuickBASIC when I can do it easily with Pillow.

I also re-ran the SPEEDTST.COM with no load using the ``long'' option, and came up with 3.7M parrots under maximum single-core speed (corresponding to 5.0 GHz clockspeed with no other load) against 26k parrots using the default 3000 cycles setting.

That's a theoretical multiplier of about 142×, about 20% to 48% faster than when I had VLC running at 2× replay speed and Minecraft running in the background. Nearly 38 years of improvement in single-core processor efficiency, and we're hitting 142× as compared to the 80286 then, or roughly 13% improvement year-on-year. Realistically though, we haven't had much single-core improvements in general since the current trend is to cater to multi-threaded/multi-process environments, i.e. putting more processing cores into the same die, sometimes with deliberate specialisation to also take care of the overall power consumption of the chip. So fun.

In other news, I had some issues with my over-flow auto-sorter in Minecraft. The problem here is that my 5--6 double-chest storage array was going to run out of space for some items (bamboo), and I wanted the excess to overflow over into auto-incineration. So I did the obvious thing of extending out from the original overflow chest into its own auto-sorter for items that I don't mind incinerating, before sending what is left back to the storage chest system for those items.

It didn't work. I don't know why. I'm currently dealing with it by using a manual red-stone switch shunt to bring the excess bamboo down a hopper chain into the incinerator directly. I'm going to debug that and see what's wrong after this post goes live.

Anyway, time to load up on more Jack Daniel's and figure out what's wrong with the over-flow auto-sorter. Till the next update.

Friday, October 15, 2021

Maps & Masks in One

Hmm. The weather forecast in the morning suggested rain at 0200hrs tomorrow, but a quick glance at it just now suggested rain between 0700hrs to 0800hrs instead.

Okay... meanwhile, it is still as hot as can be.

And that lubricant trick for the fan? Well... I don't think it worked. I probably need to really take it apart completely to get it right. Or wear enough parts down to trigger the service contract.

I'm carefully making my way through Mathematics for Engineers (2nd Edition) by Raymond W. Dull. The early fifth of the book is very algebraic in nature, reminding me of material from upper secondary/early junior college from Back In The Day. There's a sizeable chunk of information on how to use much fewer [significant] digits to get approximate calculations that fall within some specified tolerance; that's interesting when one realises that this book was written in a time where the most potent and ubiquitous calculatory tool is a slide rule.

In retro-programming news, I messed a bit more of my DOSBox installation. The main concern was the general slowness it felt. I know I said I'd like to do retro-programming, but 3000 cycles emulated just felt more sluggish than I remembered. I pulled up the associated Wiki, and according to this table, the approximate system emulated was closer to an 80286. Sadly, I cut my teeth in systems that were faster than that---it was at least an 80486. No wonder I found it super sluggish, and it also explained how the old LED(II) was acting slower than I remembered too.

I think I settled upon the following configuration for my own edification:
[cpu]
core=dynamic
cputype=auto
cycles=max
cycleup=10
cycledown=20
The setting of core=dynamic allows a ``dynamically recompiling core'', which aided in speed. Setting the cycles=max means that we run at whatever the maximum clock rate of a single core is. I also set output=ddraw under the [sdl] section, hopefully for more speed.

And oh boy. A jump to about 96× to 119× compared to before. And this was with VLC running at 2× replay speed and with Minecraft running in the background as I AFK-ed at my mob farm.

Configuration issues aside, I worked a little on LED2-20 today using the concept of ``hybrid bitmaps''. The problem that needed ``hybrid bitmaps'' was the management of arrays from within the QuickBASIC environment. For each bitmap with an associated mask, one would normally need to have two array names defined. Multiply this by the number of sprites and what-not, and the management of these array names are a downright pain in the ass.

Thankfully, the GET and PUT graphics statements allow the passing of an array name with an associated index to start the bitmap from. With that in mind, I decided to solve my ``too damn many arrays'' problem by combining bitmap and mask arrays into a single integer array using an offset to separate them. The first thing to note is that with a bitmap of 320×200 in this screen mode (screen 7's full screen), it requires 32004 bytes. Double that (one for bitmap, one for the mask) yields 64008 bytes. Using the 16-bit integer primitive data type for the array, the index goes up to 32004. Adding an additional 16-bit integer to record the offset yields an array with only 32005 entries. This is less than 65536 bytes (limit of a non-huge array), and more importantly, has an index range of less than 32767. These two limits are not busted by the largest image with mask that I can come up with (the whole screen), so it is not a problem for the much smaller sprites that I have in mind.

And thus, the ``hybrid bitmap'' is created. I updated the various sub-routines to handle this, and also tweaked the sample sprite-generator code to save the generated sprites according to the new ``hybrid bitmap''. The sub-routine updates were quite painless since QuickBASIC allows one to define array indexes using any range of signed 16-bit integers---all I did was to ensure my ``hybrid bitmap'' array was defined like DIM a(0 TO ...) AS INTEGER while the regular bitmaps were defined as DIM a(1 TO ...) AS INTEGER.

Now I'm wondering how best to do pixel-perfect collision checking. I envision basic bounding box collision checking before we apply the pixel-perfect collision.

That's about it for now. Till the next update.

Thursday, October 14, 2021

Manipulating Pixels

Ah, Thursday.

The weather is still nut-so, but what can I do about it? Anyway, the weather has been bad enough that I had to bring out the four laptop ``leg'' stands. I had put those away for quite a while because the angle that I was using them that allowed a better channeling of wind (tilted away from me) was screwing my wrists. The ``as-designed'' angle was really to have the laptop tilting towards me, with the rear raised higher than the front, but the problem with that was that the fan on the right side of Eileen-II would randomly sound like it was rubbing on something bad, causing some scary sounding vibrations.

Previously when those vibrations came about, I would hastily suspend Eileen-II before opening up the back cover, and try to clean out the dust. Then it got a little bit more frequent than expected, but I realised that if I left it alone for a while, the fan would eventually slow down/stop, and the next time it restarted, the vibrations would be gone.

Well, today the vibrations happened again. I was annoyed enough that I took apart the back cover and stared at the fan again. Back in the day, I would take the fan out from the casing and lubricate the moving parts, but the way Eileen-II was set up, it was very risky to take the fan out completely. But I realised that there was just enough leeway to get some lubricant in, which I did, carefully. My lubricant of choice was, of course, Vaseline, mostly because it is non-conductive. I slipped some of it in, and after putting things back together and setting up the legs ``as-designed'', there hasn't been any major vibration incident.

A win, perhaps?

Anyway, it was comfortable enough to type on, and I worked a little on LED2-20. I got the right-rectangle (rectangle with edges parallel to the screen edges) intersection sub-routine working, and with that, managed to get the ``put sprite anywhere on screen'' sub-routine working. The problem that I had to solve was that the built-in PUT graphics statement automatically fails if any part of the bitmap image exceeds the boundaries of the screen. This means that, for example, if I have a 16×16 sprite, I cannot use PUT with the upper left corner being at (−10,−10). But in LED2-20 (and other games), we should expect ``partial'' sprites to appear on screen for that immersion. My solution to this was to grab the reduced sized bitmap (and mask) on the fly and use that with QuickBASIC's internal PUT statement.

It works well enough. I did switch up the way I separated out the cases though, relying on error-trapping to handle the cases where the more time-consuming bitmap handling was required while avoiding the cycles spent on validation checking before using the PUT graphics statement in the beginning. This can be quite a time saver in the long run when considering just how often we are drawing sprites on the screen.

So at this point, keyboard handling, and basic sprite/background renderer (the background renderer is similar to the sprite handler, but without the mask) are done. I'll probably need to worry about pixel-perfect collision testing next, or think about the game data structures that I need---either way is fine.

------

In Minecraft, I dug out another row of rocks from my mine, and built a glass enclosure for my bees and flowers. I had to do that second bit because the damn bees kept on disappearing. They first disappeared because they kept on running into my lava wall (I removed that), and then they probably disappeared because they wandered too far off from my service platform and didn't return or something.

Anyway, that's about all I want to talk about for now. Till the next update.

Wednesday, October 13, 2021

My Head Still Hurts, But in a Different Way

That headache from yesterday? It went away this morning, came back a little this evening, and has manifested itself as general fatigue now. I really wonder if getting those blackout curtains can make a big enough difference.

It really isn't the heat alone that is the cause of all these symptoms---I think it is also related to the change between the various weather states that is causing all these discomfort.

I'm going to turn in immediately after I am done with today's entry.

I've finished reading the KonoSuba light novel series, Best of BYTE magazine compendium, and even book 4 of the Mahabharata. KonoSuba was fun, it began with a lot of potential, made its way through the situation, and ended on a plausible-enough note. At seventeen volumes though, it did feel as though the author had written himself into a corner with the main character of Kazuma. The world was built well enough to provide interesting encounters, and the main characters had some kind of character development, so it wasn't as bad as I made it sound. As this is my first light novel series, I'm really uncertain if this was the norm, but it was gripping enough that I wanted to keep on reading to know more.

Best of BYTE was a great nostalgic trip in time. The revisit of the technological trends and associated reasoning from the early days of microcomputer/personal computer with a little more detail (compared to my first reading of this compendium nearly twenty years ago) was quite eye-opening. Already I am seeing the cyclical nature of technology with greater clarity; my recent little rant was based on an article that was present within the book. The number of transistors that can be shoved into one square millimetre of silicon substrate may have increased by several orders of magnitude today, but the human-factor aspect of things have barely budged---there is much to learn from the triumphs and mistakes of the past that infocomm technology practitioners seem to be adverse to.

I'm going to be starting on God's Prophetic Blueprint by Dr Bob Shelton, and Mathematics for Engineers (2nd Edition) by Raymond W. Dull after this; the former is an explanation on Revelation, while the latter is a nice 800+-page refresher on some old school [continuous] mathematics that I used to use a lot of [in school] that I haven't touched in a while.

Alright, that's about it. I'm going to turn in for the night and see if I can sleep away this fatigue-feeling. Till the next update.

Tuesday, October 12, 2021

My Head Hurts

Weather's a horrible joke. It's back to being bloody hot again (interior ambient temperature of 31°C) and I now have a stupid headache.

Can't win.

I'm going to go lie down.

Till the next update.

Monday, October 11, 2021

Manzi

From Jim Manzi, then President & CEO of Lotus Development Corp. (``The Productivity MacGuffin'', BYTE Magazine 1992:8 p360):
Over the last 10 years, many companies have fallen into the trap of technology for technology's sake. This has not been entirely their own doing. They have had ample encouragement from members of our industry, who have never hesitated to trumpet their latest product release with no thought to customers' business goals. In all the excitement, people lost sight of a few simple economic truths.

The first is that real value in an organization is generated not by machines, but by people. It applies not just to computers, but to the steam engine, the printing press, and the pencil. The second principle is that the greatest value is generated not by individuals, but by teams.
What he said is still relevant today, nearly 20 years later. The ``AI Winter'' of yesteryear seemed to have given way to an ``AI Spring'', but the harsh truth is that even in the current ``AI Spring'', the propensity of snake oil is just still too high. Looking at technology with a sober look can often seem to be something that reeks too much of conservatism, but that cannot be helped---even the second paragraph from a technology leader acknowledges that point.

Machines, thinking or otherwise, allow us to do things faster, and hopefully cheaper. In the engineering rule-of-thumb of ``cheap, fast, good; choose two out of three'', machines can be seen as a way of allowing us to concentrate on pursuing quality, while using such automation tools to ``cheat'' in getting the other two along the way, a means of beating the aphorism. The thing is, we are still fundamentally a human-centric society, which means that at the core of it all, the human ought to be primal in any type of decision. That's what the second paragraph of the above quote is trying to capture: that the value of an organisation (be it a company or a society) is an evaluation of the value generated by the people that make it up. If everything is a race to producing more with cheaper and faster techniques with no innovation whatsoever, then the [short-term] winners will be those who have a predominance in machine.

The second principle as highlighted in the second paragraph is a caution against treating individual people as disembodied attributes/wish-lists the way ``human resources'' have been championing, and to take into consideration how the person, as a whole, can contribute to an existing team. This means that personnel decisions in organisations ought to be taken with team-fit playing a larger role than mere matching of some reductionist collection of attributess. This also means that staff retention with respect to maintaining effective teams should be a priority over the greed of hiring the absolute cheapest and cobbling them together in the hopes that they make an effective team.

Now, I'm not saying that Manzi is absolutely right here on all things. Following the history of Lotus Development should allow one to draw their own conclusions on Manzi's leadership capabilities and how they relate to his perspective. But in this case on how technology, business, and people relate, what he says has a certain ageless truth to it for as long as our societies are to be lived in by humans.

The unfortunate thing is that in this time and age, I am not even sure if we are running societies for the benefit of humans any more. In more ways than one, it seems that we have steadily moved our societies towards supporting that of corporate personhood over the individual. Many laws across the many countries have a tendency towards prioritising giving [substantial] benefits to these corporate persons over looking out for the humans that make them up, and really, no one should be surprised at this from a purely utilitarian perspective: that single corporate entity may be ``one'', but it has the clout (capital, which translates to socio-political eventual) that can rival some of the smaller countries in the world. In other words, for any legislator/enforcer to achieve so-called ``great return of investment'' or ``low-cost high-impact'' type deals, they can do the easy thing and pander to these corporations instead.

I would normally claim that this is a major fallacy solely through reasoning that the corporate entity is still legal fiction that, if all the people in it are absent or if all the people who trade with it are gone, it will also ``die out''. But with massive automation in both physical (think robotics) and mental (think reasoning/``AI''), it becomes increasingly possible to create corporate entities that can literally take on a life on its own devoid of most human intervention.

Think about it: a self-sustaining network (or ``society'') of corporate entities that trade information/material/logistics with each other, accruing capital among themselves that need only a minimal number of people to supply the missing innovation parts until they too can be replaced, where even their ``owners'' can eventually be made up of only other corporate entities as the bootstrapping human leaders get ``digitised'' into pure institutional knowledge before they eventually die out from old age. A world of the biggest class divide: the humanly untameable corporate entities who own everything, and the humans who can only hope to lease at ever-increasing prices over ever-decreasingly available resources.

I think that we are part-way there already at this point. It seems incredible to believe that after fifty years of exponential improvements in technology, we end up having to work more hours than our predecessors to have a chance at a lesser quality of life, and to be abused that somehow we have been the greater ne'er-do-wells.

Then why do we invest so much into innovation for, if the end result is more misery? Just who benefits from all these innovation then? It can't be for God, despite how many might want to claim---everything that we have, He gave it to us first. Besides, God is all-powerful---there is nothing that we produce that he wants/needs.

So, why then?

Sunday, October 10, 2021

Machiavellian

It's a little late, but here's a short one.

The past few days of ridiculous heat continued in the morning, with the interior ambient temperature hovering near 30°C at around 1000hrs local time. Then it decided to rain hard twice.

The interior ambient temperature now is still about 29°C. Remember what I mentioned about humidity and wind? Well, I think that the humidity is a little lowered, so despite the lack of wind and still-ridiculous interior ambient temperature, it actually feels sort of cooler now.

I read a couple more volumes of KonoSuba. I think I can probably finish the entire series by tomorrow. I did spend the early morning reading a few more articles from The Best of BYTE: Two Decades on the Leading Edge, again tapping into the natural light from the sun to assist in the reading off the dead-tree book. It's still largely a passive-entertainment sort of day for me, so nothing that involved heavy [intellectual] lifting was needed.

I did update Eileen-II through the support assistant software that comes with her though. This included the side-loading of the new BIOS firmware, an always harrowing experience---if you brick that, you brick the whole machine with little to no hope of recovering.

In other more current-affairs type news, the ``conscientious objectors'' to vaccination against COVID-19 (or was it vaccination in general?) have raised their collective heckles against the new rules that were released yesterday, claiming that the decisions discriminated against those who were unvaccinated.

Well, no shit, Sherlock. All decisions are discriminatory in nature, with the only question on whether that discrimination along the decision boundary was morally/ethically/socially acceptable or not. And in this particular instance, it is, with the addition of some heavy-duty science in demonstrating that the vaccinated, if they do get hit with COVID-19, do tend to get less dangerous symptoms than those who are not.

I had mentioned in meatspace many times that the true way out of perpetual lock-downs from a pandemic is to have it burn through an entire population, an outcome that was unthinkable before vaccines were available, but is now plausible once vaccines are available. The only reason why we can't say things like that is because of how brutally inhumane it sounds despite it being the eventual outcome that every society needs to get through in order to be ``COVID-resilient''. This is doubly true for politicians because anyone who says this out loud will be committing political suicide through a demonstration of anti-empathy of a rather personal nature, which brings the message of how they are not really ``representing'' the voters in the starkest most inhuman sort of way.

But, just because no politican can say this out loud doesn't mean that they cannot pursue it as part of an exit strategy. And the latest adjustments of restrictions can be seen as subtly moving towards that end-state. Of course, they will not allow it to burn through the population completely out of control---overwhelming the public healthcare system is always a legitimate concern---but through what they hope to be a controlled release.

I suppose this might be the new modus operandi of the government of SIN city---instead of strong-arming people with heavy-handed laws, they just make things super annoying and rage-inducing for those who refuse to comply, maliciously or otherwise. But to be fair, this modus operandi doesn't seem to be generally applied---it seems to only be for actions that tend to affect a larger number of people at once. In situations where the target group is small, the old heavy-handed ways seem to be preferred. Which makes sense in the Machiavellian sort of way.

Anyway, I see myself staying home still for this week (other than the usual Saturday worship service at church). I don't need to go anywhere specifically, but I do like to head out to a nice place to sit, drink/eat, and read. I can do that safely from home, but after a while it probably feels nice to just head out for a change of scenery.

I think I'll stop about here for now. I might want to go cycling for a bit tomorrow---my mind's not made up just yet. Gotta get more of that kind of care-free fun going before my sabbatical comes to an end, where I need to snap back to what society expects/demands from me.

Till the next update.

Saturday, October 09, 2021

Melting

Well, I could talk about the recently released speech from the Prime Minister regarding the recent developments on COVID-19, but I won't.

I'm not a news blog. Nor am I interested in being one. Something about not wanting to draw unnecessary attention so as to make it easier to ``keep it real''. Because when things get too popular/large, it becomes much harder to stay to the original roots due to the need to meet a large number of expectations.

It's funny in some ways---in infocomm tech, we are always talking about how we should be building systems that can scale out and/or scale up, but every other piece of experience that we learn from in real life seems to suggest that doing either is generally a Bad Idea. The dissonance between these two is deliciously confusing, and it has begun to show its true dangers as infocomm tech starts to encroach more directly into the living spaces of people.

I think it goes back to the epiphany that I had in my second paragraph.
Because when things get too popular/large, it becomes much harder to stay to the original roots due to the need to meet a large number of expectations.
When infocomm technology was developed and deployed to improve the flow of business-related [structured] information, it helped to streamline and optimise existing business processes. Part of the reason was the need to perform the necessary analysis of the existing [manual] process, identify the associated requirements, impose structure and logic upon them, all before a single line of code is written. That kind of analysis is largely manually done, and requires some intelligent combination of domain experts from both the business process and system sides. When there was a need to scale up/out, it was ``obvious''---the scaling was meant to handle the sheer volume of the data moving about, not necessarily to scale for new conjunctions/interactions that these data might have. So much of algorithm/systems theory is about handling such asymptotic cases.

When such disciplines first met humans in the form of expert systems (and then later on, search, followed by the dreaded ``social media''), this inherently reductionist perspective proved to be inadequate outside of some extremely narrowly defined specialties, at which point the number of beneficiaries often could not justify the cost of developing/deploying such a system. Similar arguments can be made for search engines too---early search engines were nothing more than indexes whose concepts were borrowed from regular library information sciences. Early innovations that made it [computationally] scaleable was when Google was founded with the PageRank algorithm.

But were those systems ever ``interaction scalable''? I would say... no. For if they were, then there wouldn't be a need to incorporate more and more personal-level information to bias output towards what the single person might truly prefer over all others.

It is the same with social media, after they started to expand outside of their original demographic. Facebook wasn't completely garbage when it started out---the true beginning of its fall towards population polarisation was when its user base was expanded to include more than just college students. It got worse when it started to heavily adopt advertising as its source of revenue---I claim the degradation because with advertising and associated stakeholders coming into the play, it becomes more profitable to deliberately isolate population groups enough that they form a single homogenous unit that can be marketed as a targetable audience to convince advertisers to part with their money. That said, a word of fairness is in order---I say ``deliberately isolate'', but that's a description of the outcome rather than the means; the methods were more through ``lying by omission'' to create the necessary echo chambers that would amplify that tribal feel.

Being the largest social media presence on Earth (is it?), the modus operandi eventually became copied elsewhere too, or at least, those who felt suspicously empowered through the segregation in Facebook brought along their self-righteousness into every other space that they exist in, be it some other communications platform or even in real life.

What I am trying to say here isn't about bashing Facebook specifically; it's more about highlighting that while we know how to properly scale out/up infocomm systems to handle volumes of data at acceptable bit-rates, that human interaction bit is still sorely lacking, and is one big source of the paradoxical headache that comes from literate(?) people demonstrating the kind of dark-ages science-fearing bumpkin-ness that we thought we had banished after the renaissance and ages beyond that, with the added irony that they are using science (and business) powered infocomm technology to do their collective belly-aching.

The relevance of what I just mumbled with the beginning of this post will now come to light. Had platforms that connected people (like Facebook) allowing arbitrary pseudonymous connections stayed small, the expected number of ``off-the-rails radicalisation'' events is likely to be small. That's likely due to a combination of the founders' influence, and the innate self-policing nature that a small, tight-knit, group has. I trust someone because I know that someone. When the platforms get large though, it is no longer possible for me to trust someone because I know that said person; I'd have to be satisfied with trusting someone because I know someone that the person also knows, and I trust that proxying third party. The problem then is when people mistake this proxied acceptance as true trust. Because then such people, if sufficiently motivated, can then become the source of the disinformation.

I believe that finding out such bad-faith actors from the get-go without hindsight is likely to be as hard as teaching a machine to emulate the full range of human emotionns to express natural language.

Anyway, for some reason I'm really feeling it in my head right now. I think the consistent 30+°C interior ambient temperature despite it being nearly 2300hrs local time doesn't help.

Till the next update then.

Friday, October 08, 2021

Melodrama?

The itch of Minecraft came by again today and so I indulged a little by taking on a bastion remnant in the nether. I also updated my spawn-chunk based low-volume iron farm to include an item auto-sorter that would separate out the poppies from the iron ingots, sending the former directly into a composter to create bonemeal while redirecting the latter into the receptacle located at my small warehouse level. I also took the opportunity to sort my chests in my deep mine, grouping blocks according to type in the double chests, providing associated labels, and expanding the total capacity as well. I also continued to deforest the jungle biome, before retiring for the day leaving myself AFK at the mob farm to gather more mob-drops.

In other news, I have read another couple of volumes of KonoSuba.

I did have a light existential moment today thinking about how I would dispose of my items on death, but quickly realised that unless I was intending to die by my own hand, it was really out of my control. I mean, I could, in theory, write a will, but there's never a guarantee that it will be followed/enforced.

Besides, who would want a dead man's musical instruments?

Till the next update.

Thursday, October 07, 2021

Matinee

A week of passivity, it seems to be.

More reading from The Best of BYTE: Two Decades on the Leading Edge, and more volumes of KonoSuba (『この素晴らしい世界に祝福を!』) read, even as I have various cached Hololive videos running in the background.

I am also thinking about writing a locally-run RSS aggregator service as a way of ensuring that I am not beholden to my cell-phone when it comes to following up on news. I find that ever since I've gone on the hermit life, I haven't really been looking at my cellphone much, and as a result, have not really looked at the associated RSS reader output. This is a little problematic not because I then become less aware of world news (look, there really isn't anything good in world news these days anyway), but that it is affecting my ability to respond to the new direction of the group study that is happening in my care group.

Since I'm staring at Eileen-II most of the time anyway, having my own RSS reader is probably the best option.

There are probably many nice RSS aggregators out there, but ever since the killing of the default RSS reader on the smartphone, I have started to get rather wary of relying on services out of my control for anything that I care enough about. I am using some kind of third-party RSS reader on my phone that is thankfully not completely screwed up, but being tethered to my phone is one of those things I don't like. Part of the reason is that transferring information out of that infernal device is usually non-trivial, as compared to the many options I have on a PC.

Anyway, that's about all I really want to talk about. Skin's been acting up a little, and the ``drying up'' of the random splotches of rash on my torso can sometimes be itching a little too much to ignore completely. Maybe it is due to the return of the hot weather---I don't know. What I do know is that the town council has again decided to have landscapers lob fertiliser into the cross-patterned grass patches that grew in between the laid out concrete that made up the parking lots again.

🤦‍♂️

Till the next update.

Wednesday, October 06, 2021

Messiness

There is something charming about light novels that just makes it ever so irresistible to continue reading. The pacing tends to be faster, the language (even after translation) tends to be more straightforward, and it is also fairly short as far as written works go. I mean, that's probably why I completely enjoyed my time today reading a few more volumes of KonoSuba.

But the frivolity of light novels aside, I would really want to talk a little bit more about recent happenings.

A couple of neighbourhood shops have finally wound up within the past couple of months. One was a shop that sold toddlers' apparel/toys, and the other was a home-made gelato shop. The toddlers' apparel/toys place's demise was really a matter of time, considering just how niched their particular clientele is---toddlers' clothes are probably of a higher velocity than even women's ``fast fashion'', considering how fast they grow, and how often it is to have hand-downs from others within the cohort just to stretch the dollar to ensure that consumables such as disposable diapers and formula milk can be consistently replenished.

The home-made gelato shop though... it's such a waste. I liked that shop---I've purchased quite a few high-quality gelato cones from them over the two or three years that they have existed. They had interesting flavours, and had even brought out an interesting milk-shake drink that was based on ice-blending their gelato as well. The price point wasn't too shabby considering what they were selling, and I could see it as something that could have some staying power as a sort of hang-out place to cool off after a day's work.

The only problem was that this whole management of the pandemic just made it neigh impossible to keep things going. Restriction rules for dining in came in at seemingly unpredictable moments, with inconsistencies of rules and bad technological implementation. For those in the F&B industry, timeliness of the supply chain is of paramount importance. No matter what type of food/beverage they sell, the freshness of the ingredients that make these was a necessity to ensure that people do not get sick from consuming the foods/beverages that are made from them. These kinds of supply chains require a certain amount of predictability, partly to ensure that money/supply isn't wasted, and partly to continue complying with basic food hygiene requirements.

This can be made much worse for shops that rely on even more specialised supplies. Take my favourite sushi place for example. They use fresh fish, which requires them to be brought in from boats that deep freeze their catch as soon as possible to maintain freshness throughout the entire fishing period. Boats may come often, but the availability of supply is often booked well in advance of the boats' arrival in port. When rules on restrictions kick in with only three days to spare, such stock needs to be disposed off quickly enough, otherwise there will be a surfeit of them that needs to be accounted for using local freezers, with artificially lowered demand.

It makes things really hard to handle. It's no wonder that even the proprietor just gave up after the umpteenth restriction and just called it a day, opting (like me) to wait things out before striking forth once more.

I guess the same reasoning might work for the gelato place as well.

A pity.

Anyway, while all these nonsense were going on, a new wave of nonsense has come on---the whole ``return your tray'' movement that was somehow ``made'' into law. More precisely, the National Environment Agency (NEA) has decided to add new rules to more strongly enforce CAP 95, §17(1) in the sense of re-interpreting the offenses as stipulated in that section to include the non-clearing of dirty trays, or the remnants of cutlery and what not on the trays that have been used to carry one's food from the stall to the table after said food is consumed as a fine-able offense, as explained here.

Is a non-consumable item like a tray and associated cutlery/bowls/plates/cups considered ``refuse'' or ``rubbish'' in the sense that CAP 95, §17(1) claims? I don't know---I'm not a lawyer, but a lay reading of the relevant statute as claimed by NEA suggests over-reach of some sorts. The only way to find out for sure is to have it legally challenged, but it does feel kind of silly to push through just to find out about that. Especially in a place that prides itself on its bureaucratic efficiency and thoroughness.

Did anyone really think that the laws/rules were written without careful thought about its ramficiations?

After all, there are many more laws that exist that have broader-reaching effects than this puny one that ought to have a more direct challenge. But, ah, good luck with that. In a small place like SIN city, the issue of the principal-agent problem is much heightened. For those in the professional line, where only reputation separates one from a life-time of work and a life-time of being shunned from the professional society, this problem can cause some rather strong disincentives for those who may want to engage the service of the professional to mount such challenges. It's not about corruption... it's straight up self-preservation issues. Any client is just one case for a short period of time, but the human factor in the relationship of the professional lives throughout the entire career of that professional. It can always be said that all decisions will be made as objectively as it is possible...

...but for those of us who have 混-ed in society for a while, how many of us believe that whole-heartedly? Sure, the official response can be defined objectively, but the impetus towards the decision may come from elsewhere that is not necessarily provable/disprovable.

But let's backtrack a bit on why I find the tray return thing nonsensical. I don't know when/how did we transitioned from the ``mostly stallholder delivers your order to your table'' model into a ``mostly you self-serve'' model when it comes to ``public dining''. Was it due to the rise of the food court model that this became predominant? Because I remembered that back in the 1990s, one would usually just order from the stallholder at the hawker centre/kopitiam, tell them your table number, and then go sit the heck down. They will come by with your food eventually.

There were no trays involved. Let me say that again: there were no trays involved.

I cannot remember when the first food courts became a thing. For reference, a ``food court'' can be thought of as a primarily air-conditioned collective of stalls with seating, and operated by a company. I think that was roughly when the whole numbered tables went away, as well as the whole ``stallholders managing their own crockery'' thing. At that point, all the stallholders drew upon a common pool of serving equipment, with standardised forks, spoons, chopsticks, plates, bowls, and trays. That last item was necessary because the design of the stalls generally sequestered the stallholders behind their stalls to be dedicated cooking machines. Combine that with the lack of table numbers of rapid identification of labels, it meant that the ``self-service model'' became the norm.

Food courts being run by companies mean that they benefit from economies of scale, which meant that overall there were more of them compared to the other types of [cheap] public food places. Them operating in the air-conditioned malls throughout SIN city helped, and I suppose it was from the mid-2000s that the model took off.

Come to think of it, the food courts seemed to take the model of the fast food counter & self-service concept (think McDonald's/KFC) and expanded upon it.

I guess that it was from then on that the whole tray business became a thing.

As for tray return... sigh. Right now they are couching it under anti-COVID-19 terms (which legislation these days doesn't rely on the bogeyman of COVID-19 as a motivation?), but I guess it's really a case of...

I actually don't know what it is a case of. That's very strange. Is it some kind of morality statement hidden behind hygiene (mind you, there are cleaners who were/are hired to clear the tables before/and at present), a statement of patriarchical power, a pet peeve, a ``slippery slopes'' type set up?

I don't actually know.

What I do know is that I have gone on long enough with this post, and it is time to hit that publish button.

Till the next update then.

Tuesday, October 05, 2021

Milquetoast

Yet another day of hiding in the apartment as the world around me burns for one reason or another.

Today's a passive sort of day. I didn't play any games, not even running Minecraft in the background AFK-ing while the auto-sorted chests fill slowly with mob items, nor did I work on LED2-20. I read a couple more chapters of Luke under analysis in the ESV Study Bible, read a couple more articles from The Best of BYTE: Two Decades on the Leading Edge, finished reading Thaïs, and volume 1 of KonoSuba, and am about slightly under half-way through for volume 2.

Thaïs is a tragedy. While the epynomous character ascends through her reconciliation with her previous baptism under the name of the Lord Jesus Christ, the protagonist (Paphnutius) himself who started as being holy eventually became a backsliding Christian when he discovered that his quest to evangelise to Thaïs had mutated into a devolution of his original morals and ethics, becoming plagued with demons and the like after delivering her to the nunnery. While not scripture, it is a parable of sorts to remind ourselves that even the truest of believers must be constantly aware of how the world affects them, and to be honest to both oneself and to God to ensure that one does not backslide to falling back into sin. The story ends on a cliff-hanger of sorts, where Paphnutius finally realised his sin, but does not provide the resolution on whether he had come back from that or not. There were bits of discussion among the pagan philosophers amidst Thaïs, but they were really more of a sidetrack that contributed little to the main story---think of it like how Victor Hugo went on various tangents explaining/describing his pet topics while writing Les Misérables.

Apparently Facebook, Instagram, and Whatsapp had outages for a few hours while I was asleep. That was... surprising, but it didn't faze me much. As I had mentioned in reply to someone who was kind enough to share with me the news:
Besides, it's not like anything of value was truly lost when those services went down. 🤣
Which is true. Facebook was never a ``serious'' thing, no matter how seriously they want to take themselves (they have to---it's literally their business). Instagram is a cesspool of attention-seekers selling the pleasures of the flesh for the most part, whether it is lust, gluttony, or general envy/covetousness. And Whatsapp... oof... where to start? Mis-information central, spam central... with vague communication uses. I mean, don't get me wrong, I like me some instant messaging systems that allows short (both in length and duration of validity) messages to be sent. But it is a terrible medium for conducting ``serious'' business in, since it is bloody impossible to hunt down references the way that email can handle in a more effective manner. And it being a misinformation/spam central comes from the ease of forwarding all kinds of rubbish-y messages without a safe means of checking them; that last bit, I blame it on the form factor of being primarily accessible over a smartphone. Smartphones aren't exactly conducive for rigour in any sense of the word---that ``tap'' versus ``long tap'' distinction makes it very easy to trigger off the wrong gesture, compared to the ``left click'' versus ``right click'' that one can do in PC-land.

I am thankful that my hard-ass personality has more or less ensured that the people who do have ``my'' Whatsapp contact do not abuse it the way that I have heard from the nightmares shared online; one of the perks of being who I am, eh?

I think that's about it for now. Maybe I'll complete volume 2 of KonoSuba tonight before heading to sleep. I don't really feel like doing anything active today.

Till the next update.

Monday, October 04, 2021

Mumbles

Hmm.

It's a slow-ish day today. I built the automated bamboo farm at my mob farm in Minecraft, bolstered the defenses at the nether-portal in the jungle biome in the overworld, reconstructed my ``Adventurer's Shovel'' to not have fortune enchantment (the original one was generating 100% flint instead of retrieving the gravel---it was bad because gravel was more useful for concrete making, while I had a surplus of arrows, thus needing less flint than expected), and harvested quite a bit of jungle logs from the jungle biome itself.

I also thought a little bit about how to reduce the number of screen pages that I would like to use in LED2-20---I think I might have a viable solution, but it will require testing.

Apart from those, I was just doing some reading here and there: the analysis of Luke in the ESV Study Bible, and a bit more of Thaïs while waiting for my head shave.

Anyway, I was just thinking, I know that I wouldn't want children for a variety of reasons, but I could never figure out if I would like to be on the look out for a spouse. Over the past few weeks though, I had been thinking about it on and off, realising that as time went on, there were fewer and fewer reasons on why I should have a spouse. I am not fearful of responsibility, but I am realising that given my mental state about the world, probably the last thing that I want to do is to increase the number of ties I have with the world through the union between me and some female. It wouldn't be fair to me, nor her.

But things like these, i.e. involving interactions with other people, are largely outside of my control. They are, however, well within the control of God. So if God wills it, I will end up with a spouse, and if otherwise, so be it. I just need to keep my faith and trust in His plan, and do what I can with whatever I've got, gifts by grace, or otherwise.

It's freeing in many ways. Reduction of the need to worry too hard about how to accomplish things on my own, even in the face of situations that are completely out of my control. This is especially true in the face of this pandemic where the normal order of things are generally on the brink of being upset, where much of the past knowledge that we have is even less capable for predicting what is happening next. The sins of the past are fast catching up to us, particularly so for the morally questionable decisions that were made in the bid for quick, short term gains.

The true question is, will we learn from these mistakes and choose resilience through forging a new social/cultural contract, or will we end up doubling down and digging ourselves deeper into morass to allow those who have benefited from before to continue benefiting while we all suffer the consequences.

Today, more than ever, we are at the cusp of a watershed moment in SIN city. I pray that God will grant us all the wisdom to proceed in the direction that He wills, and may He be merciful and allow us to continue existing despite all the challenges like how we have existed before.

That's all for today. Maybe tomorrow's gonna be a different day.

Sunday, October 03, 2021

Mind & Minecraft

I spent much of the day reading, completing The Inner Game of Music: The Classic Guide to Reaching a New Level of Musical Performance by Barry Green, and W. Timothy Gallwey, and starting on Thaï by Anatole France, translated by Robert B. Douglas.

Why Thaïs? One word: Méditation by Jules Massenet. That piece came from the opera that was inspired by Thaïs, and had piqued my curiosity about the source material. And so, began reading it I have.

------

I spent some time adjusting my storage for my twin sugar cane farm located beneath the main kill-floor of my mob farm. Previously, the output of the farms were piped via hoppers directly into a 2 double-chest storage system with a double-chest buffer in between. The problem was that the rate of production of the sugar can farm was closer in order of magnitude to that of the arrows (or about two-thirds that of the bone), and so the 2 double-chest storage system was insufficient. I had set up the more sophisticated storage for the other items that come from the mob farm, and wanted to upgrade the one for my sugar cane twin-farm as well.

The only problem was that I built my twin-farm ``too low'', which meant that I need to somehow move the sugar cane upwards so that it can be gravity fed into the storage system.

Unfortunately, there are just too few ways of moving items upwards compared to moving them downwards or even horizontally. There were two major designs that were cheap enough to build: a dropper elevator, or a upward water elevator. A dropper elevator is a bit more costly than the upward water elevator since it requires 6 cobblestones per dropper, and more importantly, I have experience building an upward water elevator over the dropper one. And so it was decided that I would do that.

Much of the time was spent trying to get it just right. The full source-blocks water column could be held in place without leakage by the wall of chests and hoppers, but their geometry made it exceedingly easy for any entities tossed out by the dropper into the upward water column to get stuck there. The entities getting stuck is also random, since the launch velocity from the feeding dropper into the water column is all over the place. I tried minor tweaks here and there to improve the trajectory, but to no avail.

So I had to isolate the water column itself, and manoeuvre the chest/hopper stack around it. It took me a while, since I had to rebuild that part of the storage system and ensure that redstone signals were not contaminated in the limited space, but I managed to get it to work.
The screenshot is after I spent a little bit of time rotating the finally-working model so that it sits flush and can have the little item-frame sign show up similarly to the rest.

I also spent some time building a melon farm from the melons that I had found from the jungle biome that I had tracked down. The next thing that I would like to do is to build a bamboo farm and feed it into the storage system below the mob farm, and think about how to fix the spider farm so that I can get the string production going as well. I also need to figure out how to grow the cocoa beans that I found in the jungle biome, and maybe explore more of the biome itself as well.

Alternatively, I could build a nether-rail to connect to the end-portal. Hmmm... choices, choices, choices.

Anyway, that's all I have for today. Till the next update.

Saturday, October 02, 2021

Main-Loop Accurate Delay

I talked in the earlier post for today about trying out a stochastic approach towards computing the number of vertical retrace cycles needed to enact a specific main-loop processing rate. What I missed out is a lot on why.

Think of the main-loop using any conceptual framework: I'll use OODA because it corresponds closely to what the main-loop of a game does. Roughly, we process user input, update internal data structures, draw sprites and/or compute collision, wait for vertical retrace, flip page, in that order per iteration of the main-loop. For most of the time, each successful iteration through this main-loop counts as a frame of [logical] video output.

The easiest way of programming the main-loop is to lock-step the physics engine (typified here as ``update internal data structures'' and ``compute collision'') with the actual rendering pipeline. That's why for many older games, when the frame rate is unlocked to allow hundreds of frames per second (fps), the physics can get... wonky.

I know I say older games, but truth is, this particular main-loop design is easy to build and thus shows up almost everywhere. Anytime a ``frame-rate dependent physics engine abuse'' type bug/feature shows up, this should be the first thing that comes to mind.

This is also a reason on why some games seem to react more quickly when the frame rate limit is raised.

But I'm not here to talk about the merits of lock-stepping the physics with the rendering pipeline. I'm just assuming that it is the case.

For consistency in behaviour, it is often a good idea to limit the processing rate of the main-loop. This means that it is necessary to ensure that each iteration takes roughly the same time, which means padding it with some sort of delay mechanism. I'm working in retro-world, so I have few modern day options like using a high-precision sleep() command that gives micro-second precision. In LED(II), I used empty FOR-loops, relying on a pre-main-loop calibration process counting up the number of iterations to complete in a given amount of time---this is in contrast with the prevalent method then of counting a fixed number of loops and determining the duration takken, a method that led to ``divide by zero'' errors when run on fast enough PCs (we're talking the difference between the program running well on an 80386 and having a ``divide by zero'' error on a Pentium I).

In LED2-20, I'm using a different method: use a known higher-precision timing mechanism as the workload in a busy-wait loop instead. In this case, I'm relying on the VGA port of 0x3da that yields a return time of exactly the vertical retrace duration. The duration is well-documented: for my selected screen mode, the vertical retrace rate is 70 Hz, which has a vertical retrace duration of 0.014 s. Comparing this to the 18.2 Hz of the built-in timer, it is nearly 4× more precise.

This delay per iteration is not necessarily constant, since it depends on how much time the actual main-loop workload consumes. I do have a low-precision timer (the 18.2 Hz one) running as an event trap in the background that helps me recalibrate the delay according to the actual number of iterations fully completed in between the timer interrupts, and it is from there that I discovered that the loop count was wildly unstable. I dug in and realised that I faced the problem of needing delays that were more precise than 0.014 s. Is it possible using this fixed clock of 70 Hz?

The answer is yes, if I'm allowing myself to expand my definition of the target delay to the average delay over time. So if I need a delay of about 0.05 s which requires 3.5 ticks of the 70 Hz, I can achieve it by counting 3 ticks 50% of the time, and 4 ticks 50% of the time.

A wholly deterministic method to obtain the same result can be seen in the theory of pulse-width modulation (PWM), but I cannot do it since the delays can change between recalibration, but PWM needs a defined pulsing cycle. Moreover, the function that translates the duration in floating point seconds to screen ticks does not use any static variables to assist in tracking the pattern for the pulsing cycle [for the additional tick].

Hence, using a random number is the best ``independent'' sort of way. The idea is to return at least the smallest integer number of 70 Hz ticks that do not exceed the delay duration, and add 1 tick to it with probability equal to the remaining fraction of a tick that will yield us the correct one. The principle is therefore similar to that of PWM, except that I replace determinism with a stochastically-driven behaviour instead.

It seems to work as the main-loop processing rate is definitely within the range of whatever I set it to be after one recalibration cycle.

That's enough for now.

Momentum

I'll keep it short as it has been a short day of few (but time-consuming) things that happened.

I read some more commentaries within the ESV Study Bible, after which I spent some time making safe my paths to the nether-rail and the nether-rail itself. I went to church, and now I'm home, thinking about a stochastic mechanism to get sub-vertical refresh rate precision given the 70 Hz hard limit, while watching Gawr Gura's Minecraft stream in the background.

I've also updated my stream cacher to use yt-dlp instead of youtube-dl because it has fixed a critical bug involving bad timestamps for video streams that last longer than 2 hours. I have also tweaked the incantation used for caching these streams to use the 480p quality (true resolution of 854 px×480 px) instead of 1080p because I seem to run it in my vertical side-screen (horizontal width: 1080 px) more often these days while I am working on either writing, coding, or gaming on the main [horizontal] screen. It seems like I am in the active phase again, compared to that time period where I was doing more reading instead.

I used to not do that stream caching bit because of the bug in youtube-dl, but have returned to it recently because the web browser-based Youtube viewer simply consumes too much resources to render the video. Caching it through downloading and then running it through VLC Media Player is more resource efficient, not to mention a finer grained control over the speed-up (that's how I can watch several multi-hour streams within a day). Doing that in the web browser-based Youtube viewer makes it consume even more resources, and also puts it at the mercy of the server download rate.

Anyway, that's all I have for now. Till the next update.

Friday, October 01, 2021

More Minecraft Fun

Oh hey, look: it's Friday, and simultaneously the start of October. We are fast reaching the end of this tumultous year, and to me, it feels as though I've only just begun this new chapter in life.

I spent much of the day pottering about in Minecraft, adjusting the item auto-sorter to use five double-chests (that's 5×54 slots×64 items per slot, giving a total item capacity of 17280 items) with associated hoppers to handle some of the higher rate loot that the dead mobs drop (I'm staring at you, skeleton with the expected number of bones being roughly 1.5×4.5=6.75 per group spawn. I added two more items to the item auto-sorter, hoping to get a spider farm working simultaneously, but the set up I created had issues that I didn't know how to resolve. Using the original gravity-type set up similar to my existing mob farm, I had spiders spawning, but they seemed trapped in the 2×2 holes, refusing to fall. I switched over to a side-spawn flow-pushing set up, but that didn't spawn any spiders at all. I am a little disappointed, and have abandoned that for the moment.

I also adjusted the item auto-sorter to route the unneeded zombie flesh from the dead zombies into an automatic trash can---it's a set up that uses a redstone clock circuit to pulse a dropper fed with items through a hopper which will drop each item into a cauldron of lava, the last of which would destroy the entity by removing it out of the game. The clock circuit was needed because the dropper only operated on a change in redstone signal, which meant that a simple unmodulated redstone signal from a lever was insufficient.

I also improved the way to get up and down between the main mob farm floor and the storage floor that contained the warehouse, item auto-sorter, auto-trash can, and the automatic sugar cane farm.

After doing all that I, I decided on a whim to build the nether-rail that I talked about. That was completed in a jiffy, considering that one block in the nether corresponded to 8 blocks in the overworld. So that 2.7k+ block railway that I built while exploring my way to a deep ocean biome became a much shorter 300+ block nether-rail. That distance compression comes at a price though---travel through the nether is more dangerous than in the overworld. For instance, the main way to get structures destroyed in the overworld is carelessness with regard to creepers. The mobility of the creepers is limited to land, and more importantly, they only cause structural damage when they are in very close range of the player.

In the nether though, there exists ghasts. Ghasts are ranged mobs that fire projectiles that explode on impact. Any building material that doesn't have enough blast resistance will just disappear in that circumstance. Thankfully, my primary building material for structural elements has been smooth stone, whose blast resistance of 6 can withstand the damage from the ghasts' fireballs. But the rails that sit on them... those aren't as resistant, and can prove to be a problem. So one of the projects that I will need to do later on is to build a protective covering around the rails for the parts that are heavily exposed.

Anyway, that's all I have for now. I'm going to work a little bit on synchronising mechanisms in the main-loop of LED2-20 before calling it a night.

Till the next update.