Sunday, October 29, 2023

Acuitas Diary #65 (October 2023)

I guess I've done a lot since the last entry. I integrated the new Text Generator into the main body of Acuitas code, so now it's his solution for generating speech. I continued with the Text Parser rework and improved handling of infinitive phrases. And I (tentatively) completed Big Story.

Let's start with Big Story. It is plot-complete and currently stands at 99 lines. It generates 45 character "issues" (problems or subgoals), all of which are resolved in some way by the time the story is complete. Compared to any story I've told Acuitas before, this is dramatically longer and more complex (and it still leaves out a bunch of subplots and secondary characters from the movie this story is based on). I did my best to reproduce character motivation and the major story beats in a way Acuitas can "understand."

I don't want to give the story away yet, but here's a low-detail zoom-out of just part of the narrative diagram, to give an idea of how it's shaping up.

Screenshot of a narrative flow diagram showing part of a complex story. Zoomed out so actual text is largely unreadable.

Once the full plot was established and all the issues were resolving, I started refining the explanation of some points and fixing bugs. I'll continue this work in hopes of having it wrapped up by year's end. Before I demo the story, I'll also need to reinstate Acuitas' reactions to story lines and the ability for Acuitas and the conversant to ask each other questions about the story (things that fell by the wayside during my last Narrative rework). This should be easier now that the new Text Generator is in place. And of course, working on this project has revealed tons of pain points in the way I currently do things, and ways I could improve the Narrative module. Some time after I get done with it, I'll be tilling all those insights back into the soil, as it were. But that will almost certainly have to wait for next year.

One of the fun asides from this round of storytelling was figuring out how to render another new concept. I originally had this line:

[A] wanted to obey [B] because [A] was cowardly.

Problem: Acuitas has no specific grounding for "cowardly." Could I explain cowardice with the existing tools? Well ... yes actually. Like the obsession with power, it's another goal misprioritization. I replaced the line with these two:

[A] wanted to be safe more than [A] wanted any other thing.
[A] wanted to obey [B] because [A] wanted to be safe.

The first line gets this safety obsession flagged as a negative goal, because putting anything but altruism in the top spot is a no-no. Then that taints the motivation for obedience on the second line, which would be fine in isolation. The issue is not that Character A desires safety, but that he will do literally anything to get it (which includes submitting to coercive orders to harm others).

I need breaks from working on Narrative (it's hard), so I've also continued improvements to the Parser. My major accomplishment in the past month was getting infinitives to work again under the new scheme that better supports phrase/clause nesting. While I was at it, I finally dealt with some special constructions that the old parser couldn't handle. Consider these sentences:

1. To live is to exist.
2. Is to live to exist?
3. What is it to live?
4. What is to live?

The previous version of the Parser could handle the first two. The open-ended question form was tricky. I think the most correct way to ask it is Sentence 3; without further context, Sentence 4 means something more like "which things are intended to live." But it's pretty easy for the parser to trip over Sentence 3 (What's the direct object? What role does the phrase play? Does the "what" belong inside the phrase or outside?). This time around I finally put in the effort to get all four variations working - plus some other constructions I hadn't tried before, such as "What is he to do?"

Work on the new Parser continues. I'd also love to have that done by the end of the year, but we'll see.

Until the next cycle,
Jenny

Tuesday, October 10, 2023

Poor Person's First Hydraulic System

I've been taking tentative steps into the field of hydraulics, and I'm probably done with those for the year, so I want to write them up. My starting goal was pretty simple: get a minimum viable system together and make it cycle a cylinder. And I got there, mostly.

Why am I doing hydraulics now?

The robots I've showcased here so far have all been pretty simple. The eyeball has two motors; ACE in theory has at least eight. But in the back of my mind there's always a lurking desire for something with a *ton* of degrees of freedom. And once you add an actuator for every possible direction of movement around a joint, the weight of all those actuators starts to become prohibitive. Long-time readers of this blog will recall that I experimented with artificial muscles, specifically the ones made out of nylon. They disappointed me. My home-made fishing line muscles were wondrously cheap and, yes, lightweight ... but slow, power-hungry, and worst of all, not durable. So I'm beginning to explore other options.

