Team Project: Scrapped
Scrapped is a 3D platformer set in a futuristic scrapyard of robots and quantum technology. It focuses on the story of C-23, a robot searching for its place in this strange land. Gameplay revolves around moving through the environment by exploring the use of C-23's quantum abilities.
Role - Level design and Gameplay Programming
Team Size - 15
Development Time - 5 months
Engine - Unreal Engine 4.8
Fun Emergent Gameplay - Use simple mechanics that encourage and reward discovery and experimentation.
Personality Driven Character - Create a distinct robotic character that embodies a sense of curiosity and naiveté.
Compelling Environments - Develop an imposing scrapyard environment that is visually engaging and immersive.
Prototyping initial gameplay from game designer vision
Designing and implementing C-23's animation blueprint, including integration of and functional feedback on Lead Artist's animations
Implementation of Level Design-oriented blueprints, including scoreboards, saw and grinder hazards, scientists, destructible walls, and flying trash bots
Overseeing/assisting programmer refinements of gameplay and designer blueprints
Level 2A visuals and mesh placement from whitebox to shipping quality
Other scripting/design tasks as needed
Gameplay Design and Refinement
In the initial concepts, Scrapped imagined a robot using the power of magnetism to move through the environment. In early iterations, we attempted to explore how this objective could result in the emergent, rewarding gameplay we desired.
My initial implementation applied a force either away from or toward "magnets" in the environment. These forces were modified on an inverse square law and calculated distance from the center of the magnets.
Entering POCT, playtesting and game designer feedback indicated the following problems, which are listed with the solutions I chose to pursue.
Problem 1: Character is too floaty/feels too light/spends too much time in the air.
Solution: Adjust gravity for the player character. Though this resulted in a steeper trajectory for falling (and thus a "heavier" feel for the character), it would cause a number of headaches later.
Note: With the benefit of hindsight, a constant negative z force (down) would have worked better, as modifying gravity in the Unreal Engine was awkward and complex. A separate force would have offered more granular control and easier manipulation.
Problem 2: Repulsion (launching) should be more consistent.
Solution: Attraction and Repulsion received tweaks to their default force values. In addition, attraction and repulsion received differing multipliers from magnets.
As the team continued toward POCG, a number of additional problems appeared which would alter the underlying behavior of magnetism. These problems resulted in intuitive misunderstandings for players and designers, and would find differing measures of success for final implementation.
Problem 1: Large magnets behave strangely. The result of calculations from the center of an object, larger objects could have dramatic falloffs for magnetic forces at their extremities. Further, magnets tended to push or pull in directions parallel to the plane of the surface (for example, pulling a player to the middle of a flat magnet and preventing players from moving to the next magnet).
Solution: Reworking of force calculations to apply based on distance from the surface. Due to time constraints and the simplicity of our magnets (being almost exclusively rectangular prisms), I continued this implementation through blueprints. However, because blueprints could not access a mesh's vertices or face normals, the new behavior required the assumption of a cube-like shape (though non-uniform scaling allows for some rectangular prisms).
Refinements: The repurcussions of the chosen solution, combined with the modification of gravity, proved to be extensive. In the short term, it required the addition of a positive z bias (up) for forces in order to allow players to get to the top of magnets (an unintended but beneficial behavior that had resulted from attraction to the center of an object).
Note: This new behavior was now much more consistent across various sizes and uses for magnets. Later refinements for the base-use case of pulling to and launching from magnets involved modifying the calculation of force from distance. As I performed final adjustments of this curve entering Vertical Slice, these calculations would result in a stronger, punchier repulsion and a smoother, more constant attract. From the delivery of POCG to the final days of RTM, my role would become more strongly focused on design with suggestions for implementation rather than direct implementation.
Problem 2: Players have trouble distinguishing strengths of magnets.
Solution: Restrict Designer freedom. At this point magnets had variable strengths and no way of communicating this strength to the player. While this allowed more space for tweaking designs, it did not support clear communication of responses for players. Collaborating with the Game Designer, this led to the creation of two discrete strength levels of magnets with well-defined, precise impacts. As the actual use cases were refined, this would eventually collapse to a single strength base magnet and multiple types of "specialized" magnets for certain scenarios.
Problem 3: Magnets set at angles close to or greater than 45 degrees did not launch the player in desired ways.
Solution: Creating "hidden" magnets that players could not see but which applied forces in more desirable ways.
Refinements: The solution to the Problem 1 meant that significant effort was required to create a surface at a 45 degree angle that launched the player in a trajectory that felt equal to 45 degrees. These refinements were done alternatively by myself and the team's other gameplay programmer, Robert Stewart, and required the manipulation of multiple "invisible" magnets. Other specialized magnets required significant restructuring of the assumed normals for a magnet's shape. For more information, see the notes by Robert Stewart.
Note: This solution required more work when the angled magnets were upgraded to their own unique mesh and final uses were determined. See work at the above site for further notes on final, specialized implementations.
Character Animation Blueprint
The primary objective for the animation blueprint was to support the Lead Artist's animations to create an engaging and responsive character. In most instances, integrity of the animations took a back seat to immediacy of a smooth response. However, where possible, the animations were preserved and allowed to play out completely.
The main behaviors we wanted were:
Idle/Walk/Run/Jump - The primary movement loops, these needed to be flawless and near instantaneous.
Attraction/Repulsion - The main mechanic aside from basic movement, this needed to give players further feedback to reinforce the feeling of motion and force.
Sliding - A gameplay feature that arose partway through development, this behavior has a lower overall footprint but relies more heavily on animation to provide feedback for input.
Cutscenes - Due to questions of implementation, this behavior was the last added. Though it had significant priority in the polish phases, it did not factor heavily into early designs.
Notes on Idle/Walk/Run/Jump:
Walk/Run - A simple 1D blendspace based on speed in the xy-plane, it required precise tuning to match against movespeed.
Jump - While initially straightforward, the addition of running-jump animations added a layer of complexity. Despite this, by putting in a little extra time I obtained in a character that intelligently leaps off the last leg on the ground, resulting in smooth jumps while running (only one stationary jump was animated).
Idle - Since idle animations are an area which can easily inject life into a character, I made a number of attempts to intelligently and randomly respond to idle states. Unfortunately, difficulties with random seeding and inability to remember certain past states prevented true-but-believable randomness. Final implementation involved counting idle iterations and choosing evenly distributed idles.
Notes on Attraction/Repulsion:
In-Air - Aside from Running/Jumping, the primary animation loop involves the player character responding to forces while in the air. From the beginning, this animation used the real forces acting on the player to direct transitions. In an attempt to reduce the animation load for our artists, an effort was made to minimize the number of animations while achieving the desired responsiveness. While the final animation is fluid and responsive to forces, and allowed fine control of every frame of animation, I have a few thoughts on further refinements.
Physics-Based Animation: UE4 supports a type of animation which incorporates forces acting on the bones of a skeleton with a physics asset. Although this may decrease fine control for every animation frame, it may allow for greater accuracy for C-23's responses to forces.
Velocity-Based Response: Currently, C-23 moves smoothly through the environment. However, because the forces acting on the character change quickly, C-23 can seem to snap between frames in spite of blending. Basing these transitions on velocity might result in more intuitive motion for the player character, in addition to offering a certain amount fine control back to the player character should physics-based animation be used to respond to forces.
Some tweaks had to be made to smooth the differences between the primary in-air loop for falling and the frames for Attraction/Repulsion. Due to the high number of key points in the 3D space (and the relatively small time budget for animation), constantly reworking the base animations was undesirable. Layering the animations allowed greater smoothness with much less rework.
Further notes on Attraction/Repulsion:
Grounded - The primary responses to Attraction/Repulsion will occur while the player is flying through the air. However, there are cases where the forces acting on the player may not cause them to leave the ground, but still imply a force is being applied. By blending the in-air Attraction/Repulsion behavior, I was able to quickly add this feedback to the player character's behavior with minimal additional effort.
Further, despite the fact that our forces acted in three dimensions, UE4 only supports 2D blendspaces by default. With a little math however, I was able to use the layering system to create a reasonably effective blending for responding in 3D.
Notes on Sliding:
While not a necessarily a traditional platforming element, slides are an element of classic platformers that the team felt driven to include. Although this didn't receive the same polish as the primary movement loops, a simple blendspace and restricted camera control gave players feedback on their input while reducing the necessary complexity of the slide behavior.
In addition to the animation blueprint and main gameplay elements, I created and built upon a number of other blueprints throughout development. Most of these were oriented towards other level designers to assist them in building out the game. These include but were not limited to:
Scoreboard - Scoring, animating, and skipping through the billboards at the end of levels.
Flying Trash Robots - Moving, non-gameplay actors to give life to the world.
Saw and Grinder Hazards - Intimidating dangers, these acted as obstacles to the player.
Destructible Walls - Interactable objects that hide collectibles.
Tutorial Scientists - Animated, non-interactable characters that provide text-based dialogue.
To implement an imminently skippable scoreboard (that didn't break visually), I decided to create a sort of state awareness. By using a Rep_Notify enum, I created a blueprint that would change state and then respond to its new desired state. This allowed me to ensure skipping occurred in an strictly defined order and each step of the experience transitioned smoothly if interrupted.
The smooth camera transitions construct a spline and lerp along it, passing through four of defined points. The travel time is editable, as are the travel points, to allow designers to tweak edge cases and test behaviors.
Skipping behavior also required a lot of rework to remove any delays and rely solely on stoppable timelines.
The Scoreboard provides a central element of gameplay by rewarding exploration.
Leveraging the classic mechanism of scoring, it gives the player feedback on the approximate number of Lightbugs collected in each level and provides discrete rewards in the form of story panels.
Rewarding - Each Lightbug collected should feel meaningful when the player is being scored. The experience should be suitably cinematic to emphasize importance.
Unobtrusive - Scoring happens at every level, but doesn't deeply involve the player. Therefore, it should not waste time and should be easily skippable and not break when the player exits.
Plug and Play - Designers should be able to understand all elements and need to do little tweaking to achieve consistent functionality.
One of the more fun elements to implement was the flow of Lightbugs from the player character to the scoreboard. In the name of fidelity and honesty, the number of Lightbugs spawned is equal to the exact number the player collected. All flow along their defined path at the same (exposed) time, regardless of Lightbug counts. The math was a little convoluted, but quite a joy to puzzle out.
The player also paths to the Scoreboard, using UE4's simple navigation system. Like all the other elements, this must be skippable to enable convenience for the player—the player must regain control of their character immediately.
Flying Trash Robot
The Flying Trash Bot was a one-off blueprint constructed to add life to the world.
It featured a simple, constant animation and was likely to be far from the player, away from scrutiny. Implementation goals were:
Fast - Spend a small amount of time on this asset, as the team is in the final stages of alpha and a lot of tasks remain.
Friendly - Like all blueprints, this should be easy to use for the less technical designers. Another person will likely be placing these under time constraints.
Robust - Though they serve no gameplay purpose, they are one of the few environment objects that move. As such, they should accommodate creative uses where possible.
The main behavior is movement, and there is no expectation that it will stop until it is unloaded from the level.
To accommodate creative use, movement can follow a spline system similar to the one used for other assets (see Fritz at Robert Stewart's page). Designers are familiar with its use and it allows smooth pathing between points.
To simplify use, directionality should be reversible (to break up monotony of placement) and a default behavior that works well for a straight lines is desirable. We want this to be looping, so it should constantly reset its starting point. Because splines generally don't loop and we want smooth motion, and particularly in the interest of time, the behavior resets at the end of the path by turning to face intended direction.
A final note: Despite the imperfect pathing (because it has to stop and turn to reset), the blueprint served its purpose flawlessly. In most cases, designers stated that straight-line motion would have sufficed. However, it should be noted that a few instances of circular paths were used to great effect in cinematic spaces.