Noel Llopis's Games from Within blog touched on this recently in the "Remote Game Editing" post. The opening paragraph:
I’ve long been a fan of minimal game
runtimes. Anything that can be done
offline or in a separate tool, should
be out of the runtime. That leaves the
game architecture and code very lean
(The article is a highly recommended read, as with most of Noel's stuff, whether you agree 100% or not.)
I believe the key here is to keep the complexity outside the engine. You can still have flexibility, but it's flexibility in the content pipeline. And you get better performance by not spending time converting and moving data around.
Better performance may translate into lower iteration time, strangely, despite losing some of the in-engine editing abilities: it's easier to try something if you can load the game in a second.
Adopting some of the tenets of the "unix philosophy" will help you keep your toolchain flexible: a small modular pipeline.
My personal philosophy: bake as much of the data as much as possible offline, but provide engine support to receive new baked data at any time. (Note that this new data doesn't need to come into play until a convenient point: the "refresh" button is pressed, the next level begins, you transition to a new area, whatever. The key is finding the sweet spot that minimizes iteration time with minimum code complexity and coding effort.)
At our company most of our artist/designer-facing tools are focused on UI issues: ease of manipulation of single assets or batches thereof, etc. Sometimes they're just 3rd party tools like Photoshop or 3DS Max. These tools export to an intermediate format (often xml that references source binary data, but not always). The intermediate format is picked up by a backend "data make" tool, which bakes it into something useful and quick-loading for the target platform.
Portability is achieved by adding additional backend data make tools, or expanding the existing backend data make tools, which has the additional advantage of being invisible to the content creators.
Now, with a proper incremental data make, you can have changes in baked format within seconds; your engine can spider, or a tool can spider, and then these will appear in your resource system, ready for reload when it's convenient.
The tools -- especially the backend data make tools -- are often sloppier and buggier than the engine code. This is OK, because they're easier to refactor/rewrite, extend, and test; you have specs for their behavior and it's fairly easy to unit test them as compared to some engine code.
My opinions on your questions:
Should engine be capable of loading various image formats? A TGA
only loader is pretty easy to hand
(Aside: even if you use a TGA decoder in-engine, don't handcode it. You're just asking for trouble -- there are a lot of subtleties with most image formats, and a lot of tools that don't adhere exactly to the probably-underspecified format. You're best off finding existing well-tested library code for image processing.)
I'd have the tool here convert from TGA to whatever your internal texture format is, plus metadata.
What about audio formats? Is it
feasible to only support loading wav
files? What about ambient music files
which are often huge.
We use three formats here: tracked music (.xm), ADPCM (.wav), and Speex (.spx). This is mostly because we're on handhelds, and these formats are very lightweight to decode.
Should the engine be capable of
dynamic TTF parsing and atlas
Atlasing is a hard problem: see your recent question's answers. It's almost always worth doing offline.
Plus you can make the per-character metadata into a near-zero-load-code baked struct.
In closing, you can clean up and package this pipeline with your game, for the mod community. You can always add more source formats. And there's nothing preventing you from bridging the gap between the content creation tools and the engine in specific cases; hopefully your data baking code and spider/transfer code can be refactored into libraries that might eventually be used directly by the content creator tools in some cases. But I wouldn't make that my first goal, necessarily... Just be aware that it will be an eventual goal and let that influence your design a bit, and go for the low hanging fruit first.
As an update, you may want to consider using the KTX File Format for textures. It has the advantage of being mostly "read into
struct and go" for most GL usecases (and from your comments it sounds like you were targeting GL) while still being flexible and well-defined.
The KTX header overhead may be a bit high for fully-baked data, depending on your target, and you may want to forgo endian swap support, depending on your usecase... but it's definitely at least worth a gander for design considerations.