fix(client): entity lerp, fog shader safety, type fixes

Entity renderer: add framerate-independent position lerping so entities
slide between tiles instead of snapping. Tuned for Sprint snappiness
and Walk/Careful fluidity.

Fog shader: set ColorRect to transparent fallback so a shader load
failure doesn't paint solid white over the world. Track camera position
(not player position) so fog stays synced during smooth camera pan.
Restructure GLSL to avoid early return (some GPU drivers miscompile it).

Minor type fixes: typed Array[Vector2] in cursor_renderer tick drawing,
untyped Array in inventory_grid to avoid Godot typed-array cast issues.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 23:26:23 +01:00
co-authored by Claude Opus 4.6
parent bc875d607f
commit 8bf7f6e610
5 changed files with 84 additions and 41 deletions
+13 -3
View File
@@ -11,13 +11,18 @@ const TILE_SIZE := float(Constants.TILE_SIZE)
func _ready() -> void:
# Create the fog overlay ColorRect
# Create the fog overlay ColorRect — transparent fallback so a shader failure
# doesn't paint solid white over the entire world (z:900 covers everything).
_fog_rect = ColorRect.new()
_fog_rect.name = "FogRect"
_fog_rect.color = Color.TRANSPARENT
add_child(_fog_rect)
# Load shader and create material
var shader := load("res://shaders/fog.gdshader") as Shader
if shader == null:
push_error("FogShader: failed to load res://shaders/fog.gdshader — fog disabled")
return
_shader_mat = ShaderMaterial.new()
_shader_mat.shader = shader
_fog_rect.material = _shader_mat
@@ -38,14 +43,19 @@ func _ready() -> void:
func update_fog() -> void:
if _shader_mat == null:
return # Shader failed to load — fog disabled
# 1. Update FogState textures from GameState
FogState.update_from_state()
# 2. Position ColorRect to cover the current viewport
# 2. Position ColorRect to cover the current viewport.
# Use the camera's actual position (not player position) so the fog rect
# tracks the smoothed camera and never desynchronizes during smooth pan.
var vp_size := get_viewport().get_visible_rect().size
var cam := get_viewport().get_camera_2d()
var zoom := cam.zoom if cam else Vector2(2.0, 2.0)
var camera_pos := GameState.player_position * TILE_SIZE
var camera_pos := cam.global_position if cam else GameState.player_position * TILE_SIZE
var half_view := vp_size / (2.0 * zoom)
_fog_rect.position = camera_pos - half_view
_fog_rect.size = vp_size / zoom