Notifications
Article
2D Action Platformer
Updated 6 days ago
675
4
A 2D Action Platformer made with ECS

Backstory

I was so keen on trying ECS and learning all about it, that one day I decided I would make a simple and hopefully fun game utilizing it. I decided on making a 2D game, as Unity has seen a lot of action and has refined its tool over the years. As it was a learning project I decided to throw in everything new and experimental I could get my hands on. I started working on the project just as ECS was going public. Along the way I had some struggles, going along with little to no documentation and ever changing API. The fact that I used dependency injection from the start, coupled with ECS data and logic separation, lead to a relatively smooth development, despite the struggles. As development went on, I started to dream about stories and mechanics. Memories of old and beloved games started to mix, and in the end I saw. If I decide, one day to do something more with it, it would be a mix of games such as The Chronicles of Riddick: Escape from Butcher Bay, The Alien series and Dead space. The player, a prisoner on a space station, about to be overrun by alien abominations. Fighting his way out to freedom. It took me about 2 to 3 months, including learning and prototyping.

Tech Used

  • Dependency Injection (Zenject)
  • Unity Entity Component System - ECS
  • Unity Adressables
  • Goal Oriented Actions - GOAP
  • 2d Lighting engine
  • 2D Platformer Pathfinding
  • Unity 2D Inverse Kinematics
  • Unity 2D Tilemap
  • Unity Cinemachine 2D
  • Unity Post-Processing Stack
  • 2D Motion Blur

2D Platformer Pathfinding

Not going to lie, the custom platforming took more than it should. Initially I was using hand placed nodes and driving actor rigidbodies with physics forces. That caused a lot of problems and was quite unreliable. Then I experimented with the new Unity ML agents, and tried to teach the AI to navigate a complex platformer environment. Suffice it say it didn't work out, as it was taking way more time than expected. It looked promising on simple platforms, but when it came to more complex ones the AI struggled, so I decided to scrapped it. Then I decided to just go about a more guided navigation. I made a post-processing step that calculated and optimized all possible points on the tilemap. It then calculated for potential drop and jump spots. Then at runtime, agents use multithreaded A* to find their way and lerp along the path. When they come to a jump or a fall path node they animate on a parabola between two points.

Unity Adressables

I wanted to make the game as modular as possible, so when I found out about Adressables I immediately wanted to use it. I always liked asset bundles, but never got around to using them. The Adressables solved that. It did take some getting use to, writing and planning for a more asynchronous code, but after a while, it just started to fit in and to work great with ECS, as asynchronicity was one of its allures. I ended up using Adressables for things like items, weapons and enemies.


ECS

The main reason for starting the project was for me to learn and try the new ECS. I wanted to try and do a more standard game with it, as most of the demos we've seen were quite specific. It ended up working quite well, especially when coupled with dependency injection. The game stayed modular and easy to manage as it grew in scale. I did find it hard to manage so much components and to remember what components were needed for what system. But the ECS debug tools did help with that.










Tilemaps and 2D Ik


At the start I used Anima2D, as you can see by the robot characters, but once the 2D Inverse Kinematics package was out I immediately switched. It was quite more lightweight and integrated with Unity. I wanted to minimize the art I created, so 2D bones were quite a welcome tool. Of Course, where would a 2D game be without the tilemap. Especially when I wanted a more dynamic game with some procedural areas. The tilemap was a great choice, as it had a powerful tile API. I've gotten a simple cave generation working for the time being. I was a bit disappointed that the IK solution wasn't playing that well with ECS. I wanted to rewrite it with ECS in mind, but decided not to. Maybe unity will have a ECS solution in the future.


Custom 2D Lighting

From the start I wanted atmospheric lighting, even in 2D. I wasn't satisfied by the 3D lighting and how it played with 2D, so I decided to search for a specific lighting solution tailored for 2D. I did a bit of digging and saw a GPU accelerated solution built by this guy/gal. I went and made a fork for my own use, made it work with the newer Unity versions and added some features. It is available here.

Cinemachine

I was pleasantly surprised at the power of Cinemachine and how nicely it integrated with 2D. I even used the Impulse Extension to add some nice camera shake, so that the weapons feel like they pack a punch.

GOAP and AI

I've worked with most of the popular AI systems, like Behaviour Trees, Finite State Machines, Utility AI and even Hardcored AI. But when I saw F.E.A.R.'s AI technique and what it could bring to the table I was immediately hooked. I've never worked with GOAP before and did have some hard time implementing it into a ECS pattern. But in the end it worked out fine. I was quite happy with the results, even with the simple AIs I have.

Dependency Injection

Dependency injection was one of the things added to the project, as I've fallen in love with it in recent years. Zenject was my framework of choice. It fit right in with ECS, even though ECS itself had Dependency Injection and I had a bit of hustle bridging the Zenject and ECS APIs.

Post-Processing

I used the unity post processing stack, as it was the most complete package and was the fastest and easiest to expand. I used the standard effects, like color grading, bloom, AA and chromatic aberration. There was one effect in particular I really wanted, that I grew accustomed to. I'm talking about Motion Blur. Unfortunately motion blur requires motion vectors and the default Sprite shaders did not provide such functionality, so I had to extend them and add motion vector capabilities. In the end it was worth having that sweet subtle motion blur that just makes everything feel smooth and that makes motion feel more impactful.

Final Thoughts

Even though ECS is praised mainly for its performance and ability to play perfectly with multithreading, having a data and logic separation steers you towards thinking differently about the way you approach and design systems. It gives you a lot of power when it comes to memory management and not relaying on the Garbage Collection as much. Even if you don't use multithreading everywhere, the ability to so quickly is always there. I also love the fact that dependency injection plays so well with ECS. Oh and of course, serialization integration comes basically for free.
In the end I've become quite keen on using ECS and will probably keep using it in the future. I can't wait for unity to expand on ECS and see where Editor integration will lead us.

Credits and Links

  • Anima 2D Characters
  • UI and tiles - https://opengameart.org/
  • Sounds - https://freesound.org/

Simeon Radivoev
Indie-Dev - Programmer
5
Comments
Simeon Radivoev
7 days ago
Indie-Dev - Programmer
Alan ThomasI really have to get into it. My biggest issue was the lack of documentation when it was released. Hopefully that will change so I can wrap my head around it. By the way - I also checked out your lighting system. I may have to investigate that further and potentially use it. It looks beautiful!
Yea documentation was a hurdle for me as well. And the API changing constantly. But they should be about done when 2019 comes out. I also wanted to use the new prefabs, but that came way too late.
0
Alan Thomas
7 days ago
Game Developer, FishPotato Games - Owner
I really have to get into it. My biggest issue was the lack of documentation when it was released. Hopefully that will change so I can wrap my head around it. By the way - I also checked out your lighting system. I may have to investigate that further and potentially use it. It looks beautiful!
0
Simeon Radivoev
7 days ago
Indie-Dev - Programmer
@Alan Thomas It was more me trying to use ECS for everything I can. The demos unity did were showing the real strengths of ECS, performance, especially with large amounts of entities. But one thing that ECS does, is change how you think about designing code. I love the data and logic separation as well as the low level memory management and not utilizing garbage collection as much. The strengths of C++ in manageable C#.
0
Alan Thomas
8 days ago
Game Developer, FishPotato Games - Owner
This looks great. I'm curious to hear more about your use of the ECS. What specifically were the advantages in doing so? It looks like it is pretty heavily embedded into your framework.
0