The Lighthouse Keeper

Among any number of negative habits is my tendancy to come up with an idea out of desperation at the last minute, play with it for a little while, and then fall in love and want to dump six months into it. Class workshops on different aspects of game design usually trigger this problem. This one is no different. (See also a simple RPG I’m trying to get working in Tabletop Simulator.)

As boring as it sounds, being a lighthouse keeper was as much about lifesaving as shipwreck prevention. A certain solitary type seems to have been attracted to the United States Treasury’s Lighthouse Establishment/Board/Service between 1791 and 1939 (which I think we can agree encompasses the “Golden Age” of lighthouses). Hoisting a dory into four-meter swells from a flooded gear room at the base of the tower in a pitch-black howling gale was a job requirement, and having a sturdy dog with sharp senses and no fear of the water along wasn’t all about companionship. (“Saved,” from the Louis Prang Collection commemorates a real lighthouse dog’s rescue of a child.) Denis Noble’s Lighthouses & Keepers is a good intro to this world.

I’m attracted to the character of an Indian man serving as a keeper sometime around the turn of the last century–someone like WWI US Army Sergeant Bhagat Singh Thind, who under the racial ideas of the time tried and failed to gain US citizenship when the Supreme Court ruled that, while “Aryan” he was not “white.”

I envision an adventure game made up of episodes (equipment failures, hurricanes, shipwrecks) with free exploration segments before the crisis portion triggers, in which you wander the lighthouse with your dog, read water-damaged books (real ones) about “race science” and other odd but consequential ideas for your character’s situation, and maintain the equipment. The offshore lighthouse serves as a metaphor for your own situation, literally defending a shore you can never reach. In these quiet moments, most of your default push/pull interactions are small acts of cleaning and maintenance (and scritching your dog). I want to make you complicit in the feeling that you’re constantly–even lovingly–maintaining this life-preserving tower.

In truth, an offshore lighthouse was manned by a crew of 3-4. Many keepers were married, and raised families at the facilities. The “solitary” aspect would be a departure from strict historicism–though sickness, injury or just plain poor manpower planning could easily leave a single hand to run a light. It was a quiet and hardworking life, though vastly superior to the sailing trade most keepers left.

I’ll leave you with this cutaway of Britain’s Eddystone Lighthouse, and an 1892 magazine article describing a visit there. It’s a fun topic to get lost in for a few hours. But for now, I think it’s best I leave it at that.

Tags: , , , , ,

Tiny Convoy

“Tiny Convoy” is as a demo-length convoy simulator–a moving base builder–developed in Unity 2019 by Niek Meffert, Lucas Oliveira and myself. Playable betas for Mac and Windows can be downloaded here. The goal is to survive as a group of tiny robots in a big dangerous world: find power, upgrade your bots, and avoid dangers.

Remember the annoying escort missions in “Warcraft III,” where your soldiers kept hauling off to attack anything that moved, instead of protecting the things they were supposed to? It’s like that. Except your bots can’t attack anything. You are essentially robot herbivores. Looked at another way, “Tiny Convoy” is a herd simulator.

One-pager

As a small team in our first year Masters, the work was loosly siloed. Oliveira took the lead on modelling and texturing, Meffert was point on UI and the first version of the A* pathfinder, and the C# code base is about 90% mine. (I also designed the Touch-Me-Not exploding plant.)

1. Emergent visual storytelling–no dialogue, no scripted beats
2. Keep moving & exploring
3. No weapons
4. Cooperation is essential to survive & thrive

Design Pilars

Our goal was to marry emergence and progression in an interesting and satisfying way. We wanted to build a game in which the player could create in their own mind an emergent storyline around an algorithmically-generated world. If the content one encountered became too boring and undifferentiated, there would be no sense of progression, and little incentive to keep exploring. On the other hand, if too many things were deliberately laid in the player’s path at defined points, it would take on the feeling of an “on rails” story game, to the detriment of replayability.

Concept sketch

