commit b2a0dd59a826b562dd8187ad1f25e68dafc6575d Author: Your Name Date: Sat May 9 17:39:45 2026 +0200 first commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0865e84 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2025 Gil Barbosa Reis. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/lua-gdextension/CHANGELOG.md b/addons/lua-gdextension/CHANGELOG.md new file mode 100644 index 0000000..2b04656 --- /dev/null +++ b/addons/lua-gdextension/CHANGELOG.md @@ -0,0 +1,161 @@ +# Changelog +## [Unreleased](https://github.com/gilzoide/lua-gdextension/compare/0.6.0...HEAD) + + +## [0.6.0](https://github.com/gilzoide/lua-gdextension/releases/tag/0.6.0) +### Added +- Support for constructing typed arrays in Lua using the idiom `Array[some_type]()` +- Support for constructing typed dictionaries in Lua using the idiom `Dictionary[key_type][value_type]()` +- Support for typed arrays, typed dictionaries and classes in exported properties: + ```lua + MyScript.exported_node_array = export(Array[Node]) + MyScript.exported_int_valued_dict = export(Dictionary[Variant][int]) + MyScript.exported_texture_property = export(Texture) + -- or + MyScript.exported_node_array = export({ type = Array[Node] }) + MyScript.exported_int_valued_dict = export({ type = Dictionary[Variant][int] }) + MyScript.exported_texture_property = export({ type = Texture }) + ``` +- `is_instance_valid` utility function when opening `GODOT_UTILITY_FUNCTIONS` library +- Support for older Linux distros using GLIBC on par with Ubuntu 22.04 +- Parser API based on Tree Sitter + + Adds the `LuaParser`, `LuaAST`, `LuaASTNode` and `LuaASTQuery` classes + +### Changed +- `LuaScriptInstance`'s data table is passed as `self` to methods instead of their owner `Object` + + For this to work, the table now has a metatable to access its owner when necessary +- `LuaScript`s now have a "Import Behavior" property, defaulting to "Automatic" + + In "Automatic" behavior, Lua code is evaluated only if it looks like a Godot script. + Lua code that looks like a Godot script is one that ends by returning a named variable (`return MyClassVariable`) or a table constructed inline (`return {...}`) + + In "Always Evaluate" behavior, Lua code will always be evaluated + + In "Don't Load" behavior, Lua code will not be loaded nor evaluated at all + + Note that only evaluated scripts can be attached to Godot Objects. +- Variant and `LuaScriptInstance` methods are now converted to Callable, so they can be more easily passed to Godot APIs such as `Signal.connect` + ```lua + -- Before this change, we had to manually instantiate Callable + some_signal:connect(Callable(self, "method_name")) + -- Now we can pass the method directly + some_signal:connect(self.method_name) + ``` + +### Fixed +- Fixed cyclic references from `LuaScriptInstance` <-> `LuaState`, avoiding leaks of `LuaScript`s +- Fixed cyclic references from `LuaScriptProperty` <-> `LuaState`, avoiding memory leaks +- Support for built-in Variant types in exported properties when passed directly to `export`: + ```lua + MyScript.exported_dictionary = export(Dictionary) + ``` +- Convert null Object Variants (``) to `nil` when passing them to Lua +- Convert freed Object Variants (``) to `nil` when passing them to Lua +- Fixed `LuaJIT core/library version mismatch` errors in LuaJIT builds +- `LuaScriptResourceFormatLoader::_load` now respects the cache mode, fixing "Another resource is loaded from path 'res://...' (possible cyclic resource inclusion)." errors +- Error messages from Lua code using the wrong stack index +- Crashes when passing Lua primitives to `typeof`, `Variant.is`, `Variant.get_type`, `Variant.booleanize`, `Variant.duplicate`, `Variant.get_type_name`, `Variant.hash`, `Variant.recursive_hash` and `Variant.hash_compare` +- The `addons/lua-gdextension/build/.gdignore` file was added to the distributed build. + This fixes import errors when opening the Godot editor with the LuaJIT build. + + +## [0.5.0](https://github.com/gilzoide/lua-gdextension/releases/tag/0.5.0) +### Added +- Support for Linux arm64 +- `LuaTable.get_metatable` and `LuaTable.set_metatable` methods +- Support for building with LuaJIT +- `LuaState.get_lua_runtime`, `LuaState.get_lua_version_num` and `LuaState.get_lua_version_string` methods + + +## [0.4.0](https://github.com/gilzoide/lua-gdextension/releases/tag/0.4.0) +### Added +- `LuaCoroutine.completed` and `LuaCoroutine.failed` signals +- `await` function similar to GDScript's, allowing coroutines to yield and resume automatically when a signal is emitted +- Support for Web exports +- Support for Windows arm64 +- Support for calling static methods from Godot classes, like `FileAccess.open` +- Custom [Lua 5.4+ warning function](https://www.lua.org/manual/5.4/manual.html#lua_setwarnf) that sends messages to `push_warning` +- `LuaThread` class as a superclass for `LuaCoroutine`. + This new class is used when converting a LuaState's main thread to Variant. +- `LuaState.main_thread` property for getting a Lua state's main thread of execution +- Support for setting hooks to `LuaThread`s, including the main thread + +### Changed +- `LuaObject` instances are reused when wrapping the same Lua object, so that `==` and `is_same` can be used properly +- The following methods of LuaScripts run in pooled coroutines, so that `await` can be used in them: regular method calls, setter functions, `_init`, `_notification` +- Godot 4.4 is now the minimum version necessary to use this addon + +### Fixed +- Use `xcframework` instead of `dylib` in iOS exports +- Crash when Lua errors, but the error object is not a string +- Crash when reloading the GDExtension + + +## [0.3.0](https://github.com/gilzoide/lua-gdextension/releases/tag/0.3.0) +### Added +- Editor plugin that registers the Lua REPL tab, where you can try Lua code using an empty `LuaState` +- Support for calling Godot String methods using Lua strings +- Optional support for `res://` and `user://` relative paths in package searchers, `loadfile` and `dofile`. + Open the `GODOT_LOCAL_PATHS` library to activate this behavior. +- `LuaState.LoadMode` enum for specifying the Lua load mode: text, binary or any +- `LuaState.do_buffer` and `LuaState.load_buffer` methods for loading Lua code from possibly binary chunks +- `LuaState.package_path` and `LuaState.package_cpath` properties for accessing the value of Lua's [`package.path`](https://www.lua.org/manual/5.4/manual.html#pdf-package.path) and [`package.cpath`](https://www.lua.org/manual/5.4/manual.html#pdf-package.cpath) +- `LuaState.get_lua_exec_dir` static method to get the executable directory used to replace "!" when setting `package_path` and `package_cpath` properties. + When running in the Godot editor, it returns the globalized version of `res://` path. + Otherwise, it returns the base directory of the executable. +- Advanced project settings for setting the `LuaScriptLanguage` state's `package_path` and `package_cpath` properties +- `LuaState.are_libraries_opened` method for checking if a subset of libraries were already opened +- `LuaState.create_function` method for creating a `LuaFunction` from a `Callable` +- API documentation is now available in the Godot editor + +### Changed +- The GDExtension is now marked as reloadable +- Renamed `LuaCoroutine::LuaCoroutineStatus` to `LuaCoroutine::Status` +- `LuaState.load_file` and `LuaState.do_file` now receive the load mode instead of buffer size +- `Callable` values when passed to Lua are wrapped as Lua functions when `GODOT_VARIANT` library is not opened, making it possible to call them in sandboxed environments +- Lua is now compiled as C++ + +### Removed +- `VariantType::has_static_method` internal method + +### Fixed +- Bind `LuaCoroutine::status` property with correct enum type +- Bind `LuaError::status` property as int with correct enum type +- Crash when calling utility functions from Lua +- Compilation for Windows using MSVC + + +## [0.2.0](https://github.com/gilzoide/lua-gdextension/releases/tag/0.2.0) +### Added +- Lua is now available as a scripting language for Godot objects, so that you can create your games entirely in Lua! +- `LuaObject.get_lua_state` method for getting the `LuaState` of a Lua object +- `LuaTable.clear` method +- `LuaTable.rawget` and `LuaTable.rawset` methods that don't trigger metamethods +- `LuaFunction.to_callable` method to easily turn Lua functions to Callable +- `LuaState.load_string` and `LuaState.load_files` for loading Lua code without executing it +- Support for passing a `LuaTable` as `_ENV` in `LuaState.do_string` and `LuaState.do_file` +- Support for `PackedVector4Array` variant type +- "Bouncing Logo" sample scene + +### Changed +- Minimum Godot version supported is now 4.3 +- Android target API changed to 21 (Android Lollipop 5.0) +- In Lua, `print` is now bound to Godot's `printt` to match Lua's behavior of adding `\t` between passed arguments + +### Removed +- `LuaTable.get_value` and `LuaTable.set_value`, use `LuaTable.get` and `LuaTable.set` instead + +### Fixed +- Use `PROPERTY_USAGE_NONE` for `LuaState.globals` and `LuaState.registry`, fixing instance leaks +- Lua stack handling in `LuaTable` and utility function wrapper code, fixing crashes +- `typeof` utility function now returns a `VariantType` instead of a value unusable by Lua +- Lua objects coming from a different `LuaState` are passed as Variants to Lua instead of being unwrapped, fixing crashes + + +## [0.1.0](https://github.com/gilzoide/lua-gdextension/releases/tag/0.1.0) +### Added +- `LuaState` class for holding a Lua state and interacting with it. + You may create as many instances as you want, each one representing an independent Lua state. +- `LuaCoroutine`, `LuaFunction`, `LuaLightUserdata`, `LuaTable` and `LuaUserdata` classes that wrap instances from a Lua state in Godot. +- `LuaError` class that represents errors from Lua code. +- Support for registering `Variant` type in Lua states, so that any Godot data can be manipulated in Lua. +- Support for registering Godot classes in Lua, so you can create instances and access integer constants. +- Support for adding access to Godot singleton objects in Lua, accessible directly by name. +- Support for registering Godot utility functions in Lua, like `print`, `lerp` and `is_same`. +- Support for adding access to Godot global enums in Lua, like `OK`, `TYPE_STRING` and `SIDE_LEFT`. diff --git a/addons/lua-gdextension/LICENSE b/addons/lua-gdextension/LICENSE new file mode 100644 index 0000000..0865e84 --- /dev/null +++ b/addons/lua-gdextension/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2025 Gil Barbosa Reis. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/lua-gdextension/LuaScript_icon.svg b/addons/lua-gdextension/LuaScript_icon.svg new file mode 100644 index 0000000..6f3b766 --- /dev/null +++ b/addons/lua-gdextension/LuaScript_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/addons/lua-gdextension/LuaScript_icon.svg.import b/addons/lua-gdextension/LuaScript_icon.svg.import new file mode 100644 index 0000000..57338be --- /dev/null +++ b/addons/lua-gdextension/LuaScript_icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://de52k4kdp6s7y" +path="res://.godot/imported/LuaScript_icon.svg-e936c81a8c0f686739c63104e1bb3341.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/lua-gdextension/LuaScript_icon.svg" +dest_files=["res://.godot/imported/LuaScript_icon.svg-e936c81a8c0f686739c63104e1bb3341.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/lua-gdextension/README.md b/addons/lua-gdextension/README.md new file mode 100644 index 0000000..f226b19 --- /dev/null +++ b/addons/lua-gdextension/README.md @@ -0,0 +1,239 @@ +# Lua GDExtension +[![Godot Asset Library page](https://img.shields.io/static/v1?logo=godotengine&label=asset%20library%20%28Lua%205.4%29&color=478CBF&message=0.6.0)](https://godotengine.org/asset-library/asset/2330) +[![Godot Asset Library page](https://img.shields.io/static/v1?logo=godotengine&label=asset%20library%20%28LuaJIT%29&color=478CBF&message=0.6.0)](https://godotengine.org/asset-library/asset/2330) +[![Build and Test workflow](https://github.com/gilzoide/lua-gdextension/actions/workflows/build.yml/badge.svg)](https://github.com/gilzoide/lua-gdextension/actions/workflows/build.yml) + +Lua GDExtension icon + +Extension for using the [Lua programming language](https://www.lua.org/) in Godot 4.4+ + +With this addon, you can program your game or application directly in Lua. +You can also create sandboxed Lua states for external modding/scripting support, as many as necessary. + +This plugin is available in the Asset Library as: +- [Lua GDExtension](https://godotengine.org/asset-library/asset/2330) (Lua 5.4 version) +- [Lua GDExtension + LuaJIT](https://godotengine.org/asset-library/asset/4119) (LuaJIT version) + + +## Features +- Create Godot scripts directly in Lua, making it possible to use Lua as an alternative to GDScript or C# +- Create additional Lua states for external modding/scripting support, as many as necessary +- Manage Lua tables, functions and coroutines directly from GDScript, C# or any other scripting language in Godot +- Select which Lua libraries and Godot APIs will be available per Lua state, making sandboxing easier: + + Lua libraries are the same as Lua/C, like `base`, `package` and `io` libraries + + Godot APIs: + + Create and manipulate Variant values + + Instantiate objects and access class constants + + Access singleton objects by name + + Global utility functions, like Godot's `print_rich`, `lerp` and `is_same`. + Also adds an `await` function that mimics GDScript's `await` keyword (only supported when running in a coroutine). + + Global enums, like `OK`, `TYPE_STRING` and `SIDE_LEFT` + + Patch Lua `package.searchers`, `require`, `loadfile` and `dofile` to accept paths relative to `res://` and `user://` +- Editor plugin with Lua REPL for testing out Lua snippets +- Choose between Lua 5.4 or LuaJIT v2.1 runtimes (distributed as separate addons) + + Note: LuaJIT does not support WebAssebly, so Lua 5.4 is always used in Web platform + + +## Lua scripting in Godot +This addon registers a [ScriptLanguageExtension](https://docs.godotengine.org/en/stable/classes/class_scriptlanguageextension.html) so that Godot objects can be scripted directly in Lua. + +For Lua scripts to be usable in Nodes and Resources, they must return a table with the script metadata containing methods, properties, signals, etc... +```lua +-- This is our script metadata table. +-- +-- It stores metadata such as its base class, global class_name, icon, +-- as well as any declared properties, methods and signals +local LuaBouncingLogo = { + -- base class (optional, defaults to RefCounted) + extends = Sprite2D, + -- if true, allow the script to be executed by the editor (optional) + tool = false, + -- global class name (optional) + class_name = "LuaBouncingLogo", + + -- Declare properties + linear_velocity = export(100), + initial_angle = export({ + type = float, + default = 0, + hint = PROPERTY_HINT_RANGE, + hint_string = "0,360,degrees" + }), + -- Declare signals + bounced = signal(), +} + +-- Called when the node enters the scene tree for the first time. +function LuaBouncingLogo:_ready() + self.position = self:get_viewport():get_size() / 2 + self.movement = Vector2(self.linear_velocity, 0):rotated(deg_to_rad(self.initial_angle)) + + -- To connect a signal in Lua, you can use the method name just like in GDScript + self.bounced:connect(self._on_bounced) +end + +-- Called every frame. 'delta' is the elapsed time since the previous frame. +function LuaBouncingLogo:_process(delta) + local viewport_size = self:get_viewport():get_size() + local viewport_rect = Rect2(Vector2(), viewport_size) + if not viewport_rect:encloses(self.global_transform * self:get_rect()) then + self.movement = self.movement:rotated(deg_to_rad(90)) + self.bounced:emit() + end + self.position = self.position + self.movement * delta +end + +function LuaBouncingLogo:_on_bounced() + print("Bounced =D") +end + +-- Return the metadata table for the script to be usable by Godot objects +return LuaBouncingLogo +``` + + +## Calling Lua from Godot +The following classes are registered in Godot for creating Lua states and interacting with them: `LuaState`, `LuaTable`, `LuaUserdata`, `LuaLightUserdata`, `LuaFunction`, `LuaCoroutine`, `LuaThread`, `LuaDebug` and `LuaError`. + +Usage example in GDScript: +```gdscript +# 1. Create a Lua state +var lua = LuaState.new() +# 2. Import Lua and Godot APIs into the state +# Optionally pass which libraries should be opened to the method +lua.open_libraries() + +# 3. Run Lua code using `LuaState.do_string` or `LuaState.do_file` +var result = lua.do_string(""" + local vector = Vector2(1, 2) + return { + this_is_a_table = true, + vector = vector, + } +""") +# 4. Access results from Lua code directly in Godot +# When errors occur, instances of `LuaError` will be returned +if result is LuaError: + printerr("Error in Lua code: ", result) +else: + print(result) # [LuaTable:0x556069ee50ab] + print(result["this_is_a_table"]) # true + print(result["vector"]) # (1, 2) + print(result["invalid key"]) # + +# 5. Access the global _G table via `LuaState.globals` property +assert(lua.globals is LuaTable) +lua.globals["a_godot_callable"] = func(): print("Hello from GDScript!") +lua.do_string(""" + a_godot_callable() -- 'Hello from GDScript!' +""") +``` + + +## Calling Godot from Lua +- Instantiate and manipulate Godot objects, just like in GDScript. + ```lua + local v = Vector3(1, 2, 3) + print(v.x) -- 1 + -- Note: use ":" instead of "." to call methods in Lua + print(v:length()) -- 3.74165749549866 + + local n = Node:new() + print(n:is_inside_tree()) -- false + n:queue_free() + ``` +- Typed Arrays and Dictionaries are also supported + ```lua + -- Element type: int + local int_array = Array[int]() + -- Element type: Node + local node_array = Array[Node]() + + -- Key: int, Value: bool + local int_to_bool_dict = Dictionary[int][bool]() + -- Key: Variant, Value: Node + local node_valued_dict = Dictionary[Variant][Node]() + ``` +- Call Godot utility functions. + ```lua + local d1 = Dictionary() + local d2 = Dictionary() + print(is_same(d1, d2)) -- false + print(is_same(d2, d2)) -- true + + print(lerp(5, 10, 0.15)) -- 5.75 + ``` +- Access singleton objects by name. + ```lua + assert(OS == Engine:get_singleton("OS")) + ``` +- Construct Array/Dictionary using Lua tables. + ```lua + local array = Array{ "value 0", "value 1" } + -- Godot Arrays are indexed from 0, instead of 1 + print(array[0]) -- "value 0" + print(array[1]) -- "value 1" + print(array[2]) -- nil + + local dict = Dictionary{ hello = "world" } + print(dict) -- { "hello": "world" } + print(dict["hello"]) -- "world" + print(dict["invalid key"]) -- nil + ``` +- Iterate over values using `pairs` for types that support it, like Arrays, packed arrays, Dictionaries and some math types. + ```lua + local dictionary = Dictionary{ hello = "world", key = "value" } + for key, value in pairs(dictionary) do + print(key .. ": " .. value) + end + ``` +- Length operator (`#`) as a shortcut for calling the `size()` method in any object that supports it. + ```lua + local array = Array{ 1, 2, 3, 4 } + print(#array) -- 4 + ``` +- Runtime type check using the `Variant.is` method. + ```lua + local array = Array() + print(Variant.is(array, Array)) -- true + print(Variant.is(array, 'Array')) -- true + -- Also available using the method notation from Variant objects + print(array:is(Array)) -- true + print(array:is(Dictionary)) -- false + print(array:is(RefCounted)) -- false + ``` +- Making protected calls using `pcall`. + ```lua + local v = Vector2(1, 2) + print(v:pcall('length')) -- true 2.2360680103302 + print(v:pcall('invalid method')) -- false "Invalid method" + ``` + + +## TODO +- [X] Bind Variant types to Lua +- [X] Bind utility functions to Lua +- [X] Bind enums and constants to Lua +- [X] Add support for getting global singletons from Lua +- [X] Add support for getting classes from Lua +- [X] Add optional support for `res://` relative paths in `require`, `loadfile` and `dofile` +- [X] Add support for `await`ing signals +- [X] Submit to Asset Library +- [X] Lua ScriptLanguageExtension + + [X] Add support for property hints / usage flags (including export) + + [X] Add support for property getter / setter + + [ ] Add `export_*` functions mimicking GDScript annotations for better UX +- [X] Support for building with LuaJIT +- [X] Support WebAssembly platform +- [X] Support Windows arm64 platform +- [X] Support Linux arm64 platform +- [ ] Support Linux arm32 and rv64 platform +- [X] Use framework in iOS (possibly a xcframework supporting the iOS simulator as well) +- [X] Automated unit tests +- [X] Automated build and distribution +- [X] Lua REPL editor plugin + + +## Other projects for using Lua in Godot 4 +- https://github.com/WeaselGames/godot_luaAPI +- https://github.com/perbone/luascript diff --git a/addons/lua-gdextension/build/.gdignore b/addons/lua-gdextension/build/.gdignore new file mode 100644 index 0000000..e69de29 diff --git a/addons/lua-gdextension/build/libgodot-cpp.ios.template_debug.universal.xcframework/Info.plist b/addons/lua-gdextension/build/libgodot-cpp.ios.template_debug.universal.xcframework/Info.plist new file mode 100644 index 0000000..15bf8aa --- /dev/null +++ b/addons/lua-gdextension/build/libgodot-cpp.ios.template_debug.universal.xcframework/Info.plist @@ -0,0 +1,27 @@ + + + + + AvailableLibraries + + + BinaryPath + libgodot-cpp.ios.template_debug.universal.a + LibraryIdentifier + ios-arm64 + LibraryPath + libgodot-cpp.ios.template_debug.universal.a + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/addons/lua-gdextension/build/libgodot-cpp.ios.template_debug.universal.xcframework/ios-arm64/libgodot-cpp.ios.template_debug.universal.a b/addons/lua-gdextension/build/libgodot-cpp.ios.template_debug.universal.xcframework/ios-arm64/libgodot-cpp.ios.template_debug.universal.a new file mode 100644 index 0000000..3a881b6 Binary files /dev/null and b/addons/lua-gdextension/build/libgodot-cpp.ios.template_debug.universal.xcframework/ios-arm64/libgodot-cpp.ios.template_debug.universal.a differ diff --git a/addons/lua-gdextension/build/libgodot-cpp.ios.template_release.universal.xcframework/Info.plist b/addons/lua-gdextension/build/libgodot-cpp.ios.template_release.universal.xcframework/Info.plist new file mode 100644 index 0000000..40fab56 --- /dev/null +++ b/addons/lua-gdextension/build/libgodot-cpp.ios.template_release.universal.xcframework/Info.plist @@ -0,0 +1,27 @@ + + + + + AvailableLibraries + + + BinaryPath + libgodot-cpp.ios.template_release.universal.a + LibraryIdentifier + ios-arm64 + LibraryPath + libgodot-cpp.ios.template_release.universal.a + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/addons/lua-gdextension/build/libgodot-cpp.ios.template_release.universal.xcframework/ios-arm64/libgodot-cpp.ios.template_release.universal.a b/addons/lua-gdextension/build/libgodot-cpp.ios.template_release.universal.xcframework/ios-arm64/libgodot-cpp.ios.template_release.universal.a new file mode 100644 index 0000000..99b3f0a Binary files /dev/null and b/addons/lua-gdextension/build/libgodot-cpp.ios.template_release.universal.xcframework/ios-arm64/libgodot-cpp.ios.template_release.universal.a differ diff --git a/addons/lua-gdextension/build/libluagdextension.android.template_debug.arm32.so b/addons/lua-gdextension/build/libluagdextension.android.template_debug.arm32.so new file mode 100644 index 0000000..7bd62c0 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.android.template_debug.arm32.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.android.template_debug.arm64.so b/addons/lua-gdextension/build/libluagdextension.android.template_debug.arm64.so new file mode 100644 index 0000000..633cdce Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.android.template_debug.arm64.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.android.template_debug.x86_32.so b/addons/lua-gdextension/build/libluagdextension.android.template_debug.x86_32.so new file mode 100644 index 0000000..123f387 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.android.template_debug.x86_32.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.android.template_debug.x86_64.so b/addons/lua-gdextension/build/libluagdextension.android.template_debug.x86_64.so new file mode 100644 index 0000000..da98708 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.android.template_debug.x86_64.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.android.template_release.arm32.so b/addons/lua-gdextension/build/libluagdextension.android.template_release.arm32.so new file mode 100644 index 0000000..ec1a656 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.android.template_release.arm32.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.android.template_release.arm64.so b/addons/lua-gdextension/build/libluagdextension.android.template_release.arm64.so new file mode 100644 index 0000000..67334ff Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.android.template_release.arm64.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.android.template_release.x86_32.so b/addons/lua-gdextension/build/libluagdextension.android.template_release.x86_32.so new file mode 100644 index 0000000..cd40220 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.android.template_release.x86_32.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.android.template_release.x86_64.so b/addons/lua-gdextension/build/libluagdextension.android.template_release.x86_64.so new file mode 100644 index 0000000..12db363 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.android.template_release.x86_64.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.ios.template_debug.universal.xcframework/Info.plist b/addons/lua-gdextension/build/libluagdextension.ios.template_debug.universal.xcframework/Info.plist new file mode 100644 index 0000000..e3e19cd --- /dev/null +++ b/addons/lua-gdextension/build/libluagdextension.ios.template_debug.universal.xcframework/Info.plist @@ -0,0 +1,27 @@ + + + + + AvailableLibraries + + + BinaryPath + libluagdextension.ios.template_debug.universal.a + LibraryIdentifier + ios-arm64 + LibraryPath + libluagdextension.ios.template_debug.universal.a + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/addons/lua-gdextension/build/libluagdextension.ios.template_debug.universal.xcframework/ios-arm64/libluagdextension.ios.template_debug.universal.a b/addons/lua-gdextension/build/libluagdextension.ios.template_debug.universal.xcframework/ios-arm64/libluagdextension.ios.template_debug.universal.a new file mode 100644 index 0000000..dd0590a Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.ios.template_debug.universal.xcframework/ios-arm64/libluagdextension.ios.template_debug.universal.a differ diff --git a/addons/lua-gdextension/build/libluagdextension.ios.template_release.universal.xcframework/Info.plist b/addons/lua-gdextension/build/libluagdextension.ios.template_release.universal.xcframework/Info.plist new file mode 100644 index 0000000..3ff3f4b --- /dev/null +++ b/addons/lua-gdextension/build/libluagdextension.ios.template_release.universal.xcframework/Info.plist @@ -0,0 +1,27 @@ + + + + + AvailableLibraries + + + BinaryPath + libluagdextension.ios.template_release.universal.a + LibraryIdentifier + ios-arm64 + LibraryPath + libluagdextension.ios.template_release.universal.a + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/addons/lua-gdextension/build/libluagdextension.ios.template_release.universal.xcframework/ios-arm64/libluagdextension.ios.template_release.universal.a b/addons/lua-gdextension/build/libluagdextension.ios.template_release.universal.xcframework/ios-arm64/libluagdextension.ios.template_release.universal.a new file mode 100644 index 0000000..ced6b3f Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.ios.template_release.universal.xcframework/ios-arm64/libluagdextension.ios.template_release.universal.a differ diff --git a/addons/lua-gdextension/build/libluagdextension.linux.template_debug.arm64.so b/addons/lua-gdextension/build/libluagdextension.linux.template_debug.arm64.so new file mode 100644 index 0000000..a59827d Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.linux.template_debug.arm64.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.linux.template_debug.x86_32.so b/addons/lua-gdextension/build/libluagdextension.linux.template_debug.x86_32.so new file mode 100644 index 0000000..dc846b3 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.linux.template_debug.x86_32.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.linux.template_debug.x86_64.so b/addons/lua-gdextension/build/libluagdextension.linux.template_debug.x86_64.so new file mode 100644 index 0000000..3337201 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.linux.template_debug.x86_64.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.linux.template_release.arm64.so b/addons/lua-gdextension/build/libluagdextension.linux.template_release.arm64.so new file mode 100644 index 0000000..739d632 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.linux.template_release.arm64.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.linux.template_release.x86_32.so b/addons/lua-gdextension/build/libluagdextension.linux.template_release.x86_32.so new file mode 100644 index 0000000..05004f6 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.linux.template_release.x86_32.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.linux.template_release.x86_64.so b/addons/lua-gdextension/build/libluagdextension.linux.template_release.x86_64.so new file mode 100644 index 0000000..d84c0d1 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.linux.template_release.x86_64.so differ diff --git a/addons/lua-gdextension/build/libluagdextension.macos.template_debug.universal.dylib b/addons/lua-gdextension/build/libluagdextension.macos.template_debug.universal.dylib new file mode 100644 index 0000000..bb44f2c Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.macos.template_debug.universal.dylib differ diff --git a/addons/lua-gdextension/build/libluagdextension.macos.template_release.universal.dylib b/addons/lua-gdextension/build/libluagdextension.macos.template_release.universal.dylib new file mode 100644 index 0000000..b300d95 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.macos.template_release.universal.dylib differ diff --git a/addons/lua-gdextension/build/libluagdextension.web.template_debug.wasm32.nothreads.wasm b/addons/lua-gdextension/build/libluagdextension.web.template_debug.wasm32.nothreads.wasm new file mode 100644 index 0000000..1bc408b Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.web.template_debug.wasm32.nothreads.wasm differ diff --git a/addons/lua-gdextension/build/libluagdextension.web.template_debug.wasm32.wasm b/addons/lua-gdextension/build/libluagdextension.web.template_debug.wasm32.wasm new file mode 100644 index 0000000..fff8081 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.web.template_debug.wasm32.wasm differ diff --git a/addons/lua-gdextension/build/libluagdextension.web.template_release.wasm32.nothreads.wasm b/addons/lua-gdextension/build/libluagdextension.web.template_release.wasm32.nothreads.wasm new file mode 100644 index 0000000..0fd3c0a Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.web.template_release.wasm32.nothreads.wasm differ diff --git a/addons/lua-gdextension/build/libluagdextension.web.template_release.wasm32.wasm b/addons/lua-gdextension/build/libluagdextension.web.template_release.wasm32.wasm new file mode 100644 index 0000000..e8a84c3 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.web.template_release.wasm32.wasm differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.dll b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.dll new file mode 100644 index 0000000..d57050e Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.dll differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.exp b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.exp new file mode 100644 index 0000000..2ff9836 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.exp differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.lib b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.lib new file mode 100644 index 0000000..e549fb5 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.arm64.lib differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.dll b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.dll new file mode 100644 index 0000000..10417dc Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.dll differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.exp b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.exp new file mode 100644 index 0000000..0c75dff Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.exp differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.lib b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.lib new file mode 100644 index 0000000..396c0aa Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_32.lib differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.dll b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.dll new file mode 100644 index 0000000..3936dcb Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.dll differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.exp b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.exp new file mode 100644 index 0000000..cddcfcc Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.exp differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.lib b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.lib new file mode 100644 index 0000000..f9b1f28 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_debug.x86_64.lib differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.dll b/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.dll new file mode 100644 index 0000000..65a212e Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.dll differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.exp b/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.exp new file mode 100644 index 0000000..b500dcb Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.exp differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.lib b/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.lib new file mode 100644 index 0000000..811c372 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.arm64.lib differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.dll b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.dll new file mode 100644 index 0000000..df29316 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.dll differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.exp b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.exp new file mode 100644 index 0000000..5527777 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.exp differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.lib b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.lib new file mode 100644 index 0000000..9e791b6 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_32.lib differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.dll b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.dll new file mode 100644 index 0000000..f4fae59 Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.dll differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.exp b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.exp new file mode 100644 index 0000000..4ce95fa Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.exp differ diff --git a/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.lib b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.lib new file mode 100644 index 0000000..dc747ab Binary files /dev/null and b/addons/lua-gdextension/build/libluagdextension.windows.template_release.x86_64.lib differ diff --git a/addons/lua-gdextension/icon.png b/addons/lua-gdextension/icon.png new file mode 100644 index 0000000..759b48a Binary files /dev/null and b/addons/lua-gdextension/icon.png differ diff --git a/addons/lua-gdextension/icon.png.import b/addons/lua-gdextension/icon.png.import new file mode 100644 index 0000000..fb41eac --- /dev/null +++ b/addons/lua-gdextension/icon.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cih6ia8rwpfa3" +path="res://.godot/imported/icon.png-a1b6b69ff83c17f55db0a93e5e3a4f5d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/lua-gdextension/icon.png" +dest_files=["res://.godot/imported/icon.png-a1b6b69ff83c17f55db0a93e5e3a4f5d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/lua-gdextension/lua_repl.gd b/addons/lua-gdextension/lua_repl.gd new file mode 100644 index 0000000..2a945a3 --- /dev/null +++ b/addons/lua-gdextension/lua_repl.gd @@ -0,0 +1,134 @@ +# Copyright (C) 2025 Gil Barbosa Reis. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the “Software”), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends Node + +@onready var _output: RichTextLabel = $Output +@onready var _input: LineEdit = $Footer/Input +@onready var _history_popup: PopupMenu = $Header/HistoryButton.get_popup() +var _lua: LuaState +var _history = PackedStringArray() +var _current_history = 0 + + +func _ready(): + _history_popup.about_to_popup.connect(_on_history_popup_about_to_popup) + _history_popup.id_pressed.connect(_on_history_popup_id_pressed) + reset() + + +func reset(): + _lua = LuaState.new() + _lua.open_libraries() + _lua.registry.print = _printn + _lua.do_string(r"print = function(...) debug.getregistry().print(table.concat({...}, '\t')) end") + + _history.clear() + _current_history = 0 + clear() + + +func do_string(text: String): + text = text.strip_edges() + if text.is_empty(): + return + + _history.append(text) + _current_history = _history.size() + _input.clear() + _printn(text) + + # support for "= value" idiom from Lua 5.1 REPL + text.trim_prefix("=") + + var result = _lua.do_string("return " + text) + if result is LuaError: + result = _lua.do_string(text) + + if result is LuaError: + _print_error(result.message) + else: + _printn("Out[%d]: %s" % [_current_history, result]) + _prompt() + + +func clear(): + _output.clear() + _prompt() + + +func set_history(index: int): + if index < 0 or index >= _history.size(): + return + + _current_history = index + var text = _history[index] + _input.text = text + _input.caret_column = text.length() + + +func _prompt(): + _print("\nIn [%d]: " % [_current_history + 1]) + + +func _print(msg: String): + self._output.add_text(msg) + + +func _printn(msg: String): + _print(msg) + _print("\n") + + +func _print_error(msg: String): + var color: Color = EditorInterface.get_editor_settings().get_setting("text_editor/theme/highlighting/brace_mismatch_color") + self._output.append_text("[color=%s]%s[/color]\n" % [color.to_html(), msg.replace("[", "[lb]")]) + + +func _on_history_popup_about_to_popup(): + _history_popup.clear() + for line in _history: + _history_popup.add_item(line) + + +func _on_history_popup_id_pressed(id: int): + set_history(id) + + +func _on_input_text_submitted(new_text: String): + do_string(new_text) + + +func _on_run_button_pressed(): + do_string(_input.text) + + +func _on_input_gui_input(event: InputEvent): + var key_event = event as InputEventKey + if not key_event or not key_event.pressed: + return + + if key_event.keycode == KEY_UP: + set_history(_current_history - 1) + get_viewport().set_input_as_handled() + elif key_event.keycode == KEY_DOWN: + set_history(_current_history + 1) + get_viewport().set_input_as_handled() diff --git a/addons/lua-gdextension/lua_repl.gd.uid b/addons/lua-gdextension/lua_repl.gd.uid new file mode 100644 index 0000000..7626d98 --- /dev/null +++ b/addons/lua-gdextension/lua_repl.gd.uid @@ -0,0 +1 @@ +uid://bjod0yq2efea8 diff --git a/addons/lua-gdextension/lua_repl.tscn b/addons/lua-gdextension/lua_repl.tscn new file mode 100644 index 0000000..60c8c9c --- /dev/null +++ b/addons/lua-gdextension/lua_repl.tscn @@ -0,0 +1,59 @@ +[gd_scene load_steps=2 format=3 uid="uid://4lq5s4lnqg8c"] + +[ext_resource type="Script" uid="uid://bjod0yq2efea8" path="res://addons/lua-gdextension/lua_repl.gd" id="1_gf8ka"] + +[node name="LuaRepl" type="VBoxContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_gf8ka") + +[node name="Header" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="Title" type="Label" parent="Header"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Lua REPL" + +[node name="HistoryButton" type="MenuButton" parent="Header"] +layout_mode = 2 +text = "History" +flat = false + +[node name="ResetButton" type="Button" parent="Header"] +layout_mode = 2 +tooltip_text = "Reset the Lua environment and REPL history" +text = "Reset" + +[node name="ClearButton" type="Button" parent="Header"] +layout_mode = 2 +tooltip_text = "Clear the output text" +text = "Clear" + +[node name="Output" type="RichTextLabel" parent="."] +layout_mode = 2 +size_flags_vertical = 3 +focus_mode = 2 +scroll_following = true +selection_enabled = true + +[node name="Footer" type="HBoxContainer" parent="."] +layout_mode = 2 + +[node name="Input" type="LineEdit" parent="Footer"] +layout_mode = 2 +size_flags_horizontal = 3 +keep_editing_on_text_submit = true + +[node name="RunButton" type="Button" parent="Footer"] +layout_mode = 2 +text = "Run" + +[connection signal="pressed" from="Header/ResetButton" to="." method="reset"] +[connection signal="pressed" from="Header/ClearButton" to="." method="clear"] +[connection signal="gui_input" from="Footer/Input" to="." method="_on_input_gui_input"] +[connection signal="text_submitted" from="Footer/Input" to="." method="_on_input_text_submitted"] +[connection signal="pressed" from="Footer/RunButton" to="." method="_on_run_button_pressed"] diff --git a/addons/lua-gdextension/luagdextension.gdextension b/addons/lua-gdextension/luagdextension.gdextension new file mode 100644 index 0000000..305ca9f --- /dev/null +++ b/addons/lua-gdextension/luagdextension.gdextension @@ -0,0 +1,45 @@ +[configuration] +entry_symbol = "luagdextension_entrypoint" +compatibility_minimum = "4.4" +reloadable = true + +[libraries] +macos.debug = "build/libluagdextension.macos.template_debug.universal.dylib" +macos.release = "build/libluagdextension.macos.template_release.universal.dylib" +ios.debug = "build/libluagdextension.ios.template_debug.universal.xcframework" +ios.release = "build/libluagdextension.ios.template_release.universal.xcframework" +windows.debug.x86_32 = "build/libluagdextension.windows.template_debug.x86_32.dll" +windows.release.x86_32 = "build/libluagdextension.windows.template_release.x86_32.dll" +windows.debug.x86_64 = "build/libluagdextension.windows.template_debug.x86_64.dll" +windows.release.x86_64 = "build/libluagdextension.windows.template_release.x86_64.dll" +windows.debug.arm64 = "build/libluagdextension.windows.template_debug.arm64.dll" +windows.release.arm64 = "build/libluagdextension.windows.template_release.arm64.dll" +linux.debug.x86_32 = "build/libluagdextension.linux.template_debug.x86_32.so" +linux.release.x86_32 = "build/libluagdextension.linux.template_release.x86_32.so" +linux.debug.x86_64 = "build/libluagdextension.linux.template_debug.x86_64.so" +linux.release.x86_64 = "build/libluagdextension.linux.template_release.x86_64.so" +linux.debug.arm64 = "build/libluagdextension.linux.template_debug.arm64.so" +linux.release.arm64 = "build/libluagdextension.linux.template_release.arm64.so" +android.debug.x86_32 = "build/libluagdextension.android.template_debug.x86_32.so" +android.release.x86_32 = "build/libluagdextension.android.template_release.x86_32.so" +android.debug.x86_64 = "build/libluagdextension.android.template_debug.x86_64.so" +android.release.x86_64 = "build/libluagdextension.android.template_release.x86_64.so" +android.debug.arm32 = "build/libluagdextension.android.template_debug.arm32.so" +android.release.arm32 = "build/libluagdextension.android.template_release.arm32.so" +android.debug.arm64 = "build/libluagdextension.android.template_debug.arm64.so" +android.release.arm64 = "build/libluagdextension.android.template_release.arm64.so" +web.debug.threads.wasm32 = "build/libluagdextension.web.template_debug.wasm32.wasm" +web.release.threads.wasm32 = "build/libluagdextension.web.template_release.wasm32.wasm" +web.debug.wasm32 = "build/libluagdextension.web.template_debug.wasm32.nothreads.wasm" +web.release.wasm32 = "build/libluagdextension.web.template_release.wasm32.nothreads.wasm" + +[icons] +LuaScript = "LuaScript_icon.svg" + +[dependencies] +ios.debug = { + "build/libgodot-cpp.ios.template_debug.universal.xcframework": "" +} +ios.release = { + "build/libgodot-cpp.ios.template_release.universal.xcframework": "" +} diff --git a/addons/lua-gdextension/luagdextension.gdextension.uid b/addons/lua-gdextension/luagdextension.gdextension.uid new file mode 100644 index 0000000..8a53780 --- /dev/null +++ b/addons/lua-gdextension/luagdextension.gdextension.uid @@ -0,0 +1 @@ +uid://d3k6wyksykaj2 diff --git a/addons/lua-gdextension/plugin.cfg b/addons/lua-gdextension/plugin.cfg new file mode 100644 index 0000000..d425723 --- /dev/null +++ b/addons/lua-gdextension/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Lua GDExtension" +description="Tools for Lua GDExtension: REPL tab" +author="gilzoide" +version="0.6.0" +script="plugin.gd" diff --git a/addons/lua-gdextension/plugin.gd b/addons/lua-gdextension/plugin.gd new file mode 100644 index 0000000..11eeb3a --- /dev/null +++ b/addons/lua-gdextension/plugin.gd @@ -0,0 +1,37 @@ +# Copyright (C) 2025 Gil Barbosa Reis. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the “Software”), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +@tool +extends EditorPlugin + + +var _lua_repl: Control + + +func _enter_tree(): + _lua_repl = preload("lua_repl.tscn").instantiate() + add_control_to_bottom_panel(_lua_repl, "Lua REPL") + + +func _exit_tree(): + if _lua_repl: + remove_control_from_bottom_panel(_lua_repl) + _lua_repl.queue_free() + _lua_repl = null diff --git a/addons/lua-gdextension/plugin.gd.uid b/addons/lua-gdextension/plugin.gd.uid new file mode 100644 index 0000000..15bcde4 --- /dev/null +++ b/addons/lua-gdextension/plugin.gd.uid @@ -0,0 +1 @@ +uid://cwp2hwkpbitgx diff --git a/assetcfg.json b/assetcfg.json new file mode 100644 index 0000000..4fb0aa7 --- /dev/null +++ b/assetcfg.json @@ -0,0 +1,5 @@ +{ + "grass":{"allowRandRot":true,"textname":"grass.png","collidable":false}, + "wood":{"allowRandRot":false,"textname":"wood.png","collidable":false}, + "woodbarrier":{"allowRandRot":false,"textname":"wood.png","collidable":true}, +} diff --git a/code/lua_env.lua b/code/lua_env.lua new file mode 100644 index 0000000..2be0db8 --- /dev/null +++ b/code/lua_env.lua @@ -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 diff --git a/code/lua_env.lua.uid b/code/lua_env.lua.uid new file mode 100644 index 0000000..d1edc12 --- /dev/null +++ b/code/lua_env.lua.uid @@ -0,0 +1 @@ +uid://c01rdot180cne diff --git a/code/player.gd b/code/player.gd new file mode 100644 index 0000000..9fdebc5 --- /dev/null +++ b/code/player.gd @@ -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)) diff --git a/code/player.gd.uid b/code/player.gd.uid new file mode 100644 index 0000000..5360c04 --- /dev/null +++ b/code/player.gd.uid @@ -0,0 +1 @@ +uid://cc4y82skj2obl diff --git a/code/world.gd b/code/world.gd new file mode 100644 index 0000000..9c110d7 --- /dev/null +++ b/code/world.gd @@ -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) diff --git a/code/world.gd.uid b/code/world.gd.uid new file mode 100644 index 0000000..935f3ca --- /dev/null +++ b/code/world.gd.uid @@ -0,0 +1 @@ +uid://be6h32vns32hm diff --git a/default/aud/epik.ogg b/default/aud/epik.ogg new file mode 100644 index 0000000..f716f22 Binary files /dev/null and b/default/aud/epik.ogg differ diff --git a/default/aud/epik.ogg.import b/default/aud/epik.ogg.import new file mode 100644 index 0000000..4d2ed2c --- /dev/null +++ b/default/aud/epik.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://s3dk5wcpewdd" +path="res://.godot/imported/epik.ogg-f995cde1eaba93014784f659c6e89a2b.oggvorbisstr" + +[deps] + +source_file="res://default/aud/epik.ogg" +dest_files=["res://.godot/imported/epik.ogg-f995cde1eaba93014784f659c6e89a2b.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/default/aud/pam.wav b/default/aud/pam.wav new file mode 100644 index 0000000..56deaf4 Binary files /dev/null and b/default/aud/pam.wav differ diff --git a/default/aud/pam.wav.import b/default/aud/pam.wav.import new file mode 100644 index 0000000..452c57b --- /dev/null +++ b/default/aud/pam.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://bbirs8atmuo1k" +path="res://.godot/imported/pam.wav-45b7a37afabf841cc9a8d9efb2a9febf.sample" + +[deps] + +source_file="res://default/aud/pam.wav" +dest_files=["res://.godot/imported/pam.wav-45b7a37afabf841cc9a8d9efb2a9febf.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/default/aud/pew.ogg b/default/aud/pew.ogg new file mode 100644 index 0000000..eaad754 Binary files /dev/null and b/default/aud/pew.ogg differ diff --git a/default/aud/pew.ogg.import b/default/aud/pew.ogg.import new file mode 100644 index 0000000..dd3eadb --- /dev/null +++ b/default/aud/pew.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://vv4jb2e8f1uo" +path="res://.godot/imported/pew.ogg-c255adcf287c8d5e866c681e2e1494e8.oggvorbisstr" + +[deps] + +source_file="res://default/aud/pew.ogg" +dest_files=["res://.godot/imported/pew.ogg-c255adcf287c8d5e866c681e2e1494e8.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/default/aud/walk.ogg b/default/aud/walk.ogg new file mode 100644 index 0000000..4cfb240 Binary files /dev/null and b/default/aud/walk.ogg differ diff --git a/default/aud/walk.ogg.import b/default/aud/walk.ogg.import new file mode 100644 index 0000000..fcbc7c9 --- /dev/null +++ b/default/aud/walk.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://bcca08s3kqhkf" +path="res://.godot/imported/walk.ogg-7f398fe415d99884ceb48b13ce0ba4c4.oggvorbisstr" + +[deps] + +source_file="res://default/aud/walk.ogg" +dest_files=["res://.godot/imported/walk.ogg-7f398fe415d99884ceb48b13ce0ba4c4.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/default/aud/wind.ogg b/default/aud/wind.ogg new file mode 100644 index 0000000..a62acb8 Binary files /dev/null and b/default/aud/wind.ogg differ diff --git a/default/aud/wind.ogg.import b/default/aud/wind.ogg.import new file mode 100644 index 0000000..ae56d7b --- /dev/null +++ b/default/aud/wind.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://cpxp5qfgsjwuo" +path="res://.godot/imported/wind.ogg-7e6f4a88ed48e7485fb51c0f247f3a0b.oggvorbisstr" + +[deps] + +source_file="res://default/aud/wind.ogg" +dest_files=["res://.godot/imported/wind.ogg-7e6f4a88ed48e7485fb51c0f247f3a0b.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/default/text/grass.png b/default/text/grass.png new file mode 100644 index 0000000..d6d955b Binary files /dev/null and b/default/text/grass.png differ diff --git a/default/text/grass.png.import b/default/text/grass.png.import new file mode 100644 index 0000000..13cefc5 --- /dev/null +++ b/default/text/grass.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b08pmo4b1vu2v" +path="res://.godot/imported/grass.png-32c0ea7ae306e3e97ce93958a097a086.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://default/text/grass.png" +dest_files=["res://.godot/imported/grass.png-32c0ea7ae306e3e97ce93958a097a086.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/default/text/player-w1.png b/default/text/player-w1.png new file mode 100644 index 0000000..a51bd3a Binary files /dev/null and b/default/text/player-w1.png differ diff --git a/default/text/player-w1.png.import b/default/text/player-w1.png.import new file mode 100644 index 0000000..e4953bd --- /dev/null +++ b/default/text/player-w1.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bndf6ulk38x8w" +path="res://.godot/imported/player-w1.png-2d83ddef195d31d2854854be7b5eb929.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://default/text/player-w1.png" +dest_files=["res://.godot/imported/player-w1.png-2d83ddef195d31d2854854be7b5eb929.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/default/text/player-w2.png b/default/text/player-w2.png new file mode 100644 index 0000000..ea2061f Binary files /dev/null and b/default/text/player-w2.png differ diff --git a/default/text/player-w2.png.import b/default/text/player-w2.png.import new file mode 100644 index 0000000..a7c31e2 --- /dev/null +++ b/default/text/player-w2.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://klft47dygepk" +path="res://.godot/imported/player-w2.png-63721d009b7ff1c6b9572befdcde63c8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://default/text/player-w2.png" +dest_files=["res://.godot/imported/player-w2.png-63721d009b7ff1c6b9572befdcde63c8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/default/text/wood.png b/default/text/wood.png new file mode 100644 index 0000000..15839a3 Binary files /dev/null and b/default/text/wood.png differ diff --git a/default/text/wood.png.import b/default/text/wood.png.import new file mode 100644 index 0000000..26cb9fe --- /dev/null +++ b/default/text/wood.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://chmxh4w36byso" +path="res://.godot/imported/wood.png-02ad6b4a9c2c95bcd439d5ff9fe93251.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://default/text/wood.png" +dest_files=["res://.godot/imported/wood.png-02ad6b4a9c2c95bcd439d5ff9fe93251.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/export_presets.cfg b/export_presets.cfg new file mode 100644 index 0000000..e48234e --- /dev/null +++ b/export_presets.cfg @@ -0,0 +1,45 @@ +[preset.0] + +name="Web" +platform="Web" +runnable=true +advanced_options=true +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="../../../scratch/exports/3/WeedMaker.html" +patches=PackedStringArray() +encryption_include_filters="" +encryption_exclude_filters="" +seed=0 +encrypt_pck=false +encrypt_directory=false +script_export_mode=2 + +[preset.0.options] + +custom_template/debug="/scratch/godot.web.template_debug.wasm32.dlink.zip" +custom_template/release="/scratch/godot.web.template_release.wasm32.dlink.zip" +variant/extensions_support=true +variant/thread_support=true +vram_texture_compression/for_desktop=true +vram_texture_compression/for_mobile=false +html/export_icon=true +html/custom_html_shell="" +html/head_include="" +html/canvas_resize_policy=2 +html/focus_canvas_on_start=true +html/experimental_virtual_keyboard=false +progressive_web_app/enabled=false +progressive_web_app/ensure_cross_origin_isolation_headers=true +progressive_web_app/offline_page="" +progressive_web_app/display=1 +progressive_web_app/orientation=0 +progressive_web_app/icon_144x144="" +progressive_web_app/icon_180x180="" +progressive_web_app/icon_512x512="" +progressive_web_app/background_color=Color(0, 0, 0, 1) +threads/emscripten_pool_size=8 +threads/godot_pool_size=4 diff --git a/game.tscn b/game.tscn new file mode 100644 index 0000000..cf6947d --- /dev/null +++ b/game.tscn @@ -0,0 +1,76 @@ +[gd_scene load_steps=7 format=3 uid="uid://dx3edvokvnhss"] + +[ext_resource type="Script" uid="uid://be6h32vns32hm" path="res://code/world.gd" id="1_e2o6t"] +[ext_resource type="Script" uid="uid://cc4y82skj2obl" path="res://code/player.gd" id="1_feb5d"] +[ext_resource type="Texture2D" uid="uid://bndf6ulk38x8w" path="res://default/text/player-w1.png" id="3_feb5d"] +[ext_resource type="AudioStream" uid="uid://bcca08s3kqhkf" path="res://default/aud/walk.ogg" id="4_fc0e3"] +[ext_resource type="Script" uid="uid://c01rdot180cne" path="res://code/lua_env.lua" id="5_7jktm"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_feb5d"] + +[node name="Node2D" type="Node2D"] +metadata/resourcepack = "default" + +[node name="cam" type="Camera2D" parent="."] + +[node name="World" type="Area2D" parent="."] +script = ExtResource("1_e2o6t") +metadata/world = "world" + +[node name="Player" type="CharacterBody2D" parent="." groups=["player"]] +script = ExtResource("1_feb5d") +metadata/canWalk = true + +[node name="Sprite2D" type="Sprite2D" parent="Player"] +scale = Vector2(3, 3) +texture = ExtResource("3_feb5d") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"] +scale = Vector2(2.3, 2.3) +shape = SubResource("RectangleShape2D_feb5d") + +[node name="Walk" type="AudioStreamPlayer" parent="Player"] +stream = ExtResource("4_fc0e3") +volume_db = -5.0 + +[node name="Fader" type="CanvasLayer" parent="."] + +[node name="ColorRect" type="ColorRect" parent="Fader"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 2 +size_flags_vertical = 0 +color = Color(0, 0, 0, 1) + +[node name="LuaEnv" type="Node" parent="."] +script = ExtResource("5_7jktm") + +[node name="UI" type="CanvasLayer" parent="."] + +[node name="bg" type="ColorRect" parent="UI"] +anchors_preset = -1 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -9.0 +grow_horizontal = 2 +grow_vertical = 0 +size_flags_horizontal = 2 +size_flags_vertical = 0 +color = Color(0, 0, 0.48235294, 0.5529412) + +[node name="RichTextLabel" type="RichTextLabel" parent="UI/bg"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_font_sizes/normal_font_size = 50 +theme_override_font_sizes/bold_font_size = 50 +theme_override_font_sizes/bold_italics_font_size = 50 +theme_override_font_sizes/italics_font_size = 50 +theme_override_font_sizes/mono_font_size = 50 diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..3513d84 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dmbavwbdqk8qm" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..7b2cd53 --- /dev/null +++ b/project.godot @@ -0,0 +1,62 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[animation] + +compatibility/default_parent_skeleton_in_mesh_instance_3d=true + +[application] + +config/name="WeedMaker" +run/main_scene="uid://dx3edvokvnhss" +config/features=PackedStringArray("4.6", "GL Compatibility") +boot_splash/bg_color=Color(0, 0, 0, 1) +config/icon="res://icon.svg" + +[editor_plugins] + +enabled=PackedStringArray("res://addons/lua-gdextension/plugin.cfg") + +[input] + +moveup={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +movedown={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) +] +} +moveleft={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) +] +} +moveright={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) +] +} + +[rendering] + +textures/canvas_textures/default_texture_filter=0 +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" diff --git a/worlds/exported_world.json b/worlds/exported_world.json new file mode 100644 index 0000000..5cc379a --- /dev/null +++ b/worlds/exported_world.json @@ -0,0 +1,195 @@ +{ + "width": 20, + "height": 15, + "fill": "grass", + "pspawn": { + "w": 1, + "h": 1 + }, + "features": [ + { + "w": 8, + "h": 5, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 11, + "h": 5, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 13, + "h": 5, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 16, + "h": 5, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 18, + "h": 5, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 8, + "h": 6, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 11, + "h": 6, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 13, + "h": 6, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 14, + "h": 6, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 15, + "h": 6, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 16, + "h": 6, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 8, + "h": 7, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 11, + "h": 7, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 13, + "h": 7, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 16, + "h": 7, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 18, + "h": 7, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 13, + "h": 8, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 16, + "h": 8, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 18, + "h": 8, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 8, + "h": 9, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 11, + "h": 9, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 9, + "h": 10, + "t": { + "thing": "woodbarrier", + "action": "none" + } + }, + { + "w": 10, + "h": 10, + "t": { + "thing": "woodbarrier", + "action": "none" + } + } + ] +} \ No newline at end of file diff --git a/worlds/totr.json b/worlds/totr.json new file mode 100644 index 0000000..b2c7810 --- /dev/null +++ b/worlds/totr.json @@ -0,0 +1,11 @@ +{ + "fill":"wood", + "height":50, + "width":50, + "features":[ + {"w":5,"h":2,"t":{"thing":"grass","action":"tp","target_world":"world"}}, + {"w":8,"h":2,"t":{"thing":"grass","action":"tp","target_world":"exported_world"}}, + {"w":5,"h":5,"t":{"thing":"grass","action":"none"}} + ], + "pspawn":{"w":5,"h":5} +} diff --git a/worlds/world.json b/worlds/world.json new file mode 100644 index 0000000..d8f976d --- /dev/null +++ b/worlds/world.json @@ -0,0 +1,12 @@ +{ + "fill":"grass", + "height":50, + "width":50, + "features":[ + {"w":5,"h":2,"t":{"thing":"wood","action":"none"}}, + {"w":5,"h":5,"t":{"thing":"woodbarrier","action":"none"}}, + {"w":15,"h":15,"t":{"thing":"wood","action":"tp","target_world":"totr"}} + ], + "pspawn":{"w":14,"h":15}, + "mapscript":true +} diff --git a/worlds/world.lua b/worlds/world.lua new file mode 100644 index 0000000..9b2f0f0 --- /dev/null +++ b/worlds/world.lua @@ -0,0 +1,6 @@ +local arg = {...} +local node = arg[1] + +print("loo a") +print(node.name) +node:ui_showmesg("hellao") diff --git a/worlds/world.lua.uid b/worlds/world.lua.uid new file mode 100644 index 0000000..43de547 --- /dev/null +++ b/worlds/world.lua.uid @@ -0,0 +1 @@ +uid://dvyu2wxyj5ibu