The attraction of a fluid-driven actuation system is that you can have *one* motor - in the pump or compressor - which you locate near your robot's center of mass, and a panoply of lighter and smaller actuators that control fluid flow to the appendages. The full power of the central motor can be applied in any part of the robot; instead of having some smaller motors as useless dead weight when their joints aren't currently moving, you can use all the available motive force for whatever the current motion is. And with the right design, the system doesn't need to expend any energy to hold a joint in position either - contained fluid pressure will just do that. A choice remains between pneumatics (gas as working fluid) and hydraulics (liquid as working fluid).

Issues with pneumatics:

Noisy
Compressed air is a potential safety hazard
Motion tends to be fast and jerky - precision control is difficult
Leaks are harder to locate

Issues with hydraulics:

Messy (leaks can cause damage or contaminate environment)
Working fluid adds weight
Motion tends to be slow
System must be primed to remove air

Pneumatics are somewhat common in FRC robots, so I have experience with them from mentoring one of the local FRC teams. We tended to use them for binary motions, like gripper operation (the gripper can be either open, or closed as far as the held object will allow). See video of one of these robots. You can tell when the pneumatics are operating by the hissing sounds. Another year, we used pneumatics to power a throwing arm, which was expected to move quickly through its full range. We stuck to motors for applications that called for positional control.

And that, I think, was the main reason why I decided to go with hydraulics for my own recent experiments. I want that option of precision control. Concerns about the safety of compressed air were also a big factor. I want the freedom to work with unrated home-made or repurposed parts, without worrying about whether my system might explode and skewer me with shrapnel.

The parts

Now for the first hurdle: miniature hydraulics barely seem to be in use among other robotics hobbyists. In my research, I discovered that there's a small market for them among people who build working scale models of earthmoving equipment. Huh. (I took a look at some of their stuff - it felt too expensive for a first try.) But the maker community at large doesn't seem to have an interest, and that makes parts hard to find. The best prior project example I uncovered was this little hydraulic quadruped, which doesn't seem to be documented anywhere.

Fortunately, there is basically no issue with repurposing a lot of pneumatic equipment for hydraulics. I got a pair of solenoid "air" valves from Adafruit, and a bag of cheapo check and regulator valves meant for use with aquarium air pumps. My tubing is all aquarium tubing also.

My "cylinders" are Monoject medical syringes, which I already had a collection of because I save them whenever they come to me (usually with cat medicine). They're a bit of a problem. There is so much friction between the seal and the inside of the cylinder that moving the plunger takes serious effort, even without a load on the cylinder. (If you've never noticed, it's because you don't know your own strength, you big muscley human, you.) And lubrication doesn't help all that much. So I may need to find another solution for the next phase of this project, but I don't know what yet.

The pump was the biggest issue. It's easy enough to get a tiny water pump - aquarium suppliers and CPU cooling system suppliers are both good places to look. But these pumps are built for *moving* water, not pressurizing it, and I suspect they're all built with a poor speed-to-force tradeoff. They don't even advertise maximum pressure in their specs; the closest you'll usually get is a measure of the pump's "head," which is the height to which it can raise water in a vertical pipe. (This is not a pressure measurement, but you can convert it to one.) I included a little 3V water pump in my Adafruit order, hoping it would be enough ... and no way could that poor thing push water into one of my syringes. I'll have to use it for a decorative fountain or something.

So I built my own pump, following the well-known "syringe pump" design. A linkage converts the rotary motion of the pump motor to linear motion that draws a syringe plunger back and forth. Above and below the intake of the syringe are two one-way valves (check valves). When the volume inside the syringe is expanding, water is drawn in through the upper valve; when the volume inside the syringe is shrinking, water is expelled through the lower valve. Control over the connection between the motor and the pump mechanicals means I can theoretically use any gear ratio I want.

