Low resolution pixel art game

Hi there,
I’ve just started using DeFold and it looks really interesting.
I have a question. I’m currently making a game at a very low resolution, in pixel art. The viewport resolution would be 64x64 pixels.
Quite obviously, in order to get the game playable, I would like to make it run a 2X (like, just 128x128 but keeping all the game logic related to the original 64x64 resolution). I can of course change manually the window dimension, but it’s impossible to keep the proportions correct.
Is there a way to force the final app to be, say 64x64 with a 2X zoom, so 128X128?
I guess I have to fiddle with the renderer, probably, but how?
Thanks!

2 Likes

There might be some renderer settings that you could alter, but alternatively you can accomplish what you are looking to do by scaling up all of your sprites by a factor of 2. From there, if you set the sprite filters to ‘nearest’ then your sprites won’t be blurred and each pixel will be magnified. If you want to restrict movement of your sprites to a 64x64 grid to give a true impression of a 64x64 viewport, you could do that with this code:

local grid_mag = 2
local pos = go.get_position()
local x = math.floor(pos.x / grid_mag + .5) * grid_mag
local y = math.floor(pos.y / grid_mag + .5) * grid_mag
go.set_position(vmath.vector3(x, y, pos.z))

Keep in mind, depending on how you want physics to work, that might produce some oddities - if something odd comes up physics-wise, I’d modify that code a little to only apply to an object’s sprite and not itself.

By the way, is this for lowrezjam?

Oh, also, I think you’d want to run the same code on the camera.

Maybe it is. I mean, I was just playing a bit with Defold just to see how it works and since I like te idea of lowrezjam, I tried to make something in that area. Don’t know if I’ve got time to finish it, though.

Your idea is more or less what I had in mind, but if there is a way on the render side, I guess everything would be easier and cleaner. Well, I’ll see, thanks!

1 Like

You can definitely keep all content at scale and do the scale-up in a custom render script.

1 Like

I think would you like to do is explained in a couple of my livestreams at livecoding.
One example is here: Pacman example the actual “scaling up” is happening 26 min into the video.

In short you could copy the default render script and change the set_projection to something like:
render.set_projection(vmath.matrix4_orthographic(0, render.get_width() * 0.5, 0, render.get_height() * 0.5, -1, 1))

1 Like

Lowrez game jam? Please share with us whatever it is you decide to create!

I would also do like @Andreas_Jirenius and modify the render script. First, set your game.project to the size in which you want to play your game (you suggested 128x128). Next, copy the default.render_script to some folder in your project. Create a new Render File and point it to your copied render_script. In the render script you need to change how the view and projection is defined.

I would change:

render.set_projection(vmath.matrix4_orthographic(0, render.get_width(), 0, render.get_height(), -1, 1))

to

render.set_projection(vmath.matrix4_orthographic(0, 64, 0, 64, -1, 1))

to force sprites to render to only 64x64 pixels.

Then I’d also ensure that the viewport is rectangular to avoid it being stretched. For this I’d probably change:

render.set_viewport(0, 0, render.get_window_width(), render.get_window_height())

to

local size = math.min(render.get_window_width(), render.get_window_height())
render.set_viewport(0, 0, size, size)

And the same for the gui projection further down.

You probably also want to change default_texture_min_filter and default_texture_max_filter in game.project to nearest to get that blocky pixel feeling.

2 Likes

Also, the rendering manual contains further info on how this works. http://www.defold.com/manuals/render/

1 Like

Thank you so much for all the help! Very very crammed week, but I’d be glad to come up with something for the jam!

1 Like

hello there!
Now i`m trying to learn how-to pixel-art-games in defold and got the next problem:
With GO in game all done perfect (they are moving right, pixel by pixel), but Particles and GUI’s are rendering wrong: there is subpixels
there is way to solve this problem?

(this both animations from gui and go .animate)

This indicates to me that we maybe should have an option (just as we have for sprites) to turn of subpixel rendering for GUIs and particles (or an option to toggle all rendering).

A workaround could be to have your own (make a copy of the ones in builtins/materials) gui.vp and font.vp shaders, that round the position values. Something like:

    vec4 p = round(position.xyz);
    gl_Position = view_proj * vec4(p.xyz, 1.0);

(I haven’t had time to try it myself, but something like that could work. :slight_smile: )

5 Likes

thanks you!
I got to work it right, except situations with scaling
if i am scaling something (particles, sprites), they scaling with subpixels. Is it possible to fix it with shaders too?
(but they scaling not smooth, with some step. I think size is correct, but posing is not)

1 Like