libgdx / gdx-ai

Artificial Intelligence framework for games based on libGDX or not. Features: Steering Behaviors, Formation Motion, Pathfinding, Behavior Trees and Finite State Machines
Apache License 2.0
1.2k stars 242 forks source link

Reduce coupling with libgdx by extracting shared functionality into a new dependency #25

Closed pakoito closed 8 years ago

pakoito commented 9 years ago

Related: https://github.com/libgdx/libgdx/issues/2793 http://www.reddit.com/r/gamedev/comments/2u8ytc/gdxai_150_released/co6b3hx

To ease using this library in other projects without bringing the whole graphic library, it'd be nice if it was split into a shared module and the core library,

tomcashman commented 8 years ago

+1 This also gets rid of dependency on specific versions of libgdx. I want to use gdx-ai with mini2Dx but they have conflicting libgdx versions and I have to update mini2Dx to use a matching version.

davebaol commented 8 years ago

@tomcashman Please add your vote to https://github.com/libgdx/libgdx/issues/2793 too. It's your best bet to get it sooner or later.

davebaol commented 8 years ago

Ok I'm going to start working on this. From my analysis gdx-ai has 2 kind of dependencies from libgdx:

To fix the last set of dependencies I have to change how gdx-ai works internally by adding an abstraction layer. I think that the service locator pattern should be used here. The locator should get you a LogProvider, a TimeProvider and a FileSystemProvider. You just have to initialize the service locator with proper providers. What do you think?

tomcashman commented 8 years ago

Service locator makes sense. I guess there would be something along the lines of Gdx.logProvider, Gdx.timeProvider, etc. to statically access them rather than passing references to everything?

davebaol commented 8 years ago

@tomcashman Yeah, sure. You won't have to pass the service locator anywhere. You'll have just to initialize it. Service locator is a decoupling pattern after all. By the way, regardless of this particular issue It's worth reading the entire book linked above. :wink:

davebaol commented 8 years ago

Just realized that most of the times you don't even need to set proper providers on the service locator. if Gdx.app != null libgdx has been initialized and gdx providers will be set when the service locator class is loaded by the class loader. If Gdx.app == null libgdx has not been initialized so we can safely assume that gdx-ai is running inside a standalone application and default desktop providers will be set. Of course if you want to use gdx-ai in Android (or any other non desktop platform) out of lbgdx then you have to implement and set proper providers.

davebaol commented 8 years ago

Ok I got it working with the auto-configuration mentioned in my previous post. Now non-libgdx applications only need gdx.jar in the classpath (native libraries and libgdx initialization are no longer required). I'm going to push changes to the repo after some code cleanup.

erlend-sh commented 8 years ago

Awesome! You're welcome to post an update about this on the jMonkeyEngine forum as well once it's ready ;)

davebaol commented 8 years ago

Done! The snapshot jar is up already. The wiki page will be updated in the next days. See CHANGES and ask if you have problems. Also, notice that now you have to call this at the very beginning of the game cycle

GdxAI.getTimepiece().update(deltaTime);

where deltaTime is the time in seconds since the last frame. Of course, if the game is paused you don't have to update the timepiece (unless your pause screen needs AI, which is rather unlikely).

Please, test and report :blush:

@erlend-sh Sure, I'll post an update on jMonkeyEngine forum as soon as I get some positive feedback here. :wink:

tomcashman commented 8 years ago

Not sure if it's just me or if Timepiece seems like the incorrect terminology here?

Apart from that it looks good, will take it for test run tomorrow :)

davebaol commented 8 years ago

@tomcashman The timepiece is just a clock that gives you current time and last delta time. It's needed because some parts of gdx-ai (like for instance message dispatcher, jump steering behavior and wait task) have a notion of spent time and I want to support game pause, so TimeUtils cannot be used here. When the game is paused you simply don't update the timepiece.

That said, English is not my native language. So If you have a better name I'm all ears of course. :blush:

tomcashman commented 8 years ago

It makes sense that it is needed. Maybe Timestep is a more suitable term? Delta is often referred to as the timestep value (e.g. http://gafferongames.com/game-physics/fix-your-timestep/)

davebaol commented 8 years ago

Don't know. Regardless of whether the timestep is fixed or not, you continuously give the timepiece a delta to update the current time. From the application's point of you it's just a clock. Maybe TimeService ?

tomcashman commented 8 years ago

Good point. Yeah I'd say TimeService or even just Time.

davebaol commented 8 years ago

The problem with Time is, so to speak, the repeated possibly ambiguous getTime()

float currentTime = GdxAI.getTime().getTime();
davebaol commented 8 years ago

New wiki page done.