godot-nim / gdext-nim

Nim for Godot GDExtension. A pure library and a CLI tool.
MIT License
47 stars 5 forks source link

extenstion structure and games vs add-ons #32

Closed insomniacUNDERSCORElemon closed 3 months ago

insomniacUNDERSCORElemon commented 3 months ago

Split from https://github.com/godot-nim/gdextshell/issues/30#issuecomment-2264518883

So, that feature [nimble publish, the reason for more redundancy] will be mostly for extension developers, not game developers.

Particularly as the number of demos increases and as add-on structure changes for nimble publishing.

Even better is a project that uses both structures. I can confirm this works, and have even altered the structure a bit easier to follow on what's required/linked. core/src seems like a sane default for the code (this also means it's not cluttering the root folder) while also being an obvious parallel to the addons folder.

The other name change would be to the .nimble bin line which controls both the entrypoint .nim file and the resulting library file, so that this connection is more obvious.

Also the .gdextension file (much like the .nimble file, which I mention below) can be named anything as long as the editor has been loaded at least once before. There is no need for a user to change the filename. This could have a generic name, especially if it were generated.

I don't think we should bother to define separate extensions made with Nim.

I have suggested a redundant configuration here because, as noted above, it is to be the same configuration as the nimble package

For part of that, I would prefer if a custom .nimble file were not required. Currently it seems the .nimble file name has no other effect, so I'd say it'd make more sense to:

Or tie bin line to .nimble name.

So, that feature will be mostly for extension developers, not game developers. Everything in config.nims is only needed for the build. There is no need to have it in each package.

There is not much distinction when we are here. Solo devs will have to wear both hats, even if they don't plan on publishing an add-on.

I see now that config.nims has flexible loading. Maybe you meant that but it wasn't initially clear.

Setup project wiki page should mention that config.nims is not required per-addon, if missing will load from higher directory EDIT: Not needed as this is no longer in src folder

I'm sorry. I did not understand what this paragraph meant

What I was replying to you misunderstood (but in something relevant to what I was thinking), I mentioned that in the edit. I covered my original meaning above (names) and below is clarifying the other thing I was talking about.

Currently, for the work of defining an add-on to some degree, you don't need to do it again(aside from if you want to rename the folder): it is portable. If I made an FPS meter add-on it could work in any project, and I am perfectly fine with the label node it used being hidden if I delete it (or only needing to delete said node beforehand). This is good, I hope this is not made more tedious.

It'd be nice if class names had that flexibility (at least for the self-created stuff, or some alternative like (re)generating definition lines with renames/new classes), though I'll admit that some of that feeling is influenced here by the 14 $projectname values that the current info suggests you change.

Another thing I discovered particularly good for small extensions, is that because the entry point file is .nim it can also be used for main code and register itself (so long as it does so after the class has been defined). Aside from 1 less file, it also means registration is done in a file that has a reason to be open.

If this is not a good idea, I'd really prefer something with an unchanging name not in the src folder.

Note: I could do some of the wiki work myself with current info, I just figured I'd bring it up here first. Same for updating the mentioned re-structure of my project (obviously) and an alternate (easy) template. Current wiki page and template could be re-named to be add-on specific.

panno8M commented 3 months ago

WIP

gdext Project

insomniacUNDERSCORElemon commented 3 months ago

So we are on the same page there with the current format at least? With $workspaceA being core what I'm proposing for local and $workspaceB being your addons structure? Are you fine with me making a non-addon template and wikipage?

I would also go with nim_core.nimble*. Going with a non-project-specific name here for non-addons would also mean no need to edit .gdextension. Which would mean that using the simpler template, no names would be need to be edited for first-time users who just want to tinker on a personal project.

Also planned to have a section discussing the steps for converting core into an add-on, as that is easy enough (rename specific things first, rename core folder to desired addon name, move said folder to addons folder). Though for addons that are to be publish-ready, I'd refer to something of yours.

config.nims can go in the root of the project folder so it doesn't need to be defined again unless there is a specific reason. Or it can go in addons folder to cover addons specifically.

