first commit

This commit is contained in:
Your Name
2026-05-09 17:39:45 +02:00
commit b2a0dd59a8
101 changed files with 1930 additions and 0 deletions

29
code/lua_env.lua Normal file
View File

@@ -0,0 +1,29 @@
local lua_env = {
extends = Node,
env = {}
}
-- optional helper to reset environment
function lua_env:reset_env()
self.env = {}
setmetatable(self.env, { __index = _G }) -- fall back to globals
end
-- the core runscript
function lua_env:run_script(code, node)
local chunk, err = load(code, "runscript", "t", self.env)
if not chunk then
print("[LuaRuntime] Syntax error: ", err)
return false
end
-- Call the chunk, optionally passing context
local ok, result = pcall(chunk, node)
if not ok then
print("[LuaRuntime] Runtime error: ", result)
return false
end
return result
end
return lua_env

1
code/lua_env.lua.uid Normal file
View File

@@ -0,0 +1 @@
uid://c01rdot180cne

50
code/player.gd Normal file
View File

@@ -0,0 +1,50 @@
extends CharacterBody2D
var speed = 16*16; # godot transformation per second
# Called when the node enters the scene tree for the first time.
var texts = [];
var lastChange = 0;
var hit = 0;
func _ready() -> void:
RenderingServer.set_default_clear_color(Color.BLACK)
var root = get_node("../")
var texturespace = root.get_meta("resourcepack");
for text in ["player-w1","player-w2"]:
texts.append(load("res://"+texturespace+"/text/"+text+".png"))
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta: float) -> void:
var movedelta = Vector2.ZERO
if not self.get_meta("can_walk"):
return
if Input.is_action_pressed("movedown"):
movedelta.y += 1
if Input.is_action_pressed("moveup"):
movedelta.y -= 1
if Input.is_action_pressed("moveleft"):
movedelta.x -= 1
if Input.is_action_pressed("moveright"):
movedelta.x += 1
if movedelta.length() > 0:
movedelta = movedelta.normalized() * speed
move_and_collide(Vector2((movedelta * delta).x,0))
move_and_collide(Vector2(0,(movedelta * delta).y))
lastChange += delta
if lastChange > 0.4:
lastChange = 0
hit += 1
if hit > texts.size()-1:
hit = 0
get_node("Sprite2D").texture = texts[hit]
get_node("Walk").play()
func _process(delta: float) -> void:
var camera = get_node("../cam")
var campos: Vector2 = camera.position
camera.position = campos.lerp(self.position, 1.0 - exp(-8 * delta))

1
code/player.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://cc4y82skj2obl

205
code/world.gd Normal file
View File

