Question about external assets

Hello all,

I was curious about external assets, and I originally was told that I could use textures and such from an external file and all I need is to add the location with a FileLocator. That works fine, but here it mentions some other things.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:intermediate:multi-media_asset_pipeline

Don't leave textures or models in a folder outside your JME project: The game cannot load or reference them from there.

What is considered “the project?”

Must I convert to .j3o? Yes!

The .j3o file format is an optimized format to store parts of a jME3 scene graph for 3-D games.

A .j3o file can contain one shape, one model, or a whole scene.
Only .j3o files can store all of jme3’s material options and other features. Other formats can only be considered meshes with UV mapping data and always need extra work.
.j3o files work seamlessly across platforms and can also be automatically adapted for certain platforms on distribution.
(Optional) You can store the model’s physical properties, materials, lights, particle emitters, and audio nodes, in the .j3o file.
Use Java commands, or use the jMonkeyEngine SDK SceneComposer as a user-friendly interface to add these properties.
The default Ant build script copies .j3o files, .j3m files, sounds, and textures, into the distributable JAR automatically.

Important: Unoptimized external model files (.mesh.xml, .material, .obj, .mat, .blend, etc) are not bundled by the default build script into the final game builds in the dist directory! If you or your customers try to run games containing code that loads non-.j3o models, you get a AssetNotFoundException Runtime Error (resource not found). Your final application code should only reference .j3o files. – Note that your developers will not get this runtime error when running development builds straight from the SDK.

So currently I can run everything fine, but I don’t have user supported models… yet. Once I do am I going to run into an issue… or what? Can I allow users to input their data, and then save/load the .j3o file instead? I was going to save all of the files originally, but after it was all said and done. Also the j3o files need the original location of the textures and models right?

If you’re developing in NetBeans or the JME3 SDK, then the folder/directory which contains the “assets”, “build”, “dist”, “nbproject”, “src”, and “test” subfolders/subdirectories is your project folder.

When packaging/bundling a game for distribution, however, only files in the “assets” folder/directory get archived to the asset JAR. So all your textures and models should specifically be in THAT folder/directory–and not (for instance) in “src”, or on another filesystem.

Your game can open unoptimized files when it runs within the SDK, which is convenient during development. Unoptimized files become problematic when you want to distribute the game, because as the wiki points out, they get excluded from the asset JAR. There are ways around this, but why would you want to distribute unoptimized files?

1 Like
@sgold said: If you're developing in NetBeans or the JME3 SDK, then the folder/directory which contains the "assets", "build", "dist", "nbproject", "src", and "test" subfolders/subdirectories is your project folder.

When packaging/bundling a game for distribution, however, only files in the “assets” folder/directory get archived to the asset JAR. So all your textures and models should specifically be in THAT folder/directory–and not (for instance) in “src”, or on another filesystem.

Your game can open unoptimized files when it runs within the SDK, which is convenient during development. Unoptimized files become problematic when you want to distribute the game, because as the wiki points out, they get excluded from the asset JAR. There are ways around this, but why would you want to distribute unoptimized files?

Well one of the things for my game is that I allow users to use their own textures and such, then I use a FileLocator on their file path to the external items.

The game runs bundled, but I haven’t tried it on another computer. It should work as long as the files are already there. Also it seems once I make the .j3o the files would be optimized, but it’s said I still need the location of those files, which is fine.

Everything I personally add to the game is for sure included in the assets folder, and no where else.

So you should keep all assets that ship with the game in the assets folder and manage the other folder manually as you do for your project. Meaning you retrieve the location on the user machine and add the FileLocator to that folder. Then the assetManager can read both the files from the assets folder and the user data folder.

1 Like
@normen said: So you should keep all assets that ship with the game in the assets folder and manage the other folder manually as you do for your project. Meaning you retrieve the location on the user machine and add the FileLocator to that folder. Then the assetManager can read both the files from the assets folder and the user data folder.

Yup, thanks Normen, just wanted to make sure that this was the correct approach.

Would you say I should create a .j3o file from the scene and load that, or should I go with my original plan of load their files as is, then when they exit save the scene as a .j3o and use that to reload in the future?

Yeah, the latter way is probably the best, importing another file basically means “creating a j3o” in memory. I don’t know about your application though, if you don’t want to alter the users files but only display them and you can live with the overhead of importing them each time you can just do that. If you have for example a role playing game where people can import weapon models or so you should probably store them as j3o as you can also store any modifications made to the models (e.g. fixing textures and materials and things like that). Model import in itself is a complicated issue, you can’t expect that your users can import any kind of model they throw at your application.

@normen said: Yeah, the latter way is probably the best, importing another file basically means "creating a j3o" in memory. I don't know about your application though, if you don't want to alter the users files but only display them and you can live with the overhead of importing them each time you can just do that. If you have for example a role playing game where people can import weapon models or so you should probably store them as j3o as you can also store any modifications made to the models (e.g. fixing textures and materials and things like that). Model import in itself is a complicated issue, you can't expect that your users can import any kind of model they throw at your application.

I see, thank you. So it seems once the file is a .j3o it will be faster/less overhead as you say? But you’re saying it’s not a good idea to create the .j3o after the fact? Basically users are able to create their own levels, rooms, and such, so this .j3o file is an entire scene and they will be reloading these most likely again. I figure keeping them as their original files would be good if they are only loaded once, but if they for sure will be using them multiple times than the .j3o might be better from the beginning, but that also means I have to convert it and wait for that to happen each time they want to create a new one.

Also is it possible to take their creations and add it to my main game? Would that have to do with somehow connecting to the internet using the networking capabilities ( I believe it’s called “SpiderMonkey”)? Which would then save it and update server code, or possibly be added to something for a new realize to the client later on?

j3o is the only file format that you can save all engine features in and external formats need some reworking in most cases is all I’m saying :slight_smile: As said its hard to say whats good for your application. Sounds like you should really just import external formats and then go on with j3o files (or any other suffix for your files, you can register file types in the assetManager while still using the BinaryImporter and “j3o” type data).