Git Product home page Git Product logo

swiftgodotkit's Introduction

SwiftGodotKit provides a way of embedding Godot into an existing Swift application and driving Godot from Swift, without having to use an extension.

Take a look at the TrivialSample here to see how it works.

You will need Swift 5.9 for this (Xcode 15 release candidate will do).

Reference this Package.swift and then you can write a simple program like this:

import Foundation
import SwiftGodot
import SwiftGodotKit

func loadScene (scene: SceneTree) {
    let rootNode = Node3D()
    let camera = Camera3D ()
    camera.current = true
    camera.position = Vector3(x: 0, y: 0, z: 2)
    
    rootNode.addChild(node: camera)
    
    func makeCuteNode (_ pos: Vector3) -> Node {
        let n = SpinningCube()
        n.position = pos
        return n
    }
    rootNode.addChild(node: makeCuteNode(Vector3(x: 1, y: 1, z: 1)))
    rootNode.addChild(node: makeCuteNode(Vector3(x: -1, y: -1, z: -1)))
    rootNode.addChild(node: makeCuteNode(Vector3(x: 0, y: 1, z: 1)))
    scene.root?.addChild(node: rootNode)
}


class SpinningCube: Node3D {
    required init (nativeHandle: UnsafeRawPointer) {
        super.init (nativeHandle: nativeHandle)
    }
    
    required init () {
        super.init ()
        let meshRender = MeshInstance3D()
        meshRender.mesh = BoxMesh()
        addChild(node: meshRender)
    }
    
    override func _input (event: InputEvent) {
        guard event.isPressed () && !event.isEcho () else { return }
        print ("SpinningCube: event: isPressed ")
    }
    
    public override func _process(delta: Double) {
        rotateY(angle: delta)
    }
}

func registerTypes (level: GDExtension.InitializationLevel) {
    switch level {
    case .scene:
        register (type: SpinningCube.self)
    default:
        break
    }
}

runGodot(args: [], initHook: registerTypes, loadScene: loadScene, loadProjectSettings: { settings in })

A standalone sample that you can use as a starting point is available here, when used as SwiftPM:

https://github.com/migueldeicaza/SwiftGodotKit/tree/main/StandaloneExample

Sausage Making Details

If you want to compile your own version of libgodot.framework, follow these instructions

Check out SwiftGodot and SwiftGodotKit as peers as well as a version of Godot suitable to be used as a library:

git clone [email protected]:migueldeicaza/SwiftGodot
git clone [email protected]:migueldeicaza/SwiftGodotKit
git clone [email protected]:migueldeicaza/libgodot

Compile libgodot, this sample shows how I do this myself, but you could have different versions

cd libgodot
scons target=template_debug dev_build=yes library_type=shared_library debug_symbols=yes 

The above will produce the binary that you want, then create an xcframework out of it, using the script in SwiftGodot (a peer to this repository):

cd ../SwiftGodot/scripts
sh -x make-libgodot.xcframework ../../SwiftGodot ../../libgodot /tmp/

Then you can reference that version of the libgodot.xcframework

Details

This relies currently on the LibGodot patch that is currently pending approval:

https://github.com/godotengine/godot/pull/72883

For your convenience, I have packaged the embeddable Godot for Mac as an xcframework so merely taking a dependency on this package should get everything that you need

swiftgodotkit's People

Contributors

estevanbr avatar migueldeicaza avatar pcbeard avatar tishin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftgodotkit's Issues

4.2 on Mac: failure

In the 4.2 branch, I have not managed to get the libgodot powered by 4.2 to work at all.

It produces Vulkan errors with swap_buffers as soon as it starts up, even if running as a standalone does not have this problem.

Compile for iOS

Hello!
Thank you so much for this package, I've been able to launch the sample demo on mac and start doing my own swift game with godot engine!

However, if I try to compile it for iOS it gives the error

While building for iOS Simulator, no library for this platform was found in 
'/Users/crypto/Library/Developer/Xcode/DerivedData/godotest2-gpffnlaboxbwjxfsoygydhlmxanz/SourcePackages/artifacts/swiftgodotkit/libgodot/libgodot.xcframework:1:1 While building for iOS Simulator, no library for this platform was found in '/Users/crypto/Library/Developer/Xcode/DerivedData/godotest2-gpffnlaboxbwjxfsoygydhlmxanz/SourcePackages/artifacts/swiftgodotkit/libgodot/libgodot.xcframework'.

