In Sira, the player takes on the role of a soldier attempting to escape the planet Earth with his dying brother as the sun expands towards the supernova stage. Staying out of open sunlight is key to survival, and the player must avoid it while also navigating through the malfunctioning machinery of the abandoned city of Sira.
Sira was started by Christopher "Berryman" Berry and Slaton White of Arsenic Playground as a senior project at SCAD, which they carried through for two quarters and are continuing to service as a Kickstarter project alongside their sound designer, Timothy Liedel. I served as the lead programmer for this project, doing most of the front-end programming of Sira's core features, supervising other programmers for sound and weapons programming, and acting as a technical design advisor for other teams.
The initial sunlight damage system involved a Kismet trace; this was not fast or precise enough, however, so I was asked to program a better version of it in Unrealscript.
UDK isn't able to acquire lighting information directly, as it does not provide source-level access; therefore there was no way to directly determine whether or not the player was in sunlight. Materials information is available, but as Sira is a first-person game the player pawn does not possess a model.
To circumvent this problem, the sun is actually a pawn. Pawns have a set of eyes and the ability to discern line of sight; said line of sight becomes obstructed by objects and can have any range that the designer deems necessary. Light also becomes obstructed by objects; hence shade. Therefore, as long as the sun occupies the same space as the light that's meant to represent it, that line of sight will provide an accurate approximation of what's in light. The sun's AI, therefore, uses this line of sight to do damage to the player. This provides a cheap and elegant solution as the engine is designed to handle a relatively large number of enemies processing line of sight, and in practice zones of safety conform perfectly to visible areas of shade.
I created custom AI and behavior for two distinct enemy classes on this project -- the Leech Bot and the Eye Bot (also referred to as a "Medical Droid" ingame). This is a flexible enemy type, as it can be put in a "passive" mode for providing ambiance, or an "aggressive" mode for acting as an enemy, indicated by the presence of malfunctioning sparks.
Leech Bot is a small, simple enemy that wanders close to the player and delivers a kinetic shock, less designed around doing damage and more around pushing the player towards open sunlight. Their behavior is augmented by means of a "Swarm Director" detailed below.
Eye Bot is a medium-class "sniper" enemy that spends a short time taking aim at the player with a tracking laser, then fires a full-blown, lethal laser shot. I designed its behavior as well as implementing its code. It is easy to avoid provided that the player keeps moving, as it is designed to stop aiming for a fraction of a second just before firing. The purpose of this bot is to tax the player by forcing them to move in an environment where taking a wrong step can be hazardous, either in order to dodge the laser or in order to close ground. It's also meant to create a more resilient and intimidating opponent than the swarm of roombas detailed above.
Making the Eye Bot work was contingent on a unique relationship between its animations and required me to create a custom BlendBy Node for both the "charging" and "firing" AI states in addition to accommodating the custom anims with Play Custom Animation nodes.
The first iteration of the "leech bots" didn't give the designers the control that they wanted. Initial specs only concerned individual leech bots, which were assumed to be placed directly in-level rather than spawned through an actor factory. The designers, however, employed leech bots in large, factory-fed swarms. The actor factory is ill-suited to providing control over groups of enemies, so I created a special swarm director path node. This node contains an array of leech bots that can be dynamically added to via kismet or manually added to via a properties menu.
I created a series of Kismet actions that could send commands to this node, which would then re-direct them to each of the leech bots stored in its array. Huge leech bot ambushes or swarm-wide shutdowns could be initiated via a variety of ingame events controlled by the designers. Additionally, the director node serves as a "home" node that the leech bots will return to and wander around should they lose their target. In the absence of an AI director, the bots are programmed to take their initial location as "home" instead.
The user interface of Sira is integrated entirely via gametype script, including the frontend menu. While kismet was used for initial prototyping stages of the menus and health indicator, all FsCommands were removed from their final implementation. The only FsCommand-based UIs are the tooltips provided during gameplay, which were integrated at a late stage of development.
During the initial revision stage, Slaton White requested me to make a mechanic that would enable players to pick up and manipulate objects in the style of Half-Life 2. This would enable players to use large objects as shields from the sunlight and open up substancial possibilities for puzzles. The grabber was programmed but left unused as it was felt that this was trying to introduce too many mechanics in too short a time.
The "grabber" code is derived loosely from the UDK Physics Gun, but with several key modifications. First, instead of attaching the rigidbody handle to the point where the trace's collision hits, it attaches to the Origin of the object's Bounds property. This means that the player grabs an object by the center of its geometry, providing a more stable grip. Second, the object also orients itself in the player's grip, being sure to keep its front-side facing towards the player, giving a more consistent sense of manipulation. Third, there's a limit to the range at which the player can grab an object. Fourth, it was engineered to function more like the Half-Life gravity gun by incorporating an impulse that would release the object from the player's grip when used. Fifth and finally, the linear and angular damping are cranked up to 10000 to prevent objects from floating around in the player's grip, and a function has been added that prevents grabbed objects from taking angular momentum when released, thus no longer allowing players to throw objects infinite distances.