-
Notifications
You must be signed in to change notification settings - Fork 58
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: Editor-Player-IPC #139
Comments
I would actually prefer the IPC approach. Even with a IPC protocol you can still achieve alot (even event debugging/single-stepping will still work) Question is how the IPC protocol is supposed to look like. For comparison. What CMake uses: The new CMake mode which looks much more ugly, it works by putting files on the Filesystem and then CMake uses file system watches to detet when a file appeared (so kind file-based REST) https://cmake.org/cmake/help/v3.18/manual/cmake-file-api.7.html |
Test play crashes (which it will since I'm actively developing new features), kills editor. And I lose all my saved work or end up with corrupted data.. Just for that I'm sold. Lets do IPC :)
One major problem with REST is that it's unidirectional. The editor will have to poll the player for state updates. Given the randomness of frame rate timing, this can be lossy. To have frame accurate debugging we probably want to synchronize per frame updates between player and editor. I think something bi-directional would work better. Editor will need to send commands to player, or query for things. Player will also need to push back state updates every frame. If you're talking http, then a websocket based API could work. Ultimately I think the transport mechanism is less important. More important is what is the payload and the communication protocol used to exchange data. I haven't really thought about this too deeply yet. We could look to remote debugging protocols like used in gdb for inspiration. I don't know how those work yet, haven't looked into it. |
Another option which can simplify. If we limit ourselves to IPC and not general network programming. We could use shared memory and just put a thread safe queue on it. Lots of ways this can go.. A lot to think about |
Besides the channel used more important is also the API avaliable. Which features do we need? From the Qt side we can basicly use anything: https://doc.qt.io/Qt-5/ipc.html but it should be something that is not painful to build into Player. Debugging protocols for reference: GDB Remote Serial protocol: (LLDB uses the same) Chrome Dev Tools (web-sockets) Firefox: |
Thinking about it more, a unidirectional REST protocol could work. You could hit an endpoint to pause the player. Then inspect it's state. You can single step or continue. Queries should fail if player is not paused For live editing, we can have a quicksave reload command. Which saves and reload the game. This quicksave/ load can be done in memory. I used this library in the past, it's really easy to run a server in a few lines of code. Unmaintained since 2017, so if we use this we would probably need to fork and maintain our own copy. |
so always one frame forward and then send commands to Player? At least one use case I'm seeing already is: Audio Playback. To integrate this in the Editor I'm required to copy-paste the entire Audio Decoder. Player IPC could help here by asking the Player to play the audio for me :) (though here a frame-based protocol wouldn't work here I guess because this isn't really related to game state?) |
Initial ideaCommands
For get, set format we can use lcf / lcf json. We could add debugging data and structs and codegen them with liblcf. This will integrate very easily with what we have already for save games. |
By fmatthew:
There's a few use cases I see really
For this, what we can and should do is isolate the interfaces we want to reuse from global state using dependency injection. This also helps with making Player itself unit testable. More refactors like the
Algo
library for this.To be able to start and stop player within editor itself, yes I agree we need a very clean creation and destruction sequence that doesn't leak any global state between runs. We need this anyway for load game and player unit tests.
That being said, I wonder if IPC is also the way to go here. Then you could run a separate player binary and attach the interpreter debugger and other tools to it. We also again don't need to worry about player global state at all. Each player run starts and exits a new process for 100% guaranteed cleanliness.
The IPC approach would require us to add stuff to player to pipe the necessary data back and forth, as well as a protocol for the game strate (enhanced LSD?). That can be a lot of work but it would enforce a clean separation. If we did this though, it also opens the door to additional capabilities for regtesting and other introspection tools.
The biggest amount of work with doing IPC / networking is the serialization code, but we already have liblcf giving us a fast binary protocol.
If we don't go the IPC route, I would want to still see a very clean separation. Let's not pollute Player with random
// needed for editor
hacks.Not going to IPC route would allow a much tighter and easier integration with edtior, and allow live editing while playing, which could be a big productivity booster for developers.
To run multiple editor instances for different games at the same time with their own embedded players, I would only do it by spawning multiple processes. Then we don't need to worry about player globals, ui globals, renderer state, audio state, etc.. etc... If needed a parent UI process can manage all the child ui instances. Trying to manage all the global state ourselves, especially for all the backend third party libraries I'm 99% sure will end up in frustration and failure, not to mention massive complexity. This also completely shields us to state cleanup bugs from multiple editor/player instances.
If we embed a running player directly into editor widget, we'll need this.
Options are:
Regardless of editor, this is in my near term future plans. I want to make sure new game / load game bugs are impossible.
We're very close to being able to stand up and tear down player game instances. Once the character PR goes in I'll be unlocked to refactor the player global state to achieve this.
The text was updated successfully, but these errors were encountered: