Saturday, July 26, 2025
HomeIndie GameCursed Existence

Cursed Existence


Bananicorn


Hmm, fascinating concerning that render. Undecided, why you want lot of such small tiles, for me seems as effectively higher to render one massive scene and break up massive scene to tiles if wanted in some post-process (such as you do in imgmagick).

Anyway, if I perceive it accurately, my guess for lengthy render time is: the truth that it took 20 minutes, it is as a result of internally it rendered entire scene many occasions. Even when you then took small picture minimize, pixels in that minimize are affected by different geometry, gentle sources, and so on.. exterior of that minimize. Thus, there was not a lot saving in rendering to smaller tile. In reality making smaller and smaller tiles and calling render for them in loop will simply make it worse. (I hope I understood accurately your intention that tiles had been simply 2D cuts of massive rendered scene).

You bought that 100% right!
And yeah that is the sensation I received from it too – you mentioned it far more concisely although^^
Utilizing the event to indicate the visible degree information and the depthmap aspect by aspect:
Cursed Existence

(they are a bit scaled down, the small full degree is 1280×1280 and the big one I take advantage of on my machine is already twice that dimension)

The depthmap is for per-pixel occlusion testing on the gpu. I am not 100% positive if I want to separate into these small tiles, however numerous units have a restrict on texture dimension on the gpu, so I wish to be sure that I do not run into that. Adjusting the tile dimension in a second second is pretty straightforward Smiley


Logged

Bananicorn


Devlog #013:

I have been combating with the extent up display screen – all of the bits and items animating in, with the correct timing and the whole lot.
Became an entire unreadable heap of spaghetti, which simply barely labored. Any additions and I might be utterly misplaced.
Y’know the kind of “after I wrote this code, solely god and I knew what it did – now solely god is aware of”, however already 5 minutes after the very fact.
Simply had a bit state variable, only a counter, which I’d increment someplace in the entire heap of spaghetti, after which go into one other if-else case updating the blood splatters, or the playing cards animating into the display screen.
I believe I simply anticipated this to be much less advanced, however I needed a number of issues occurring after each other, and shortly I used to be left with a 200-ish line monstrosity that was shortly rising out of hand.

A literal bathe thought introduced me to the easy resolution: My information construction (none) was the mistaken one for this sort of factor.
All I wanted to scrub it up was a fundamental loop that known as an array of capabilities with the corresponding replace and draw capabilities break up into them.

