Chromed editor
17/Nov 2008
As you probably have heard - some months ago Google released its own browser - Chrome. One of it’s distinguishing features is that every tab is a separate process, so if one tab crashes, it won’t bring whole application down. I’ve read in different places about tries of applying this scheme for game editors. Imagine game (renderer) and editor being two separate processes. Should one of them crash, the other is still running, so that we can at least save our work. As an added bonus - they dont have to be written in the same language. How about an editor in C# and renderer/game in C++? Sure, it’s possible with CLI as well, but it’s not the most comfortable setting ever. General idea intrigued me enough to give it a shot.
Basic outlines for the system are simple:
game/renderer is server. It’s coded in C++.
editor written in C#, acts as client. It tries to connect to server and at the beginning sends crucial informations about render window (handle + dimensions).
all the interprocess communication is done via pipes. I could use sockets as well, but a) I’ve not experimented with pipes before, so they were more interesting and b) they seemed easier to use for my purposes. C++ side of IPC system was strongly inspired by code from Nocturnal Framework by Insomniac. I modified it mainly to fit my system and I don’t use all the features (I don’t need C++ client, so it’s server-related code only). For the client I used built-in NamedPipeClientStream (introduced in .NET 3.5).
all the messages (client ‘> server) are recorded, so that they can be replayed at later time. This can be invaluable when investigating bugs. With some more effort it could probably be used for creating editor macros and automate designer’s work. There’s important choice to be made here: it’s possible to significantly cut down amount of transferred data by not sending mouse position changes (>90% of traffic). Instead we can use GetCursorPos/ScreenToClient in C++ application. It will work, but the problem is, we no longer can replay saved messages, choice’s yours.
there’s some marshalling required to convert messages. To make it easier, I generate C++ header using C# reflection. Comparing to CLI approach, it’s a little bit more work with sending/receiving messages, but after the basic system is in place, it’s rather trivial to add new kind of data.
Below you can find movie of my first system test. I create several game objects and modify their properties. There’s an intentional crash bug that occurs on creating a torus. As you can see, only server crashes in such case. Data on client is unaffected by this. We can save it and load later. We can simply restart the server, connect again and continue working! Notice how both objects are there, untouched, at their most recent positions, with new properties. Finally, we can save the message queue that leaded to crash and try to fix it. Main point is: crash doesn’t mean lost data anymore. Movie quality may not be the highest, but that’s my first try with Windows Movie Maker, behold my director skills. There’s higher resolution version for each of them to download, just in case someone’s interested enough.
[flv:http://msinilo.pl/download/videos/ipc01.flv 352 184]Get higher resolution DivX here.
Second movie shows how we load our saved messages and try to pinpoint the bug. This is an easy case, crash is 100% reproduceable, it’s enough to replay the messages. In fact, for this one it’d be even easier to just double click the last message (to perform it CreateObject TORUS), but let’s show the whole sequence, because it’s more interesting :). [flv:http://msinilo.pl/download/videos/ipc02.flv 352 184]Get higher resolution DivX here.
Finally, I ‘fixed’ the bug and replay same sequence of events to verify it. It seems to work, indeed. Torus is created, we can modify it’s properties and continue with creating our great world of intelligent geometric primitives. [flv:http://msinilo.pl/download/videos/ipc03.flv 352 184]Get higher resolution DivX here.
Presented sample is relatively simple, but hopefully it shows the strength of the system. Initially, I was afraid that sending mouse events back and forth would result in unresponsive control system. It turned out, it’s not even noticeable on my laptop, it ‘feels’ like single application, not one rendering in the window of another. I’m not sure if it’d be still OK for full game control or applications where more precision is required like animation editors/viewers, but for game editor purposes it works very good.
Source code can be downloaded here. In order to compile C# part of the system, you’ll need DockPanel package by Weifen Luo. For C++, Delegate library by Sergey Ryazanov is required. Code is a little bit messy in some places, but I wanted to get it working as soon as possible, to test the idea, so I took several ugly shortcuts (in fact most of this has been created during previous weekend, later I’ve been too busy fighting with Air France strike and other attractions).
Old comments
hollowone 2008-11-27 20:19:51
short test of the between-processes relationship in Chrome. Try to open task manager while you have google chrome opened. Open as many tabs as you like and try to kill one of the processes. You should expect that only one tab disappers, right?
In my case whole app vanished.
admin 2008-11-27 21:28:45
It was actually one of the first things I did after downloading Chrome. In my case tab shows “unhappy face” graphics and reports an error, but app still works.
Chris 2010-02-01 22:30:24
I think the best reason to do something like this is to allow people on multiple computers to edit the same level at once by connecting to the same server. This is like the pinnacle of game editing awesome.
admin 2010-02-01 23:35:48
Well, yeah, but it also opens a whole new can of worms. I’m not sure there are many engines with full collaborative real-time editing. Possible a little bit easier when using layers/zones, but still not a trivial problem by any stretch.
GameCoder.it − L’assert, questa sconosciuta 2010-02-28 21:59:32
[…] del C++0x. riferimenti: http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/ http://msinilo.pl/blog/?p=212 Share and […]
getcursorpos 2010-03-25 12:58:54
[…] As POINTAPI) As Long Dim Z As POINTAPI Private Sub Timer1_Timer() GetCursorPos Z Debug.Print …Chromed editor | .mischief.mayhem.soap.Article about game editor written in C# communicating with game/renderer in C++ via IPC. … Instead […]