Every “Civilization” player remembers when the Mongols took their capital, and they rallied back to win. What happened was only the randomized game content interacting with the rules and the player’s choices, but it took on the quality of a narrative moment because it was different and valued by the player. Likewise, we wished to create moments like “When Little Blue got stepped on,” and  “When we found the field of Touch-Me-Nots on the other side of the desert”—moments created entirely by the game systems interacting with the player’s choices, but which would feel personally meaningful.

The game loop for Upgrade Mode

 To do this, we needed to construct a series of game loops, with systems of player feedback. We would gradually challenge the player by introducing limits on stock (not enough power available) and new sinks (dangers that damage parts). The game engine would introduce new content and changes to the starting conditions in a measured manner as the player moved farther and farther across the game world.

Since I was mostly the programmer, I’d like to look at some of the systems that make the game engine work. But first…

Inheritance?

For me, what made this game possible was an email exchange with Michael Schmidt at Unity, in which he cleared up something critical. Since Unity regards every script as a different C# type, how can you subclass a script into different variations? More specifically, how can one script interact with another when it doesn’t know if it’s the class, one of the subclasses, or one of the subclass’s subclasses?

Crunchy McCrunch-Crunch

The key is that Unity will treat a subclass script as if it were any class up its chain of inheritance. When I subclass ActualThing into Upgrade, and Upgrade into Sensor, other scripts can reference a Sensor script as if it were an Upgrade script or an ActualThing script. So these lines are equivalent:

float currentMass = someGameObject.GetComponent<ActualThing>().mass;
float currentMass = someGameObject.GetComponent<Upgrade>().mass;
float currentMass = someGameObject.GetComponent<Sensor>().mass;

A Sensor script can then override, for instance, ActualThing’s takeDamage() function, and respond to it differently than, say, a rock would:

