I may have sort of figured a way out without having to apply a unique material to every face.
I can select a face, unwrap just that face, and then scale/rotate/translate as needed across a tiling texture loaded in Blender. Islands may overlap but I'm ok with this.
Comparing the UV layout from manually unwrapping each face individually and just doing a Cube Projection shows that the cube projection method produces nearly identical results. The main difference is that the angled faces are projected (hence the name) to a plane and so their uvs align perfectly with the planar faces. Manually unwrapping has the UV straightened out and running with the direction of the face causing visible seams where it meets a face sitting on an axis.
For example, here's cube projection on the left, and a manual unwrap of the angled face on the right.
The latter would typically not be an issue (and would actually be desirable) because I never usually would tile textures across angled faces like that when mapping for Quake 3. Angled faces were usually a cue to apply a trim texture to separate two axis-aligned surfaces and "hide" the texture seam by avoiding it altogether.
Additionally, I found that I have better results with the cube projection if I enable "scale to bounds" so it uses up all of the texture space for the uv islands. I have a color grid at 4 different resolutions (256x256, 512x512, 1024x1024, and 2048x2048) that I can swap between and it appears to be a lot easier to wrangle with the density issue.