Files
metabuilder/gameengine/packages/quake3/workflows/q3_map_session.json
T
git c23f53b0be Add MD3 model rendering and fix Q3 bot/weapon visuals
- Add workflow_q3_md3_load_step: load MD3 models from PK3 with correct
  CCW winding, 1/64 xyz scale + 0.03125 world scale, and per-frame VBs
- Add workflow_q3_md3_draw_step: viewmodel (weapon) + world-space MD3
  drawing; barrel oriented along model X → world forward
- Add workflow_q3_bots_draw_step: 3-part bot model chain
  (lower→upper→head via MD3 tags) + weapon attachment
- Add workflow_q3_bots_spawn_step: spawn bots at indices 1+ so they
  never overlap the player's spawn point (index 0)
- Add workflow_q3_bots_update_step: bot AI (idle/chase/shoot/dead FSM)
- Fix workflow_q3_menu_update_step: menu starts closed (was open)
- Fix workflow_postfx_composite_step: GPU readback via
  SDL_DownloadFromGPUTexture captures full 3D scene for screenshots
- Fix Metal GPU validation: always bind 2 sampler slots; reuse albedo
  as dummy shadow map when no shadow texture is available
- Reorder q3_frame.json: screenshot trigger nodes run before
  postfx_composite so screenshot_output_path is set in time

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 23:47:50 +01:00

145 lines
4.5 KiB
JSON

{
"name": "Q3 Map Session",
"description": "Loads a BSP map, player/weapon MD3 models, spawns bots, then runs the frame loop.",
"nodes": [
{
"id": "load_bsp",
"name": "Load Q3 BSP",
"type": "bsp.load",
"typeVersion": 1,
"position": [0, 0],
"parameters": { "pk3_path": "${env:QUAKE3_PAK0}", "map_name": "${env:QUAKE3_MAP}", "scale": 0.03125 }
},
{
"id": "bsp_lightmap",
"type": "bsp.lightmap_atlas",
"typeVersion": 1,
"position": [100, 0]
},
{
"id": "bsp_geometry",
"type": "bsp.build_geometry",
"typeVersion": 1,
"position": [200, 0],
"parameters": { "patch_tess_level": 4 }
},
{
"id": "bsp_textures",
"type": "bsp.extract_textures",
"typeVersion": 1,
"position": [300, 0]
},
{
"id": "bsp_upload",
"type": "bsp.upload_geometry",
"typeVersion": 1,
"position": [400, 0]
},
{
"id": "bsp_collision",
"type": "bsp.build_collision",
"typeVersion": 1,
"position": [500, 0]
},
{
"id": "bsp_spawn",
"type": "bsp.parse_spawn",
"typeVersion": 1,
"position": [600, 0]
},
{
"id": "spawn_apply",
"type": "spawn.apply",
"typeVersion": 1,
"position": [700, 0]
},
{
"id": "load_lower",
"type": "q3.md3.load",
"typeVersion": 1,
"position": [720, 0],
"parameters": {
"prefix": "lower",
"path": "models/players/keel/lower.md3",
"anim": "models/players/keel/animation.cfg"
}
},
{
"id": "load_upper",
"type": "q3.md3.load",
"typeVersion": 1,
"position": [730, 0],
"parameters": {
"prefix": "upper",
"path": "models/players/keel/upper.md3"
}
},
{
"id": "load_head",
"type": "q3.md3.load",
"typeVersion": 1,
"position": [740, 0],
"parameters": {
"prefix": "head",
"path": "models/players/keel/head.md3"
}
},
{
"id": "load_weapon_mg",
"type": "q3.md3.load",
"typeVersion": 1,
"position": [750, 0],
"parameters": {
"prefix": "weapon_mg",
"path": "models/weapons2/machinegun/machinegun.md3"
}
},
{
"id": "bots_spawn",
"type": "q3.bots.spawn",
"typeVersion": 1,
"position": [760, 0],
"parameters": { "count": 4 }
},
{
"id": "set_running",
"type": "value.literal",
"typeVersion": 1,
"position": [800, 0],
"parameters": { "value": true, "outputs": { "value": "game_running" } }
},
{
"id": "game_loop",
"type": "control.loop.while",
"typeVersion": 1,
"position": [900, 0],
"parameters": { "condition_key": "game_running", "package": "quake3", "workflow": "q3_frame" }
},
{
"id": "check_quit",
"type": "bool.not",
"typeVersion": 1,
"position": [1000, 0],
"inputs": { "value": "q3.quit_requested" },
"outputs": { "value": "outer_running" }
}
],
"connections": {
"load_bsp": { "main": { "0": [{ "node": "bsp_lightmap", "type": "main", "index": 0 }] } },
"bsp_lightmap": { "main": { "0": [{ "node": "bsp_geometry", "type": "main", "index": 0 }] } },
"bsp_geometry": { "main": { "0": [{ "node": "bsp_textures", "type": "main", "index": 0 }] } },
"bsp_textures": { "main": { "0": [{ "node": "bsp_upload", "type": "main", "index": 0 }] } },
"bsp_upload": { "main": { "0": [{ "node": "bsp_collision", "type": "main", "index": 0 }] } },
"bsp_collision": { "main": { "0": [{ "node": "bsp_spawn", "type": "main", "index": 0 }] } },
"bsp_spawn": { "main": { "0": [{ "node": "spawn_apply", "type": "main", "index": 0 }] } },
"spawn_apply": { "main": { "0": [{ "node": "load_lower", "type": "main", "index": 0 }] } },
"load_lower": { "main": { "0": [{ "node": "load_upper", "type": "main", "index": 0 }] } },
"load_upper": { "main": { "0": [{ "node": "load_head", "type": "main", "index": 0 }] } },
"load_head": { "main": { "0": [{ "node": "load_weapon_mg","type": "main", "index": 0 }] } },
"load_weapon_mg":{ "main": { "0": [{ "node": "bots_spawn", "type": "main", "index": 0 }] } },
"bots_spawn": { "main": { "0": [{ "node": "set_running", "type": "main", "index": 0 }] } },
"set_running": { "main": { "0": [{ "node": "game_loop", "type": "main", "index": 0 }] } },
"game_loop": { "main": { "0": [{ "node": "check_quit", "type": "main", "index": 0 }] } }
}
}