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
[RFC] Amethyst as bin #6
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got a couple of questions concerning this. It still feels pretty vague.
Also I'm a bit afraid we will lose customization power by doing this.
You can't run amethyst as a thread in a bigger application when doing this for example.
Here's one of my use case for reference:
An application listens for tcp connections. When it receives one, it creates a process with the amethyst engine and passes a "game replay" as an argument to it. The process plays the "replay" and ensures it is valid (no memory manipulation, physics are correct, time is correct, no teleportations, etc...). At the end, it returns a value to the host process. 0 if it is valid, 1 if it isn't. Then the host process reports back to a backend server.
Is this still achievable under this architecture? It is a bit unclear.
Thanks for opening the RFC!
`!Default` resources. Most commonly, these resources come from the rendering system, such as `ScreenDimensions`. In order to | ||
gain the most benefits from this we are going to have to introduce a "core dispatcher" concept to the engine. | ||
The core dispatcher would be responsible for input, and rendering, both of which would be optional. If neither are enabled | ||
then we simply don't run the core dispatcher. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd assume this would reduce parallelism since dispatchers are run sequentially.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a bit, but I provide the following counterarguments
-
Rendering wasn't parallel anyways, it's a thread local system.
-
Input is pretty lightweight, mostly O(1). It doesn't get more complicated the more entities there are for example.
work for most needs. If you don't want a window for your game (such as for a headless game server) then you can return `None` here. | ||
|
||
# Reference-Level Explanation | ||
[reference-level-explanation]: #reference-level-explanation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does it do it? What does it implies? What are the steps the user has to do to compile (their game?, amethyst?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does it do it?
Intentionally left open so as to permit flexibility in implementation, but right now my first guess would be that on the user computer we have a amethyst_bin
executable project whose Cargo.toml
file contains a reference to a user crate, then we just use that crate like we would any other crate making some assumptions along the way about what functions and types it will provide.
What does it implies?
This question is so vague I don't know how to answer it. It implies <insert contents of the RFC here>.
What are the steps the user has to do to compile
Probably something like amethyst run
wherein our tools handle the build for them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah but also that is the section of the rfc where you are supposed to describe step by step what happens internally. What is the amethyst run
command actually doing, and in which order.
This issue is very interesting to me. It has been debated whether or not Amethyst truly is a game engine or merely a game framework. I think we could try the novel approach of being both. As this RFC mentions, engines usually handle everything for you, while you handle everything for the framework. What if Amethyst remained a crate that users can use like a typical game framework as they will, but as soon as they create an Amethyst project in the "official" editor, it transparently generates all of the setup code? In other words, the editor would codegen the scaffolding crate with everything to load the engine, and hook in what is modified in the editor (no real-time codegen, just a typical template crate with all the hooks to the editor). That approach has the advantages of:
In the end you get most of the advantages of an engine-as-a-binary with customisation and static linking. The obvious drawback is that you also need the build toolchain, but I don't think it's a noticeable issue considering how automatable Rust installation can be. |
@Moxinilian yeah I like that approach. The only thing that really concerns me about it is having the distinction between Atelier users and framework users, as framework users won't get all of the same benefits as Atelier users. My objective is to design this with enough flexibility to where people don't feel like they need to have |
Actually nevermind, the game crate could just call My objective is to flesh out our interface enough that people don't feel a compelling need to have their own |
Well, I think the main appeal of Amethyst would be in its engine side anyway, as most people involved in the framework side would probably be hobbyist more curious about the technology than anything (I mean it might become the most powerful game framework available so I'm not sure about that). I think if we focus our marketing on the Atelier experience, most people will expect the difference in experience they will get by using the framework mode. |
Also, if you want to make it more managed even in framework mode, you can make the user implement an |
@Moxinilian I'm legit kind of mad I didn't think of that. That's great! Using traits we could drastically reduce the amount of "magic" that happens by having everything come through a single interface. We should do that for Atelier users too! |
That also has the added benefit that we can now have optional functions in the trait implementation. |
Wouldn't it be the opposite? I'd assume hobbyist would want to get started as quickly as possible, while game studios need a larger amount of control over the execution. |
Game studios expect to have a nice and easy to use workflow they can give to their artists. When I was referencing hobbyists, I meant the people making games for the love of the craft more than the game itself. But it is clear that studios also want control over things. As you may have noticed, engines like Unity do not deliver, but they still believe workflow is worth more. We can fill a gap here. |
I'm all for the You could simulate a set of inputs coming into the engine and check for outputs. |
I've been thinking about this some more, and I wanted to provide a few answers for some of my own questions
I don't think we should support multiple crate names, because folder names don't have to match the name of the crate inside them. Inside the Cargo.toml file we can name all user crates
This is where we'll probably want an |
Oh and another cool thing we can do with this approach: since we're installing Amethyst anyways why not make a pre-compiled amethyst.rlib file part of that installation? Then we can just have the |
appropriate times during initialization of the game and/or editor so as to place the user provided values into the correct locations | ||
during the startup process. | ||
|
||
# Drawbacks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this section could use more details.
I see one major drawback which is not being able to no longer call Amethyst, but now being called by Amethyst. That means a huge lost in flexibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That means a huge lost in flexibility.
That's exactly what I'm trying to avoid with this RFC process. The biggest and most important question this RFC needs to answer is "What do we need to do to make it so that none of our users miss being bin
?" If we can't answer that question then this whole approach falls apart.
|
||
The major alternative is to leave things as they are. While it's a little easier to maintain this way, we're somewhat limited in | ||
what we can do as a lib. Several people have commented on the issue tracker before "libs shouldn't do this" or "libs shouldn't do that" | ||
in response to us doing things that are very reasonable for a game engine to need to do. So my takeaway is that we shouldn't be a lib. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that are very reasonable for a game engine to do
Well, that depends a lot on what you expect a game engine to do 😄 It also depends on if you prefer facilities that are provided or frameworks. The latter imposes more structure on your code. This can have advantages sometimes (think of the ECS pattern), but it can also feel very restricting.
At the moment, I can grab my favorite application framework, write a complete application there, and if I want and need, start and stop rendering Amethyst, just like that. Heck, I can go and build an Amethyst launcher, from which I start unrelated Amethyst games, all in one application - how cool is that? However, with this RFC, something like that would become impossible, which would be a pity. A usage like that might be an edge case, but you'd cut all edge cases and Amethyst would become a 100% game engine, no other uses supported (without modifying engine code). That's why I want to throw in another idea: How about providing both, Amethyst as an engine and Amethyst as a framework? The engine would have the framework as a dependency and implement all the nice ideas mentioned here. It basically is the convenience layer anyone creating a game wants and people would pay money for the support. This wrapper, though would only contain the bindings and convenience, no shiny tech. That would be the framework's job. It would contain all the low-level stuff and awesome shiny things we have today, which could be used in exiting ways, which might not be the need of game studios or things anyone here can come up with on the spot. I don't think that only hobbyists would be happy about that, but also professionals who need a modern integrated 3D framework for other jobs than one big game. Something like the Amethyst framework is missing from the Rust ecosystem, so if Amethyst would go engine-only, who would fill the framework gap? Do you want to send people over to C++ and Ogre3D for that? Or should others create a new project, which basically uses most of Amethysts crates or even duplicates code, just to remove the engine part? Amethyst is shiny, and I'd welcome a focused effort a lot :) |
So to recap after this amethyst will exist as 3 major "sections" of code.
Both So, all in all this RFC does not remove any existing capabilities for users, only adds a new way to use the If we're all in agreement I'll add this to the RFC officially. |
Could you explain again what |
It is the executable that the user crate hooks into. It's where |
I don't understand why this is still necessary considering what we discussed above? |
Uh ok can you please provide quotes and links to comments that I may have misunderstood? It is my understanding currently that we want to expose both our current setup as a game framework, and our new proposed setup here as a game engine. None of what I've read above indicates we want to nix this RFC, instead we just want to make it supplemental to an already provided interface. |
Well I expected the framework workflow to be what it currently is, and the engine to build a sample project on top of the framework that is piloted by the editor. How does the external binary fit in that? |
And therein is my point, we can't pilot without |
But why wouldn't the editor generate the fn main? You don't have to touch any Rust when using the editor, it generates everything. |
after this RFC is implemented the engine would provide |
From what I understood, the bin would be built over the framework, as a separated crate. That way the user can either get their code call, or call the framework depending on the choosen dependency (bin or lib) |
I think @Moxinilian 's original idea was basically " I actually think the In this model, you aren't controlling |
I think that the While I agree that it might seem appealing to own the As I see this RFC mostly tries to solve two problems: scripting and editor integration. I think that both can be better solved with other solutions. Editor could indeed have it's own binary, but that would just be an Scripts can be treated like assets. Any compilation step can be handled by asset pipeline, reloading them will already be handled by hot reloading. I don't see any reason why |
I see the problems you've brought up, and I do agree they're problems I just also am struggling to figure out how to resolve them without a stable Rust ABI. The fact that static linking is the only well supported way for two pieces of Rust code to interact with each other right now really puts a damper on the whole thing. We could use the C ABI, but I think that would result in a severely mangled and disjointed code base that misses out on a lot of the benefits of Rust.
Can you please provide more technical details as to how this would work? What is an "RPC hook" and how do I make one in Rust? |
I think there are many interesting ideas in this RFC. It seems to me that the main motivation is solving the issue with high compilation times and the resulting inconvenient ECR cycle. As much as I can understand this rationale, I think this comes at a too big cost, as many previous comments have explained in detail. The most important step in this direction is scripting, followed by other suggestions such as RPC communication. Thus, I'd like to propose to close this RFC. It would be completely impossible to do this right now, and I'm not sure if we want to do this at a later point. In such a case, we should at least have a working prototype of this feature, and open a new RFC. |
Perhaps now just isn't the right time. I'd recommend re-visiting the idea when Rust stabilizes their ABI. |
So I sought to answer my own question about the "RPC hooks". I found it. https://docs.rs/libloading/0.5.0/libloading/ This might serve as good inspiration for future RFCs. |
@Xaeroxe My idea about hooks was more like having some points in the engine that could send/receive data over network/ipc pipe in order to cooperate with the editor. DLLs solve different problems. With DLLs, you are loading foreign code into your process (or loading your code into a foreign process, depending on the perspective). What i was referring to is to actually have two processes talking together. That way failures on one can be handled by the other without necessarily bringing the whole setup down. |
Rendered