Okay I think I found it. I swear I've been puzzling over this for a few days, but in db.c there's the following code:
mob = create_mobile( pMobIndex );
in the reset_area function. So I guess that loading the area just sets up the data, then resetting it actually populates the world? It appears to be something like that.
Yes, create_mobile() takes a MOB_INDEX_DATA (the 'prototype' for the mob, read from the area file) and turns it into a CHAR_DATA of a live character (PC or NPC) within the game.
However, in fight.c, all combat happens between CHAR_DATA types.
So how does the mobile become a CHAR_DATA?
It probably has something to do with this line: