godotengine / godot-demo-projects

Demonstration and Template Projects
https://godotengine.org
MIT License
5.75k stars 1.59k forks source link

Improved art assets of 2d platformer #898

Closed Dynline closed 1 year ago

Dynline commented 1 year ago

image image

This PR was sponsored by Ramatak with 💚

Calinou commented 1 year ago

This is pretty good!

However, this has the side effect of making the lack of built-in integer scaling in Godot more obvious due to the higher base resolution. This can be noticed on your screenshots by pixels having uneven sizes (some are 1×1, some are 2×2). Therefore, I'd prefer to wait until https://github.com/godotengine/godot/pull/75784 is merged, then we can move along and merge this PR too (while enabling integer scaling in pixel art projects).

Riteo commented 1 year ago

@Calinou this targets the 3.x branch though, https://github.com/godotengine/godot/pull/75784 won't help with this.

Calinou commented 1 year ago

@Calinou this targets the 3.x branch though, godotengine/godot#75784 won't help with this.

Ah, I didn't notice that. In this case, I guess we will need to integrate https://github.com/Yukitty/godot-addon-integer_resolution_handler in the 3.x branch of this demo.

It would be great to have https://github.com/godotengine/godot/pull/75784 backported for 3.6, but this will need someone to be available to do the work.

Riteo commented 1 year ago

@Calinou The 3.x code looks very similar and considering the fact that my change is relatively non-invasive (it just changes the window size the stretching code believes to be working with) it should be pretty easy to port: https://github.com/godotengine/godot/blob/b0c399ec8c9f5f71c64656e8463907153f8459ff/scene/main/scene_tree.cpp#L1331-L1428

Riteo commented 1 year ago

I ported integer scaling to 3.x with godotengine/godot#75918. While testing stuff I found some interesting things:

  1. There are import problems as both the coin and enemy texture files are referred to with an uppercase initial instead of their proper, all lowercase names (e.g Coin.png and Enemy.png instead of coin.png and enemy.png).

  2. The project's resolution is set as 1920x1080. This isn't really a good idea if we want integer scaling, as we'd need 3840x2160 window before we even just scale x2, plus the game would be unusable on smaller screens.

  3. The whole things renders in 2d mode instead of viewport. This is understandable, due to the UI, but I notice that it brings lots of "sub-pixel" problems for everything else, including the parallax and the wind shader.

  4. The camera's zoom is set to 0.6. While the integer content scale mode allows the whole thing to be stretched at a nice integer value, a non "even" camera will render and scale everything itself, still allowing pixel wobbling to occur.

The best I could "improve" the situation was by setting a resolution that's half of 1920x1080 (960x540), (partially) addressing point 2, and using a zoom value of 1.0, addressing point 4, which is close enough to the original. For testing purposes I also set the stretch mode to viewport, which improves things further. For the result see the last picture and note that it has some downscaling artifacts, but not pixel wobble.

I made some comparisons to have an idea of what happens when playing with each setting. I forgot to enable integer scaling for the smaller ones but it shouldn't make a difference as I rendered on an 1920x1080 window, which is exactly its double.

1920x1080, camera zoom 0.6, stretch mode 2d (current status) ![a picture of the 2d platformer demo with "uneven" pixels](https://user-images.githubusercontent.com/31065808/231055109-b4b336fa-6510-4700-9916-f86a67f4936d.png)
1920x1080, camera zoom 0.5, stretch mode 2d ![a picture of the 2d platformer with less "uneven" pixels than the original](https://user-images.githubusercontent.com/31065808/231055330-774abc7d-608c-4087-bebe-a680ede66952.png)
1920x1080, camera zoom 0.5, stretch mode viewport (in this case it does very little as the base resolution is very high) ![immagine](https://user-images.githubusercontent.com/31065808/231055552-eccb3aa3-aea6-4600-be19-7f78ac538c4f.png)
960x540, camera zoom 1.0, stretch mode 2d ![another very similar example, still with "uneven" pixels. The camera position feels is a bit different](https://user-images.githubusercontent.com/31065808/231056560-de513138-4faf-4cf0-827e-c372e3227d86.png)
960x540, camera zoom 1.0, stretch mode viewport ![a picture from the demo with some scaling artifacts but completely "even" pixels](https://user-images.githubusercontent.com/31065808/231058030-e143b9ba-cc93-4457-8476-471aabf07c19.png)

In short, if we want to have a nice crisp pixel game aesthetic there are lots of small things that should be done, starting from deciding (and working with) a nice resolution, avoiding non-integer scales in the viewport and so on.

I'm starting to think that we should seriously improve this use case as there are lots of small things that anybody, especially newcomers, might trip on.

Dynline commented 1 year ago

Regarding point 1, I will make them all lowercase again if that's the preferred naming convention.

I scaled the project to 1920x1080 because that's the standard starting size I worked with on all projects so far that were for console/mobile. However I am new to Godot and I surely lack understanding of how it works. I changed the camera value to be able to see more of the background, stretch mode 2d was the original mode before I added the new assets.

I'll change to the resolution you think it's best for this case to get the crisp aestethic.

Riteo commented 1 year ago

@ValeS-Ramatak

Regarding point 1, I will make them all lowercase again if that's the preferred naming convention.

IIRC snake_case is the preferred convention. They are lowercase in the filesystem, but for some reason the scenes are still pointing to files with an uppercase initial. Perhaps you renamed them outside of Godot?

I scaled the project to 1920x1080 because that's the standard starting size I worked with on all projects so far that were for console/mobile. However I am new to Godot and I surely lack understanding of how it works. I changed the camera value to be able to see more of the background, stretch mode 2d was the original mode before I added the new assets.

Oh, so you changed lots of more stuff; I thought they were already like this, hence the weird tone, sorry. Regarding your being new, that's exactly what I meant, there are lots of small things! It's not your fault, currently pixel games are very hard to do properly. We can fix as much as possible here :)

I'll change to the resolution you think it's best for this case to get the crisp aestethic.

The one I proposed is a pretty unusual one, perhaps we could experiment further. Also, it currently has downscale issues with the coins, as they require an even higher resolution.

In these cases ideally one works with a specific resolution ahead of drawing the sprites. Think like designing the sprites of Super Mario Bros., they are already "in scale" and don't need heavy transformations. Anyways, these sprites are really nice and I'm sure that we can find a good resolution that can capture everything. Perhaps, at the cost of making the camera a bit less "comfy", we could use something like 480x270? I don't know, as I said we should experiment further.

Also, there's still the issue of the 2d mode making everything worse, as it kind of "oversamples" most stuff. This was done for a crisp UI but, now that we have more fancy things like wind shaders and the parallax, it looks like it moves up lots of stuff in fractional values and messes up the scaling. The viewport mode would avoid issues like these at the cost of a less crisp UI.

Calinou commented 1 year ago

Perhaps, at the cost of making the camera a bit less "comfy", we could use something like 480x270? I don't know, as I said we should experiment further.

For reference, a common base resolution for PC 2D platformers in the late 90s is 640×480 (like Jazz Jackrabbit 2), though some players used 800×600. For a slower-paced platformer, 512×384 might work out OK. 320×240 is definitely too cramped though.

Dynline commented 1 year ago

IIRC snake_case is the preferred convention. They are lowercase in the filesystem, but for some reason the scenes are still pointing to files with an uppercase initial. Perhaps you renamed them outside of Godot?

I changed the names with the rename option within Godot, but I think I found where the problem with enemy and coin sprites was: coinUppercase coinLowercase

enemyUppercase lowercaseEnemy

I reloaded the sprites so they now point to lowercase.

For reference, a common base resolution for PC 2D platformers in the late 90s is 640×480 (like Jazz Jackrabbit 2), though some players used 800×600. For a slower-paced platformer, 512×384 might work out OK. 320×240 is definitely too cramped though.

The original resolution was this one: image

and this is the original values in the camera: image

Riteo commented 1 year ago

@ValeS-Ramatak IIRC for some reason the zoom works kinda backwards, so a 0.5 value should be equal to a 2x scale. Setting it to 1 should work fine with the new hi-res sprites.

Calinou commented 1 year ago

@ValeS-Ramatak IIRC for some reason the zoom works kinda backwards, so a 0.5 value should be equal to a 2x scale. Setting it to 1 should work fine with the new hi-res sprites.

Camera2D's zoom behavior was inverted in 4.0 (higher values are more zoomed in). However, in 3.x, lower values are more zoomed in.

Dynline commented 1 year ago

Set it back to 800x480 camera zoom 1, it is very similar to what I was trying to achieve, thank you

image

Riteo commented 1 year ago

@ValeS-Ramatak way crispier, nice.

Calinou commented 1 year ago

Merged manually with https://github.com/godotengine/godot-demo-projects/commit/c17d803a1becb2b0fac47fa87d3572486fd77131, which includes some additional changes:

Thanks a ton!