Files
tactical-shooter/client/bake_lightmaps.gd
T
shawn e7299b17e9 Phase 7: netfox + godot-jolt stack upgrade
Stack installed:
- netfox v1.35.3 (core + extras + noray + internals)
- godot-jolt v0.16.0-stable

Architecture:
- Server: ENet transport (works headless, no netfox deps)
- Client/Editor: netfox rollback (RollbackSynchronizer, TickInterpolator)

New/modified:
- docs/migration-netfox-plan.md — migration architecture
- scripts/network/network_manager.gd — netfox-aware ENet fallback
- scripts/network/player.gd — clean base player
- client/characters/player_netfox.gd — rollback player w/ WeaponManager
- client/characters/input/player_net_input.gd — BaseNetInput subclass
- client/characters/character/fps_character_controller.gd — netfox input feed
- client/weapons/ — weapon data, registry, TacticalWeaponHitscan, WeaponManager
- client/scripts/round_replicator.gd — client-side round state bridge
- server/scripts/round_manager.gd — improved state machine
- server/scripts/plugin_api/plugin_manager.gd — refined plugin system
- config: enemy_tag, ally_tag for meatball targeting

Removed: old C++ SimulationServer GDExtension (replaced by netfox rollback)
2026-07-02 17:39:22 -04:00

211 lines
5.9 KiB
GDScript

extends SceneTree
# Generalised Lightmap Baking Config Checker
# ==========================================
# Validates that a map scene's LightmapGI is configured correctly for baking.
# Generalised replacement for scripts/bake_lighting.gd — works on ANY map scene.
#
# Note: Godot 4.7 LightmapGI baking is editor-only. This script validates
# configuration only; actual baking must be done from the Godot editor.
#
# Usage:
# godot --headless --script bake_lightmaps.gd -- res://maps/my_map.tscn
#
# Exit codes:
# 0 — All checks passed (or warnings only)
# 1 — One or more checks failed (fatal)
# 2 — Scene file could not be loaded
var _scene_path: String = ""
var _checks: Array = [] # [label, passed, is_warning]
func _init() -> void:
_parse_args()
if _scene_path.is_empty():
printerr("ERROR: No scene path provided.")
print("Usage: godot --headless --script bake_lightmaps.gd -- res://maps/my_map.tscn")
quit(2)
return
print("")
print("=== Lightmap Baking Config Checker: %s ===" % _scene_path)
print("")
var scene = ResourceLoader.load(_scene_path)
if not scene:
printerr("ERROR: Could not load scene: %s" % _scene_path)
quit(2)
return
var instance = scene.instantiate()
if not instance:
printerr("ERROR: Could not instantiate scene!")
quit(2)
return
root.add_child(instance)
print("Scene loaded and instantiated successfully.")
print("")
print("Note: Godot 4.x LightmapGI baking is editor-only.")
print("This script validates configuration only.")
print("To bake: Open scene in editor > Select LightmapGI > 'Bake Lightmap'")
print("")
var lightmap: LightmapGI = _find_node_of_type(instance, LightmapGI)
if not lightmap:
printerr("ERROR: No LightmapGI node found in scene!")
quit(1)
return
_print_config(lightmap)
_run_checks(lightmap, instance)
_print_results()
func _parse_args() -> void:
var args := OS.get_cmdline_args()
var found_sep := false
for a in args:
if a == "--":
found_sep = true
continue
if found_sep and not a.begins_with("-"):
_scene_path = a
return
for a in args:
if a.contains("res://") or a.ends_with(".tscn"):
_scene_path = a
return
func _check(label: String, passed: bool, is_warning: bool = false) -> void:
_checks.append([label, passed, is_warning])
func _print_config(lightmap: LightmapGI) -> void:
print(" LightmapGI configuration:")
print(" Quality: ", _quality_name(lightmap.quality), " (", lightmap.quality, ")")
print(" Bounces: ", lightmap.bounces)
print(" Texel Scale: ", lightmap.texel_scale)
print(" Max Tex Size: ", lightmap.max_texture_size)
print(" Interior: ", lightmap.interior)
print(" Denoiser: ", lightmap.is_using_denoiser())
print(" Energy: ", lightmap.lightmap_energy)
print(" Bias: ", lightmap.lightmap_probe_bias)
if lightmap.light_data != null:
print(" Baked data: PRESENT ✓")
else:
print(" Baked data: NOT YET BAKED")
print("")
func _run_checks(lightmap: LightmapGI, instance: Node) -> void:
# Configuration checks
_check("Quality ≥ Medium (1)", lightmap.quality >= 1)
_check("Bounces ≥ 2", lightmap.bounces >= 2)
_check("Texel Scale ≤ 2.0", lightmap.texel_scale <= 2.0)
_check("Interior = true", lightmap.interior == true)
# Denoiser recommended
_check("Use denoiser enabled", lightmap.is_using_denoiser(), true)
# Max texture size ≤ 4096 (sanity)
_check("Max texture size ≤ 4096", lightmap.max_texture_size <= 4096)
# Energy shouldn't be zero
_check("Lightmap energy > 0", lightmap.lightmap_energy > 0)
# Check for lightmap-enabled meshes
var meshes: Array = _find_nodes_of_type(instance, MeshInstance3D)
var static_meshes := 0
var dynamic_meshes := 0
for mi in meshes:
if mi.gi_mode == GeometryInstance3D.GI_MODE_STATIC:
static_meshes += 1
elif mi.gi_mode == GeometryInstance3D.GI_MODE_DYNAMIC:
dynamic_meshes += 1
_check("Static geometry meshes found for lightmapping", static_meshes > 0)
# Baked data status (informational)
if lightmap.light_data != null:
print(" ✓ Lightmap has baked data.")
# Check bake timestamp if available
var ld = lightmap.light_data
if ld is LightmapGIData and ld.has_method("get_user_data"):
print(" Bake data size: %d bytes" % ld.get_user_data().size())
else:
print(" ⚠ Lightmap NOT YET BAKED. Open in Godot editor and bake.")
# Summary
print("")
print(" Geometry summary:")
print(" MeshInstance3D nodes: %d" % meshes.size())
print(" GI_MODE_STATIC: %d" % static_meshes)
print(" GI_MODE_DYNAMIC: %d" % dynamic_meshes)
func _print_results() -> void:
print("")
print(" ─── Validation Results ───")
var passed := 0
var failed := 0
var warnings := 0
for c in _checks:
if c[1]:
passed += 1
print("%s" % c[0])
else:
if c[2]:
warnings += 1
print("%s" % c[0])
else:
failed += 1
print("%s" % c[0])
print("")
print(" Passed: %d Warnings: %d Failed: %d" % [passed, warnings, failed])
print("")
if failed > 0:
printerr("Validation FAILED — %d check(s) failed." % failed)
quit(1)
else:
print("=== Config check complete ===")
quit(0)
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
func _quality_name(q: int) -> String:
match q:
0: return "Low"
1: return "Medium"
2: return "High"
3: return "Ultra"
return "Unknown"
func _find_node_of_type(parent: Node, type: Script) -> Node:
for child in parent.get_children():
if is_instance_of(child, type):
return child
var found = _find_node_of_type(child, type)
if found:
return found
return null
func _find_nodes_of_type(parent: Node, type: Script) -> Array:
var results: Array = []
for child in parent.get_children():
if is_instance_of(child, type):
results.append(child)
results.append_array(_find_nodes_of_type(child, type))
return results