tangled
alpha
login
or
join now
soda.bsky.social
/
editor
Game / editor prototyping with Godot
0
fork
atom
overview
issues
pulls
pipelines
Compare changes
Choose any two refs to compare.
base:
master
main
no tags found
compare:
master
main
no tags found
go
+151
-13
4 changed files
expand all
collapse all
unified
split
.gitignore
scenes
Editor.tscn
scripts
editor.gd
editor.gd.uid
+1
.gitignore
···
1
1
# Godot 4+ specific ignores
2
2
.godot/
3
3
/android/
4
4
+
qemu/
+28
-13
scenes/Editor.tscn
···
1
1
-
[gd_scene load_steps=2 format=3 uid="uid://dijojmon7te1k"]
1
1
+
[gd_scene load_steps=4 format=3 uid="uid://dijojmon7te1k"]
2
2
3
3
+
[ext_resource type="Script" uid="uid://djfeg1nlxsdad" path="res://scripts/editor.gd" id="1_3kl07"]
3
4
[ext_resource type="FontFile" uid="uid://cpj11tjx6ifqg" path="res://fonts/monogram.ttf" id="1_ndpqs"]
4
5
5
5
-
[node name="Control" type="Control"]
6
6
+
[sub_resource type="SyntaxHighlighter" id="SyntaxHighlighter_3kl07"]
7
7
+
8
8
+
[node name="Control" type="Control" node_paths=PackedStringArray("run_button", "code_edit")]
6
9
layout_mode = 3
7
10
anchors_preset = 15
8
11
anchor_right = 1.0
9
12
anchor_bottom = 1.0
10
13
grow_horizontal = 2
11
14
grow_vertical = 2
15
15
+
script = ExtResource("1_3kl07")
16
16
+
run_button = NodePath("CodeEdit/FoldableContainer/VBoxContainer/Run")
17
17
+
code_edit = NodePath("CodeEdit")
12
18
13
19
[node name="CodeEdit" type="CodeEdit" parent="."]
14
20
layout_mode = 1
···
20
26
theme_override_fonts/font = ExtResource("1_ndpqs")
21
27
theme_override_font_sizes/font_size = 24
22
28
scroll_smooth = true
29
29
+
syntax_highlighter = SubResource("SyntaxHighlighter_3kl07")
23
30
gutters_draw_breakpoints_gutter = true
24
31
gutters_draw_executing_lines = true
25
32
gutters_draw_line_numbers = true
26
33
indent_size = 2
27
34
indent_use_spaces = true
28
35
29
29
-
[node name="Step" type="Button" parent="CodeEdit"]
36
36
+
[node name="FoldableContainer" type="FoldableContainer" parent="CodeEdit"]
30
37
layout_mode = 0
31
31
-
offset_left = 1008.0
32
32
-
offset_top = 592.0
38
38
+
offset_left = 963.0
39
39
+
offset_top = 12.0
33
40
offset_right = 1132.0
34
34
-
offset_bottom = 631.0
41
41
+
offset_bottom = 104.0
42
42
+
title = "Commands"
43
43
+
44
44
+
[node name="VBoxContainer" type="VBoxContainer" parent="CodeEdit/FoldableContainer"]
45
45
+
layout_mode = 2
46
46
+
47
47
+
[node name="Run" type="Button" parent="CodeEdit/FoldableContainer/VBoxContainer"]
48
48
+
layout_mode = 2
35
49
theme_override_font_sizes/font_size = 24
36
36
-
text = "Step"
50
50
+
text = "Run"
37
51
38
38
-
[node name="Stop" type="Button" parent="CodeEdit"]
39
39
-
layout_mode = 0
40
40
-
offset_left = 875.0
41
41
-
offset_top = 592.0
42
42
-
offset_right = 999.0
43
43
-
offset_bottom = 631.0
52
52
+
[node name="Stop" type="Button" parent="CodeEdit/FoldableContainer/VBoxContainer"]
53
53
+
layout_mode = 2
44
54
theme_override_font_sizes/font_size = 24
45
55
text = "Stop
46
56
"
57
57
+
58
58
+
[node name="Edit" type="Button" parent="CodeEdit/FoldableContainer/VBoxContainer"]
59
59
+
layout_mode = 2
60
60
+
theme_override_font_sizes/font_size = 24
61
61
+
text = "Edit Flags"
+121
scripts/editor.gd
···
1
1
+
# QEMURunner.gd
2
2
+
# Alpine Linux ARM64 QEMU Runner as a Node
3
3
+
# Add to your scene and call run_vm()
4
4
+
5
5
+
extends Node
6
6
+
7
7
+
# Configuration
8
8
+
const ALP_ARCH = "aarch64"
9
9
+
const PORT = "2221"
10
10
+
var DISK_NAME = "alpine.%s.qcow2" % ALP_ARCH
11
11
+
12
12
+
# Working directory - qemu/ folder in project root
13
13
+
var working_dir: String = ""
14
14
+
15
15
+
@export var run_button: Button
16
16
+
@export var code_edit: CodeEdit
17
17
+
18
18
+
signal vm_started()
19
19
+
signal vm_stopped(exit_code: int)
20
20
+
signal vm_error(error_message: String)
21
21
+
22
22
+
var qemu_pid: int = -1
23
23
+
24
24
+
func handle_run():
25
25
+
print(code_edit.text)
26
26
+
27
27
+
func _ready():
28
28
+
# Set working directory to PROJECT_ROOT/qemu/
29
29
+
working_dir = ProjectSettings.globalize_path("res://qemu/")
30
30
+
print("QEMU working directory: %s" % working_dir)
31
31
+
32
32
+
# Create qemu directory if it doesn't exist
33
33
+
if not DirAccess.dir_exists_absolute(working_dir):
34
34
+
DirAccess.make_dir_recursive_absolute(working_dir)
35
35
+
print("Created qemu directory: %s" % working_dir)
36
36
+
37
37
+
run_vm()
38
38
+
39
39
+
run_button.button_up.connect(handle_run)
40
40
+
41
41
+
func _exit_tree() -> void:
42
42
+
stop_vm()
43
43
+
44
44
+
func check_file_exists(filename: String) -> bool:
45
45
+
"""Check if required file exists in working directory"""
46
46
+
var full_path = working_dir.path_join(filename)
47
47
+
print(full_path)
48
48
+
if not FileAccess.file_exists(full_path):
49
49
+
print("Error: %s not found!" % full_path)
50
50
+
return false
51
51
+
return true
52
52
+
53
53
+
func run_vm():
54
54
+
print("Alpine Linux ARM64 QEMU Runner")
55
55
+
print()
56
56
+
57
57
+
# Check required files
58
58
+
var required_files = [
59
59
+
"AAVMF_CODE.fd",
60
60
+
DISK_NAME
61
61
+
]
62
62
+
63
63
+
var missing_files = []
64
64
+
for file in required_files:
65
65
+
if not check_file_exists(file):
66
66
+
missing_files.append(file)
67
67
+
68
68
+
if not missing_files.is_empty():
69
69
+
print("\nMissing required files:")
70
70
+
for file in missing_files:
71
71
+
print(" - %s" % file)
72
72
+
print("\nPlease run the setup script first to create these files.")
73
73
+
vm_error.emit("Missing required files: " + str(missing_files))
74
74
+
return
75
75
+
76
76
+
# Display connection info
77
77
+
print("Starting Alpine Linux VM...")
78
78
+
print("SSH Port: %s" % PORT)
79
79
+
print("Connect with: ssh -p %s <username>@localhost" % PORT)
80
80
+
print()
81
81
+
print("To exit QEMU: Press Ctrl+A then X")
82
82
+
print()
83
83
+
84
84
+
# Build QEMU command
85
85
+
var qemu_cmd = PackedStringArray([
86
86
+
"qemu-system-aarch64",
87
87
+
"-accel", "tcg,thread=multi",
88
88
+
"-machine", "virt",
89
89
+
"-cpu", "cortex-a53",
90
90
+
"-smp", "cores=1",
91
91
+
"-m", "512",
92
92
+
"-bios", working_dir.path_join("AAVMF_CODE.fd"),
93
93
+
"-nographic",
94
94
+
"-drive", "if=virtio,id=hd,format=qcow2,file=%s" % working_dir.path_join(DISK_NAME),
95
95
+
"-nic", "user,hostfwd=tcp::%s-:22,model=virtio" % PORT,
96
96
+
"-device", "virtio-rng-pci",
97
97
+
"-rtc", "base=utc,clock=host",
98
98
+
"-s"
99
99
+
])
100
100
+
101
101
+
# Run QEMU
102
102
+
vm_started.emit()
103
103
+
104
104
+
qemu_pid = OS.create_process(qemu_cmd[0], qemu_cmd.slice(1))
105
105
+
106
106
+
if qemu_pid == -1:
107
107
+
print("\nError: qemu-system-aarch64 not found in PATH")
108
108
+
print("Please install QEMU for Windows: https://qemu.weilnetz.de/w64/")
109
109
+
print("Make sure qemu-system-aarch64 is in your system PATH")
110
110
+
vm_error.emit("Failed to start QEMU process")
111
111
+
return
112
112
+
113
113
+
print("QEMU started with PID: %d" % qemu_pid)
114
114
+
115
115
+
func stop_vm():
116
116
+
print("Attempting to kill QEMU")
117
117
+
if qemu_pid != -1:
118
118
+
OS.kill(qemu_pid)
119
119
+
print("QEMU stopped")
120
120
+
vm_stopped.emit(0)
121
121
+
qemu_pid = -1
+1
scripts/editor.gd.uid
···
1
1
+
uid://djfeg1nlxsdad