//in ActualThing:
public virtual void takeDamage(float damageAmount){
     //reduce hp
//in Sensor:
public override void takeDamage(float damageAmount){
     //reduce hp
     //reduce sight distance

This is how basic object inheritence patterns can be implemented in Unity.

Systems

The Grid: The first programming challenge was an infinite, non-repeating grid. Based on my previous thinking on large pseudorandom world generation, I worked out a system that places BigTiles (containing a 10×10 grid of normal game Tiles and other content on top of them) from a list of available BigTiles. A given x and y will always generate the same BigTile, allowing the game to dispose of BigTiles it no longer needs, but generate them again if needed. Each game picks a random x and y offset to the starting position–a pair of C# ints of value -2 billion to 2 billion. The x and y offsets are summed and used as another pseudorandom seed to further shuffle things around atop the BigTile. The list of available BigTiles changes based on the distance from the game’s starting point, allowing the game to gate more powerful and challenging content. Specific BigTiles can also be forced to appear, like the starting location.

Lots of stuff, not-quite-randomly generated

Pathfinding: The bots use an A* pathfinding system. Niek worked out the initial code, and I adapted it to allow planning without executing the route (for AI reasoning) and to talk to the existing grid-based systems. This required a deep dive into Amit Patel’s A* Pages, a deep summation of pathfinding systems, which I highly recommend.

AI: The bots not being driven by the player have competing desires, to which they assign weights based on need and availability of a solution. The highest weight wins. They may reevaluate their options several times on the way to their goal, but the current “plan” has a sunk-cost-fallacy bonus attached, to reduce indecisiveness. The AI can query the Pathfinder (a separate script) for the “cost” of a path; it will also store the steps needed for pathfinding, to avoid a processing-heavy path recalculation for the action it ultimately decides to take.

I grew up calling them that; turns out they’re “Touch-Me-Nots”

Mystery Boxes: Remember how every BigTile has its own pseudorandom seed number? MysteryBoxes are a system that uses these to “randomly” shuffle things around on BigTiles when they’re generated–plants, upgrades, whatever you’d like. The plant growing on top of a toppled monument? That’s not scripted. One limitation is that if something on a BigTile gets destroyed, it’ll reappear if the player ever goes far enough away and comes back. A special subclass, the CPUBox, will generate a new CPU (the base of a new bot) if your party is smaller than the allowed size, or a random Upgrade if not. Like other gated content, the maximum number of party members increases with distance from your starting point.

What Got Cut

It was always an ambitious project, and not everything made it over the finish line.

Glowing=on made it into the game, but no useful HUD feedback

UI Feedback: There’s a lot happening behind the scenes that the game doesn’t explain well. Every “CPU” (the brains of the robot, but also a physical robot part in the game) has randomized stats: Processing, Memory, Inputs and Outputs. These special stats aren’t altered by Upgrades, but they can be boosted by being close to (“meshing with”) nearby robots with higher stats. Processing governs how often an AI-controlled bot can reevaluate its choices. Memory is how much you can’t see but can “remember”–the fog of war. Inputs allow you a certain number of sensors you can equip. Outputs allow a set number of moving parts you can control. Likewise, damage isn’t well described, although your damaged parts do noticeably work less well.

Multiple “Car” Robots: Everything the bots do is designed around being able to take up more than one tile, dragging parts behind like train cars. Sadly, none of this made it into the final game, making even the word “convoy” seem slightly out of place. Bots sitting on top of other bots, and being carried along is–as best I can tell–entirely possible even in the demo build, but without trailers there’s not much point to it. So, no, we don’t get to play Tiny Convoy: Fury Road.

The Conversation Grid: The idea was to coordinate with your convoy without using words. You’d click on a friend and their internal map (from the Pathfinder) would come up as a grid of little icons. You could click on things to give them “ideas,” or to dissuade them from doing something dumb. It would have fed into their AI, not as a command, but as one of the AI’s competing ideas, with a boosted weight–sort of like the forgotten but brilliant “Galapagos.”

This is Running Long…

Tutorial subs came very late in the design process, when it was clear playtesters couldn’t understand much of what they could do in the game–breaking design pillar #1

With those caveats, there is the start of a fun little game here. The many interacting systems largely work as intended, and cross-talk in interesting ways. The whole visual and audio presentation is inviting and detailed. With more content, fine-tuning and iterative playtesting, this could easily become a very good game.

But, on to second semester!

Tags: , , , , , , , , , , ,

“Per Aspera Ad Astra” In One Image

The complete silhouette illustration by the German Symbolist master Karl Wilhelm Diefenbach, assembled as one ultra-wide image. “Per Aspera Ad Astra” (“Through Hardship to the Stars”) is a complex, striking and joyful work defying easy explanation. Diefenbach himself was an untethered, original thinker–Theosophist, Symbolist, Naturist, Himself-ist–perhaps best summed up in the paradox that virtue pushed past reason becomes vice. The silhouette procession of children, animals and much more was originally a 68 meter long frieze, designed in 1875 and executed by Diefenbach’s protegé Hugo Höppener (“Fidus”) while Diefenbach was in a sanitarium. It was adapted into a book of 34 illustrations by 1893, scans of which can be found on the Commons along with more of Diefenbach’s work.

The images for download here are from these scans, matched and straightened nondestructively with hand cleanup, into a 2.9GB greyscale 172,058 x 2,473 px Large Document Format file.

The scrolling YouTube video (above) is probably the easiest viewing method right now. Be sure to set the quality to full 1080p60 and go fullscreen.

The TIFF is 110MB, full sized (172058 x 2473 px) and may be compatible with more software. I’d recommend downloading the zip file, as trying to render the TIFF might crash your browser.

The PNG is full sized and only 67MB, but may be harder to decompress. Same browser warnings.

The JPEG is 6MB, scaled down to 64,000 x 920 px (the max for the file format).

First panel

Information in English is hard to find. “Per Aspera Ad Astra” sometimes seems to be confused with “Kindermusik” (“Children’s Music”) a different series sharing themes and at least one figure. Diefenbach spent many of his later years on Capri, where there is a museum dedicated to his surviving works. (Too few, sadly.) His reputation improved by the passing century, the original 68 meter frieze of “Per Aspera Ad Astra” is now on display in the town of his birth at the City Museum Hadamar.

Please note that this assembled version should not be considered a “transformative work” for purposes of copyright, so the image files here are in the public domain. I don’t currently have the storage and bandwidth on SpaceToast.net to host the original file, but if you’d like to work with it please contact me through the About page and we’ll figure out a way to get it to you.

Tags: , , ,

Forest: Beta 7

Introducing beta 7 of Forest, with better graphics, a more dynamic game world, and many behind the scenes tweaks. This project is released under an MIT License.

Updates

Forest Gods. Nearly all aspects of the board can now be influenced by randomly-generated, free-floating roamers. Some are dramatic (like lightning gods) others practically invisible (like soil porosity gods). They’re intended to make the forest more varied, and perhaps even less lonely and more mysterious.

Improved Fire. Fire has been an aspect of the game world for several versions, but is completely rewritten in beta 7 to be much more graphical, dramatic, realistic in its effect on the forest, and unpredictable.

Better Graphics. The band of the sun now moves throughout the year more accurately, and the stars now properly blur into rings as well. Fog is a custom shader, the minimum of height fog and linear distance fog. Lighting for the ground and water now comes from an array of lights aligned with the sun ring. (Trees are still sprites, however, and don’t yet respond to lighting.) The randomly generated forest’s average temperature is used as a stand-in for latitude.

Smaller Board. Moved from a 200×200 tile grid down to 128×128. This seems to tax the CPU a little less without noticeably changing the scale of the game.

Erosion. Soil is now washed along by water. Stream system formation is still rare, but it does happen.

Tags: , , , ,

I miss productivity, I hate the unskippable logos, I’m not a big fan of Steam, and it runs my laptop red hot, but wow is this game something.

Forest: Beta 6

Introducing beta 6 of Forest. This release should bring a much higher framerate in all browsers, and a number of small fixes.

Click Here to Play Forest

Architecture – A Quick Outline

I’ve tried to organize Forest into a series of big JavaScript Objects that group related activities, and Classes to cleanly manage everything I need more than one of. Please take a look at the game loop and WebWorker code if you’re interested in how any of it works. This project is released under an MIT License.

  • Control Objects
    • World: Manages weather, climate cycles & fps
    • Ground: Manages ground conditions, GridTiles, RenderGroups
    • Roamers: Everything that needs to be updated each frame, including the camera, the camera’s (invisible) target, lightning bolts, etc.
    • Mats: Materials and texture maps, including the ground’s dynamic texture
    • Sprites: Lifecycle and behavior management of trees, energy balls, etc.
    • PostProcessing: Manages GPU special effects for the scene, like bloom
    • Shaders: Overwrites some of Babylon.js‘s shaders with custom versions
    • Actors: Container for the Actor classes
  • Classes
    • GridTile: Manages one point on the map grid, and holds the Actors currently active on it
    • TileAlias: GridTiles in the first row and column use these to keep track of the geometry they must also update to smoothly wrap the map
    • RenderGroup: A block of GridTiles, which can be prioritized for drawing depending on the camera’s current position
    • Fire: An Actor which consumes other actors, then temporarily blackens the GridTile
    • Tree: A large, slow-growing Actor
    • FallenTree: An Actor which slowly loses mass, producing new soil
    • Grass: A small, fast-growing Actor, which greens the GridTile
    • DeadGrass: An Actor which slowly loses mass, producing new soil, while it browns the GridTile
    • ProtoRoamer: Class containing data fields and actions for things that roam around on the board
    • Camera: Subclass of ProtoRoamer, which moves the camera
    • Target: Subclass of ProtoRoamer, at which the camera is aimed
    • Energy: Subclass of ProtoRoamer, short-lived, produced where you click, which feeds energy to the Actors there
    • LightningBolt: Subclass of ProtoRoamer, very short-lived, obliterates all Actors on its GridTile and starts Fires on surrounding tiles

Updates

Better performance in all browsers. Beta 6 moves the process of updating water flow and ground conditions into a WebWorker, a second processor thread. Beta 5 was a major rewrite to accomodate this, moving most of the data of each GridTile object into a single, large Float32Array, and adding Getters/Setters to the GridTile class to make the array data behave like normal properties. Parts of the array can then be rapidly copied, to update the vertex data or to be sent to the worker thread, via the .subarray() function. Data returned from the worker thread can then be copied back into the main array via a .set() operation. Currently, any changes made to the board by Actors or Roamers during thread execution will be overwritten

Better performance in Firefox and Chrome. The GridTile prototype uses Getters/Setters to manipulate the data in the master Float32Array. This was originally done in Beta 5 to allow moving some updating to a WebWorker, but for whatever reason the major speedup of moving the data into the Float32Array alone ended up being worth the change. The index lookups in the Getters/Setters (e.g. ground.data[ground.indices.watertable+this.index]) bring virtually no overhead in Safari, but Chrome and Firefox struggled with them. Beta 6 caches the lookup indices in each object, which speeds up Firefox and Chrome considerably even absent the WebWorker thread.

Tags: , , ,

Forest: Beta 5

Screenshot from Safari 13.1 Mac

“Forest” is a peaceful, meditative god game. It is free, runs in any modern browser, and is played with one button (or finger). Each time the page is loaded, a forest with a random climate is created. You may interact, observe, or any combination of the two. There is no objective.

Click Here to Play Forest

The game is written in JavaScript, using WebGL via the Babylon.js framework. Beta 5 is a preview release for which I’m grateful for feedback– a major rewrite, much faster and more memory-efficient than previous betas, with most of the major systems in place for the game as I’d originally conceived it. If you’re interested, please take a look at the source code.

MIT License

Copyright (c) 2020 Matt Rasmussen

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Tags: , , , ,

Forest Fire: A Game for Kids v2

Forest Fire is a simple Pandemic-like (or Pandemic-lite) game for 2-4 kids, age 5 and up. The players work together to put out the fires in a forest. Encourage them to talk over their moves, and strategize as a team.

Make a 6×6 grid. Number the rows and columns 1-6. These are the Forest Squares. Place a player piece for each kid around the outer edge of the grid, next to any square they choose.

Get 2 dice. These are the Fire Dice, which you will roll to add Fires (counters) to the board–one roll of the dice per player per round. Announce the rolls to the players as down then across (e.g. “1 down, 4 across.”) Have the players add a Fire counter to the square you call out. Squares can have more than one Fire counter at a time. Now explain that when there’s a non-burning (empty) square between a new Fire and an existing Fire, the Fire spreads to the square inbetween–horizontally, vertically, or diagonally. (This is like Go, only Fire can only “flip” a single empty square.) Roll once for each player, then begin.

If at the end of a round anyone is still on a square with a Fire, they’re out of the game. Disaster! If all forest squares are burning, it’s game over. When the kids put out all the Fires, they win!

Difficulty: A Firebreak is a clearing (natural or artificial) in the forest that fire can’t easily cross. With a second type of counter, you may at the beginning of the game roll to add Firebreaks to the board. Players can move onto Firebreak squares, but if a Fire is rolled on a Firebreak square, nothing happens. For an easier game, roll up to one Firebreak per player. Roll fewer or none for a challenge game. (Remember, the players still lose if every non-Firebreak square is ablaze at the same time!)

Introduce the types of player characters one game at a time:

Hotshot

Have the kids mime holding a firehose. Explain that a Hotshot Team is the firefighters on the ground with hoses and shovels who work to put out forest fires.  (This is where the term comes from!)

A Hotshot gets 2 moves per round. Each move can be either: 1) Putting out the Fires (removing all Fire counters) from their own or an adjacent square (N, S, E, W or diagonally), or 2) Moving 1 square N, S, E or W. Moving one square off the board, like at the beginning, is allowed.