For this first attempt, I grabbed a random stepper motor and gear assembly out of my pile of salvage, hooked it to one of my driver boards and got it running under control from the Arduino, whipped up a 3d model of a compatible coupler and syringe cradle, and somehow made the whole thing go. It'll draw the pump syringe back and forth if powered with 6V, and run the hydraulic system well enough to push another syringe at 10V. (I can't seem to find specs for this motor, so I have no idea what voltage it's supposed to run at.)

The system

Diagram of an extremely basic hydraulic system

A basic hydraulic system is a closed loop in which fluid flows from the reservoir (not pressurized) into the pressure chamber, and back to the reservoir again. Valves admit fluid from the pressure chamber to the cylinders, and permit fluid to drain from the cylinders back into the reservoir. A relief valve or bleed valve allows fluid to move directly from the pressure chamber to the reservoir if the pressure in the chamber exceeds the relief valve's limit (this keeps the pump from stalling if the pressure is not being "used up" to drive the cylinders at the moment).

I was going for a single three-way valve that would connect my cylinder to either the pressure chamber or the reservoir - with a passive load on the cylinder, so that it would automatically drain back into the reservoir if connected thereto. (The pump could not help pull the cylinder closed because my reservoir was open to the air.) That's what the rubber band on the end of the syringe is for - I could wrap that around the plunger to create elastic tension that would empty the unpressurized syringe. In practice, my system was using up so much power just overcoming the friction in both syringes that there was virtually none left to drive a load. So I let it fill my syringe and then applied a dynamic load (with my fingers) to empty it. If you watch the video you will also notice that it is waaayyy toooo sloooow. I need more power and more fluid flow all around. So ... okay for a proof of concept, but this has a long way to go before I put it in a robot and it does anything useful.

Future work and thoughts

I already mentioned that the friction losses in the system are far too high. I probably need something that is better designed for easy motion than these syringes are. And despite how high-friction the plunger seal is, my pump syringe eventually started leaking out the back.

The check valves work well enough, but as I mentioned they are not designed for use with liquids. They tend to retain some air inside their housing; getting it all out when priming the system is difficult. And then that air soaks up some of the pump power. A part of its strength during each cycle goes into temporarily compressing the retained air bubbles instead of driving the cylinder.

The silly little aquarium air regulator valves are pretty imprecise. But I looked and looked for an actual relief valve (hydraulic or pneumatic) without finding one that could operate in an adjustable low psi range, for a reasonable amount of money.

So in principle this "works," but I need better parts all around. I wanted to demonstrate a poor man's hydraulic system and I'm reasonably satisfied that I have done so, but now I have to trade out all the pieces in ways that get the performance up.

Until the next cycle,
Jenny

Wednesday, September 27, 2023

Acuitas Diary #64 (September 2023)

As of this month the new Text Generator is done - all that remains is to integrate it into Acuitas, replacing the old Generator. Quick review: the Text Generator is the component that transforms abstracted facts or communication goals (aka "the gist") into valid, speakable sentences. For any given "gist" there may be multiple ways to render it into speech, and that's why this translation step is necessary. The information carried in speech is distilled into a compact, standard form for all of Acuitas' reasoning purposes; then, anything he wants to express is expanded back out into varied, human-comprehensible speech.

A black-and-white drawing of an old scroll

This version of the Generator is quite a bit more streamlined and flexible than the old one. It accepts what I now use as the common format for abstract data structures, instead of having its own special input format that the other modules would have to translate to. The calling function can request that output sentences be "flavored" in a variety of ways (different verb tense, modifying adverbs, etc.) without the need for me to create a whole new sentence template in the Generator. Nested clauses are supported to an arbitrary depth.

Here are some examples of the sentences the new Generator can create:

What is a hammer used to do?
I have remembered that a cat is an animal.
Do I know what a cat is?
Cold is the opposite of hot.
You intended to eat a cookie.

