dbeef / spelunky-psp

Spelunky remake for Sony PSP.
Other
138 stars 10 forks source link

Reworked existing logics in ECS paradigm #73

Closed dbeef closed 3 years ago

dbeef commented 3 years ago

This is end up being partly a development diary, partly actual pull request description, since I wanted to present motives that led me to introducing ECS paradigm into the codebase, which has significant impact on future development.

Background

As I proceeded to draft the next two functionalities - namely, items and NPC's, I realized that it may be hard to fit them into the frames of object-oriented programming and not end up tangling multiple domains of project together (a thing that I am trying hard to prevent from the beginning).

I have previously encountered component pattern in the Game Programming Patterns, however, I didn't have a clear picture of how an entity-component-system works as a whole. The supposed benefits of having an ECS mentioned in discussions I've followed are:

I've also encountered some kind warnings, that OOP is still a reasonable choice in projects of low complexity.

I gave it a try and created a separate branch for a rework of existing features, which are - mesh rendering, calculating physics, handling input and updating animations. Yet, before re-working in ECS paradigm, I had to get an ECS framework (writing my own was off the table - developing a game is enough of a challenge, I don't want to put more on my plate with potential bugs and maintenance).

I choose EnTT:

https://github.com/skypjack/entt/wiki

It has great reputation, extensive wiki-page, is MIT-licensed and it even claims that Mojang's CPP Minecraft implementation uses it.

I placed it in the /vendor directory - it requires C++17 or higher, so I had to update all my CMake targets from 14. Fortunately, gcc bundled with the PSP toolchain supports it and EnTT cross-compiled successfuly.

Now, what do I do?

Some reference use-cases of projects integrating EnTT can be found in its wiki-page on Github (i.e PacMan clone or a tower-defense game), so I followed them patiently. Fast forward - took me around a week until I had my re-work and could call it "feature complete" comparing with master branch. At that point I wasn't satisfied. I put relatively high amount of time, and in the best case I had the same thing I already accomplished without ECS, at worst - I had same thing but it felt much less familiar.

I sat again by my notebook and started doodling how I will implement items, but now in frames of EnTT. Then it struck me - how about implementing particle effects at this moment instead? After all, now I have this PhysicsComponent, PositionComponent, AnimationComponent and MeshComponent, how about adding a component that will store amount of time to live in milliseconds after which a system will dispose an entity with attached components (named it TimeLimitComponent), and also ParticleEmitterComponent that eventually would spawn named particles?

This small distraction was the moment in which EnTT (and ECS in general) started really shining to me.

BOOM

Took a time to rewire my thinking from OOP to ECS, but now, as I am actually in the process of implementing items to the game, development got much more satisfying.

What's in this PR

It's hard to split this rework into multiple parts so to not submit one gigantic diff and what's worse, I was treating this branch as a scratchbook in the beginning, a sandbox for testing ideas (as I wasn't sure of how to use EnTT and whether I'll even merge it to master), therefore I squashed all my changes to not litter git history.

Changelist:

No items nor particle effects included in this particular branch.