To begin the game, explain that it takes time to get Hotshot Teams to a forest fire. Because of this, the fire has time to spread. Add 2 rounds’ worth of fires to the board (one roll for each player x2) then have the players begin.

Smoke Jumpers

Have the kids mime holding onto the straps of a parachute. Explain that a Fire Jumper parachutes into the forest near a fire. Because of this, they can’t carry as much equipment, but once they hike out they can jump in again anywhere they’re needed.

A Smoke Jumper gets 2 moves per round. Similar to the Hotshot, each move can be either: 1) Putting out 1 fire (removing only 1 counter) from their own or an adjacent square (N, S, E, W or diagonally), or 2) Moving 1 square N, S, E or W. They also have a special ability: Upon moving off the board, they can “jump” to any square on the board. (Moving off the board and jumping count as a single action.)

Add 2 rounds’ worth of Fires to the board, then have the players begin.

Pilots

Have the kids make an airplane with they hand (palm flat, index and ring finger together underneath the middle finger, pinky and thumb straight out to the sides). (If this is too hard, just pretend to be holding the flying yoke.) Explain that Pilots fly seaplanes which land on a body of water, fill a large tank, and then dump the water directly onto a fire.

Movement-wise, the pilot works a little differently. Every other turn, they must leave the board to refill their water tanks. Thus, every second turn, the players pick up their piece and hold it in their hand. The next turn, however, they can put out all the fire on any 3 squares in a row (N, S, E, W or diagonally).