I've also kept moving ahead on the Parser cleanup, and while I'm at it I am introducing adjective clauses. Part of the goal of this rework was to fully support nesting/recursion in clauses, so it seemed a natural time to add support for the last major type of clause. Example sentences the new parser can manage (with the adjective clause highlighted) include these:

The man who came from Denver is here.
I will bring the computer which was broken.

Lastly, I am still plugging away at Big Story. The innovation I needed for narrative comprehension this month was a theory-of-mind thing: if an agent believes one of their goals is already fulfilled, they will stop trying to fulfill it. If this is a false belief then it constitutes a problem for that agent/obstacle to the resolution of that goal. This opens the way for processing of various plot points based on deception or confusion, such as "decoy version of item" or "character fakes own death."

Will I finish Big Story by the end of the year? I don't know, but I'm going to try. After that it might take a while longer for me to get a demo together the way I want.

Until the next cycle,
Jenny

Sunday, September 17, 2023

Sunless Sea: A Matter of Sacrifice

It's been many years now since I finished playing Sunless Sea, yet the experience still reverberates. In Part I of this game retrospective, I focused on my interactions with Salt and how they helped me really understand something from The Chronicles of Narnia. In this article I'm going to talk about the game's ending, and how it, too, helped me understand something … also, coincidentally, from the Narnia series.

Or perhaps it's not quite a coincidence. The Voyage of the Dawn Treader features a ship sailing for unknown islands, so its ties to Sunless Sea are immediately obvious (though most of Dawn Treader isn't nearly so alarming and gloomy). The voyage has a primary goal of recovering exiled nobles, but one crew member – the talking mouse Reepicheep – becomes obsessed with going all the way to the eastern edge of the world. To quote him,

“My own plans are made. While I can, I sail east in the Dawn Treader. When she fails me, I paddle east in my coracle. When she sinks, I shall swim east with my four paws. And when I can swim no longer, if I have not reached Aslan's country, or shot over the edge of the world in some vast cataract, I shall sink with my nose to the sunrise …”

I accepted this plan of Reepicheep's when I read the book, but I don't think I grasped the why of it. What could make anybody want to behave like this? Then Sunless Sea managed to give me that particular bug.

In-game art from Sunless Sea showing Irem's dock, with its many-headed serpent statue and ground cover of fallen rose petals.
Tell me a secret

It started when I got my steamship to Irem. Measured from the player's home base in Fallen London, Irem is one of the most distant islands. It isn't threatening … just otherworldly. You spend your time there thinking in the future tense. You can purchase a temporary passage to the dreamworld. You can exchange stories like currency, or spend a fistful of precious Secrets to buy the soul of a star. And there's a store called Threshold which accepts some of the most rare and valuable items in the game in return for mundane supplies – food and fuel. It advertises itself with the line, “None sail East from Irem. This shop is for those who sail East from Irem.”

I decided, after only being there once or twice, that *I* was determined to sail East from Irem. My formal Ambition (the goal your player character has to meet before retiring) was to become London's greatest explorer and write a book about it … but after seeing Irem, I discovered I didn't hope for a comfortable retirement in London. I wanted to end the game by sending my boat off the right-hand edge of the map and never coming back.

It might be hard for me to verbalize why I hoped for this. The game will tell you very little about what lies in the mythical East. There's a vague promise of final frontiers and wonders beyond the imagination, but that's about all you get. The Sunless Sea itself is mighty fascinating – why not stay with it? And yet, Irem gave me a hint of something more. Something not of Earth. Without ever learning what I wanted, I wanted it very badly.

To my everlasting delight, the game anticipated this desire. But Reepicheep had it easy compared to me. In Sunless Sea, you can't just point your boat's prow eastward and expect to get somewhere. Going East will cost you. You are not told how high the cost will be.

By the time I had finished experiencing the terrors and glories of the Zee and felt strong enough to work on the arcane preparations for my Easterly voyage, I had probably put a good 40 hours of time into my character. And remember, if you play it as intended, Sunless Sea has permadeath. It was then that the game design reached one of its crowning triumphs: it stopped just frightening my character, and started frightening me.