*= as I've said better if this filename resulted in nim_core.nim and nim_core.so (/.dll) instead of needing to edit file would make configuration more straightforward.

bootstrap-less workspace..purely to be imported into other workspaces

Alright, that sounds better.

I do not see what is controlling importing/registering classes (GDExtension_EntryPoint), is that what bootstrap.nim will be, or is this handled automatically similarly to allowing bootstrap-less? I don't see that info for [Nimble Style] which is where I'd expect it to be enforced for security.

panno8M commented 3 months ago

With $workspaceA being core what I'm proposing for local and $workspaceB being your addons structure?

There is no difference between workspaceA and B. Separate contexts, environments with different build options coexist. It is also expected that you can place your own program in $workspaceB. If we dare to separate core and addons, the directory under workspace*/src would be core and the dir under *pkg would be addons.

I do not see what is controlling importing/registering classes (GDExtension_EntryPoint), is that what bootstrap.nim will be,

The bootstrap.nim will probably contain the following:

# workspace*/bootstrap.nim
import gdext
import localsource
import $mypkg

process initialize_scene:
  register localsource.XXX
  register $mypkg.YYY
  ...

GDExtension_EntryPoint init_library

Mainly for pathfinding at this time, workspace/config.nims is used:

# workspace*/config.nims

include bootstrapconf.nims
##########################

platform = @["linux"]

--path: "src"
--path: "$mypkg/src"

In bootstrapconf.nims, the settings necessary to make the workspace work as an extension are written. Therefore, as long as you include bootstrapconf.nims, you are free to do anything in config.nims.

# workspace*/bootstrapconf.nims

switch("define", "projectName", projectName())
--app: lib
--noMain: on
...

The reason I am changing the dll build from nimble build to nim c is that I wanted to avoid the dispersion of configuration files involved in the build. If you don't distribute packages, there's little point in using nimble. And if it's too much trouble to type nim c workspace*/bootstrap, you can provide a build command with wizard, or define a build task in config.nims and use nim build.

I don't see that info for [Nimble Style] which is where I'd expect it to be enforced for security.

not for security. This is only the format for distribution. It is a requirement of nimble to use this format. If distribution is not a consideration, there is no reason to use this format.

Are you fine with me making a non-addon template and wikipage?

fine.


As an aside, the process statement for registering classes can actually be distributed. For example, the following will work correctly:

type MyClass = ref object of Node
process initialize_scene: register MyClass

method ready(self: MyClass) {.gdsync.} = ...

type MyClass2 = ...
process initialize_scene: register MyClass2
insomniacUNDERSCORElemon commented 3 months ago

There is no difference between workspaceA and B. Separate contexts, environments with different build options coexist.

Of course. I was just saying I already have that working:

structure

And think it's a good setup. Not strictly needed for my project, but shows that coexistence.

As an aside, the process statement for registering classes can actually be distributed

Neat. But it still needs to be imported to the entry point, which will work but will also give an [UnusedImport] warning. I assume maybe it could be exported, but I couldn't seem to get that to work.

Though maybe you meant multiple classes per file (and registering right after typing) which does indeed work perfectly. :+1:

panno8M commented 3 months ago

Neat. But it still needs to be imported to the entry point, which will work but will also give an [UnusedImport] warning. I assume maybe it could be exported, but I couldn't seem to get that to work.

I thought about automatically importing them into bootstrap, but decided against it because it would have only increased the complexity of the system, including the need for a function to allow exclusion of imports.

The UnusedImport warning can be disabled by appending

{.warning[UnusedImport]:off.}

to the beginning of the file.


This is the minimum configuration when neither add-ons nor multiple workspaces are used. When we let $workspaceA := core, it would be similar to your example. After this, it is up to the user to add add-ons to the core workspace or create an addons workspace. So far, is there any conflict between my opinion and yours?

gdext Project

insomniacUNDERSCORElemon commented 3 months ago

I'm happy with the track we're on now.