Navigation/Shaders/Gameplay

Guillem Costa Miquel

Programmer

free site creation software

Project overview

I am Guillem and, as a coder, since the base engine was forked from an early version developed by Sandra Alvarez and me, I was capable to become the responsible of the Navigation system, scene-nodes and scenes structure, render pipeline, shaders, and gameplay.


Shaders

Deferred Shading

  • Why deferred. At pre-production, one of the main ideas from design was to implement a dark level where Alita focuses on discovering the city at night. As soon as Joan Valiente asked me for lots of lights to play with the brightness and contrast I started looking for a way to implement them without being a big hit in the performance. Together with the benefits for post-production effects, deferred shading was the best choice.
  • Problems. Once I got the first iteration of an early deferred rendering pipeline implementation the problems started appearing. Due to the different types of graphics cards from the team integrants and the ones provided from University we got some artifacts and errors in the scene. It required from a bit of time to fix the artifacts and get the pipeline working correctly.

Lights

One of my first tasks was to implement a lighting system for the game. Following the deferred pipeline, a directional and point light types were implemented. Together with Víctor Masó (art) and Joan Valiente (design) tried different styles as explained below.

First Approach. To respect the original manga, from the art department was decided to implement a cartoon stylish art style. Sandra Alvarez (who was in charge of cartoon shader) and I implemented a cartoon light effect.

Mobirise
Mobirise

Final implementation. After some milestones and deliberation, the last decision was to implement realistic quadratic lighting and this is what I did. It was an interesting investigation and finished super happy with the result. The cartoon lights were maintained for the characters. As you can see in the image, I also implemented customizable patterns.

Wall Shader

In the first level, due to the high buildings, often Alita or some enemies are hidden behind some geometry. To resolve this odd, I implemented a shader to draw with a plain color all the geometry affected by this. The first idea was to use the stencil buffer but as soon as I remembered that we got a free texture channel from deferred shading (we use RGBA for compatibility reasons) I decided to take advantage off this. Since animations were one of the most expensive (in terms of milliseconds) systems of the engine, I focused on avoiding to draw the characters twice to obtain the desired effect.

Mobirise

Optimitzations

  • Sorting by shader. when the first level was fully decorated, we were drawing about 3000 meshes per frame sometimes (in the engine) and together with improving the camera culling and all matrix calculations, I sorted all the geometry per shader (shader swap call is the most expensive OpenGL call).
  • Reducing OpenGL calls. I also implemented a mini c++ class to manage and reducing all the OpenGL related calls.

Gameplay

During the first steps of the project, and to achieve some milestones, David Valdivia implemented an early in-engine prototype of Alita with good results. Despite this, the game was expected to evolve fast and, as soon as we got a stable and functional engine, I took the role of gameplay programming, redoing Alita and all related scripts together with Sandra Alvarez, who was in charge of enemies AI and Jonathan Molina-Prados, the one I always was looking for when I needed a new c# functionality.

Class based FSM

I had no much time (about a week and a half) to get Alita fighting again in the game with the new code and, because of that, the first approach was to implement a simple switch based FSM. I discarded this option fast due to the scalability of the project and the number of persons who would need to iterate on the code to implement some effects so, finally, I decided to choose a class based FSM. Thanks to the fact that I read Game Programming Patterns by Bob Nystrom not so much time ago, it was not that hard to get everything working again in just a few days.

Now I can say that this was a super good decision because we got every state encapsulated in classes and it was an easy solution to avoid spaghetti code in an entity that was expected to be edited for every designer/programmer in the project in a moment or another.

Mobirise

Alita features, passives and actives

I was the person in charge of implementing every feature required for Alita (except for steering behaviors and some boss-required states that were implemented by Sandra Alvarez and statistics implemented by Guillermo García). I was the one who implemented all related features such as Alita's shield, combo, dead, picking items and interacting with narrative states, save and load, second combo, levels, active and passive skills, etc. The main idea was to achieve the gameplay feel of Torchlight.

Actives and passives
I also was the one who implemented all the active skills following the design decisions by Alex Campamar and Joan Valiente. One of the hardest Alita's systems to implement was the passive tree. I wanted it to be as scalable as possible and just taking a few lines of code to get a new passive working. I am pretty glad with the result obtained and I also implemented all the current passives available in the game (life leach, powerful hit, burning enemies...).

Mobirise

Entities Structure

In order to get a good interaction between Alita and enemies, I implemented an entity structure for the game. I followed a hierarchical structure and prepared every entity such as enemy entities, chests, NPCs, etcetera.

Events and game manager

Because of the number of systems required for the game and all the persons involved in them, it was hard to communicate the different scripts. To avoid problems, I implemented an easy to use event system. Any script interested can be subscribed to the events so when anyone pushes an event (Alita dead for example) everyone interested in receiving the data would be called at the beginning of the next frame. It avoids lots of crashes and readability problems.

Another feature that I was in charge to implement was the game manager. This is the script in charge of maintaining the "flow" and general data of the game. It was also the main script for input petitions and raycast. In this kind of game, raycasts are necessary per frame, so to avoid the use of tons of them, one ray is casted in this script an stored in a static var so we can reuse this information for everything.


Navigation

Recast and Detour

I was super motivated with the project so I started working on something two weeks before it started. This something was a really important system for this kind of game: the navigation system. I first was thinking about implementing a waypoint system because most games used this approach in the past, but after some investigation and boosted by my interest for the state of the art in navigation I decided to integrate Recast and Detour.

It ended as one of the best decisions we did in the project and I am glad I got the navmesh generation working one or two days before the first day of the project.

Mobirise

Detour Crowd

Firstly I also integrated the Detour Crowd (an extension for steering behaviors) and implemented a navmesh agent and obstacle component. It was working fine during the early days of the project and was highly used especially by David Valdivia but as soon as the game evolved it was hard to manage. Steering behaviors are game specific dependant and the code base of Detour was too big and complex to be modified in the time we got. After talking with the team I ended up working together with Sandra Alvarez. She implemented our own steering behaviors and I was improving and integrating all the queries required by her. 

Mobirise

Other

Scenenodes and Scene system

Despite forking the engine developed by Sandra Alvarez and me, the code needed to be refactored in some areas since the engine was being developed during Engine's subject. I was in charge of refactoring all the game object (statics, dynamics, save and load, etc) and scenes system (play, pause, etc). I also implemented together with Jonathan Molina-Prados the binary save and load for scenes.

Improved RAM resources management

In the last days of the project, we got some problems with RAM management. The game has been developed in a 32 bits architecture and the 2gb available were starting to not being enough. I improved the way we manage RAM in the reference counting system and now every mesh, texture, and material is only stored in memory if the current scene is using it.

Water shader

Together with Víctor Masó (art), we improved the water shader that Sandra Alvarez and I developed for the Engines' subject. We added 

Alita Unbreakable Warrior