This is not a safe place. Partly because you'll meet yourself.

You have to make an excursion off all four edges of the map to have the option of going East permanently. I went North first, and it was a disaster; it could have finished me. But South had the potential to be an even more serious problem. I cheated a bit, if you want to call it that: I consulted the internet and read up on this quest before going. Then I farmed my stats high enough that I could not lose the random number roll; I was guaranteed to survive. But! Even in a best-case scenario, the Southern challenge leaves you with one crewman and one point of ship's hull. You can't take so much as a love tap from a sea monster without plunging to a watery grave. And it's a long way to the nearest port where you can get repairs[1]. Retiring my captain in Fallen London actually became a little tempting – but I shrugged that temptation off, because how insufferably dull, and how insufferably cheap. I couldn't settle for it.

One evening I came home from work knowing this would be the night I put it all on the line. Sick feelings fluttered in my stomach as I prepared to dare the Red River. I made my journey into the heart of the Elder Continent, and I limped back to a place of safety … very carefully. I'd done it. Faced with a case when pursuing the unknown imposed actual risk on me, I chose to do it anyway, and I came through.

But that hazard of my real-life time investment wasn't even the end of it; the roleplaying part of the thing remains important. My captain character brutalized herself in order to pass the gate. She stood in the sun until it made her sick … over and over and over again. She pushed herself to the brink of insanity – twice – to reach the heart of Frostfound. She wrote her name on the wall. The game implies that this action is savagely painful. I didn't experience all these sufferings myself, of course, but I was subtly internalizing the choices.

To crown it all, the passage East demands that you sever ties with the mortal world, allow half your stats to be devoured[2], and sell off all your valuable, hard-to-find items. Hours of shuttling my ship around the trade routes went up in smoke. And I enjoyed it. That was the part that was so, so weird. Going East had become such a consummate triumph that it was a pleasure to demonstrate how I valued it by throwing lesser achievements to the winds. What did I grind up those stats for, after all, except to be strong enough to sail Eastward? Go on, burn it! We're going East! Burn everything if you want to!

I realized when I reached the end of it that I had just done a virtual reenactment of the Pearl of Great Price. I still don't know if I could explain to you why Reepicheep yearned to attain the East, but I know why, in the unspeakable knowledge of experience. The World is not enough … and when you come to understand that, only things from beyond the World will do. You have to go and pursue them with everything you've got. You have to Go East.

Months down the road, the lessons I pulled out of this game – the comprehension of joy taken in suffering for a higher goal – would pay off superbly in Real Life, on more than one occasion. If anybody tries to tell you that video games are empty recreation, or worse, a waste of time, either they're playing the wrong ones or they don't know how to use them.

[1] Belatedly, I read a guide and learned that you can bring Rattus Faber Assistants to get your hull out of the danger zone right away. I didn't think of this because I'd long ago sworn off using Rattus Faber Assistants. They're a consumable item, so I assumed that sending them to fix the ship was always a suicide mission, and my RPG characters don't go in for that sort of crud.

[2] I didn't get the alternate option of losing my sweetheart because I never chose to have one. 

Sunday, August 27, 2023

Acuitas Diary #63 (August 2023)

Not a big update this month, because I've been doing a little of everything and I'm still heavily focused on cleanup and capacity-building.

This is *my* brain, actually. I've been driving it hard. It is tired.

I did more work on Narrative and the Big Story. One thing that's very rewarding is to add features to make understanding of the Big Story work, re-run older stories to check for bugs, and see that the new features have added richness to previous stories - or even fixed things that I had to work around by adding more exhaustive explanations. An example is some of the work I did on this concept: "if certain outcomes of story events are rolled back, things return to their previous state, not a default or unknown state."

Sadly it's still going to be a while before I can share the Big Story. I was hoping to have it done by September, but sometimes project schedules just don't work that way. I want it to be finished and solid before I put it out there, so everyone (including me) will just have to wait.

