Sunday, December 10, 2017


Part twenty-four in a weekly(α) devlog.

Standard development disclaimers apply. This is alpha content, everything is subject to change, features may not be present in the final version, there's a chance none of this will ever be released, etc. etc.

There shouldn't be any plot spoilers in these posts, but there will be occasional discussions related to characters, locations, mechanics, and other aspects of my potential upcoming Shadowrun campaign (tentatively titled "CalFree in Chains"). You may wish to skip them if you'd like to be completely surprised.

First things first: CalFree in Chains has officially entered alpha testing. If you're interested in participating, send me a friend request on Steam if we aren't already connected, and then head on over to the workshop page to subscribe.

My tentative plan is to run the private alpha for about two weeks. I'm not expecting to catch and fix all remaining bugs during this phase: the goal is to find major show-stopping issues, some of which may only manifest as the result of certain branching choices.

I'm still not committed to it, but if things go smoothly I'm hoping to release the public beta on December 22nd (the same day Bright releases on Netflix). As with my previous campaigns, I'll be actively maintaining and updating the campaign as reports come in, but this time around I wanted a clearer demarcation between "This likely has many bugs!" and "I don't think this has many bugs!"

In the run-up to this, HadesScorn has been doing a very detailed playtest (thanks!) complete with tons of helpful notes and feedback. I'm acting a bit like the sweeper at the end of a parade, cleaning everything up behind as the progress continues. The most painful fix so far has been a character rename. As you might have seen in some earlier dialogue snippets, one of your crewmates is named Isas. It wasn't until HadesScorn pointed it out that I realized this is uncomfortably close to the name ISIS, which is not at all the association I wanted him to have.

The reason this was so painful was that a crew member's name shows up in a LOT of places: not just the text you see in dialogues, but also in variable names, data files, and so on. There's a huge potential for bugs.

In most of these posts I've shown the work I do inside the Shadowrun editor, but I also do a fair amount of work in raw text files. Sometimes it's easier (or necessary) to open up a file in VIM and manually edit stuff in there instead of going through the editor. Something like the Isas -> Isao rename absolutely requires this sort of approach. There were well over a thousand references to update, and there's no way I could do all that manually.

Here's a handy command that will take care of the bulk of the work for me:

This one only updates the lower-case version of the name, which I need to be careful about - otherwise, it will update works like "disaster" to "disaoter".  The capitalized version turned out to be safe to run everywhere; this version had to be restricted to only run on certain folders, excluding "convo".

Anyways - what this command does is look under my project folder for all text files, and globally renames "isas" to "isao" in all of them. Pretty easy! This blows through hundreds of files in less than a second.

