{“content”:”---\nname: godot-windows-cli-setup\ncategory: gaming\ndescription: Setup Godot 4.x on remote Windows PC via SSH when you only have CLI access. Includes download, extraction, and creating scenes via text files.\n---\n\n# Godot 4.x Windows CLI Setup via SSH\n\n## Context\nSetting up Godot 4.x on a remote Windows PC when you don’t have local GUI access, only SSH. \nUsed for creating Godot projects and scenes via CLI without physically touching the PC.\n\n## The Problem\n- Godot editor .exe is ~165MB, too large for direct SCP (times out at ~600s limit)\n- Godot 4.x uses .exe.zip distribution (NOT plain .zip) — wrong URL = 9-byte “Not Found” response\n- 7-Zip x command extracts the .exe as PE sections (.text, .data, .rdata) instead of self-extracting properly\n- PowerShell curl is an alias for Invoke-WebRequest (doesn’t support -L)\n- Godot headless --script mode cannot create .tscn files directly (file creation works but .tscn format requires proper PackedScene.pack() which needs display context for some operations)\n\n## Setup Steps\n\n### 1. Download Godot .exe.zip ON the PC (NOT via SCP)\n\npowershell\n# On PC via SSH - use curl.exe (NOT curl alias!)\n$url = \"https://github.com/godotengine/godot/releases/download/4.6.1-stable/Godot_v4.6.1-stable_win64.exe.zip\"\n$output = \"D:\\Games\\Godot\\Godot_v4.6.1-stable_win64.zip\"\n& curl.exe -L -o $output $url\n\n\nCRITICAL: URL must be .../Godot_v4.6.1-stable_win64.exe.zip — NOT .zip alone.\nWrong URL returns a 9-byte “Not Found” HTML page, not the actual zip.\n\n### 2. Extract with 7-zip\npowershell\n& \"C:\\Program Files\\7-Zip\\7z.exe\" x $output \"-oD:\\Games\\Godot\" -y\n\n\nThis extracts to two .exe files (Godot 4.x is self-contained, no data.pck):\n- Godot_v4.6.1-stable_win64.exe — main editor (164MB)\n- Godot_v4.6.1-stable_win64_console.exe — headless/CLI (198KB)\n\nNote: 7z x extracts as PE sections. Use 7z e for archive contents (no subdirs). 7z x preserves directory structure — both work for Godot since it produces the same two .exe files.\n\n### 3. Verify CLI works\ncmd\nD:\\Games\\Godot\\Godot_v4.6.1-stable_win64.exe --version\n# Expected: 4.6.1.stable.official.14d19694e\n\n\n## Creating Godot Projects via CLI\n\n### 4. Create project structure on PC\nThe project.godot file format for Godot 4.x:\nini\n; res://project.godot\nconfig_version=5\nname=\"GameName\"\nrun/main_scene=\"res://scenes/main.tscn\"\n\n\n### 5. Create .tscn scene files\nFormat 3 (Godot 4.x) .tscn files are text-based:\n\nPlayer scene (CharacterBody2D):\n\n[gd_scene load_steps=4 format=3 uid=\"uid://cxplayer001\"]\n\n[ext_resource type=\"Script\" path=\"res://scripts/player.gd\" id=\"1_p\"]\n[ext_resource type=\"Texture2D\" path=\"res://assets/sprites/player.png\" id=\"2_sprite\"]\n\n[sub_resource type=\"RectangleShape2D\" id=\"RectShape1\"]\nsize = Vector2(14, 14)\n\n[node name=\"Player\" type=\"CharacterBody2D\"]\nscript = ExtResource(\"1_p\")\nposition = Vector2(200, 200)\n\n[node name=\"CollisionShape2D\" type=\"CollisionShape2D\" parent=\".\"]\nshape = SubResource(\"RectShape1\")\n\n[node name=\"Sprite2D\" type=\"Sprite2D\" parent=\".\"]\ntexture = ExtResource(\"2_sprite\")\n\n\nInstance a scene in parent (main.tscn):\n\n[gd_scene load_steps=2 format=3 uid=\"uid://dmainscene\"]\n\n[ext_resource type=\"PackedScene\" path=\"res://scenes/player/player.tscn\" id=\"3_player\"]\n\n[node name=\"Main\" type=\"Node2D\"]\n\n[node name=\"Player\" parent=\".\" instance=ExtResource(\"3_player\")]\nposition = Vector2(200, 200)\n\n\nKey differences from Godot 3.x:\n- format = 3 (not format 2)\n- [sub_resource] blocks inline (not separate .tres files)\n- instance=ExtResource(\"id\") for scene instantiation\n- uid=\"uid://...\" for external resources (auto-generated by editor, optional for CLI-created files)\n\n## Key Gotchas\n\n- Chunked SCP for large files: If SCP times out, split with split -b 10M file part_ then copy /b part_* file on PC (~19s per 10MB chunk)\n- Godot .exe IS the engine: No data.pck needed — the .exe is the full editor\n- Player script exports: If player.gd uses @export var sprite, the Sprite2D node must exist in scene or exports cause null reference errors on ready()\n- CharacterBody2D requires: CollisionShape2D child node to work properly\n- PowerShell curl: Must use curl.exe not curl (which is an alias for Invoke-WebRequest)\n\n## File Transfer Methods (Best to Worst)\n1. PC downloads directly (best for >50MB files) — use curl.exe on PC\n2. Chunked SCP (10MB chunks, ~19s each on SSH) — for files <100MB total\n3. rsync with compression — if available\n4. Google Drive intermediate — last resort\n\n### Chunked SCP Workflow (when direct SCP times out)\nOn local (Termux/Linux):\nbash\n# Split into 10MB chunks\nsplit -b 10M large_file.exe godot_part_\n# Upload each chunk (~19s on SSH)\nfor part in godot_part_*; do\n scp -i ~/.ssh/key -C \"$part\" user@host:\"D:/path/$part\"\ndone\n\nOn PC (cmd):\ncmd\ncopy /b godot_part_aa+godot_part_ab+... godot_v461.exe\n\n\n## Common URLs\n\nGodot 4.6.1: https://github.com/godotengine/godot/releases/download/4.6.1-stable/\nVerify URL: curl -sL \"https://api.github.com/repos/godotengine/godot/releases/tags/4.6.1-stable\" | grep \"browser_download_url\" | grep \"win64\"\n\n”}