Like last month, here’s a summary of last month’s work around Beneath The Order, with a little summary / reflection at the end.
Fall Detection and Reaction
Height is an important element in my world building. Even the lower part of the Aegis is “high” in the overall structure and a fall from any of the unsecured edges, bridges and planks could be fatal. And sometimes a jump from a little height is necessary to progress. I wanted the player to react accordingly, with audible groans and screams depending on the height.
This revealed another issue. As I am not using a full body avatar and rather neutral hand models, I didn’t have to put any thought into the player’s in-game gender. But once I searched my assets for matching sound effects I noticed that I didn’t have any “gender neutral” ones. So I (reluctantly) introduced a new setting for the player to select their gender.
Crowd Simulation
I wrote a bit more detail already in my earlier post on reusing spawn points for light probes.
On top of what’s described there, I added functionality to disable and reenable spawning from triggers, and I use it e.g. when the player enters a mine. The existing common folk, as instantiated from the pool so far, can continue to exist and roam, but no new characters should be created around the player as they go deeper into the mine.
I thought about other options, like adding qualifiers to every spawn point so that common folk are spawned on the outside and mine workers on the inside of mines. This would bring more flexibility and reusability, but would require more manual adjustment, so I decided against it for now.
I have yet to improve the NPC behavior. Right now characters are navmesh agents and consequentially always take the shortest paths around corners, and as they wander, they often stop on edges of the navmesh and stare against walls. I need to make this a bit more believable. I also plan to reduce the wandering and spawn stationary groups of 2-3 characters: I first thought that continuously passing by Subsumed would be the the best way to generate a sense of a crowded, busy world, but after observing some other games I changed my mind.
I did some profiling while working on the crowd and found that the synchronization of the character object, the navmesh agent, and the animator, as well as the melee handling requires quite some update time. Contrary to that, the Fimpossible tools like Look Animator seem to be really lightweight.
Merchants
Merchants are stationary characters offering their goods on their market stands. In Beneath The Order, the offered food is used to replenish health.
Fleshing out the merchant turned out to be quite complicated! There are several things to consider, affecting not only the trading but also other systems: (Feel free to skip this list.)
- The merchant should be busy working on their stand while the player isn’t close.
- As the player approaches, the merchant should stop their work to greet the player and offer their items, but not so often that it gets annoying.
- The merchant should display their payment terminal once the player grabs one or multiple items. Just like with the terminal from last month, payment happens by “hand scanning”.
- The payment needs to give some visual, haptic, and audible feedback for the payment process and outcome.
- The payment amount depends on the items grabbed. Items may have different prices.
- The player needs to know the full price. Since we’re not in a supermarket with state of the art checkout lanes and displays, the merchant needs to tell the player the full price.
- The player needs to know their currently available work credits.
- No matter whether the items are held in hand or attached to an inventory slot, they’re considered taken and need to be paid for.
- The player can put items back on the stand if they don’t want to buy them,…
- …but if the player throws items away, they still need to be paid for.
- Payment success depends on the player’s available work credits. If they have enough credit, the amount needs to be deducted and all items need to be marked as paid. If not, the player needs to get corresponding feedback, too.
- If the player leaves with unpaid items, the merchant calls for them. If the player ignores it, the merchant calls for the Black Guards.
- The Black Guard needs to arrive with their Hover Sentinel at a nearby position and then chase after the player.
- The player should be able to run from the Black Guard and the Black Guard should give up searching after some time.
- If player and Black Guard fight, the pooled characters nearby should run away.
- If the player stole before, the corresponding merchant should reject trading with them.
- Items offered by a merchant may need a dedicated representation when attached to an inventory slot, opposed to the item being active in the game world.
- Depending on the merchant and item type, taken items may have to be replenished after the player left.
- The player might try and present a different hand than his own to pay the bill. Contrary to the terminal, the merchant would have to react to that.
Yeah, that’s a lot. Hold that thought for the summary.
I’m quite happy about the visual scripting support I have, because this makes iteration relatively easy and fast.
Here’s a video how it currently looks like, with many but not all of the features mentioned above implemented:
Dialogue Improvements
There are two dialogue improvements coming out of this merchant interaction, one already in place and one planned.
While working on the merchant and testing interaction in fast succession, I noticed that I didn’t have a way to queue dialogues. The merchant greets the player, then comments on the player’s item choice, then requests a payment. All of these actions come with a corresponding dialogue line, and they’re independently triggered by player actions. Obviously I need to avoid that they’re overlapping, both visually and audibly. I thought about simply cancelling previous lines, but I didn’t want to interrupt the voice audio. So instead, I built a special instruction to queue dialogue lines and wait with playing them until previously queued lines are done.
Some merchant dialogue lines might be triggered when the player isn’t looking at the merchant, e.g. if they steal something and just try to get away from the merchant. You can see that in the video, too. For these cases, I’ll need to build a separate dialogue display which appears in the player’s viewport. I’m not sure if I’ll keep the speech bubble on top of a character’s head up when I’ll have this in place; I like it a lot but having two different representations of dialogue might be too confusing.
Another rigged entity
As you can see from the video, I rigged another entity, the rat food. I wrote a script which distributes rigidbodies, colliders and joints from the tail root to the end on start. There’s still some work to do to make it look even more “body-like” and avoid weird bends, but I’m happy for now – remember, I rigged my very first entity just a few weeks back.
The tail’s rigidbodies start kinematic and toggle when the player grabs them, which is, again, solved through visual scripting and a new event I wrote to trigger when a “Grabbable” object from VR Interaction Framework is grabbed, released, enters a snapzone, or leaves a snapzone.
Machine Rooms
Every shelter needs life support systems. That’s why, apart from the mines, there’s another category of environment explorable in the lower Aegis: the machine rooms.
As I wrote in my inspiration post, I always found the Maginot Line bunkers fascinating. Narrow corridors, enclosed rooms, cut off from the rest of the world; steel bunk beds, steel pipes on the walls, steel doors with large handles; diesel generators, neon lights, air filters, and water purification systems generating a constant humming sound; electric equipment with large dials and switches everywhere, next to cabinets with folders full of instructions and emergency protocols.
So I tried to replicate that feeling. Here’s a first impression:
I didn’t find any matching walls in my assets, so I modeled special corridor parts in Blender by extruding a medieval archway from Synty Studio’s POLYGON Fantasy Kingdom pack.
Here are some of the elements in Blender:
At the time of this writing, I have already continued building long and twisted corridors with stairways leading up and down to other floors. The player will have to explore them for several occasions.
Rot Spawners
Rots are monsters attracted by the smell of Vitae, and they’re a constant threat to the mine workers.
I built a spawner component which works a little different than the pooling for other NPCs: the spawner ensures that a given number of Rots is instantiated in succession, typically from a spot invisible to the player. Once created, the spawner instructs the Rots to move to a certain position where they’re likely to see NPCs or the player to attack. If they don’t find any humans to attack, they mindlessly wander. The spawner keeps track of its Rots and can also be configured to respawn a new Rot of a previous one gets killed.
The Rots are one of these stereotypical improvised entities which are probably going to stay until the very end: the animations are actually zombie animations, and the sound effects are troll sounds. I don’t have anything more specific for these mutants, so I won’t change it any time soon. The Rots’ logic needs some more work, though, they’re very basic right now.
I would love to have many of them on the screen, along with many fleeing mine workers and other Subsumed, and Black Guards coming to support fighting the Rots, but performance just doesn’t permit that, so I’ll have to compromise.
(Another small effect shown in the video is how the velocity of the pick axe affects the water sound effects.)
A mailing list
Summary
Overall, I’m not happy with the progress this month. I had all the time in the world, but I only got so little done.
The complexity of the merchant as outlined above was one reason. It didn’t look complicated at first, but the more I worked on it, the more things I found. I wanted to do all of that in the best and most reusable way possible, which put me in some kind of analysis paralysis followed by a decision paralysis. Eventually I gave myself a push and just tried to get a first version done. It’s still miles away from where I want it to be, though. And that’s just one merchant and currently just one item prepared for purchase…
The other reason was a wave of doubt, triggered by a number of things: from conversations with professional developer friends who were less enthusiastic about VR (little adoption, low quality compared to PC titles, etc.) and my own realization that I won’t get close to the better looking VR titles; to realizing I spent hours on things that neither contribute to the fun of the game nor to the medium; and extrapolating this time; to first significant performance issues becoming evident, like the one with many skinned meshes visible for the crowd simulation, as described earlier.
I’ll try to improve my own efficiency and effectiveness, and I’ll try to focus on more VR specific gameplay.
What else?
I did some things outside of Beneath The Order, too. I started digging into the Epic Stack (as a I want to move away from Java / Spring Boot as my current backend stack, which is great for the enterprise payments stuff I did but not so much for my smaller projects), learned about PaaS solutions to ease operations on my own servers (looked into Dokku and Dokploy), and continued learning and applying ML/AI: I started building a feature extractor for Unity maps and tried throwing fixed length feature matrices into a Random Forest algorithm to predict the most likely nearby prefabs at the current mouse position: for example, if the mouse is on the edge of a road crossing, a likely object nearby would be a traffic light or a street sign, and this can be “taught” by extracting corresponding feature data from existing demo maps. If it works, it’s going to be an extension to my Prefabby product.
Do you find these monthly reviews interesting? Please share your thoughts in the comments!
Leave a Reply