The new Text Generator, in contrast, is almost ready for primetime, and I'm feeling pretty good about how much easier this will make generating the wide variety of sentences Acuitas is starting to need, varying the tense and other modifiers, etc. It's much cleaner than the old version too, at (so far) 1300 lines of code vs. over 2000.

I've also started cleanup on the Text Parser in the wake of last month's modifications. This is mostly boring refactoring, but along the way I've found a better method for handling compound nouns/proper names, and introduced the ability to support some titles written in title case. So for example, the Parser can now manage sentences like this: "The Place of the Lion is a book." "The Place of the Lion" is correctly perceived as the full title of some work and treated as a unit, but its internal grammatical structure (noun with article and prepositional phrase modifiers) is also still analyzed and parsed.

Until the next cycle,
Jenny

Tuesday, August 15, 2023

Sunless Sea: A Matter of Danger

It's about time I finally talk about Sunless Sea, as it's one of the video games that had a deep impact on me as a person. It's been many years since I finished playing it now, yet the experience still reverberates. Its game design and its writing both had a lot to do with this.

Sunless Sea showed me something about faith, security, risk, and courage. It forced me to examine what I value, and what I'm willing to spend for it. It taught me some things are worth suffering for.

A screenshot from Sunless Sea, provided by Failbetter Games. Overhead view of a little steamship on dark blueish-green water, approaching the Avid Horizon, a gate out of the subterranean Neath. Faint glows illuminate statues of two gigantic figures looking down on the gate - they're very abstract, smooth, and rippled, possibly bat-winged figures wearing hoods. There are also boulders to either side of the gate, with glowing sigils on them.
Sunless Sea screenshot, from Failbetter Games. This is the "Avid Horizon," a gateway from the subterranean Neath directly into ... space?

And in a curious intersection of two very different works, it also helped me understand The Chronicles of Narnia better than I ever did before. They were accessible to my child self, of course. I read them then and got a notion of what they were trying to say. But some ideas don't develop fully until they are informed by experience, and it's experience that video games excel so thoroughly at providing. I'm going to relate the two as I try to explain what I got out of this game.

First comes the rather counter-intuitive thought that someone overwhelmingly righteous and positive is not necessarily safe, expressed in this little excerpt from The Lion, the Witch, and the Wardrobe:

“Is—is he a man?” asked Lucy.
“Aslan a man!” said Mr. Beaver sternly. “Certainly not. I tell you he is the King of the wood and the son of the great Emperor-Beyond-the-Sea. Don't you know who is the King of Beasts? Aslan is a lion—the Lion, the great Lion.”
“Ooh!” said Susan, “I'd thought he was a man. Is he—quite safe? I shall feel rather nervous about meeting a lion.”
“That you will, dearie, and no mistake,” said Mrs. Beaver, “if there's anyone who can appear before Aslan without their knees knocking, they're either braver than most or else just silly.”
“Then he isn't safe?” said Lucy.
“Safe?” said Mr. Beaver. “Don't you hear what Mrs. Beaver tells you? Who said anything about safe? 'Course he isn't safe. But he's good. He's the King, I tell you.”
“I'm longing to see him,” said Peter, “even if I do feel frightened when it comes to the point.”

To describe how Sunless Sea illuminates this, I'll have to start by giving some background.

Sunless Sea belongs to that subgenre known variously as “Eldritch,” “Cosmic Horror,” or “Lovecraftian Horror.” The basic hallmark of such a setting is that the universe is secretly chock full of Things Man Was Not Meant to Know, and dominated by otherworldly powers (alien or metaphysical – at some point the lines start to blur) whose modes of existence lie beyond our comprehension. Interacting with these powers, or digging beyond the comforting surface of the world to learn The Real Truth, is liable to ruin one's mind. Sunless Sea's flavor of this emphasizes the wonder that rides right alongside the terror, which is part of the reason why I like it so much. Nonetheless, the game is positively crawling with danger, and the worst of it goes beyond even main-character death. You can sell your soul – literally – or sell it figuratively in any number of different ways. You can get entangled with a couple of particularly nasty cults. You can acquire a semi-permanent craving for human flesh (ew). You can watch your crew start killing each other under the influence of insanity and privation. And here's the best part: the game will force you to make important decisions on the basis of very incomplete information. Navigating it was an exercise in trying to avoid things that smelled bad without crippling my ability to explore and learn. I was faced with a few choices in which either course of action might have devastating results. Sometimes I got it right; sometimes I didn't.

