There are three abhorrent memories that come to mind this morning when I think of Donald Trump.
The first is that during his presidency, he took a vacation just about every weekend. And he didn’t just go anyplace; he always went to one of his own golf resorts. By doing so, he promoted his commercial brand (which you’re not supposed to do as president) just like he did when lining up Trump steaks in front of the press corps, and he spent our taxpayer dollars directly upon his own enrichment (after all, the Secret Service had stay in hotels somewhere). The Secret Service blew their budget protecting him during these dalliances.
The second memory is of his gaslighting about the COVID pandemic. Although he knew early on how serious it was, he lied about it to the public. He lied because he knew presidential fortunes can be tied to boom economies. To acknowledge the threat might have hurt our economy and therefore his re-election chances. And because of his gaslighting, the government responded slowly and ineffectively at a time when it could have made a difference. So he lied, and we died.
Finally, my third memory is of January 6, 2021. I’ve been watching the Congressional hearings this week instead of Tucker Carlson’s “pay no attention to the man behind the curtain” routine. Trump corruptly tried to subvert our democracy. He and his rioters tried to overthrow our government. A majority of Americans believe he should be criminally charged.
So here’s what I don’t understand. A majority of Americans also say they would re-elect that fool.
Could both polls be correct? Could a majority of us both want him charged and want him re-elected?
I hope not. I hope we’re not that lost.
You might have noticed my publishing output has waned over the last couple years. My last major publication was a novel, Mage Tech Duet, a scifi/fantasy hybrid. That’s because I’ve been exploring other creative outlets, such as video game programming. My latest hobby has been Meta’s Horizon Worlds, a sandbox application for creating VR games and art.
Over the weekend, I published what’s called a hub world, “Vulture’s Nest,” to provide easy access to my VR creations and collaborations. This will be updated as time goes on, just like a website. Now, whenever I make a new game/art/whatever, I can drop just a single door into that world, linking back to this one, so visitors can explore other ones. Here’s a video of what it looks like:
I’m not sure where my publishing “career” is headed, if I even had one. I’ve been submitting stories for publication, performance, and production for over 30 years now, and I’m burnt-out. So I’ve decided it’s okay to have other creative pursuits. I have to do it for my psychological health. So I don’t know what’s next: another video game, a song, a piano performance, a dramatic performance, a painting, or more fiction. It depends on what tickles my fancy and what you ask for.
Look for a website redesign in 2022, plus more unpredictable creations and some minor publishing news. C’est la vie!
Tips & tricks learned on the set of “Horizon Hipsters”
Here is a great behind-the-scenes video/tutorial about filming in the metaverse. Jay (Film Sensei) included my speech during the wrap party about VR-specific acting techniques.
If you have a programming background and have just begun to code in Horizon Worlds for the Oculus virtual reality headset, I feel for you. Here’s the article I wish I’d read when I started there a few months ago.
HORIZON … WHAT?
When I received an invitation to beta test the Meta app then called Facebook Horizon, I had no prior experience programming in virtual reality. Horizon Worlds — which users simply refer to as “Horizon” and which is not to be confused with its sister app Horizon Workrooms — is a collaborative creation tool to make gaming “worlds.” It’s a competitor to Rec Room. The experience of building and styling virtual environments from simple shapes reminds me of watching my sons play Minecraft and Roblox. The whole experience is wonderful and addictive. I haven’t played with any of my other Oculus programs in the last three months.
As with website creation, its users tend either to design things, like my friend Jay Haynes, who can craft realistic-looking chess pieces and cars, or code. I’m in the latter category, being more comfortable scripting than sculpting. And like with website designers and programmers, Horizon creators frequently team up, as Jay (Sensei_Jay) and I (Vulture667) have done on projects like Chess Parlor. For a recent entry in a contest, for example, Jay made a beautiful gun and wormhole out of primitive shapes, and I programmed them to shoot and teleport things.
Scripting in Horizon can be difficult to understand at the beginning. It can be like approaching a new martial art: you learn by doing and by consulting mentors and not necessarily by following a step-by-step curriculum. I come from a PHP and JavaScript coding background, and despite the heroic efforts of the Vidyuu Tutorials YouTube channel, I was thoroughly confused by Horizon’s “script gizmo” object. Script gizmos are literal (but virtual) cubes you pull from your building tools menu. They contain a visual scripting editor similar to Blockly in which you drop colorful blobs of code into other coloful blobs of code, thereby programming your creations’ behaviors.
There’s no requirement to attach script gizmos — let’s just call them SGs — to objects. You can make flowers and rocks or whatever all day long. You can even animate those objects through their internal properties panels. But the use of SGs raises your Horizon world to the next level.
So, are you ready to get started, Mx. PHP/JavaScript programmer? Here’s a primer. Civilians should be warned the following discussion will get technical.
OOP WITH LITERAL — BUT VIRTUAL — OBJECTS
After much hemming and hawing, I admit Horizon’s coding concepts are similar to the object-oriented programming concepts of PHP classes. The distinction, however, is we’re not instantiating objects from a class like we do in this PHP snippet:
<?php class Shape { // Properties public $quality = 'juicy'; // Methods public function get_quality() { return $this->quality; } } // Run time $apple = new Shape(); echo $apple->get_quality(); // juicy ?>
Instead, we create an object out of primitive shapes and attach an SG to it. You can only attach one SG to an object or to an object composed of a group of objects. However, the same SG can be separately attached to different objects, and in that sense, each object becomes an instance of a class defined by the SG.
Figure 1. The ‘Shape’ script gizmo has been attached to the apple object. The SG has a string quality with ‘juicy’ as its default.
VARIABLES
Here are some things to know:
Figure 2. The ‘Shape’ script gizmo has been attached to the apple object. The apple has overridden quality‘s default value with ‘rotten.’
while incrementor is > 0
set incrementor to incrementor - 1
Figure 3. Iterating through a list to print values to the debug console.
EVENTS
Whenever you see a “when event is received” code block, that’s the equivalent of the get_quality() method in the PHP example above. It’s basically a function definition that lays out what things should happen whenever it’s called. There are no return lines, however, unless the event explicitly sends data back out. For instance, this PHP method:
public function get_quality() { return $this->quality; }
Would look like this in Horizon Worlds:
when get_quality is received with calling_object
send return_quality to calling_object with quality
Those commands would live within colorful, Blockly-like blobs, of course.
It’s worth noting here that the calling_object parameter is also a variable, but it’s a variable that’s local to this event block, whereas quality references a string variable declared on the SG’s Variables tab. In other words, calling_object is an input argument. This means that calls to the get_quality event must have a corresponding number of arguments:
send get_quality to receiving_object with self
And just like in JavaScript and PHP, the typecast of the input and receiving arguments — called parameters — must match, too. So if the call sends in string, boolean, object, then the recipient listens for string, boolean, object, in that order. You can send and receive up to three of them. You can’t send lists.
An event that returns some point of data isn’t a common use of event definitions, though — but I think it would be an awesome use of them. Most events act directly upon objects in the game world. For example:
when paint_yourself is received
Set self color to color_variable
ASYNCHRONOUS VS. SYNCHRONOUS, ROUND 1
Without getting into a discussion of whether Horizon scripting is async or sync — because inevitably I will confuse those definitions — I’ll just tell you how I believe it works.
An SG’s commands within a given event block are performed sequentially but so quickly that they’re practically simultaneous. Before the introduction of the else and else if commands a few weeks ago, all we had were while and if. Boolean switches were a pain. Consider this snippet:
when world is started
if booleanvalue
set booleanvalue to false
if not (booleanvalue)
set booleanvalue to true
In my naiveté, I thought that was a great way to toggle booleanvalue until I realized that if the first if statement set a boolean to false, the second if statement would fire as well. This meant that (again, before the advent of else), toggling booleanvalue required firing events back to self on a delay:
when world is started
if booleanvalue
send togglefalse to self after #1 seconds
if not (booleanvalue)
send toggletrue to self after #1 seconds
when togglefalse is received
set booleanvalue to false
when toggletrue is received
set booleanvalue to true
In other words, if booleanvalue were true when the script began, the “if not (booleanvalue)” line within the when world is started block needed the command parser to move past it so it wouldn’t fire as well; so that’s why the togglefalse event was fired on a delay slower than the parser. Wow, what a pain, huh? So thank God they came out with else so we can simply write:
when world is started
if booleanvalue
set booleanvalue to false
else
set booleanvalue to true
ASYNCHRONOUS VS. SYNCHRONOUS, ROUND 2
Why is this so important, other than simplifying our code? I’m glad you asked.
Horizon allows us to send events to self or other objects on a delay. This is critical when doing things like rotating objects:
when world is started
send rotateme to self
when rotateme is received
send rotateme to self after #1 seconds
rotate self by 90.0.0 over #1 sec
Two things are happening here you need to notice. The first is the event listener you saw earlier, when world is started, which causes an event (rotateme) to fire. There are lots of event listeners to play with concerning things like collisions and grabs and button pushes, and you’ll have fun with those.
The second thing to note is what I’m talking about here regarding the near-simultaneity of the parser. Within the rotateme event, the “send rotateme to self after #1 seconds” command and the “rotate self by 90.0.0 over #1 sec” command basically occur at the same time. The send line is like saying in JavaScript: setTimeout(function(){ rotateme(); }, 1000);. So if you ever loop your events on a delay, like we’re doing here, then make sure your motion-over-time seconds parameter and your event-on-delay seconds parameter match, or you’ll get some crazy rhythm.
SCRIPT GIZMOS CAN ATTACH TO OBJECTS, OBJECT GROUPS, AND OBJECTS WITHIN THE OBJECT GROUPS
This fact made my brain explode. Let’s say you have a gun. If you’re me, it’s just an object group consisting of two perpendicular rectangles (for the handle and barrel) and one projectile launcher at the muzzle. If you’re my partner Jay, it’s a highly realistic looking sculpture to make you weep at its beauty.
The way you build this is to lay everything out, select them all, and then group them together and name them “gun” or something. You can then impart properties to the group such as physics, gravity, and grabbability, via its properties panel.
To make it fire, you attach an SG called “Fire Gun” to the gun. It says that when the player pulls the trigger on their controller to fire a projectile from the projectile launcher. The projectile launcher, being an object within the gun object group, is referenced locally within the SG’s Variables tab but passed into the script through the gun’s “Attached Script” panel.
Figure 4. One damn ugly gun shape with attached script to make its projectile launcher fire.
This causes the projectile launcher to fire a pretty little sphere. If you want those spheres to do something, however, you have to attach a separate SG to the projectile launcher itself.
The parent gun object can be referenced within the projectile launcher’s SG if you like. Maybe upon projectile impact, you want the player to drop the gun for some reason.
Figure 5. Script attached to the projectile launcher, which is inside the gun object. Its script references the gun object to make the player drop the gun upon projectile impact.
This is just one example, but it’s an important concept for you to know if you want to impart your complex objects with complex behaviors.
DEEP WEED THOUGHTS: A SCRIPT GIZMO IS AN OBJECT’S BRAIN
Since an object can only have one SG attached to it, I find that comparing the SG to a brain is a useful analogy. Perhaps this is body-over-brain bias at work, but this comparison reminds me that the SG is an optional attachment to the object and that the object is not really an instance of the SG. The SG is only a set of instructions, and if separate objects use the same SG, then fine; they won’t necessarily think the same thoughts. The SG is nothing without the object; you hear me? Nothing!
Philosophy aside, I hope this primer helps break the ice between your programming brain and Horizon Worlds. If you have anything to add, please leave me a comment or holler at me on Facebook. I overly ambitiously intend to keep this article updated with new Horizon code releases.
This morning, I did something I’ve never attempted before: a cinéma vérité performance of “The Tell-Tale Heart” by Edgar Allan Poe, originally published in 1843. You’ll be able to watch it Halloween weekend online and hear it broadcast on WQSV 106.3 FM Staunton.
It began at my house, where Jay Haynes filmed my ad-libbed interaction with my landlady, Deena Warner. I wore full costume. As a continuous-shot, Office-style monologue, Jay stayed with me during the drive to WQSV, the “police station.” There, station manager Ben Leonard heard my murder confession, Poe’s story.
The WQSV radio broadcast and the film will be aired on Halloween weekend, details TBA. Thanks to Jay for his help, and thanks to Ben and WQSV for the venue!
And now, to get you ready, here is Vincent Price performing “The Tell-Tale Heart”:
This has been the year of video game programming. In a few weeks is the deadline for IFComp2021, to which I’m submitting a text-adventure adaptation of the short story “Second Wind.” You’ll have an opportunity to vote on it against all the other competitors.
Below is a screenshot of my current doodle: a random maze generator, through which you have to navigate while avoiding NPCs. My kids and I are still coming up with ways to make it better, but I’ll share it with you soon.
Here within the city limits of Staunton, we regularly pay city fees for our water and sewer and for our trash and recycling. However, perhaps because they are nonsensically spending $200,000 on golf carts, the city now needs to tighten the budgetary belt a little. Their solution is to eliminate curbside recycling. (See the discussion beginning on page 117 of the April 1 budget work session minutes.)
The City Council is holding a public hearing on the budget tomorrow night at 7:30 p.m. I encourage everyone who cares about this subject to participate either by in-person or phone-in comments or by sending an email to the Clerk of Council like Deena and I have done below. (Click for instructions.)
Here is the email we sent:
Dear Clerk of Council:
We are writing in opposition to the proposed change to the city recycling program, as contemplated during the April 1 budget work session, to eliminate curbside recycling.
As we understand it, if Staunton citizens wish to recycle their household glass, paper, and metal wastes, they will no longer be able to place them in curbside bins for collection. Instead, they will have to transport their materials to a collection center at Gypsy Hill Park.
While the objective to reduce fees is laudable, the council overlooks the effect human behavior will play in all this. Most of us do not have the time, energy, and some cases, the transportation to cart our recycling to the park every week. We pay city fees for this service, so that is the service we expect to receive. If the city expects us to port our own recycling to the park, then most of us will simply choose not to do it. We will instead opt for the convenience of throwing it all into the regular trash, the environmental impacts be damned.
The council’s analysis suggests that their new model will permit the resumption of plastic recycling through Dave’s Recycling in Harrisonburg. Fine; if having a collection center at GHP will facilitate plastic recycling, then by all means establish a plastic-collection center there. But do not tie that to general recycling unless you wish participation in general recycling to be severely impacted.
Sincerely,
Matthew & Deena Warner
It’s taken nearly five months, but I now have a bug-free (I think!), responsively designed game you can play against three computer opponents. They’re very stupid opponents because they randomly make their decisions, but at least they follow the rules. The next programming phase I’m beginning should be the fun one: how to make the computer smarter. This is the part that should scare all sci-fi writers, because obviously I am just one boolean function call away from creating an apocalyptical computer sentience.
No update yet on when Juhyo will be available for the general public. As always, stay tuned!
Watching and reading the impeachment trial is doomscrolling of news we’re currently powerless over. The managers have a slam-dunk case and top-notch presentations, while the defense is comically feckless, but fascist sycophants like Lindsay Graham, Ted Cruz, and Josh Hawley will lie and acquit him anyway.
I hope that, thanks to the overwhelming evidence being presented, the foregone conclusion of this trial will prove very costly to the Republican party. Trump’s actions were a deep betrayal of his oath, and the resultant, continuing damage to our republic is an existential threat to the United States.
Below is the 13-minute video played in the Senate on the first day. If you have the stomach for it, I urge you to watch the whole thing.
It is so obvious that this is exactly what Trump wanted to happen. The screaming crowd, which crushed and killed police officers, is an appalling thing to behold. And to think that Staunton Mayor Andrea Oakes tried to justify this evil with the words of Martin Luther King, Jr., is just shameful.
As long as GOP members and their families weren’t personally threatened, it was all right with them if Donald Trump betrayed everything the USA stands for. That’s one of my takeaways from Wednesday’s events at the U.S. Capitol.
Fine, then. Maybe now they’ll do the right thing, and the right thing will be on their desks tomorrow when the House introduces an Article of Impeachment. It will surely pass the House and go to the Senate, where Mitch McConnell will surely sit on it for the remainder of his party’s majority.
After that, the Democrat-led Senate will surely hold another impeachment trial. It will be done over President Biden’s objections. And there’s a good chance that, again, the Senate will not convict, because that requires a two-thirds vote, and the Democrats will only have a razor-thin, one-half majority.
So, again, the integrity of our nation will fall to the dubious care of Republican senators, those who make up the difference between one-half and two-thirds.
If I were one of the impeachment managers standing in the well of the Senate on closing-arguments day, I would present those particular senators with the reasons for why they must convict: