godot-nim / gdext-nim

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

Enable automatic generation of *.gdextension file #8

Open panno8M opened 3 months ago

panno8M commented 3 months ago
insomniacUNDERSCORElemon commented 3 months ago

For icons, a stopgap would be just having a general icon with 4 versions (white, green, blue, red) that are automatically chosen per-class. Single-digit variations could easily be designed manually. That at least covers the basic stuff, and would be better than only the basic node icon.

A different stopgap would be just be... theme packs, where icons are imported as-needed. I know it's at least easy/fun to make icons at 16x16 (2 shown here, top node is more general, bottom node is specific):

custom_icons

I am not sure how well visibility will be for different users, though (I tried different display scales, the node tree seemed like it kept icons the same size whereas the inspector sub-resources combobox made them blurry). That'd probably be the benefit of theme packs though, they could be tailored to certain resolutions/zooms/svg-only etc.

panno8M commented 3 months ago

Since the official icon is here, I was thinking of making a command that to download and save it in combination with the pre-prepared crown svg.

insomniacUNDERSCORElemon commented 3 months ago

Since the official icon is here, I was thinking of making a command that to download and save it in combination with the pre-prepared crown svg.

Placement may be an issue, and scale definitely is.

At 1080p and default (100%) scale, this is what it does to an svg:

svg_16x

I mean alright, but the crown looks like it's bent/melted. Maybe you could get a good result, but probably would need adjusting.

insomniacUNDERSCORElemon commented 3 months ago

I was thinking of making a command that to download and save it in combination with the pre-prepared crown svg

I made an svg that should render at low-resolution better, because I went by a grid:

base_nim_icon

Note that I left some of the Godot icons as hidden objects if you want to quickly see other variants.

Here is what it looks like at 16x, the svg manually combined beforehand:

svg_pixel

High-res look:

crown_128x

Notes:

Also, I think the .gdextension designation of generated icons should be handled separately than custom icons if possible.

EDIT: In a search I saw that you can get the icons from Godot itself, so potentially you still use one icon (or again, single-digit variations) and then combine the icons at runtime as needed.

var load_icon = gui.get_theme_icon("Load", EditorIcons")

panno8M commented 3 months ago

I am late in introducing this, but tips on creating editor icons are compiled in the document. I haven't had a chance to peruse it yet, but it appears that there are also regulations regarding size and color.

insomniacUNDERSCORElemon commented 3 months ago

but it appears that there are also regulations regarding size and color.

That only applies if you're contributing it, but yeah noted and I did leave the svg at 16x16 (and used a grid). Also I think it'd be readable on a light background (and I used a gradient), though stroke could be used to add an outline if needed (Edit note: yes, and change order setting so original shape is not changed, also maybe opposite gradient on it as well).

Another option though: Let the node keep its original icon*, add an extra icon that all Nim classes use (ideally where the script icon would be... though currently you can add a script to a class so that would need to be handled).

*=unless it is manually overriden

panno8M commented 2 months ago

@insomniacUNDERSCORElemon

I generated a set of node-like icons. godot-nim/resources The crown icon I received would not look good with several full surface icons, so I created a temporary one here.

You can overwrite all icons by editing crown.svg and running nim makeicons, if you like. (Please give me a PR if you get a good one)

insomniacUNDERSCORElemon commented 2 months ago

The crown icon I received would not look good with several full surface icons, so I created a temporary one here.

Which "full surface" icons, and did you try the under/over approach that I noted above? Either manually categorizing icons (maybe inheritance+abstract base classes would help here?) or detecting their top-margin (particularly near the edges of the crown, I don't know if there is a good way to do this to determine if visual information is actually blocked/out-of-place or not).

EDIT: Or over-but-offset-down, perhaps even offsetting the original node icon to help with clarity. For instance,

crown_path_offset

For the "alternate design" that I mentioned I had 2 ideas in mind:

  1. A taller crown, background only (which was my original design actually, so the only difference is the bottom half of vertices)
  2. A smaller/lower-width crown, for nodes to "wear" (Characterbody 2D/3D) or to offset into the background in the most empty space.

EDIT:

smallcrown_offset_under

EDIT: Smallest crown+different style. Perhaps something like this may work best if you can scale it up in-line (or just different width to fit certain designs) with a 16x grid for larger(/more symmetrical) node icons.

smallest_crown

And .svg with multiple styles of crown:

base_nim_icon

Either way I think if it is the same for all nodes, it's going to be lacking somewhere. The only way a standard combination would work for all icons would be if the icons were designed to do that (or, all having a similar design, same margins etc).

panno8M commented 2 months ago

Which "full surface" icons, and did you try the under/over approach that I noted above?

Such as AnimationPlayer.svg is it. In addition under approach cannot be applied in such examples. Changing the design for each icon type seems like overkill. Consistency is important for visibility and maintainability.

The crown_small looks quite good. Still, I think the shapes are a little complex. I think it could be as simple as this, as long as it remains Nim-like.

shot

insomniacUNDERSCORElemon commented 2 months ago

Such as AnimationPlayer.svg is it. In addition under approach cannot be applied in such examples

Well yes. The normal design (with over approach) was my answer for large icons like that and area, with the under approach for small nodes like path that would be obscured. I don't think it looked bad.

The _small one might work here too, though it needs to be 1px wider to be properly centered. and...

The crown_small looks quite good. Still, I think the shapes are a little complex.

It is an easy alteration to make all of the angles 45deg like the first screenshot in my previous comment if that's what you mean. I did as such now when altering to be wider (+re-point inside middle for better aesthetics).

Though the alternate (smallest) design I don't like so much for that same reason. Other than that, I wouldn't call it complex

I think it could be as simple as this

3 spikes centered in 16x looks ugly. Unless going for a more square look (as I did with the pixel art one I did).

Changing the design for each icon type seems like overkill. Consistency is important for visibility and maintainability.

I would say it's more about multiple general styles to fit the different designs that Godot already uses. For instance the small crown will cover the entire head of the characterbody icon (though I guess maybe that's thematic with the logo I made, heh). A larger crown is better for stuff like the control icon that has no data to obscure. EDIT: Also, _normal visually looks better in 16x

I am sure my design could be altered to be parametric, for instance you may notice the _normal size has crown spikes that are twice as wide as the smaller designs but keep the top angles. Maybe detecting symmetry type (or obscuring less points?) could be part of size/offset/layer calculation

Even your design, being in the bottom-right-corner, obscures part of the shape of the camera icon. So that's why I say there is no one-size-fits-all. I think aesthetics and preserving identification are better than being 100% consistent.

panno8M commented 2 months ago

This conflict of opinion is probably between programmers and designers. (I insist on consistency because, after all, it is a pain in the ass to make.)

I hope you'll listen to me as the last resistance of someone who can't be bothered, From the looks of it, size of all icons is 14x14. Would it be possible to represent using only a margin of 1 square wide around them?

shot shot

insomniacUNDERSCORElemon commented 2 months ago

From the looks of it, size of all icons is 14x14. Would it be possible to represent using only a margin of 1 square wide around them

A bit boring IMO (and maybe not 100% obvious on being a crown), but I have had that thought as well.

Though you should note that the pathfollow2d icon is 15x15 (the arrowhead occupying the top-right of the canvas). EDIT: Another, animatedsprite (2d/3d) is also 15x15, the face itself (11x11) also using a 1px center which is different from the even designs.

I was going to suggest an alternative take:

new_take (the crown could also be shifted up 1px for this pair at least) base_nim_icon

This is not terrible with something like characterbody, just a bit funny being so wide. Though a half-width is as easy as shifting each side of points (not the center!) in with the arrow keys (assuming an offset is ok too EDIT: 1px right assuming my placement was the same as original which I am not sure of).

EDIT: If half-width is an alternate, it can also be made so the sides are pointed (delete top-corners, move bottom corners in either 1px or 2px) though I am not sure what's best especially if other node icons need consideration. Especially as I've said, Godot's interpolation being different than Inkscape's (though likely it will look better in Godot).

panno8M commented 2 months ago

It is not bad. But yes, there will certainly be more icons that will look funny. Still I don't like the approach of changing the shape of the crown. What do you think of the approach of fixing the shape to crown_small and just moving the position? The default position is the lower right (tentatively), and if specific icons, such as the camera, are to be processed, the position is slid.

insomniacUNDERSCORElemon commented 2 months ago

What do you think of the approach of fixing the shape to crown_small and just moving the position?

Is there a reason you prefer _small over crown_square? I think _square looks better at 16x16 and probably has better compatibility being wide+short, with the adjustment being offsetting it downwards.

Camera doesn't need an offset:

square_camera

EDIT: Well, I just noticed the original camera icon is more centered, so I guess it does need a 2px shift down for the original not the overlay.

Path2dfollow needs one, 5px down:

square_follow

Also, here is the alternate shape I mentioned before (the more Nim-shaped one, but applied to the wider version) in the editor:

Screenshot_2024-08-11_03-16-49

It might give a bit more horizontal flexibility (than the square-edged version) if you go with more than one offset.

EDIT: Just the new shape:

nim_icon

panno8M commented 2 months ago

Is there a reason you prefer _small over crown_square?

I think it's because there is less area to hide; it seems to me that less design is lost by hiding an 8x8 than by hiding a 16x4. Also, when the crown is placed at the top, the overall center of gravity seems to be around the top, which gives me the impression of instability.

Gradually, the direction of the solution began to emerge.

The issue now is which crown to use and which position to make default.

I am wondering if either of the following would be better.

insomniacUNDERSCORElemon commented 2 months ago

I think it's because there is less area to hide; it seems to me that less design is lost by hiding an 8x8 than by hiding a 16x4

It's 8x6 vs 12x3 if counting only the fully opaque pixels, so the wide design is 16 less pixels. EDIT:This is for the updated one as I mentioned, the older/more-square design is 2px wider

I'd say vertices being evenly spaced and margins is more of a guarantee of for 3px of free space as well. Like the camera example above is not a harder-to-read-design from 1px of (even-if-it-were-real) overlap.

Use alternative(last suggested) and make the center as default

On some designs it's fine. (areas, animationplayer) For some (node circles) it's not terrible but I'd prefer higher-but-less-high. Others (like characterbody or anything else with more of a design) will just look ugly.

Also personally I like the crown being worn as a crown.

Also, when the crown is placed at the top, the overall center of gravity seems to be around the top, which gives me the impression of instability

Maybe if placed 1px higher, but in my examples it's within the margins (again, for the opaque pixels). So it seems fine to me, though I have not tried it. Also seems like it'd be a different balance issue when you need a horizontal offset for a more-square icon (or, having it in the corner).

If I generate this, will it be usable in the editor already or is it not plugged in yet?

panno8M commented 2 months ago

If I generate this, will it be usable in the editor already or is it not plugged in yet?

Nah it is still just generating icons. To use it, you must manually copy it into your project and pass it through .gdextension.

If you are testing at this stage, it would be quicker to create a symbolic link to the icons directory in your project. (Godot recognizes symbolic links correctly.)

insomniacUNDERSCORElemon commented 2 months ago

If you still want a more-squarish icon, this may be better for 16x:

Screenshot_2024-08-11_06-26-16

base_nim_icon_2

Though you may even still need to align the Godot icons to the opposite corner (and flipping may help in some cases, assuming there is no text in the icon)

panno8M commented 2 months ago

@insomniacUNDERSCORElemon I have created a icon generator program. godot-nim/iConstructor I think it is relatively free to generate. May I ask you to work on finding the best combination?

insomniacUNDERSCORElemon commented 2 months ago

May I ask you to work on finding the best combination?

I had to figure out to put <icon/> before <defs in the text of the svg to properly load above the node icons.

The squaretooth icon looks fine, I guess. At least without further alignment (though even this might be minimal, particularly without pushing the nim icon to the bottom-right where it can't have a bottom/right outline). Good enough now, for most things.

One small issue is the text on the XR icons:

Screenshot_2024-08-12_14-45-25

Though this is probably a 2.0 type issue. I tried applying the other icon design here to the abstract base class (XRNode3D), it did not apply to 5 of those icons (some I see are outside the class, but others I don't see the in the nodes at all).

Also AudioStreamPlayer has some tiny icons, not sure what that's about. I assume it's an issue with the generator.

Other positional issues I see: marker (debatable), hingejoint, lightoccluder / pointlight, colorpicker, raycast (slight), gpuparticles (slight), shapecast3d (slight), basebutton (it is visible, but almost covered) (a user might also align to (8, 2) or () EDIT, screenshot plus 2 more (multiplayer):

Screenshot_2024-08-12_16-53-14

Even if an alternate icon is the fix for these (which may just be a different position), copy+paste+renaming these feels clunky.

If alternates to Node.svg could be done via a file that'd probably be what I'd prefer. I would do:

Also flip GPUParticlesAttractorVectorField3D (something like <icon_flip_h/> I assume).

I'm guessing for some of the center/upper alternatives you may prefer center-right alignment for consistency (not that it works for everything... lights for example do, casts not as well due to covered center). Though that could be remedied with top-right instead. Personally I think centering (in a general sense) can be good thematically and less monotonous. It is better than not fixing the issues, I guess (and for an example, markers with right alignment all have the same issue but center-right at least makes the crown look like a part of the marker).

Keyword capability like this could be useful for custom badges/icons, like related to gameplay ('boss', 'cutscene', 'item', 'hazard') or systems ('physics', 'weather', 'generate'), or components in general without needing to link specific class names.

*=This could also go in center position instead, and default isn't bad for this either, just my preference

Also, instead of manually editing in <icon/> I don't suppose this could work with an editor-created object that would not make it to the final icons? I tested it and the result of creating a rect and renaming is inkscape:label="icon_flip" />. Most of that data would be thrown out, a user might want to use a line instead if their badge is to go behind the node icon... though either way the max bounds could potentially be used to designate node icon re-alignment (like a 15x15 rect in the top-left corner, or a line that goes from (0, 0) to (15, 15)). Most of the alignment can be determined by a single point, given there isn't any scaling going on so the maximum doesn't actually mean much.

panno8M commented 2 months ago

Generator has been updated. Badge adaptation targets are now specified by attributes instead of by file name. In addition to the conventional method of judging by type, a method of matching by regular expression is also supported.

I'm guessing for some of the center/upper alternatives you may prefer center-right alignment for consistency

All I want is to use only one type of badge. (I believe it is a key element in creating the identity of godot-nim) Although it's fine that what shape it has or where it is.

Also, instead of manually editing in I don't suppose this could work with an editor-created object that would not make it to the final icons?

Since inkscape has an XML Editor, you can use it to edit elements in a natural icon design flow. (Leftmost of the ribbon menu in the XML Editor pane)

Also AudioStreamPlayer has some tiny icons, not sure what that's about. I assume it's an issue with the generator.

In this case, it seems that AudioStreamPlayer is drawn in a very small area to begin with, and the svg's attribute is used to enlarge it. I will apply a dedicated patch for this at a later date.

insomniacUNDERSCORElemon commented 2 months ago

In addition to the conventional method of judging by type, a method of matching by regular expression is also supported.

This part seems not great:

If specified together with the type attribute, the type attribute is ignored

Doing both is useful (general and specific) for badges, as I did above. This is even assuming that regex/type supports multiple names. Though an option to exclude would offer a similar functionality, same if the general assignment(s) like assigning Node.svg to everything is used last for nodes/classes that have not already been assigned (so, everything else).

If you don't need the filename to apply to classes, it might be useful to use filenames for processing order, like 01.svg would process before 02.svg etc to allow control of everything else.

panno8M commented 2 months ago

I would like to see the updated README and samples for more details, but it seems to me that it already meets 80% of what you are requesting.

Materials are processed in order of file name (full path), and if you want to create only specific icons, you can do so by specifying <icon regex="^XR.*" outdir="myXR/" />. materialA.svg(<icon regex=".*" outdir="matA" />) and materialB.svg(<icon regex=".*" outdir="matB/" />) will produce matched icons into matA/ and matB/ respectively without batting each other.

After it is generated, there is the hassle of manually renaming it if desired, but conversely, I consider the only thing missing would be.

insomniacUNDERSCORElemon commented 2 months ago

Maybe, but I was thinking more in the line of straightforward generation (for instance, even just for the badge for this project that I stated). It seems to me that messing with the output directory or renaming shouldn't be needed (unless multiple projects or testing variations).

It is more logical to just cover every specific case first and then go with increasingly more generic cases, never generating an icon for the same node/class twice.

Particularly with the .gdextension generation which I would hope is fully transparent/optional to developers until they actually need to add rules that take effect when they compile their project. As in not something that needs to be done as a separate effort, manually copied files etc.

EDIT: I am also not well versed with regex (or others like sed/awk)

panno8M commented 2 months ago

Automatic generation of .gdextension

At this stage, it seems difficult to generate .gdextension completely automatically. (Specifically, the [libraries] section of the .gdextension cannot be filled in, since it is possible to specify the output destination of the program, but there is no way to retrieve it.)

So the best I can do now is to assist with that. Pointing out/fixing configuration inconsistencies, adding icons, etc.

Regarding the binding of icons

Upload the default icons (the ones we are trying to create now) that we will provide as a godot-nim project to github in advance. Enable a pipeline to clone it and append it to the .gdextension file when --useAdvancedIcons is specified.

insomniacUNDERSCORElemon commented 2 months ago

it seems difficult to generate .gdextension completely automatically...since it is possible to specify the output destination of the program, but there is no way to retrieve it.

Seems to me like you should either handle the output destination yourself (current default behavior of using workspace name, again I'd prefer in bootstrap file) or not officially support/recommend that at all. I would say generation is a key usability feature.

Upload the default icons (the ones we are trying to create now) that we will provide as a godot-nim project to github in advance.

Alright, I sort of get what you're saying now. Regex here seems oddly overkill yet intended to be used in a wasteful fashion. EDIT: see comment below

insomniacUNDERSCORElemon commented 2 months ago

Upload the default icons (the ones we are trying to create now) that we will provide as a godot-nim project to github in advance.

I uploaded a PR with the badges to work with generation, I figured you would want want to see the results and handle the rest.

Replacing part of older versions of my previous comment, I believe overwrite="no" and overwrite="warn" (and "yes" for intended) would be good options to have to allow working with 1 directory. Priority too, for instance w/my PR all I would need is to remove the outdir bits and add order="99" overwrite="no" to default_badge.svg to ensure it generates everything else last (other two icons shouldn't have conflicting files if I've done it right).


EDIT: Also just to be clear, the icons will be installed to the users system and then this will be symlinked on-compile per-project, said link is generated into the .gdextension?

And in the future this same functionality can be used on-demand for user badges, which will be lower demand for most users as it will entirely depend on which classes they are already using

Related to the bit above, I could really see myself making a low-poly clip-art set. A ring, box, dual arrow, quad-arrow etc in 2 colors (which can be derived from type colors+darkness offset, or chosen by the user). And then I make a dozen-or-so icons that represent common use-cases or simplified concepts related to development.

Dang, having 1 dynamic color would be cool (I could see a lightbulb that could be off or set by attributes from the node), though something like that makes more sense for an editor plugin (like for enhancing light nodes) than it does for user-project functionality.

Or, unicode would bring a lot of possibility.