Add 2 rounds’ worth of fires to the board. When the kids begin, remind them that they must first leave the board to fill up–so there will actually be 3 rounds of Fires added before they can begin putting them out!

Mixed Game

Now we put the pieces together. Let the kids decide (and encourage them to discuss strategically) what each would like to be: a Hotshot, a Smoke Jumper, or a Pilot. Explain how fighting forest fires is a team effort, with people in different specialties doing different jobs. (Now we understand the pantomiming; it’s to keep everyone’s role straight!)

Add 2 rounds’ worth of fires to the board, and have the kids begin!

Tags: , ,

Builds For “The Leaves”

I love making stuff. The films I get involved with always seem to result in fun builds. It’s possible I’m getting my priorities backwards.

Old Book

Start with a real old book.
Raid Bart Howard Chandler Christy’s jaw-dropping “Lady of the Lake” illustrations for artwork. (You know him from his WWI propaganda posters.) Put together a pre-1960’s-looking dust jacket, pre-yellowed and sun faded.
Thin, distress and tear the edges. Rub salt on it to dull the finish. Just generally give it a hard, long life.
And… old book.

Board Game

Can’t imagine why no one snapped this sh*t up at Goodwill…
But it’s perfect, except for a few things.
Staples does color printing rather cheaply.
Measure once…
Cut twice. Spray adhesive is way too fun. (Not an endorsement of huffing.)
Every box of a certain age seems to get crushed. Wish I’d thought of a way to age the masking tape. (It tends to yellow, curl, turn brittle, and separate.)
“Distress”
Similar procedure for the board itself: Nonsense artwork, spray-adhesed to a couple pieces of chip board from good old Artist & Craftsman. (Say hi to Disme.)
Maybe not “hero” props, but good enough for 2K!

Rain & Sun Shirts

Can’t pay your actors? Create a thematic element/easter egg they can wear home. (Also, feed them well!)
Laura’s shirt was a new one for me: Permanent fabric paint. Other than that, just a standard sticky-back-plastic stencil. (Thanks again, Disme!)
Iron for permanence when dry.
Rob’s was a more standard sprayed bleach stencil shirt, although I’ve never tried to do lettering before.
Tape off the overspray areas, mist with bleach until light enough, let dry, rip everything off and stuff it in the dryer.
Nukulur poweird!
Tags: , , , ,