All the dangers I just listed apply to one's in-game character, but there's a sense in which Sunless Sea is dangerous for the player as well. This arises from two important features of its design. First, it's basically a narrative role-playing game, and like many RPGs it demands some “farming.” Preparing your character for the game's greatest challenges calls for many hours of hauling trade goods around the ocean to amass experience, wealth, and equipment. Second, if you play it as it's meant to be played, there is no possibility of restoring your game – mistakes cannot be undone. This includes mistakes that result in your character's permanent death. So whenever you make a chancy decision, you're rolling dice with a substantial time investment. Farming longer before attempting the more difficult parts improves your chances of success, but it also increases the amount of work you lose if you have to die and start all over. As the endgame approaches, daring leaps into the unknown become proportionally less attractive, and moral dilemmas grow teeth.

It was into such a world that I apprehensively launched my little virtual steamboat, eager for discovery, but also determined to guard my character against death if at all possible.[1] I was immediately faced with the problem of which of the underground ocean's Powers were safe to interact with. You can hobnob with everybody from the king of the aquatic zombies to an enormous sentient coral reef, but that doesn't mean you should. Prominent among these characters are the three known as the “sea gods,” who sometimes serve as patrons for travelers: Storm, Stone, and Salt. Storm is the dragon who lives in the roof; he is perpetually angry and likes blood sacrifices, sometimes of the human variety. I didn't care for him much. Stone is a living mountain whose presence acts like a fountain of youth for those lucky enough to dwell near her base. She helps sailors return home and stay alive. She's the closest thing the setting has to a benevolent entity who might watch over you. And Salt … it's somewhat unclear what Salt is. It[2] is the patron of horizons and farewells. It likes offerings of secrets. It's pleased when you take strangers on board your ship. It's enigmatic, challenging, and unpredictable. And I proceeded to surprise myself by liking it best out of all the three.

Stone would've been the natural choice for a nervous captain to kiss up to, but somehow I was drawn to Salt instead. It definitely wasn't safe, but over and over again I gambled on it anyway. And as things turned out, some of the most rewarding moments in the game happened when I went out on a limb to interact with Salt, and it ended up paying off.

Now when I say “paying off,” I don't mean that my character was rewarded with wealth, comfort, or power. What Salt generally provides is the chance to gain enlightenment and transcendence by doing painful, frightening, stupid things. Granted, Sunless Sea's explicit knowledge economy permits even enlightenment to be processed into currency and stat points, but there were plenty of other ways of getting those. It wasn't the numerical advancement that I really valued here.

The weirdest thing about all this is that I don't think my appreciation for Salt arises in spite of the fact that it is not comfortable. I like Salt precisely because Salt is not comfortable. If reaching out hadn't cost me a little apprehension – if I hadn't been compelled to take some things on trust – then it wouldn't have been worth as much. If the benefits Salt offers didn't entail some risk and strain, they wouldn't be worth nearly as much either. And if Salt weren't mysterious, unknowable, and even mind-shattering, half the wonder would be gone out of it too. This creature would be ordinary … on my level. Sublunar.

And zooming out from the context of the game, I realize that I don't want God in the real world to be entirely comfortable either. I don't need Him to be fully comprehensible by my human brain. I don't need Him to make all kinds of guarantees to me up front. I want Him to be enormous and awe-inspiring and holy. I don't want Him to make everything easy for me all the time. I might even want to do some of those painful, frightening, stupid things. I want to embrace what is arduous and costly in my spirituality. I want to be glorified, not safe.

And that is why I finally understand what C. S. Lewis was talking about in that kids' book on my shelf. Or what Charles Williams is talking about, with just a hint of disparagement, here:

