Question

I recently watched a bit of Notch's Ludum Dare live stream. He uses Eclipse's hotswap feature extensively while he works on his game. (here is a video of what I am referring to http://www.twitch.tv/notch/b/302823358?t=86m30s)

I would like to do the same with C# and XNA. Fortunately, Visual Studio has an Edit and Continue feature. However, I would like to edit my rendering code while it is running instead of pausing it.

Is it possible for me to setup Visual Studio to do the same? I noticed that there is a checkbox for Break all processes when one process breaks. Is it maybe possible to set up my rendering loop in another thread so that the game keeps rendering while I make a change?

Was it helpful?

Solution

Update: This answer is now available as a video.


I've been struggling to find a way to do this. I know this doesn't answer your exact question. But really what you are looking for is a workflow where you can make code changes with zero (or near-zero) delay, and I think I've figured out the closest you can get with just Visual Studio. (And therefore avoiding a huge engineering effort and dealing with "abnormal" projects).

The way to achieve this workflow is actually astonishingly simple, once you think of it:

Use shortcut keys!

The first way I came up with is to just use the normal edit-and-continue method of setting a breakpoint. Only by using the keyboard you can do this considerably faster. This only works with code being called in a loop (eg: draw/update). Click the code you want to modify, add a breakpoint (F9), the breakpoint will almost immediately be hit, modify your code, remove the breakoint (F9), and then run the code again (F5).

This is pretty good. You don't have to use the mouse to hit the relatively small "Add breakpoint" target in the left hand column. But it does move the input focus to the beginning of the line, so you generally have to use the mouse again to fix that before you can start editing.

I want something faster. So I came up with a better solution:

Again, using the keyboard: Press Ctrl + Alt + Break to "Break All". This enters the debugger almost instantly, without having to worry about setting a breakpoint or if the code you want to modify is running in a loop. This will change the editor window and caret focus to the document where execution break, but you can then immediately fix it by pressing Ctrl + - for "Navigate Backwards".

Then you can make your edits and simply press F5 to see them in action. You only have to use the mouse once (or not at all) to initially pick where you want to start typing - just as you would expect.

Admittedly Ctrl + Alt + Break and Ctrl + - are horrible key combinations for something you want to be able to do extremely quickly. And it would be better if there was just one key to press.

If you have the full Visual Studio, you could probably turn it into a macro or add-in. Express doesn't have those - so the best you can do is modify your key bindings (Tools, Customise, Keyboard...) and bind it to two keys that are adjacent, that you can press in quick succession. Or use an external macro utility.

Personally I have set up the two key combinations to be pressed in succession (you don't seem to need a delay between the two) by a macro set to a spare button on my mouse. Which works reasonably well - as I'm usually selecting text at the same time. I might add a keyboard macro later too.

So far I've identified two minor pitfalls of this method:

  • When you run the app again, Visual Studio gives it focus. It would be nice if it kept focus. Adding a left mouse click to my macro is a partial solution to quickly re-editing code.
  • "Navigate Backwards" does not retain the text selection, only the caret position.

OTHER TIPS

i can tell you how, but you arn't going to like it:

1) run your game executable in a visual studio instance (game.exe --> vsInstanceA)

2) code your modifiable code in a seperate dll, using a seperate visual studio instance (modifiable.dll --> vsInstanceB)

*note that doing this lets you compile your modifiable.dll, thus doing compile time error checking, etc.*

... and now is where it get's tricky ...

3a) game.exe needs to reference the modifiable.dll. NOT the .vcproj, the actual dll

3b) when you hit a "magic key" (have game.exe look for a key-press), have game.exe unload the modifiable.dll, and reload it. You can easily do this via the Assembly and AppDomain classes provided in mscorlib. Of course this means you need to unload any dependant systems in game.exe.

note, there's a lot of hand-waving in this 3b) section, it's quite a lot of work but pretty straight forward (example google search: https://www.google.com/search?q=dynamic+load+dll+.net)

... and after that, you are good to go ...

3-alt) some other choices if 3b) doesn't suit you:

  • you can invoke msbuild.exe to rebuild modifiable.dll when you press "magic key"
  • you can use the CSharp compiler dll's to dynamically recompile each class instead of the entire modifiable.dll

but unfortunatly, in my 10+ years of .net development, this is the only way, unless someone has created a 3rd party product to do it (IE: they do what i mentioned, for you)

This may not be exactly what you're looking for but it's what I've been doing. Just throw in a break point while your game is running. Once it's stopped, you can edit things, remove the break point, and then hit F5 to continue.

For the most part, this allows you to edit things while the game is running and continue running the game afterwards but it doesn't work for everything. You can't add or remove class level things and also can't add/remove entire functions or the parameters. Mostly, I do this to test out different numbers and equations for smaller things that get hit every update.

To answer the original question "in Visual Studio 2010 without pausing execution?"

No. For Java there is JRebel which allows this.

I can quickly imagine why Microsoft haven't done this - if you have some sort of committee or group of people designing things - it's easy for even one person to come up with good arguments where this "dynamic software updating"/hotswap will break. It's just too easy to shoot down. Or if they proceed with it, it will be through some entirely new "enterprise framework" that requires lot of steps, work and understanding to get anywhere, because they want to use it for complicated online scenarios.

I'd prefer there was some simple way to do this - I'll take the risks, and put up a lot of disclaimers that if you want hotswap services that talk to external systems then you need to use that complicated framework or whatever.

The most typical scenario where this could safely be used with low risk is prototyping and tweaking some sort of engine with either high startup cost or more likely, to study behaviour if something running in the engine (like rules) is buggy and to exhibit the bug, a lot of things has to happen and it's possible you don't encounter the bug always. That is the case where having this could save weeks of debugging time, atleast would have in my case.

I'm used to work in Java using IntelliJ Idea + DCEVM (Dynamic code evolution VM).

Unfortunately i haven't found anything getting closer to that configuration at Microsoft C# platform. It really sucks and you can't do much about it. You can use some user defined macros, but you can't still do much in Edit and Continue mode without restarting Debug session).

However if you can, try to use newest .NET Core which offers much better productivity using Dotnet Watch. Still not so fast as DCEVM but much better than traditional VS + .NET hot reload experience. Details here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top