(I have a bit of a history with stuff like this. I've mentioned before how Rafik was named Destin for almost the entire time I was working on The Caldecott Caper; I made that change very late, but before entering testing, so it wasn't quite as painful. Also, about a month ago I renamed the primary villain in CalFree in Chains after I became concerned that it was too close to the name of a real-life political figure. I'm not necessarily opposed to players drawing parallels to real-world events, but I've tried to avoid making any one-to-one correspondences between fictional and real people, preferring instead to focus on movements and ideologies. Anyways, that one wasn't as bad since it mostly just affected the content of dialogues, not game data files.)

Oh... while we're talking about names, this might be a good time to mention the name of this game. My initial working title for it was "Saito's Shadow". I thought that it would immediately signal to prior players that this was a continuation of my previous games, and it also has a sinister sound to it that matches the game content.

The title lost its appeal, though. First, I was worried that players would jump to the conclusion that you get to actually fight Saito in the game. (Spoiler: You don't, at least not directly.) The word "Shadow" is also massively overused in Shadowrun games, in both fan-made and official content. "Saito's Shadow" is also hard and annoying to say out loud, with multiple sibilant S's stacked side by side. Finally, it isn't super-Googleable.

I (surprise!) started another Google Doc for brainstorming names. I ran through several dozen, each with their own pros and cons. I got excited once I thought about "Welcome to the Occupation", which is the title of an R.E.M. song that I love and a great thematic match for this campaign; unfortunately, as an existing song title it would be even less Googleable. But that started my mind down another path, and I ended up settling on CalFree in Chains. It has a certain insistent rhythm to it that I like, a nice li'l acronym (CFiC), is decently Googleable, and announces its ties to the previous games.

I have an even longer list of parody titles that I would never use but I can't get out of my head, including:
Uncle Saito's Smile-Time Family Variety Hour
My Dunkelzahns Are Dead And My Saitos Are In Power
I Feel Sad: Surprise! Now You Feel Sad Too
So Much For The Tolerant Left

Back to the command line: there are tons of commands I use during development, most of which only get used once or twice but all of which save an insane amount of time. Here are a few random examples:

This one was handy when I was experimenting with options for targeting enemies and allies while creating new spells and abilities. I'm running it on the official Hong Kong source so I can see all of the available options; there's no official reference for this, so I'm essentially building one myself. "grep" is the standard text-searching command. -h will hide the filenames of matches so the output only contains the matching lines. "toHitFunction" is the string I'm looking for. "sort" will organize all of the results into alphabetical order, and then "uniq" will remove any duplicates. So, I end up with a nice, alphabetized list of all valid hit functions that Hong Kong supports. (Longer than what's shown here.) It's way better than opening hundreds of files by hand and writing my own list!

Or, here's an example of editing every file in the project that includes the string TODO. I often leave this as a comment to myself while working. It might be a placeholder for something that I need to hook up later, or a reminder about a bug that I spotted but didn't have time to fix, or a note that I need to do additional research on some dialogue.

This one line will crawl through the project and open up all the matches for editing in VIM. For text-based stuff I can just make any necessary edits directly in the buffer; otherwise, I can quickly find the corresponding content in the editor (the map or dialogue or whatever) and take care of it there.

Okay... I feel like I'm massively overdue for showing some actual gameplay. Next week might be a good occasion for that, I'll try to grab some screenshots or even a video snippet. I'll be pretty busy now that the wider alpha is underway, following up on bug reports and swiftly fixing stuff, but that's a good thing! I have a full work queue now, and it's exciting to see the game get better and better every day.

Sunday, December 03, 2017

First Past the Post

Part twenty-three in a weekly(🗿) devlog.

Standard development disclaimers apply. This is pre-Alpha content, everything is subject to change, features may not be present in the final version, there's a chance none of this will ever be released, etc. etc.

There shouldn't be any plot spoilers in these posts, but there will be occasional discussions related to characters, locations, mechanics, and other aspects of my potential upcoming Shadowrun campaign (tentatively titled "CalFree in Chains"). You may wish to skip them if you'd like to be completely surprised.

I've finished my first-ever run-through of CalFree in Chains! I think it's pretty good. It's always fascinating to actually encounter these scenes that have been trapped inside my head for months and that I've spent so much time building. I'll never experience them as a player will, but I do feel a certain sense of awe at watching them turn from idea into reality and manifesting inside this game that I'm playing.

My high-level takeaways from the game:

The difficulty curve is inverted. Early missions are too hard, and the final missions are too easy. That was exactly my experience in all of the official campaigns, though, so I suspect it's at least partly due to the underlying mechanics of the game and not something I can completely solve. In the short term I'm adding a few more healthpacks and such to the earlier missions. I'm experimenting with what I'm labeling "homemade" medkits, which act the same as a basic medkit but are worth far less. My goal is to encourage players to actually use these instead of hoarding them (which is what I, personally, always tend to do in these games).

The last battle in particular seems to be easier and faster than I had expected. This is kind of a bummer because there's a fair amount of content that only triggers after the battle has gone on for long enough. I'm still mulling over how to address this... the simple thing would be to just add more waves of enemies, but that seems dull for a final fight. I'm also tempted to bump up individual enemies to have boss-level stats and be more menacing, but then I risk having crew members die and not being available to deliver dramatic lines. I dunno. Maybe players will enjoy feeling powerful in that fight (and it is interesting, even if it isn't all that hard).

I think that the story makes sense and doesn't drag too much, but I'm too close to it to be objective. Honestly, at this point there probably isn't much I can do to change it since it's so closely interwoven with the gameplay. There may be an opportunity to add more explanations if things are unclear, but I don't think I'll be able to cut out much without hurting the game.

I do worry a little about some long-running side-content. There are a couple of references near the end to stuff that happened back near the beginning, which should be fine if someone is playing straight through, but would probably be confusing if they're going weeks between play sessions. The critical-path main plot stuff is all refreshed fairly frequently so I think that's OK, but I can see some players going "Huh?" when a companion says "Haha remember the one time you did X way back in mission Y?", when nobody has mentioned it during the five missions in between.

There's a bit too much nuyen. I thought that Hong Kong was too stingy, but in this runthrough I was able to completely kit out every slot of cyberware, buy my best armor, get some good Adept abilities, and still clear out the doctor of every platinum Doc Wagon and premium medkit before the final run (none of which I ever used...). I've already made some adjustments to tune this down a bit, though I should probably go further. Games are more interesting when you need to make choices and trade-offs, and being able to buy everything you want isn't all that compelling.

The karma level feels pretty good, though. I brought my CHA all the way up to 8 for four etiquettes, maxed out my Cyber Affinity, and came close to maxing Close Combat. And I still had some points to splash around in Qi Casting, Biotech, and other useful things. I think there's enough for specialists to max out their primary skills, but not enough to max out multiple skills, which feels like a good place to be in.

So, yeah... there's definitely more tuning and fixing to come, but the overall shape of the campaign feels decent, so I'm starting to cautiously expose it to other folks. The first person to endure the torture will be Hades Scorn, my longstanding lead tester, also known as the infamous pistol street samurai. Shortly after that I plan to open it up to a small group of alpha testers, hopefully drawn from current Steam followers and one or more of the active Shadowrun communities. It now seems possible that I might get this out before the end of the year, which would be awesome, but I'm not prepared quite yet to commit to that.

Sunday, November 26, 2017

Shake It Off

Part twenty-two in a weekly(🏃) devlog.

Standard development disclaimers apply. This is pre-Alpha content, everything is subject to change, features may not be present in the final version, there's a chance none of this will ever be released, etc. etc.

There shouldn't be any plot spoilers in these posts, but there will be occasional discussions related to characters, locations, mechanics, and other aspects of my potential upcoming Shadowrun campaign (tentatively titled "CalFree in Chains"). You may wish to skip them if you'd like to be completely surprised.

Happy belated Thanksgiving! Another week with slower-than-usual progress, but still some cool milestones crossed. The big one is that I've started my initial playthrough of the game. This is the first time that I'll actually roll a character and take them all the way through the campaign, scene by scene, to the end.

This is another opportunity for spotting and fixing bugs. As I mentioned before, a lot of issues only become apparent when experienced within their context: an isolated component may look great, but when you plug it into the surrounding content problems will occur. I already cleared out a lot of hub-related bugs of this type, and now I'm encountering and fixing similar issues for the actual missions. Carrying forward certain items or characters or plot flags may cause unexpected problems to crop up.

The single biggest thing I'm focusing on now, though, is the game's difficulty balance. Everything up until this point has just been stabs in the dark: "I dunno, maybe five enemies in this group will be okay?" "Uh, this one has a grenadier and a mage, so maybe just four?" Now I'm actually encountering these as a player would, with a certain build and amount of karma and nuyen and health, and can get a sense for how they feel.

The answer is, they are too hard! Of course they are too hard! This is the fifth Shadowrun campaign I've made (six if you count the port of Antumbra Saga to DFDC, which did revamp the combat), and I always start out making it too hard and then gradually dial it back until I can beat it. I honestly don't know why I can't just make them easier to begin with, I have plenty of data points by now that show I should tune it down from the start.

I guess maybe it's because I seem to end up with a decent difficulty, maybe after more thrashing than is strictly necessary. My standard process is to play through on the most difficult setting (Very Hard for Dragonfall, Hard for Hong Kong), using the archetype I'm most expert at (Rifle decker in DF, cybered adept for Hong Kong). I want to get to a point where this feels hard but not frustrating - ideally no more than 1 party wipe per scene, and being forced to use at least some consumables to get it through.

I think this ends up as a fair proxy for overall difficulty. I'm not the most hardcore player of these games, and I'm not playing the most optimized min/max build. But I do have the enormous advantage of knowledge capital: I know exactly what is in each mission, how much further I have to go, whether I should toss out all my fetishes on a given combat or hold them in reserve for the next one coming up. Other players will have less certainty, but Hard should still be beatable with ideal builds or brilliant tactics. I'll ultimately recommend players to play on Normal, but I want to make sure that Hard is feasible, and I can't make that claim if I can't beat it myself.

My initial thoughts:
  • Money feels a bit too plentiful. I'm currently holding about 3k and haven't unlocked the second-tier merchants yet. I've bought armor (replacing the 1 Armor starter with the 3 Armor upgrade), but with my particular build there isn't much I want to get until the better cyberware becomes available. I'm thinking of giving the player more nuyen to start (500 at the start instead of 0) and dropping down the per-mission rewards for the early missions. That will make it easier for the player to buy a decent upgrade on their first hub visit and/or hire a merc if they need one.
  • I'm dying a LOT. I initially followed the Hong Kong design where some companions have medkits, others have Doc Wagon, some have neither. But particularly in those early levels, low HP and armor values means it's very easy for people to get killed. I'm now granting all companions one Doc Wagon and at least one medkit. That's more generous than Hong Kong, but there's also a lot more fighting in my mod than in Hong Kong so I think that makes sense. I might need to revisit this at higher levels... it would feel weird to take away Doc Wagons later on, but I suspect they'll be less needed.
  • I really like the pace at which companion upgrades are unlocking. You stay at Level 2 for a while as new optional companions come in, so you can gradually build out your team instead of configuring everything at once.
  • So far it isn't feeling too talky to me. That was one of my biggest concerns while working on this game; there's more words here than in Caldecott, and I was worried that it would seem too wall-of-text. I still haven't gotten to the talkiest mission of the game yet, or the talkiest hub visits, but at least so far it hasn't seemed overwhelming (and I am reading every word as I play, though I may not be able to keep that up for subsequent playthroughs). Granted, I do have a higher tolerance for reading to begin with, so it's very possible that my players may disagree about the narrative volume.
Short update... I don't think I can really share any videos or screenshots at this stage, most of this is pretty spoiler-y. But yeah, so far I'm cautiously optimistic about how things are coming along. It's been a while since I've done this and I don't have a great memory for what the process was like on Caldecott, but I imagine that I'll continue along this for at least a couple of weeks until I've convinced myself that the game is beatable and start letting other human beings look at it.

Sunday, November 19, 2017

Lucid Heart's Refrain

Part twenty-one in a weekly(🎵) devlog.

Standard development disclaimers apply. This is pre-Alpha content, everything is subject to change, features may not be present in the final version, there's a strong chance none of this will ever be released, etc. etc.

There shouldn't be any plot spoilers in these posts, but there will be occasional discussions related to characters, locations, mechanics, and other aspects of my potential upcoming Shadowrun campaign (tentatively titled "CalFree in Chains"). You may wish to skip them if you'd like to be completely surprised.

I was fighting off a nasty cold this week, so I didn’t get as much done on the campaign as I would have liked. BUT, I did finish my first pass through the hub, so that was pretty good! That means running through all of the various side-quests and romance arcs that I mentioned in my last couple of posts, on the actual final map for the hub, and eyeballed everything to make sure it looks decent.

At a high level, I’ve now completed most of the “big things” and am now working on the “small things”. I have a massive Google Doc titled “CFiC Tasks” which is a running list of everything that needs to be done before I can release. I had a lot of stuff in there months ago when I kicked off the project, and have added to it as new problems or ideas have risen. I’m also knocking some things off, although up until now that’s been a slower rate than things getting added.

Anyways, most of the items I’ve been working on until now have been single lines like “Write all the dialogue” and “Create all the maps” and “Implement all the combat”, where a single sentence implies more than a month of work. Now, those few big things are done, and instead I have a billion smaller things to do. So I’m now looking at items like “Add karma rewards” and “Make sure X’s ability works properly” and “Write the epilogues”. Almost all of those will be a day’s worth of work or less, but there are a LOT of them to get through.

Still, it’s a very good place to be at. I have a really high sense of velocity at this stage of the project, since I feel like I’m constantly knocking stuff off and fixing specific things, instead of continuing a Sisyphean struggle. The flip side is that it will eventually start to seem like a never-ending stream of concrete tasks, so my mood will likely flip back and forth between “This is almost done, I’m so excited!” and “This will never be finished, I hate everything!”

I’ve been very disciplined about scope creep, and it becomes even more important now. There are an infinite number of good ideas out there, an infinite number of things that could be better, and unless I say “No” to them I’ll never be finished. There are a handful of exceptions, when I spot something that threatens the game as a whole (from a gameplay or moral standpoint), but I set and try to maintain an extremely high bar.

Anyways. What I’m working on right this second is music selection. This used to be my favorite part of making modules, although that’s gotten a lot more complicated in the SRHK era. Still, it does contribute an enormous amount to the overall mood and impact of the game, while requiring proportionally little time on my part since the musicians have already done the heavy lifting. My role here is more like a curator, looking through the limited menu and deciding what to present when.

This can initially seem like an overwhelming task. There are 47 potential music tracks in SRHK, which I need to distribute over (cough, cough) missions. Ideally I’ll minimize repetition, and try to keep repeated tracks as far apart as possible. Maybe more importantly, I want to pick tracks that work well for each scene. If you’re surrounded by disciplined corpsec forces, you’d expect a different vibe and sound than if you’re fighting off wild monsters or enjoying a drink at the pub.

I handle this by - you guessed it! - creating a spreadsheet. Each row lists a separate track of music. In the columns, I’ll identify the following.
  • Energy level. Theoretically one of Low, Medium, and High, but of course I’m incapable of making decisions and will ultimately classify some tracks as Medium-Low or Medium-High. This is mostly a function of volume and BPM, though it’s ultimately subjective.
  • Mood. As I listen to the track, I’ll jot down a couple of adjectives or brief phrases describing how a song makes me feel. Examples include “Restrained”, “Desperate”, “Funky”, “Joyful”, “Holy”, “Pursuing”, “Yearning”, “Proud”, etc.
  • Type. I’m really looking for either “Legwork” or “Combat”, though some tracks might work for either, and in a few cases they might be better for cut-scenes or other unusual situations.
  • Map. I’ll think of a couple of scenes within my game where this track might work, mostly relying on the previous entries.
  • Notes. Anything else that’s interesting: whether the track seems especially short or long, if it’s doing something unusual instrumentally, or whether it has a strong association with the official campaigns.

For this process, I’ve been taking advantage of (and very grateful for) the Aztechnology Aural Mindscape, a nifty stand-alone utility campaign that makes it very quick and easy to test music tracks. I can run through all of them back to back without needing to modify and debug my own campaign. I’ll typically listen to each track twice through, fill out the row in my spreadsheet, then move on to the next one.

After this, I make another sheet listing out all the slots I have for music in my own campaign. On a simple map this will just be “X Freeroam” and “X Combat”, but for some larger maps I might want different music for different areas, and in a few cases I might want a special tune for a particular character or scene. I refer back to my first sheet as I go through and slot things in, top to bottom. I’m mostly picking good fits for each one, and also keeping an eye on if and when I most recently used a given track, so it hopefully won’t be too repetitive for the player.

The final step is to actually add them in. Setting up the basic music is really simple, just add the tracks to the camera regions. If you have multiple regions and want to share music, you can leave the music blank on subsequent regions: the previously-playing music will continue playing into the next region.

The engine automatically handles transition between the default (legwork / freeroam) music and combat music. I typically keep the defaults for all of the settings like the fade interval (how long the transition between two tracks takes, during which time you can hear both playing). For CFiC, I'm not planning on using the "Intense" (Int2) and "Wrapup" music, in an attempt to get some more variety across a larger number of scenes. Oh, but note that by default the option Loop Default Music is disabled, which is almost definitely not what you want.
Edit: After more thorough testing, I've found that the best configuration for a single music track in combat is to repeat the track for Base, Intense, and Wrapup, and set all the thresholds to 1. This mirrors how HBS often does their Matrix music. The above screenshot works in general, but can lead to drop-outs and silence in some cases.

You can also control music via trigger commands. I do this sparingly, but it can be a really cool technique: in Corona / Antumbra Saga, I used musical themes specifically for Hans Brackhaus and for Tabitha, so their distinctive tunes would play when they appeared on screen or when their influence was being felt. There aren't as many opportunities for this in Hong Kong due to the more limited track selection, but just shifting from one piece of music to another can have an impact: during a particularly surprising moment in Caldecott, I dropped out the music entirely so a brutal scene would play out in silence, and then kicked back in with a high-energy track as you and your team dealt with the aftermath.

I don't do this too often. It's a bit tricky, there are few items at my disposal, and it's a classic source of bugs. In particular, the engine can get confused if you're shifting between autoplay combat music, triggered scene music, and so on; in general, stopping your triggered music will cause the region's music rules to kick back in, but the more stuff you're trying to do the greater the risk that the player will end up hearing no music at all. (There's still a lingering bug in the climactic fight of Caldecott for this very reason.)

Yup! Music is awesome, I love it a lot. I'll probably do another post later on my music, the fuel that's kept me going during this insane project.

Sunday, November 12, 2017

Hub and Spoke

Part twenty in a weekly(🏛) devlog.

Standard development disclaimers apply. This is pre-Alpha content, everything is subject to change, features may not be present in the final version, there's a strong chance none of this will ever be released, etc. etc.

There shouldn't be any plot spoilers in these posts, but there will be occasional discussions related to characters, locations, mechanics, and other aspects of my potential upcoming Shadowrun campaign (tentatively titled "CalFree in Chains"). You may wish to skip them if you'd like to be completely surprised.

Now that last week’s boring post is out of the way, we can finally move on to the topic everyone ACTUALLY cares about: spreadsheets!

I’m close to wrapping up work on the hub, the location to which you and your team return between runs. This has been a long process, and also a fairly complex one. I have a variety of goals for the hub which overlap and sometimes contradict one another.

The hub should feel dynamic. It’s boring if everything looks exactly the same every time you come back. It adds a ton if the physical space changes and if characters move around from one visit to the next; it adds to the sense that you’re occupying a real place and interacting with people who have their own desires and agency, and aren’t merely there for your bidding.

The hub should be easy to navigate. It’s frustrating if you can’t find something you need or have to waste a lot of time running around.

The hub needs to support ongoing quests, which in turn will often require certain people or objects being in a certain location at a certain time.

The hub should reflect and support the overall narrative mood at a given point in time. If something upsetting has recently happened, it would feel jarring for everyone in the hub to be jokey and silly. Conversely, if your team has recently accomplished something great, I don’t want to bring down the mood with doom and gloom.

I realized fairly early on that there was way too much going on for me to keep everything in my head at once, and so I outsourced record keeping to the cloud: in particular, a Google Sheet that I threw together. Here’s what a portion of it looks like, heavily redacted.

Everything is ultimately driven by the global (story) variable “NumMissions”. It increments by 1 every time you return to the hub, and in turn it drives everything else about the scene.

There’s some mechanical bookkeeping driven by this. Part of that is the CharacterScaleAmount, which in turn will determine when you can select upgrades for your crew and how difficult enemies will become.

The more complex thing in this shot, though, was working out where various crew members would be located. Pretty much everything here is redacted, sorry, but the idea is to move the spawned actor into the correct location for a given visit to the hub. I try to avoid clustering them all close to one another. I also try to put them in a location that makes sense for the character: some more martially-inclined crew members will often by found in the target shooting range, while a bon vivant would more likely be found in a restaurant, and a decker will spend a lot of time by a computer.

But this gets especially tricky when a character is involved in a side quest. If I want the character to walk to a certain location, then they need to be located in a place from where they can path to their destination. So, in addition to the default positions, I may override their location based on the current state of a given side-quest. There aren’t any examples of that in this screenshot, but I flagged those cells with a teal background.

Speaking of teal, let’s more on to a later section of the sheet.

You’ll note that I froze the two left columns - this is a long sheet! The number of missions is most important for scripting purposes, but by itself the number doesn’t mean anything to me. The previous mission tells me what went down immediately before this hub visit, which in turn informs what conversations would be tonally appropriate. In some cases this is variable, like [Act 2], where the player may have gone on any one of a variety of runs. The more important story missions are individually flagged and usually have bigger thematic implications for what’s happening. Anyways, freezing the columns helps me keep my place regarding the overall state of the story during a given visit.

The next three columns here show when various conversations get unlocked for different NPCs. When possible, I try to spread these around so there’s a relatively consistent amount of new content, instead of overwhelming the player early on and leaving them with too little near the end (which was one of the slightly annoying things about Heoi in SRHK). Some conversations are just for fluff or flavor and can happen any time. Others are tied to specific events; here, the ones at NumMissions 5 are specific reactions to a story mission that the player has completed. Some conversations might be interjections that take priority over everything else, and others could be tied to ongoing missions or sidequests, which are respectively flagged in yellow or teal.

The PC0 Spawn column acts similar to the companion spawn ones from before. You’ll typically start out in your bedroom, unless there’s a team meeting or similar gathering. Occasionally, an event might happen right when you spawn, which is noted here.

The remaining columns are related to the atmosphere of the hub: little bits of character that will change from one visit to the next. I actually kind of hope that players don’t notice this: ideally, it’ll be an almost subliminal effect, adding to the impression that you’re in a dynamically evolving environment without calling too much attention to itself. But folks who are very observant will find these things, which will hopefully add another fun thing to look out for on return visits.

While building out a lot of these things (conversations, romances, side-quests), I did almost all of my work in a test scene instead of the actual hub scene. I’d just activate whichever specific NPC spawners I needed, set up the global variables correctly, and then run through it. This does add a little overhead, since I later needed to re-test things in the actual hub, but more importantly, each time I need to test a scene it takes only about 5 seconds to load as opposed to the 30+ for the real hub. When I’m testing things dozens or hundreds of times, that really adds up! So it’s good to do as many of my iterations as I can on the simple test scene, and just do my final verification on the real thing.

Over the past weekend I was able to run through a streamlined test of the hub: basically starting a character at NumMissions 1, talking to and interacting with everything in the hub, advancing to NumMissions 2, and repeating it through the whole game. This let me verify that multi-stage quests were advancing properly, see how all of the different states were interacting, and so on. As expected, I caught quite a few things here that I’d overlooked during my more targeted unit testing early on. This included one really amusing unexpected interaction, when I realized that one crew member who had joined you for a side quest might be present during a particularly intimate scene. Even my vaunted spreadsheet hadn’t anticipated that interaction. But, hey, at least now I know about it!

A couple of random technical comments:

There's a fair amount of ambiguity about whether you should interact with spawners during the "On Map Setup" or "On Map Start" event. Ideally, you would activate your spawners during "On Map Setup", and then move / animate / whatever them during "On Map Start". But, from what I can tell, spawners that were activated during setup may not have finished by the time "Start" runs, so attempting to teleport a recently-spawned actor during "Start" will fail. Because of this, I generally keep "Spawn At Map Start" set on the map spawner, and then kill off unwanted actors during Map Start. This is unfortunate, since it leads to longer map loading times - I incur all the time to create the actors even though I'm tossing them - but it's the only solution I've found yet.

On a related note: this isn't very consistent, but sometimes the scene will freeze/crash during loading if you attempt to kill actors during Setup. It's safest to do this during Start instead. Which, again, is annoying - it leads to a longer gap between when the player clicks "Continue" on the loading screen and when they can actually start playing - but a longer delay is far preferable to a crashed game.

There's a longstanding bug where actors lose their animation state when reloading a saved game, so it looks like people are just awkwardly standing around and staring into space instead of doing what they should be. I addressed this back in Caldecott by setting all animations on the Curtains Up event instead of the Map Start event, since the curtains will re-fire when reloading a saved game in addition to when first starting a map. I built on that for CFiC, coming up with a system that I think works pretty well for dynamic-feeling characters.

So: my overall goal is to have individual crew members doing something on a given hub visit. They might be repairing some equipment, or talking to nearby NPCs, or dancing in a club, whatever. When you start talking with them, they stop whatever they were doing and turn their attention to you. After the conversation is over, they resume their previous action.

Initially, I implemented this with a ton of individual triggers, enabling and disabling them as conversations started and ended. But I ended up with a pretty nice and unified approach. It looks a bit like this. First of all, we place our characters in their initial position while the map initializes.

Next, start their animations. This will happen when the curtains are raised or an event fires. I do one of these for each mission, and each character's animation makes sense for what they're doing. ("Sacrifice" and "Doomventing" may sound very dramatic, but they aren't really. "Sacrifice" is just the character looking slightly upward, at some object taller than themself. "Doomventing" involves fiddling with something on the floor.)

In each conversation, set the actor to the "idle" animation. Most of them will also automatically face the PC when the convo starts; if not, you can manually trigger that as well. As a result, they'll stop dancing or whatever and focus on you for the remainder of the conversation.

Then, we wire up this one trigger to restart all animations whenever any conversation ends.

That will re-run the same trigger up above that we ran when the curtains raised. So, after every conversation, everyone will go back to what they were doing when we first started the map: now that your chat is over, they can pick up where they left off.

In a handful of cases, I might not want a crew member to resume their original animation: for example, if they are following you or have moved to another spot on the map. In this situation, I just create another trigger to handle that specific case, going back to the "Idle" animation or whatever is most appropriate. Remember that triggers always run in sequence, from top to bottom, so triggers defined later in your list will execute after ones above it. In this example, I'm checking whether one particular actor is in a specific area, and if so, have him continue standing instead of his standard animation.

That's pretty much it.

So, yeah. There’s still a ton left to do, but I’m feeling like the hub itself is in pretty good shape now: the crew conversations, romances, merchants, side quests, paydata, rewards, and lots of other stuff is now present. I still need to work on crew advancement and a couple of other mechanical-related stuff, but for the most part the overall framework is in place. Running through that end-to-end test felt awesome: I love this feeling, when the project starts to actually seem like a game, with interlocking systems and coherent progress. Excelsior!