So I played around with Ashley ECS for about a day (maybe 4-5 hours of actual work) with the thought of perhaps refactoring the existing Solitaire project to use the ECS design paradigm. I ended up with a little prototype that renders a card to the screen (face up), which will follow the mouse cursor. This was nice, as this meant that I had correctly set up some components, correctly set up multiple systems (rendering, type, player control, etc), initialized and utilized the Ashley Engine properly, and made an entity.

solitaire_ecs_test.gif

Having correctly done all that, I got to thinking about what it would require to refactor the Solitaire game to use this system. BLUF, I don’t think that that’s the way forward, for a couple of reasons. The biggest reason is that we utilize the Scene2D framework HEAVILY for all of our card movement and positioning. Scene2D is it’s own monolithic control system and we use it do to things like keeping track of all cards and card structures, user input control (touch control), button control, detecting sprite collision/overlap, etc. All of the “system” parts of these items are already controlled by Scene2D, not in an ECS system, so converting over to Ashley ECS would likely involve rewritting all of that functionality specific for our use case. I don’t think most of it would be too bad, though there is one item that I’m a little unsure how to implement in ECS, and that’s the concept of sprite “Z priority”. Aka, keeping Z reference on all renderable entities and having a clear understanding of what sprite should be rendered on top of the next. Also, catching mouse clicks on the top sprite and not letting those clicks fall through to sprites below the highest Z axis sprite, even though those clicks occured within the bounding box of the underlying sprites as well (eg when all the cards are on the deck, they all share the same bounding box, but a click on the deck only effects the top most card, and then the card under that card on the deck gains the highest z priority in that area and a subsequent click on the deck effects that card). I’m sure I could work out a way to do that if I banged on it for a little bit, but all of that functionality would likely take a couple of weeks to brew ourselves.

That by itself is only part of the reason why I’m thinking of not going with Ashley ECS for this particular project. Coupled with the above fact is the fact that I’m honestly not too sure what it will buy us. The big drive to looking into Ashley ECS was because I felt that the Solitaire codebase had gotten a bit too convoluted, and I was worried about future feature additions/code maintenance. And ECS would surely change how the structure of the program works, but there is still a bunch of mechanics in the game of Solitaire, and I think that we will still have a pretty “busy” code base when implementing it with ECS. The biggest, most touted advantage of ECS is that it really, really cleans up your class structure. It makes it far easier to answer “if enemy x can fly, enemy y can swim, enemy z swim and fly, how does your class inheritance work”. We don’t actually have that complicated of a class structure, and I don’t think we’re at risk of getting more complicated. As far as game objects go, we have “cards, card groups, and card structures”. Each are very well defined, and while there is some inheritence happening in the class structure, it’s mostly boils up to those three things (ie we have “Deck” inheriting from structure, but the deck is very clearly a card structure, and there’s not much concern about us wanting the deck class to inherit from the card class later on down the road).

Basically, I think ECS could work for this game just fine, and if we had started with that paradigm I don’t think I’d regret it. However, I dont think it’s totally “necessary” for this case. I think we will spend a lot of time refactoring/rewriting stuff to get onto ECS, and I don’t believe that we will see much return on that investment. For future note though, I think it would be very wise to start with ECS on our next game, especially if it’s a game with a large number of varying assets (which is along the lines of what I have in mind for the next project). Now how to improve our current project? I think we will see a MUCH better return on investment by simply refactoring our codebase. And I don’t mean a paradigm shifting refactor, I just mean basic code maintenance. Comment stuff well, break high congnitive complexity methods into multiple methods, keep clear lines of demarcation, remove dead code, etc. I think that that’s what this project needs, far more then it needs a new design paradigm.