So if I understand this right:
* common.lin contains filenames, so that filename-expansion code in the game can work. But the offsets and sizes associated with the files are garbage
* .lin contains a stream of every byte read from every file, while loading the level . The stream is then compressed in 16k chunks by zlib.
* There is no indication in that stream of which real file was being read, nor the length of each read, nor what seeking was done (if any). All that metadata is gone.
* The only way to recover this metadata is to run the game code and log the exact sequence of file opens, seeks, reads.
* Alternatively, extract all that Unreal object loader code from the game and reimplement it yourself, so that you can let the contents of the stream drive the correct reading of the stream. The code should be deterministic.
This sounds pretty hellish for the game developers, and I bet the debug versions of their game _ignored_ .lin and used the real source files, but _wrote_ .lin immediately after every load... any change to the Unreal objects could alter how they were read, and if the data streamed didn't perfectly match up with what was in the real files, you'd be toast.
It reminds me of the extreme optimisation that Farbrausch did for .kkrieger -- they built a single binary, then ran and played it under instrumentation, and _any_ code path that wasn't taken was deleted from the binary to make it smaller. They forgot to take any damage in that playthrough, so all the code that applies damage to the player was deleted. Oops!