diff --git a/godot-addon/addons/godotiq/godotiq_server.gd b/godot-addon/addons/godotiq/godotiq_server.gd
index 6e8b3eb..fcf03e9 100644
--- a/godot-addon/addons/godotiq/godotiq_server.gd
+++ b/godot-addon/addons/godotiq/godotiq_server.gd
@@ -258,7 +258,46 @@ func _handle_editor_context(peer_id: int, id: String) -> void:
 
 
 func _handle_run(peer_id: int, id: String, params: Dictionary) -> void:
+	# Step 1: Save all open scenes to ensure on-disk state matches editor
+	EditorInterface.save_all_scenes()
+	# Step 2: Collect script paths based on scene parameter
 	var scene = params.get("scene", null)
+	var script_paths: Array[String] = []
+	if scene == null or scene == "main":
+		var main_path: String = ProjectSettings.get_setting("application/run/main_scene", "")
+		if main_path != "":
+			script_paths.append_array(_get_scripts_from_packed_scene(main_path))
+	elif scene == "current":
+		var edited_root := EditorInterface.get_edited_scene_root()
+		if edited_root != null:
+			var nodes := [edited_root]
+			while nodes.size() > 0:
+				var node: Node = nodes.pop_back()
+				var scr = node.get_script()
+				if scr is GDScript and scr.resource_path != "":
+					script_paths.append(scr.resource_path)
+				for child in node.get_children():
+					nodes.append(child)
+	else:
+		script_paths.append_array(_get_scripts_from_packed_scene(str(scene)))
+	script_paths.append_array(_get_autoload_script_paths())
+	# Deduplicate
+	var seen := {}
+	var unique_paths: Array[String] = []
+	for p in script_paths:
+		if not seen.has(p):
+			seen[p] = true
+			unique_paths.append(p)
+	# Step 3: Check scripts synchronously
+	var errors := _check_scripts_valid(unique_paths)
+	# Step 4: Gate on results
+	if errors.size() > 0:
+		_send_error(
+			peer_id, id, "SCRIPT_ERRORS",
+			"Cannot start game: %d script(s) have errors. Use godotiq_check_errors for details." % errors.size()
+		)
+		return
+	# Original play logic
 	if scene == null or scene == "main":
 		EditorInterface.play_main_scene()
 	elif scene == "current":
@@ -272,6 +311,53 @@ func _handle_run(peer_id: int, id: String, params: Dictionary) -> void:
 	}
 
 
+func _get_scripts_from_packed_scene(scene_path: String) -> Array[String]:
+	var result: Array[String] = []
+	var packed = load(scene_path)
+	if packed == null or not packed is PackedScene:
+		return result
+	var state = packed.get_state()
+	for node_idx in state.get_node_count():
+		for prop_idx in state.get_node_property_count(node_idx):
+			if state.get_node_property_name(node_idx, prop_idx) == "script":
+				var val = state.get_node_property_value(node_idx, prop_idx)
+				if val is GDScript and val.resource_path != "":
+					result.append(val.resource_path)
+	return result
+
+
+func _get_autoload_script_paths() -> Array[String]:
+	var result: Array[String] = []
+	for prop in ProjectSettings.get_property_list():
+		if prop.name.begins_with("autoload/"):
+			var value: String = ProjectSettings.get_setting(prop.name)
+			var path: String = value.trim_prefix("*")
+			if path.ends_with(".gd"):
+				result.append(path)
+			elif path.ends_with(".tscn"):
+				var scene = load(path)
+				if scene and scene is PackedScene:
+					var state = scene.get_state()
+					if state.get_node_count() > 0:
+						for i in state.get_node_property_count(0):
+							if state.get_node_property_name(0, i) == "script":
+								var script_val = state.get_node_property_value(0, i)
+								if script_val is GDScript:
+									result.append(script_val.resource_path)
+	return result
+
+
+func _check_scripts_valid(script_paths: Array[String]) -> Array[Dictionary]:
+	var errors: Array[Dictionary] = []
+	for path in script_paths:
+		var res = ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_IGNORE)
+		if res == null:
+			errors.append({"file": path, "error": "Failed to load script"})
+		elif res is GDScript and not res.can_instantiate():
+			errors.append({"file": path, "error": "Script has compilation errors"})
+	return errors
+
+
 func _handle_stop(peer_id: int, id: String) -> void:
 	EditorInterface.stop_playing_scene()
 	send_response(peer_id, id, {"stopped": true})