states = {
{ –blood splatters and title
animation_duration = 0.75,
replace = wait_update,
draw = operate ()
SCREEN_MAIN_GAME.draw()
native cw = level_up_canvas:getWidth()
native ch = level_up_canvas:getHeight()
native spl = SPRITES.ui.splatter_left.picture
native spr = SPRITES.ui.splatter_right.picture
native title = SPRITES.ui.choose_your_curse.picture
native v_unit = SCREEN_H / 25
native shadow_offset = v_unit / 2
native scale_factor = SCREEN_W / NATIVE_SCREEN_W

native spl_x = 0
native spl_y = ch / 5
native spr_x = cw – spl:getWidth() * scale_factor
native spr_y = 0

native splatter_left_percentage = UTIL.ease_in_quint(animation_percentage)

LG.setCanvas(level_up_canvas)
LG.clear(0, 0, 0, 0)

–draw the splatters
if OPTIONS.ui.childsafe_mode then
LG.setColor(INK_BLACK)
else
LG.setColor(BLOOD_RED)
finish

circular_splash_shader:ship(“visible_dist”, splatter_left_percentage * cw)
LG.setShader(circular_splash_shader)
LG.draw(
spl,
spl_x,
spl_y,
0,
scale_factor
)

LG.draw(
spr,
spr_x,
spr_y,
0,
scale_factor
)
LG.setShader()

LG.setColor(1, 1, 1, 1)

SHARED_SHADERS.reveal_shader:ship(“mask_canvas”, level_up_canvas)
LG.setShader(SHARED_SHADERS.reveal_shader)
LG.draw(
title,
cw / 2 – (title:getWidth() / 2 * scale_factor),
ch * .55 – (title:getHeight() / 2 * scale_factor),
0,
scale_factor
)
LG.setShader()
LG.setCanvas()
draw_title()
finish
},
{ –wait
animation_duration = 0.25,
replace = wait_update,
draw = operate ()
SCREEN_MAIN_GAME.draw()
draw_title()
finish
},
{ –animate in playing cards
animation_duration = 1,
replace = operate ()
animation_percentage = get_animation_percentage()

native card_rot_percentage = UTIL.ease_out_circ(animation_percentage)
for i = 1, card_amount do
playing cards[i].y = card_bottom_y – card_heights[i] * UTIL.ease_out_circ(animation_percentage)
if i == selected_card_index then
playing cards[i].y = playing cards[i].y – card_selection_height
finish
playing cards[i].rot_x = card_rot_percentage * card_rotations[i]
finish

if animation_percentage == 1 then
state = state + 1
time_start = LT.getTime()
finish
finish,
draw = operate ()
SCREEN_MAIN_GAME.draw()
draw_title()
draw_cards()
finish
},
{ –wait
animation_duration = 0.1,
replace = wait_update,
draw = operate ()
SCREEN_MAIN_GAME.draw()
draw_title()
draw_cards()
finish
},
{ –flip playing cards
animation_duration = 1,
replace = operate ()
animation_percentage = get_animation_percentage()

native card_rot_percentage = UTIL.ease_in_quint(animation_percentage)
for i = 1, card_amount do
playing cards[i].rot_z = -math.pi + card_rot_percentage * math.pi * 2
finish

if animation_percentage == 1 then
state = state + 1
time_start = LT.getTime()
finish
finish,
draw = operate ()
SCREEN_MAIN_GAME.draw()
draw_title()
draw_cards()
finish
},
{ –wait for enter
animation_duration = 1,
replace = operate ()
user_input_blocked = false
–next state is being set by consumer enter
for i = 1, #playing cards do
playing cards[i].y = card_bottom_y – card_heights[i] * UTIL.ease_out_circ(animation_percentage)
if i == selected_card_index then
playing cards[i].y = playing cards[i].y – card_selection_height
finish
finish
finish,
draw = operate ()
SCREEN_MAIN_GAME.draw()
draw_title()
draw_cards()
finish
},
{ –animate out playing cards
animation_duration = 1,
replace = operate ()
animation_percentage = get_animation_percentage()

for i = 1, card_amount do
if i ~= selected_card_index then
playing cards[i].y = card_bottom_y – card_heights[i] * (1 – UTIL.ease_out_circ(animation_percentage))
finish
–cards[i].rot_z = animation_percentage
finish
if animation_percentage == 1 then
state = state + 1
time_start = LT.getTime()
finish
finish,
draw = operate ()
SCREEN_MAIN_GAME.draw()
draw_title()
draw_cards()
finish
},
{ –fade out card spotlight
animation_duration = .3,
replace = wait_update,
draw = operate ()
SCREEN_MAIN_GAME.draw()
draw_title()
playing cards[selected_card_index]:draw(true, 1 – animation_percentage)
finish
},
{ –burn up remaining card
animation_duration = 2,
replace = wait_update,
draw = operate ()
SCREEN_MAIN_GAME.draw()
draw_title()
dissolve_shader:ship(“time”, UTIL.ease_in_quint(animation_percentage))
LG.setShader(dissolve_shader)
–TODO: optimally, I might spawn just a few embers floating away whereas the cardboard burns up
playing cards[selected_card_index]:draw(false)
LG.setShader()
finish
},
{ –wipe away blood stains
animation_duration = 1.5,
replace = operate ()
animation_percentage = get_animation_percentage()
if animation_percentage == 1 then
state = 1
UTIL.change_screen(SCREEN_MAIN_GAME)
finish
finish,
draw = operate ()
SCREEN_MAIN_GAME.draw()
SHARED_SHADERS.wipeaway_shader:ship(“animation_percentage”, animation_percentage)
LG.setShader(SHARED_SHADERS.wipeaway_shader)
draw_title()
LG.setShader()
finish
},
}

