Skip to content

Titanfall Engine notes

Jared Ketterer edited this page Nov 30, 2021 · 1 revision

Titanfall .bsp files are version 29
Titanfall 2 .bsp files are version 37
Apex Legends .bsp files are version 47

Certain areas which seem like ideal spots for func_areaportal in source .bsp have odd circular & elliptical shapes overlapping
I have a sneaking suspicion these are related to func_window_hint entities in the .bsp entity lump

Respawn's Quake mod origins & compilers

Turns out these are likely just large spritecards, similar to Godray props in Source
It looks like the compiler (q3map2 based?) allows for placing arbitrary geometry directly in the .bsp, like Source 2 or Quake 3
(Quake 1.5 -> GoldSrc + Quake 2 -> Source + Quake 3 -> Source 2 ???)

CoD

Many lumps are their use is reminiscent of MoH:AA / Quake 3, CoD 2 & CoD 4
I'd love to get my hands on MW2 to see what changes exist there, but that's not happening while Kotick's around

Infra

Having dug into Infra's /bin folder, it looks like the 2013 Source SDK has some carry over too

NOTE: Infra got the 2013 SDK around the same time as Respawn, they also left a vphysics.so.dgb gdb file lying around, whoops
To be fair, the CoD4 tools also have open code references in them, which also shows how IW internally thought they were making CoD3

LUMP_PHYSICS_LEVEL came from Left 4 Dead 2, but was rolled into the 2013 SDK
I've noted the origins of some of the lumps that got rolled together in the valve.sdk_2013 branch script

BSP splitting traces

r1_mp_colony.MESHES[0] has some clear bsp slices in it from the building above the first plane
It looks like the first brush, similar to under pl_upward's displacements
Though what makes that mesh unique and allows us to trace it back to a brush in the physics / other lumps?

Also, why are some splits so arbitrary?
Mesh seams don't reflect any pattern that looks like a patch might in editor?
And tool brush ents often split into one Model per face
Is it a BVH4 tree thing? Do Meshes have budgets? TextureVector / TexData splitting reasons?

MaterialSort, MeshIndices & VertexReservedX lumps all appear to be created in parallel if you look at the output of debug_Mesh_stats

PHYSICS

Decal Flags

Presumably the engine has some flags to tell the compiler what's a patch / decal / "triangle soup"
Question is, does this carry through to Mesh.flags?

LUMP_PHYSICS_COLLIDE

Titanfall 1 has the same embedded .phy file as all source .bsps use for physics, and the .phy format hasn't changed for props...
With a deep and well thought out SpecialLumpClass (will need it's own script), I could probably visualise the physics to identify brushwork

io_import_rbsp

Trying out appending geo to a small Titanfall 1 map in Blender (no physics)
script notes

Currently non-functional; crashes on load with an error about lump sizes
This tells me that I missed a lump with a paralell size, but idk if it's physics related
In fact, I have no clue what lump I missed, and idk enough about stack frames to trace the pointers

len(LUMP.CM_GRID_CELLS) = [rsi+0x74] * [rsi+0x70] + [rsi+0x104]
[rsi+0x074] = len(LUMP.?)
[rsi+0x070] = len(LUMP.?)
[rsi+0x104] = len(LUMP.?) + 1? models?


LUMPS TOUCHED BY SCRIPT:
* [00] ENTITIES + 1
* [14] MODELS + 1
# NOTE: PHYSICS_COLLIDE should have an entry for each Model
* [44] TEXTURE_DATA_STRING_TABLE + 2
* [43] TEXTURE_DATA_STRING_DATA + 2
* [02] TEXTURE_DATA + 2
  [82] MATERIAL_SORT + 2
* [03] VERTICES + ?
  [30] VERTEX_NORMALS + ?
  [80] MESHES + 2
  [79] MESH_INDICES + ?
  [71] VERTEX_UNLIT + ?


LUMP LOADED BY R1O:
if (bsp.version >= 25) {
  CModLoadTextures {  
*   [02] TEXTURE_DATA
*   [43] TEXTURE_DATA_STRING_DATA
*   [44] TEXTURE_DATA_STRING_TABLE
  }
  [01] LoadLump_PLANES
* [03] LoadLump_VERTICES
  [85] LoadLump_CM_GRID
  [92] LoadLump_CM_BRUSHES
  [93] LoadLump_CM_BRUSH_SIDE_PLANE_OFFSETS  // (-> PLANES?)
  [94] LoadLump_CM_BRUSH_SIDE_PROPS
  if (bsp.version < 28) {
*   [14] CMod_LoadSubModelsv25 { MODELS }
  } else {
*   [14] CMod_LoadSubModelsv28 { MODELS }
  }
  CollisionBSPData_LoadTriColl {
    [66] TRICOLL_TRIS
    [68] TRICOLL_NODES
    [69] TRICOLL_HEADERS
    [96] TRICOLL_BEVEL_STARTS
    [97] TRICOLL_BEVEL_INDICES
  }
  [70] PHYSICS_TRIANGLES
  LoadLumps_ENTITIES {
    [00] ENTITIES
    [24] ENTITY_PARTITIONS  // (+ .ent files?)
  }
  [29] PHYSICS_COLLIDE
  [91] CM_UNIQUE_CONTENTS
$ [86] CM_GRID_CELLS
  [88] CM_GEO_SET_BOUNDS
  [87] CM_GEO_SETS
  [90] CM_PRIMITIVE_BOUNDS
  [89] CM_PRIMITIVES
  
  
material_system_dx11.dll
create_vphysicsInterface
SurfaceProp???
// loadLump_CM_GRID
int LUMP_CM_GRID = 0x55;


__int64 __fastcall LoadLump_CM_GRID(__int64 a1) {
  __int64 v2;      // rdx
  __int64 result;  // rax
  int header[4];   // [rsp+30h] [rbp-148h] BYREF
  __int64 v5;      // [rsp+40h] [rbp-138h]
  _DWORD *v6;      // [rsp+48h] [rbp-130h]

  load_lump2(header, LUMP_CM_GRID);

  v2 = (__int64)v6;
  *(_DWORD*)(a1 +  96) = *v6;
  *( float*)(a1 + 100) = 1.0 / *(float *)v2;
  *(_DWORD*)(a1 + 104) = *(_DWORD *)(v2 +  4);
  *(_DWORD*)(a1 + 108) = *(_DWORD *)(v2 +  8);
  *(_DWORD*)(a1 + 112) = *(_DWORD *)(v2 + 12);
  *(_DWORD*)(a1 + 116) = *(_DWORD *)(v2 + 16);
  *(_DWORD*)(a1 + 128) = *(_DWORD *)(v2 + 20);
  
  result = *(unsigned int *)(v2 + 24);
  *(_DWORD *)(a1 + 208) = result;
  
  if (!header) {
      return result;
  }
  return (*(__int64 (__fastcall **)(__int64))(*(_QWORD *)g_pFileSystem_maybe + 736i64))(g_pFileSystem_maybe);
}

It's possible they use the Quake 3 / CoD grid system? but no new space is occupied? So I think it could be a physics BVH4 tree thing
Earl Hammon Jr's "Extreme SIMD" GDC talk refers to Titanfall 2, but it's possible he started in Titanfall 1
(I was also testing in TF:O)
After all, in Steve Lee's Titanfall Interviews, they talk about how Effect & Cause was planned as a TF1 sp_ level
With the development style & cycle of IW / Respawn, I wouldn't be surprised if they considered the engine as a thing in motion
Constantly iterating, the version that ships is just another build (albeit, a very polished and stable one)