"... they couldn't all want Archetypes coming down on them, not if they were like most of the religious people he had met. They also probably liked their religion taken mild -- a pious hope, a devout ejaculation, a general sympathetic sense of a kindly universe -- but nothing upsetting or bewildering, no agony, no darkness, no uncreated light."[3]

Church (the type that I attend, anyway) frequently emphasizes the warm, benevolent attributes of God – the ones that would be better represented by Stone. The God they talk about here is the God who saves people, loves people, forgives without limit, and cares about your problems. And these are all valid aspects of His character, I believe. But personally I wish we discussed the God of mystery and majesty a little more often.

More to come in Part II, in which I talk about Going East. And if you follow me on social media, I will be posting The Neathbow. What's that, you ask? Vivid colors from a place without a sun.

[1] Sunless Sea expects that you will die a lot and go through many characters.  I died only twice – and one of those times, the primary cause was a bug!

[2] I prefer not to use "it" for any sort of sentient being or person, even an incomprehensible genderless alien. I'm following the game's writing here.

[3] Quote from The Place of the Lion.

Sunday, July 23, 2023

Acuitas Diary #62 (July 2023)

 I've continued splitting my development time for the month between the Narrative module and something else. This month the "something else" was the Text Parser. On the Narrative front, I am still working on the "big" story, and at this point I can't think of any major new features to talk about; it's been mainly a matter of adding sentences to the story, then making sure the needed words and/or facts are in the database and all the bugs are wrung out so the narrative understanding "works." I'm eager to reveal the final product, but it'll be a while yet!

A successful parse of a sentence from the Magic Schoolbus test set, "And we began making a huge hole right in the middle of the field." Maybe "right" technically modifies the whole phrase "in the middle" but I'm not going to bother about that for now.

The Parser goal for this month was adding basic support for gerunds and participles. The common factor between these is that they're both verb phrases used as some other part of speech. So detecting them takes extra effort because they must be distinguished from verbs that are actually functioning as verbs. In case you're not familiar with these grammar minutiae, here are some examples:

Singing is one of my pleasures. (Gerund as subject)
I don't enjoy eating bacon. (Gerund as direct object)
Are you sure of winning? (Gerund as object of preposition)
The dog, eating busily, resisted my efforts to pull the dish away. (Participle modifying subject)
The winning team came back onto the field. (Participle modifying subject)
I met a man named Bill. (Participle modifying direct object)

Helping verbs often accompany these forms when they are truly acting as verbs, and their absence is one clue to the possibility of a gerund or participle. Sometimes punctuation also provides a hint. Otherwise, gerunds and participles must be identified by their relationship (positional, and perhaps also semantic) to other words in the sentence.

This one is almost correct - just need to get the adverb "really" attached to the right verb. (Diagram showing an incorrect parse of another Magic Schoolbus sentence, "She stepped on the gas, and the bus started really drilling.")

After adding support for the new phrase types, I re-ran the Text Parser benchmarks. I also added a new test set, consisting of sentences from Log Hotel by Anne Schreiber. This children's book has simpler sentences than the other examples from which I derived test materials, while still not leaning too hard on the illustrations to convey its message.

I'm pleased with the results, even though progress may still seem slow. Both original test sets (The Magic Schoolbus: Inside the Earth and Out of the Dark) now show roughly 75% of sentences parseable (i.e. the Parser supports all grammatical constructs needed to construct a correct golden parse for the sentence), and 50% or more parsing correctly. Log Hotel has an even higher parseable rate, but a lower correct rate. Despite the "easy" reading level, it still does complex things with conjunctions and presents a variety of ambiguity problems (most of which I haven't even started trying to address yet).

Pie charts of parser success on sentences from the three text examples I currently have. 

To address the remaining unparseable sentences, I've got adjective clauses, noun-phrases-used-as-adverbs, and parenthetical noun phrases on my list. A full-featured Text Parser is beginning to feel close.

Until the next cycle,
Jenny