-
-
Notifications
You must be signed in to change notification settings - Fork 908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ai): Add Pursue behavior from gdx-ai #1267
Conversation
Maybe this should be |
Well, there is nothing to bridge to. The gdx-ai library is in Java, so cannot be referenced directly. Plus, this library will eventually be deeply integrated with main Flame; for example all logic for camera motion are the examples of behaviors (seek/pursuit), so we'll refactor them later to make Camera steerable.
Here's how I understand the conditions imposed upon us by the Apache-2 license:
I've also included a line stating that the translated file's copyright really belongs to the Blue Fire project, not to the original gdxAI team. This is explicitly allowed by the Apache-2 license: "You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License." |
Porting an AI library should be done in a bridge package, like flame_gdx_ai. Similar to how we do flame_box/forge2d. |
There is In addition, this functionality does belong to the Flame core. We already have some rudimentary steering behaviors, although they are done in a bespoke non-reusable way. So, this is going to be a massive upgrade of the existing functionality (I mean, not this PR, but this project as a whole). |
Despite the name, the bridge packages don't necessarily need to "bridge" to anything external, even though most do. For example, flame_splash_screen doesn't bridge to a 3rd package; rather, it contains within itself all of its functionality, that we thought to separate from Flame just for separation of concerns. The forge2d package exists because we decided to created it, as a place to port box2d (existing non-dart lib) into dart. Similarly, if we are porting an external library from another language, it would be much more valuable to encapsulate it in a dart package, so that anyone can use it, even if they don't use Flame itself, or even Flutter. Then, the flame bridge package would just bridge that into Flame components and reusable pieces. Similar to how we extracted canvas_test and that package is valuable to anyone testing canvas, idependently of Flame. Regardless of the 3rd package being made (to provide the implementation to the dart community outside of Flame), I think the code should be better separated into its own package. I am not aware of any AI related coded currently inside Flame, sounds like a very extensive set of tools that would be great to have but feel like could be properly separated. I am not sure what you mean by steering behaviors. |
Separation of concerns is great when done on the level of methods, or classes, or even sub-packages. But separating things into different libraries is a step too far. Just because effects can, in theory, be torn away and put into a separate library -- doesn't mean they should. Just because particle systems, or collision detection, or some other components like text or parallax can be separated into their own tiny libraries -- doesn't mean they should. There is very little in terms of benefits that can be achieved there, whereas the cost is quite immediate and real. These costs are: (1) the need to maintain another 2 separate libraries, (2) the need to build a separate documentation system, (3) the need to create a new test harness, (4) the need to build a separate example library, (5) the cost of synchronizing APIs between libraries, (6) separate release schedule, etc. Taken together, that's a big cost. And I'm not saying this theoretically: from the very practical standpoint, none of the libraries that we released as separate packages achieve the same level of quality as the main Flame library. In short, I'm not in favor of shooting a project in the foot before it even had a chance to make its first baby steps. |
I agree with this, we shouldn't make bridge libraries just because we can, it will be less easy for the user to use too. But I think we need a plan for what should be ported here, if there will be a lot of changes I think this should start off as a separate package (not two) with a version <1.0.0 and then simply move it in when it is done. If this feat is expected to have a fairly stable api within 2 months (next stable release) then I think it can be kept in the main package. |
It is difficult to anticipate the amount of change that will be needed. On one hand, the source library is quite stable. On the other, there's been quite a few non-trivial adjustments to their code just in making this PR. We could simply avoid exporting this into main Flame namespace. Thus, if someone wants to use it, they'd have to access it via |
I agree with people that this should be a separate package. |
I think that sounds like a pretty good compromise, until it becomes more stable and we'll export it. Possibly rename the directory to something else than AI, I think this is much more generic than that? |
What do you have in mind? To me, "AI" sounds generic enough: artificial intelligence -- any functionality that helps make your game more smart. In addition to behaviors, we'll also have reactive actions, movement in formations, path-finding, behavior trees, etc. |
We talked in the team yesterday about having this as a separate library or not, since Erick and Luan seem to prefer that. The pros and cons I see are the following (please fill in the list with things I miss): As two packages
Inside of Flame:
If we have a pure Dart |
Here's how I view the breakdown of various factors: Inside of Flame
Externally
SummaryIn my view, the benefits of including this functionality into Flame far outweigh the alternative of releasing the package separately. Of course, many of these arguments are somewhat speculative -- but many are drawn on the existing examples of packages that we have as externals, and which present significant challenges to the development. If anything, we should start thinking of how we can bring our many disparate packages under a single umbrella (at least into the mono-repo). |
The package would live under the same organization, and that would be clear on pub, so I don't think this is an issue.
If the full gdx-ai library should be ported it is probably close to 10k lines of code, it feels like that deserves its own pipeline, but I agree, the code does still need to be maintained.
The plan is to merge all examples and docs, so I don't think this deserves three
If we document it well I don't think that Flame will be perceived as less powerful, and I don't think we'd get less stars on github on the monorepo because we have this separation. I mean, we don't even have audio support in the core library.
A lot of people have used
It is not hard to do a release to pub, you simply write
See reply on "Ease of development".
This is not an option I think.
This is the option that we are discussing? (My suggestion to have it as only one package earlier was because I thought that we could move it in once it reached stability)
What are the substantial costs that you see here?
Since the bridge library would depend on Flame we could expose an interface for different camera movements. I agree that we don't want code duplication.
What are these significant challenges?
The umbrella is blue-fire and flame-engine, packages that can be used without Flame should not live within the monorepo. Before I knew that the gdx-ai package was so big I thought it was a pretty good plan to put it within the core, but know I'm leaning towards @erickzanardo's and @luanpotter's standpoint to have it as a separate package. |
Maybe it's just me. But it took me more than 2 months to realize that
Obviously this is a great plan, deserves a 👍 or even :+2:. But for now it is still more of an idea than an actual plan. I mean, there is no tracking issue, or a project, or an approximate estimate for how long it would take, or how much effort will be required, or commitment from specific people to do it. Surely, it can all magically materialize before the New Year, but it could also take several months or even quarters.
Here's an actual example from Instead, I'd need to (1) fork the canvas_test repository, (2) set up Android Studio for the new project, (3) implement the Note that most of these concerns wouldn't apply if the ai library was inside the mono-repo and flame depended on it via relative import.
I wonder what's their use-case though? Developing game engines alternative to Flame? Do we even want to encourage that? For gdx-ai I suspect their prime motivator is to make their engine jar files smaller, so that developers who don't need AI capabilities wouldn't have to carry it along. After all, Java doesn't have tree-shaking like Dart.
There is always some hidden cost of publishing, and in general maintaining the CI infrastructure. Creating release branches and tags, making GitHub release, resolving deprecation events, updating readme, creating changelog, re-building documentation, making public announcements, etc. |
We can always design the package in such a way that it cannot be used without Flame. Ultimately, this AI engine is for use in games, it has no external purpose like, say, Ultimately, though, is the question of scope: is this functionality within the scope of Flame engine? Suppose, for example, that there was no gdxAI project. I came in and say: look, we have position-components which can be placed anywhere, and we also have move effects that can move them in a predefined way, and even a "speed" parameter that can change the effect based on the initial position of the target. But wouldn't it be nice if we also added more complicated types of behavior, where targets update their trajectory continuously, where they can react to other targets or to the environment? How do we decide what's in Flame's scope and what's outside? If the concern is that the code originates from gdxAI -- then we can develop it independently. It would still be easier than maintaining a separate project. If the concern is code size (and btw, Java is about twice more verbose than Dart), then we can limit the amount of things we are going to implement. If the concern is that the code can in theory be separated, then I don't understand what's the scope of the Flame library. Because it has plenty of things that could have been in separate packages (like particles, effects, collisions, etc). |
For me the reason for this being a package on its own is pretty simple, this is a port of another lib, better keep its code base apart from Flame. |
So, would you be ok with including this (or equivalent) functionality into Flame, if it was developed independently from gdx-ai or any other existing library? |
They were moved over quite recently from Luan's personal account, if anyone is actually concerned about the origin of a package it is very easy to see that they come from us now though.
It can be started for new projects already, so all gdx-ai docs would be written just like if they would have been included in the core.
I can see your point, 6 and 7 doesn't work like that though, we publish a new version and then we do the PR afterwards. And 8-10 could be done in the same PR as where you need the changes and you could have your PR depend on your branch before it is merged. For these kind of libraries which can develop on their own we definitely don't want them inside of the monorepo, these can live completely without flame and if someone wants to continue work on them they can simply fork only the small repo instead of the full monorepo.
Of course, anything that gives our users freedom to come up with whatever crazy ideas they have. One person for example created a site with directed graphs and each entity was controlled with a Forge2D body and springs, completely outside of Flutter. We don't want to lock in people to Flame and Flutter when we don't need to, if it isn't making our lives too hard, so that is what we are really discussing. A pure dart library with gdx-ai could be used with so much more than just Flame, compare with the a-star library for example.
Almost all of that should be automated though, and just as much work outside the monorepo as within it. We have generalized most of the pipeline actions so that they can be used in different repositories.
This is a very good question! I'll make sure that we discuss that on our next meeting! |
Ok, I surrender. I'll create a new package. |
Description
This is the beginning of the work on porting the gdxAI library into dart and integrating it into the Flame engine.
This PR adds the
Pursue
behavior, and implements some of the basic interface classes such asSteerable
,Limiter
,Location
,SteeringBehavior
, andSteeringAcceleration
.I have also made some modifications to the original Pursue algorithm, for comparison the timings of the old and the new algorithm are as follows:
Screen.Recording.2021-12-23.at.3.06.25.PM.mov
Checklist
fix:
,feat:
,docs:
etc).docs
and added dartdoc comments with///
.examples
.Breaking Change
Related Issues
WIP for #1164