I'm really new to this so I have no idea on how to fix that

And if I'm not wrong, will it be possible to export my game to windows/android as well even if I code with swift?

Thanks!

Cant load resources

I'm trying to load resources and it seems it is not working

I tried different ways, but always same error
Full path, with the file referenced as as folder

        let path = Bundle.main.path(forResource: "JandaManateeSolid", ofType: "ttf", inDirectory: "Assets/Fonts")!
        let font:Font? = GD.load(path: path)
ERROR: No loader found for resource: /Users/crypto/Library/Developer/Xcode/DerivedData/godotest2-gpffnlaboxbwjxfsoygydhlmxanz/Build/Products/Debug/godotest2.app/Contents/Resources/Assets/Fonts/JandaManateeSolid.ttf (expected type: )
at: _load (core/io/resource_loader.cpp:281)

Or added as a reference group into the project as well, and event trying to use the res:// syntax, all with same error

        let font:Font? = GD.load(path: "res://" + path)
        let font:Font? = GD.load(path: "res://JandaManateeSolid.ttf)

Unable to replicate libgodot xcframework configuration

I'm trying to make an update for libgodot.xcframework based on 4.1.3 release of Godot, but I can't replicate the current xcframework architecture-wise.
The current release has a universal arm64_x86_64 dylib inside, but when I compile libgodot using the command from readme:
scons target=template_debug dev_build=yes library_type=shared_library debug_symbols=yes
it makes a dylib only for the architecture of the host (in my current case - arm64, haven't checked it on an Intel Mac).

Godot doesn't seem to support arm64_x86_64:

scons target=template_debug dev_build=yes library_type=shared_library debug_symbols=yes arch=arm64_x86_64
scons: Reading SConscript files ...

scons: *** Invalid value for option arch: arm64_x86_64.  Valid values are: ['auto', 'x86_32', 'x86_64', 'arm32', 'arm64', 'rv64', 'ppc32', 'ppc64', 'wasm32']

Making separate builds for arm64 and x86_64 will result in a different xcframework configuration, and make-libgodot.framework doesn't support multiple dylibs, so I don't think that's how the current release was made.

Am I missing something here?

Project settings are not applied

Firstly, thanks for this project. I'm having a lot of fun with it.

As the issue title states, project settings are not applied. Specifically the loadProjectSettings callback in runGodot is never called.

I'm pretty sure this is because in SwiftGodotKit.swift the call to libgodot_bind where projectSettingsBind is a parameter has been commented out. I'll submit a PR to restore this, but I thought I'd raise an issue for discussion in case it was commented out for a reason.

Here's a minimal example to show the setting is never applied and the print statements are never printed:

import Foundation
import SwiftGodotKit
import SwiftGodot

let SETTING_KEY = "display/window/size/borderless"

func loadScene (scene: SceneTree) {
    let gui = Gui()
    scene.root?.addChild(node: gui)
}

class Gui: Container {
    public required init (nativeHandle: UnsafeRawPointer) {
        super.init (nativeHandle: nativeHandle)
    }
    
    public required init () {
        super.init ()
    }

    public override func _ready() {
        let setting = ProjectSettings.shared.getSetting(name: SETTING_KEY, defaultValue: Variant("junk"))
        print("Setting: ", Bool(setting)!)
    }
}

func registerTypes (level: GDExtension.InitializationLevel) {
    switch level {
    case .scene:
        register (type: Gui.self)
    default:
        break
    }
}

@main
class Startup {
    static func main () {
        runGodot(args: [], initHook: registerTypes, loadScene: loadScene, loadProjectSettings: { settings in
            print("Hello world")
            GD.print("Hello godot")
            settings.setSetting(name: SETTING_KEY, value: Variant(true))
        })
    }
}

Noob question - how to run the TrivialSample

If I do swift main.swift then I get:

main.swift:10:8: error: no such module 'SwiftGodot'
import SwiftGodot

Do I create a Package.swift within the same folder or did I get this wrong completely?

Thanks!

Can't run it in macOS

I am using the main branch of the project exactly as explained in https://migueldeicaza.github.io/SwiftGodotDocs/tutorials/swiftgodot/using-swift-godot-kit. Whenever I try to run the project it crashes with the error Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1984150f8) and these logs in the console:

  • Message from debugger: killed
  • Logging Error: Failed to initialize logging system. Log messages may be missing. If this issue persists, try setting IDEPreferLogStreaming=YES in the active scheme actions environment variables.
  • Program ended with exit code: 9

Current macOS version 14.2.1 and Xcode 15.1 with Swift 5.9.2 (5.9.2.2.56).

PackedScene always seems to leak

In my bouncing ball simulator, I load my audio files like this:

@Godot
class Simulation: Node {
    var bouncesNode: Node?
    var bounces: [AudioStreamPlayer] = []

    func loadBounces() {
        #if false
        // This version loads the wav resources and creates the player nodes.
        // It does not leak any resources.
        let node = Node()
        bouncesNode = node
        for i in 0...5 {
            if let stream: AudioStream = GD.load(path: "res://bounce\(i).wav") {
                let bounce = AudioStreamPlayer()
                bounce.stream = stream
                stream.unreference()
                bounces.append(bounce)
                node.addChild(node: bounce)
            }
        }
        addChild(node: node)
        #else
        // This version instantiates the nodes from packed scene "res://bounces.tscn".
        if let bouncesScene: PackedScene = GD.load(path: "res://bounces.tscn") {
            if let node: Node = bouncesScene.instantiate() {
                bouncesNode = node
                addChild(node: node)
                self.bounces = node.getChildren().compactMap { $0 as? AudioStreamPlayer }
            }
            bouncesScene.unreference()
        }
        #endif
    }

    func stopBounces() {
        for bounce in bounces {
            if bounce.isPlaying() {
                bounce.stop()
            }
        }
        bounces.removeAll()
        if let bouncesNode {
            bouncesNode.queueFree()
            self.bouncesNode = nil
        }
    }
}

If I use the first code path, where I load the audio streams using GD.load() and create AudioStreamPlayer nodes, when my program terminates, there are no leaks resported. However, if I use the approach where I load a scene that contains the same nodes, I always see these resource leaks:

WARNING: ObjectDB instances leaked at exit (run with --verbose for details).
at: cleanup (core/object/object.cpp:2208)
�[1;33mWARNING:�[0;93m ObjectDB instances leaked at exit (run with --verbose for details).
�[0;90m     at: cleanup (core/object/object.cpp:2208)�[0m
Leaked instance: AudioStreamWAV:-9222522664122317664 - Resource path: res://bounce0.wav
Leaked instance: AudioStreamWAV:-9222519365587434334 - Resource path: res://bounce1.wav
Leaked instance: AudioStreamWAV:-9222516067052551004 - Resource path: res://bounce2.wav
Leaked instance: AudioStreamWAV:-9222512768517667674 - Resource path: res://bounce3.wav
Leaked instance: AudioStreamWAV:-9222509469982784344 - Resource path: res://bounce4.wav
Leaked instance: PackedScene:-9222505621692087127 - Resource path: res://bounces.tscn
Leaked instance: AudioStreamWAV:-9222506171447901014 - Resource path: res://bounce5.wav
Leaked instance: SceneState:-9222505071936273237
Leaked instance: AudioStreamPlaybackWAV:-9222318154959551312
Hint: Leaked instances typically happen when nodes are removed from the scene tree (with `remove_child()`) but not freed (with `free()` or `queue_free()`).

This seems to indicate that the PackedScene is leaking. I've tried freeing it explicitly, but it doesn't seem to respond to the .free() message.

Compiling for Windows

Hi @migueldeicaza, your work is amazing, and I'm very much enjoying exploring SwiftGodot/SwiftGodotKit.

I've had some success using SwiftGodotKit to start a new project on MacOS. Driving Godot from Swift is fantastic. However, I need the project to run on Windows as well.

It seems that the core issue preventing use of SwiftGodotKit on Windows right now is the lack of a Windows version of libgodot. Might the solution be as simple as compiling libgodot on Windows as a DLL, and using it in place of the MacOS DyLib, retaining the same umbrella header? If so, I'm game to have a go - But I'm guessing there are some gotchas and nuances I should be aware of before I go down that rabbit hole.

Let me know how I can help.

StandaloneExample fails to build on macOS without removal of `@Godot`

Hi everyone,

While attempting to reproduce a behaviour in a minimal project, I found I was unable to build Standalone Example.

The procedure followed:

  1. Clone SwiftGodotKit fresh
  2. "Trust & Enable" plugins
  3. [Await package resolution]
  4. Build via "Run"

Result:

Build failure, "Unknown attribute 'Godot'".

Run-StandaloneExample-2023.12.28_14-26-32-+1100.xcresult.zip

Screenshot 2023-12-28 at 14 30 43

Curiously, removing @Godot and re-running allows the project to build and run successfully:

Screenshot 2023-12-28 at 14 33 03

Environment:

macOS 14.2
Xcode 15.0.1
Swift version 5.9
Macbook Pro 16 w/ M2 Max

README should specify Swift 5.9 is required

I really want to try this out, but I've run into a bunch of issues.

First, the issues I was able to resolve:

  • As stated in the issue title: The readme should probably specify Swift 5.9 is required
    I first tried to get this working in Xcode 14.3.1, but the swift dependency wouldn't load for me. When I tried to re-import the package, only then did I get an error to this effect.
  • The README should probably also link to the example project. (I found the link in a closed issue.)
  • The example project also contains your Apple Team ID, FWIW. You might want to select "none" from the code signing dropdown and re-zip.

Where I'm stuck right now is with an error on line 9 of main.swift that says No such module 'SwiftGodotKit'.

I think it might be nice to have more detailed instructions on how to get this working in the README. I do also have a lot of questions. For instance, do I need a specific version of Xcode? How about Godot?

install_name_tool

I believe that the libgodot.xcframework needs to have its name changed not to libgodot.dylib, but to @rpath@/libgodot.dylib so that when we link standalone apps it can find the library.

Possible to use with iOS?

Is it possible to use SwiftGodotKit in an iOS project? Would we need to compile libgodot for iOS to get it working?

Issues running Godot demos

Hi @migueldeicaza! Thanks for you work and effort in providing new possibilities for Swift devs. I'm regular iOS dev and I've accidentally saw your live presentation at #GodotCon2023 and was really amazed with what you've developed here.

Everything seems clear for me during tutorials from documentation site and examples running, but I've struggled to go further. As a regular lazy dev I decided to start with some pre-made demo, and migrate it to Swift part by part to start something with. I've tried next demos, which are perfectly running through regular Godot Editor:

For all of them I've used the same setup. First, I've created four Swift executable packages, named SwiftGodotTest, in which I've added SwiftGodot and SwiftGodotKit as dependencies. Then, I've placed four mentioned Godot demo projects (contents of the root project directory, including project.godot files) into Sources/SwiftGodotTest folder of my Swift packages. Resulting packages are looking similar to this:
Screenshot 2024-01-04 at 04 02 36
Here you can see package structure and that it consists only from single main Swift file and regular Godot project files.

For all demos scenes are loaded without errors and game window appears, but all of them were having issues at runtime:

  • Unresponsive mouse - mouse was not tracked when game window appeared, until command-tab out-into back to the app + errors about CursorUIView Service appearing in console (FAULT: <NSRemoteView: 0x11f4192b0 com.apple.TextInputUI.xpc.CursorUIViewService TUICursorUIViewService> determined it was necessary to configure <TUINSWindow: 0x11f4164f0> to support remote view vibrancy);
  • Irregular crash on camera movements ([MTLDebugRenderCommandEncoder setRenderPipelineState:]:1615: failed assertion Set Render Pipeline State Validation The color sample count (1) does not match the renderPipelineState's color sample count (4) The raster sample count (1) does not match the renderPipelineState's raster sample count (4));
  • Surface index out of bounds (ERROR: Index (uint32_t)p_surface = 0 is out of bounds (mesh->surface_count = 0). at: mesh_surface_set_material (servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp:522));
  • Vertex data mismatch (Size of vertex data provided (27816) does not match expected (41724) at: mesh_add_surface);
  • Same visual issue for all demos with rendering (video):
Screenshot 2024-01-04 at 04 39 26

Sorry if my question is not directly related to your Kit development, but is it supported to do such things at all? I mean running Godot projects with GDScripts via SwiftGodotKit package? Or there should be only Swift written files? Shouldn't running from Godot Project file and SwiftGodotKit be equal by result? I will be very thankful if you are able to provide me some ideas or directions in which I can investigate this further.

Firstly I thought, maybe some internal Godot settings are missing when running from Swift package, but then I've dealt with settings callback issue and found out that if I placed project.godot file at package root, settings already should be there, which is true, since I can see difference if I change something through Godot Editor (app's icon for example).

Thanks for your time and patience in advance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.