3

I'm looking for a way to update textures and other content files at runtime in XNA, such that if it's modified outside of the application, it will automatically update in the game when it regains focus.

This seems to be possible with Texture2D and loading from a Stream, but I'm unable to get a direct path to a given resource.

I realize that this won't work with the content pipeline and .xnb's, but for debugging and development purposes it would be extremely useful.

Has anyone seen something such as this implemented successfully with XNA?

Kleptine
  • 5,089
  • 16
  • 58
  • 81
  • not sure if you are still looking for this, but if you are, we have a custom built solution that works in most cases. – roundcrisis Sep 19 '12 at 17:09

1 Answers1

1

First all of you'll need to decide whether to adopt a push or pull model. In a push model, the application/environment that changed the asset will need to somehow notify the running game that the asset has changed and needs to be reloaded. This could be done with a very simple message queue.

In a pull model the game would periodically check all the game assets to see if they have been modified, and if they have, reload them. This would be a simpler, if less performant, solution.

A bigger concern is whether or not your game can gracefully handle re-loading assets while the app is running. You'd probably need to implement some kind of background thread that loads the assets and then "swaps" them in with "live" assets in game. Alternatively your game could pause briefly each time an asset is being reloaded. In either case, this could easily end up being the most complicated part of the process, depending on how your content pipeline works currently (you might already have a background loader thread etc)..

EDIT in response to comment:

You can get the fully qualified path to the content folder using this method :)

static public String FullContentDirectory(this ContentManager content)
{
    var appPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);

    return System.IO.Path.Combine(appPath, content.RootDirectory);
}

Now, I think your next problem might be, how do you know the file extension from the asset name? Or, what if the asset name is different to the filename?

MattDavey
  • 8,897
  • 3
  • 31
  • 54
  • At the moment I'm subscribing to the focusgained event for the window and simply having assets that I want to update check their path to see if the file has been modified since last load. The only difficulty is that I can't access the full system path for a given resource in xna, which makes it difficult to open the stream). – Kleptine Sep 06 '11 at 14:42
  • How do you mean you can't access the full system path? Are you getting an error? – MattDavey Sep 07 '11 at 07:40
  • XNA stores and loads content using paths with only the name of the file relative to the working directory. However, I haven't found a way to access this directory path using xna 4.0. – Kleptine Sep 09 '11 at 20:48
  • @Guy There is a root directory property in the content manager. You can override it to whatever directory your resources are in. Once this is done, you know where they are stored and can to all the path algebra you want with them. – Coincoin Sep 12 '11 at 18:24
  • Thinking about it more, if you're using the content pipeline to load assets it's going to be really difficult to reload them when they change, since modifying a source asset (say a .png) is not going to change the associated .xnb unless you invoke the content pipeline build process again.. you may have to revert to loading assets directly from file streams if you want to achieve this... – MattDavey Sep 13 '11 at 08:08