@@ -0,0 +1,205 @@
extends Area2D
# GLOBAL CFG
@onready var fade_rect: ColorRect = get_node("../Fader/ColorRect")
func fade_out(duration := 1.0):
fade_rect.visible = true
fade_rect.modulate.a = 0.0
var tween = get_tree().create_tween()
tween.tween_property(fade_rect, "modulate:a", 1.0, duration)
func fade_in(duration := 1.0):
fade_rect.visible = true
fade_rect.modulate.a = 1.0
var tween = get_tree().create_tween()
tween.tween_property(fade_rect, "modulate:a", 0.0, duration)
tween.tween_callback(Callable(self, "_on_fade_in_complete"))
func wait(seconds: float) -> void:
await get_tree().create_timer(seconds).timeout
func _on_fade_in_complete():
fade_rect.visible = false
const scalef = 3;
const textsize = 16;
func load_json(path: String): # stolen from reddit then updated to godot 4 lmao
var file := FileAccess.open(path, FileAccess.READ)
var content = file.get_as_text()
file.close()
var parsed_json = JSON.parse_string(content)
return parsed_json
func loadstring(path: String): # stolen from reddit then updated to godot 4 lmao
var file := FileAccess.open(path, FileAccess.READ)
var content = file.get_as_text()
file.close()
return content
var rng = RandomNumberGenerator.new()
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
await fade_in(1.0)
get_node("../Player").set_meta("can_walk",true)
for child in get_children(): child.queue_free()
var root = get_node("../")
var world = load_json("res://worlds/"+self.get_meta("world")+".json");
if world.has("mapscript"):
var script = loadstring("res://worlds/"+self.get_meta("world")+".lua")
get_node("../LuaEnv").reset_env()
get_node("../LuaEnv").run_script(script,self)
var assetcfg = load_json("res://assetcfg.json")
var texturespace = root.get_meta("resourcepack");
var worldassemble = {};
var plr = get_node("../Player")
plr.position = Vector2(world["pspawn"]["w"]*(16*scalef),world["pspawn"]["h"]*(16*scalef))
for y in range(world["height"]+1):
for x in range(world["width"]+1):
if not worldassemble.has(y):
worldassemble[y] = {}
worldassemble[y][x] = {"thing":world["fill"],"action":"none"}
for modifier in world["features"]:
var x = int(modifier["w"])
var y = int(modifier["h"])
worldassemble[y][x] = modifier["t"]
# assuming this script extends Node2D or Area2D that builds the world
for y in range(worldassemble.size()):
for x in range(worldassemble[y].size()):
var along = worldassemble[y][x]
var walpole = along["thing"]
var cfg = assetcfg[walpole]
# combine base data from cfg and instance-specific data from along
var tile_type = along.get("action", cfg.get("action", "default"))
var is_collidable = along.get("collidable", cfg.get("collidable", false))
var tex_path = "res://%s/text/%s" % [texturespace, cfg["textname"]]
var tex = load(tex_path)
# --- choose node type
var tile_node: Node2D
if tile_type == "tp":
tile_node = Area2D.new() # teleporter
elif is_collidable:
tile_node = StaticBody2D.new() # solid
else:
tile_node = Area2D.new() # non-collidable sensor/decor
add_child(tile_node)
tile_node.position = Vector2(x * (scalef * textsize), y * (scalef * textsize))
tile_node.name = "tile_%s_%s" % [x, y]
tile_node.set_meta("collidable", is_collidable)
# --- sprite
var sprite = Sprite2D.new()
sprite.texture = tex
sprite.scale = Vector2(scalef, scalef)
tile_node.add_child(sprite)
# optional random rotation
if cfg.get("allowRandRot", false):
sprite.rotation_degrees = 90 * rng.randi_range(0, 3)
# --- collision shape for solids and sensors
if is_collidable or tile_type == "tp":
var col = CollisionShape2D.new()
var shape = RectangleShape2D.new()
shape.size = Vector2(16 * scalef, 16 * scalef)
col.shape = shape
col.position = Vector2.ZERO
tile_node.add_child(col)
# --- teleporter setup
if tile_type == "tp":
var target_world = along.get("target_world", cfg.get("target_world", "default"))
tile_node.set_meta("world", target_world)
tile_node.connect("body_entered", Callable(self, "_on_tp_entered").bind(tile_node))
_add_world_borders(world["width"], world["height"])
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _on_tp_entered(body: Node, source: Node) -> void:
if not body.is_in_group("player"):
return
print("Teleport triggered by:", body.name)
await fade_out(1.0)
get_node("../Player").set_meta("can_walk",false)
await wait(1.0)
if body.has_method("set_velocity"):
body.set_velocity(Vector2.ZERO)
if source.has_meta("world"):
var new_world = source.get_meta("world")
print("Teleporting to world:", new_world)
set_meta("world", new_world)
call_deferred("_ready") # safely rebuild
else:
print("⚠️ Teleporter node has no 'world' meta set!")
func _add_world_borders(width: int, height: int) -> void:
var border_thickness = 32.0 * scalef
var w_px = width * (textsize * scalef)
var h_px = height * (textsize * scalef)
var positions = {
"top": Vector2(w_px / 2, -border_thickness / 2),
"bottom": Vector2(w_px / 2, h_px + border_thickness / 2),
"left": Vector2(-border_thickness / 2, h_px / 2),
"right": Vector2(w_px + border_thickness / 2, h_px / 2)
}
for name in positions.keys():
var wall = StaticBody2D.new()
wall.name = "border_%s" % name
var shape = RectangleShape2D.new()
if name in ["top", "bottom"]:
shape.size = Vector2(w_px + border_thickness, border_thickness)
else:
shape.size = Vector2(border_thickness, h_px + border_thickness)
var col = CollisionShape2D.new()
col.shape = shape
wall.position = positions[name]
wall.add_child(col)
add_child(wall)
@onready var label: RichTextLabel = null
@onready var uitypebox: ColorRect = null
var typing_speed := 0.03 # seconds between characters
var typing = false # to prevent overlapping animations
func ui_showmesg(t: String) -> void:
label = get_node("../UI/bg/RichTextLabel")
uitypebox = get_node("../UI/bg")
if typing:
return # skip if already typing (optional safeguard)
uitypebox.visible = true
typing = true
print(label, " valid? ", is_instance_valid(label))
label.text = t
label.visible_characters = 0
await _type_text(t)
await wait(4)
label = get_node("../UI/bg/RichTextLabel")
uitypebox = get_node("../UI/bg")
label.visible_characters = 0
uitypebox.visible = false
typing = false
func _type_text(t: String) -> void:
var i := 0
while i < t.length():
i += 1
label.visible_characters = i
await wait(typing_speed)

1
code/world.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://be6h32vns32hm