Monday, November 2, 2015

Been another while, huh?

Life has been pretty well lately; not been too "scared" lately.

I'm starting dev work on a new indie project!  Just working on it myself this time, code name "Zenith Fighter".  It's supposed to be an RoR-inspired roguelike where you go through rooms and fight enemies and grow stronger, but with more emphasis on good platforming and dodging and kiting.  Think of the dodging in games like Rhythm Gunner and Metal Slug, but put that together with action rpg-ish attacks and advancement?

Anyways, I've been thinking a lot about code architecture as I set out to start things off.  I want to take a pragmatic approach towards the code -- since it's a bit of a longer project I can't just hack in whatever the heck I feel like, and I should plan out the overarching design patterns and class hierarchy and responsibilities, but at the same time I also want to make sure I don't get too wrapped up in it because at the end of the day it's best if I can just Get Stuff Done (tm).  HaxePunk has served me well and I think I just really enjoy the no-nonsense simplicity of the framework that it offers, so I'll be sticking with that.  I also made the decision to not support networked multiplayer because doing so would be too much effort for not enough gain.  So, local multiplayer it is!  The plan is to distribute the native build and then have support for gamepads or whatever.

For a while I was considering using an Entity-Component System, like Ash (http://www.ashframework.org/) which has a Haxe port -- someone has even already done some work trying to roll Ash and HaxePunk together into the "Flaxen" framework.  But the more I thought about it, the less practical it seemed for my use cases.  I think ECS excels when you have a bunch of independent systems and lots of shared behavior across different entities.  Something like an RTS game with lots of units that have alike behaviors.  For my platformer-style game, it is true that we have a lot of logic that we want to share across enemies and such, I think a lot of the logic is FSM-state-driven...by that I mean my enemy wants to do something like "while in walking state, walk forward for 2 seconds.  Then transition to the shooting state where it does not walk and shoots at the player 3 times with cooldown.  Then transitions back to walking state".  Etc etc.  Now, this is definitely possible to do in ECS, via either having the FSM state embedded in some component, or by adding and removing components to mimic FSM states.  But I think fundamentally if you have your movement logic and shooting logic and everything split up across multiple systems, it makes it harder to reason about exactly how logic is happening within a single state?  It's much easier to have a centralized place for each FSM state where you can define exactly what happens for every aspect of the entity, as opposed to trying to think of movement, gravity, attacking, etc. independently.

So I guess it seems to me like if you have a bunch of systems that are easy to reason about independently, you should use independent systems.  But if you have a bunch of logic which are tightly coupled in your mind by design, then you should just tightly couple them in the code as well?

That said, the core idea of avoiding inheritance hell is a good precautionary warning to take heed of regardless.  For example, in my game Players and Enemies are fundamentally very different so they probably don't have a shared base class (aside from HaxePunk.Entity).  Their movement handling is very different in that Players have input-controlled movement and Enemies need some sort of state-dependent AI movement behavior.  However, we want to share the actual code for moving entities by a given amount and handling collisions, so that should be extracted into its own static shared function.  I guess what I'm saying is that ideally you share logic by having a bunch of pure input/output helper functions as opposed to trying to bake both shared data fields (member fields) and shared code functions (member functions) into some base class somewhere.

I dunno.  To be honest I think the most important part is just to start going at it; I think as I try to code things out, the use cases will become clear and I'll be able to form things sensibly.  Some parts of the design are also sort of up in the air right now too, such as how exactly character advancement and enemy difficulties will work.

Think I'm on a Seven Lions kick at the moment.  (See https://soundcloud.com/seven-lions/sets/remixes).  I feel like the dubstep-ish sound usually is a dish enjoyed in sparing, tasteful amounts because I feel like I can't handle too much of it before it gets grating, but I guess you could also say the same about normal trance and progressive, in that when you listen to =too= much of it it starts to sort of just blend together (and makes you sleepy).  Maybe I'll try experimenting with trying to move towards a Seven Lions-type sound, just to see what that's like, at some point.  For now though, I've got commission projects and such to work on.  I managed to get a good boss theme written for Copy Girl, though my first two attempts were false starts (hate those!).

Pretty behind on xmas letters, probably.  I've got only 9 done, sigh -_-;  Well, I'll try to get one more out of the way today!

Tried out my straight nib pen again yesterday...calligraphy feels really really satisfying!  Of course I'm still sort of getting the hang of it and my script is still pretty wobbly and I haven't actually gotten any actual alphabet/script memorized, but it's still fun to try and copy off of calligraphy worksheets.  I'm also quickly understanding how an oblique holder would help a lot, especially for slant styles.  Maybe I'll go and get myself some more nibs and holders soon after some more practice.

No comments :

Post a Comment