Right here it’s in motion:

All the pieces I needed in that display screen is there, however but once more, I really feel the discrepancy between my imaginative and prescient and what I can obtain. Want to review extra shaders, want to review extra maths.
I will get there some day.


Logged

Bananicorn


Devlog #016

So, what have I been as much as currently?

I will begin this off with a little bit of a narrative about my inspiration for the graphical type of cursed existence:
Lionheart: Legacy of the Crusader is responsible!

Such a stunning recreation – got here out within the early 2000s (I performed it later, as a result of a crappy PC).
Pre-rendered environments and characters. My recreation at the moment appears nothing prefer it, I will admit^^
Ah the time it was my go-to isometric recreation – I used to be too dumb or lazy for Baldur’s Gate and Icewind Dale and I do not keep in mind why I did not fall arduous for Diablo 1 and a pair of, however Lionheart is the one which caught with me.
The story was such a neat various timeline too, and it used the S.P.E.C.I.A.L system for stats, like fallout however was real-time.
The one drawback was: improvement was rushed, so I can solely suggest the primary half, perhaps 3/4ths of the sport.
Anyhow, years later, hades got here alongside and blew my thoughts – I really like roguelites?
Very good recreation in any manner I have a look at it.

All in all, I needed to take what I like from every recreation, and add them collectively for one thing new.
I am nonetheless very early in improvement and this may most likely take years, particularly with the few hours I can decide to it. Nonetheless, price a attempt – I already realized a shit-ton of issues!

As to the place I am at the moment at:
Gear and a second physique kind for gamers!
Each of those need to do with one another, since now I save the depth buffer of a sprite straight to the sprite’s alpha.

Then in-game I mix all these layers to a single spritesheet.

Once more, step-by step:

-1: render two base fashions in blender and save depth buffer to alpha.
-1.2: repeat for every animation body

– 2.1: connect weapon mannequin to human mannequin
– 2.2: set human mannequin as holdout for the weapon
– 2.3: render weapon mannequin with the depth buffer saved to alpha
– 2.4: repeat for every human animation and for every path

This is a tough approximation of the three steps wanted for this (base object, block out components that the character is masking (right here simply with the hand), after which including the depth map within the alpha channel)

3: do the identical for gear (helmets, armor, sneakers no matter]

4: mix spritesheets in-engine whereas depth testing in opposition to the alpha channel

The indices for the person animations are exported individually, to a textual content file.

Presently, the complete spritesheet for the axe would appear like this, however with colours:

(and your display screen is not soiled, these ARE the sprites)

I actually wanna crop the sprites down and effectively pack them, however I am positively leaving that optimization in direction of the top, after I’m largely doing code changes and I will not be slowed down by it as a lot. These items clearly provides to construct occasions.

That is what I am at the moment as much as. Such a rendering (at the least the in-game half) is usually known as “paper-doll” rendering of isometric characters, and in precept it is so simple as it sounds.
Ultimately it’s going to be pretty advanced, however I am including complexity with every step, refactoring as wanted on the best way.
I additionally wish to solely add actions which might be doable with every weapon to the spritesheet, like you possibly can’t use an axe like a bow, however that is someplace off sooner or later. Completely different weapon varieties usually are (like spears, two handed weapons and bows/crossbows).

Why do I think about armor and clothes earlier than that? I simply received uninterested in trying on the poor gray blob man on a regular basis and need to have the ability to change it up a bit.
A personality that wears garments additionally appears a bit extra polished than a mainly bare one^^

Have an excellent Saturday!


Logged

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments