Ren'Py Daz [InGirum] Making a sandbox Renpy prototype (and failing spectaculary)

no_more_name

Newbie
Mar 3, 2024
53
14
Goal is sharing making a prototype more than sharing a game.

Skit prologue first scene :

View attachment pythonw_ZRUmAcKWsb.mp4













Main idea was to make a "shaking cam" to bring a bit of dynamism for each shots. Each scene is composed by multiple layers that simulate movement with Renpy transforms. While it work well, it becomes quickly unbearable and tiresome to use. I'm sure there is a point to balance between regular shot and shaky ones but instead went for mouse parallax.

It has multiple advange :
-Nothing moves when just clicking (no eyes fatigue)
-Operate on x, y or xy axis -> flexible (some shots may fail a x or y axis)

Rendering in layers:

pythonw_FgvyXXUc1P.jpg

Main difference is dividing by layers, looking for depth in addition to a good angle. It may looks nightmarish to render but it's rather fast once you get the gist of it. It also had the luxe of not rendering a full image for each scene :

pythonw_IU64lkkGgy.jpg

Just layer 2 was rendered for the follow up.

DoF & Daz : Render without any DoF and do it either with PS or Renpy transforms (when you can, close-up may be tricky). I Generally use 4 px incrementation (4/8/12/16), so you can swift focus without rendering cost (time) and Daz is terribad with transparency and DoF (black outlines).
 
Last edited:

no_more_name

Newbie
Mar 3, 2024
53
14
If you deal with several layers, one of the best thing to give you visual clue when needed, is to install action editor for renpy.



It's incredibly useful. Press SHIFT+P, apply transfrom you may want -> copy to clipboard.

Mouse parallax script itself ( , it slightly modified to not create endless 'master2' empty layers) :

Python:
init 1111 python:

    class MouseParallax(renpy.Displayable):
        def set(self, *args):
            self.xoffset, self.yoffset = 0.0, 0.0
            self.layer_info = args
            for i in self.layers():
                if i in config.layers + ["master2"]:
                    config.layers.remove(i)
            index = config.layers.index("master") + 1
            for xdist, ydist, layer in args:
                if not layer in config.layers:
                    config.layers.insert(index, layer)
                    index += 1

        def __init__(self, *args):
            super(renpy.Displayable, self).__init__()
            self.set(*args)
            config.overlay_functions.append(self.overlay)
            return

        def layers(self):
            layers = []
            for dx, dy, layer in self.layer_info:
                layers.insert(0, layer)
            return layers

        def render(self, width, height, st, at):
            return renpy.Render(width, height)

        def parallax(self, xdist, ydist):
            func = renpy.curry(trans)(xdist=xdist, ydist=ydist, disp=self)
            return Transform(function=func)

        def overlay(self):
            ui.add(self)
            for xdist, ydist, layer in self.layer_info:
                renpy.layer_at_list([self.parallax(xdist, ydist)], layer)
            return

        def event(self, ev, x, y, st):
            import pygame
            if ev.type == pygame.MOUSEMOTION:
                self.xoffset, self.yoffset = ((float)(x) / (config.screen_width)) - 0.5, ((float)(y) / (config.screen_height)) - 0.5
            return

    def trans(d, st, at, xdist=None, ydist=None, disp=None):
        d.xoffset, d.yoffset = int(round(xdist * disp.xoffset)), int(round(ydist * disp.yoffset))
        if xdist != 0 or ydist != 0:
            xzoom = (config.screen_width + abs(xdist + xdist)) / float(config.screen_width)
            yzoom = (config.screen_height + abs(ydist + ydist)) / float(config.screen_height)
            if yzoom > xzoom:
                d.zoom = yzoom
            else:
                d.zoom = xzoom
            d.anchor = (.5, 1.0)
            d.align = (.5, 1.0)
        return 0

    # list for storing images with layers
    parallax_images = []

    # show several images, each on its own parallax layer
    # you can have a transform effect or even more than one
    # the number of images must not exceed the number of layers
    # otherwise extra ones will be shown on top of the others on the master2 layer
    # showp("city1", ("city2", truecenter), ("city3", [truecenter, woo])
    def showp(*args):
        global parallax_images
        layers = mouse_parallax.layers()
        for i in args:
            at = []
            image = i
            if isinstance(image, tuple):
                image, at = image
                if not isinstance(at, list):
                    at = [at]
            l = "master2"
            if len(layers) > 0:
                l = layers.pop()
            renpy.show(image, at_list=at, layer=l)
            i = (image, l)
            if not i in parallax_images:
                parallax_images.append(i)

    # remove one image from the specified (or any) layer
    def hidep(image, layer=None):
        global parallax_images
        if not layer:
            layer = "master2"
            for ii, ll in parallax_images:
                if ii == image:
                    layer = ll
        i = (image, layer)
        renpy.hide(image, layer=layer)
        if i in parallax_images:
            parallax_images.remove(i)

    # clear all parallax layers
    # and add new images if necessary
    def scenep(*args):
        global parallax_images
        for i in parallax_images:
            image, layer = i
            renpy.hide(image, layer=layer)
        parallax_images = []
        if args:
            showp(*args)

    mouse_parallax = MouseParallax((0, 0, "l0"), (0, 0, "l1"), (0, 0, "l2"), (0, 0, "l3"), (0, 0, "l4"), (0, 0, "l5"))
    #You may not need more than 6 layers
And somewhere in your options.rpy :
Python:
define config.layers = ['master', 'master2', 'transient', 'screens', 'overlay']
How to use :



You start with your background layer ->middle->Forward.

Python:
$ mouse_parallax.set((-10, 0, "l0"), (-25, 0, "l1"), (-50, 0, "l2"), (-75, 0, "l3"), (-100, 0, "l4"))
$ scenep(("p66"), ("p66_md"), ("p66_fw2"), ("lensflare012", p1_lensFlare6), ("p66_fw1"))
with pdissolve

"p66"
(-10, 0, "l0") = first number is px to move in x axis, second is y, l0 is layer. (negative value mean inversed like a mirror)

p66 is my background layer, p66_md my middle layer, p66_fw2 my second forward layer, lensflare012 a lenseflare with a transform (blurr, alpha; each layers can take multiple transforms, it's rather flexible)
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,130
14,809
It was still the 31 over there, got it like 10 hours later after I woke up :censored:
Report the thread opening, and nicely ask a mod to restore the post as it was before your edition.
 

no_more_name

Newbie
Mar 3, 2024
53
14
Slow progress but worked all night, even missed my usual friday/saturday waste with the bois.

Updated to Renpy 8.2.1 and removed all obsolete crap. Which was plenty, joy (nope) of jumping from prototype to prototype for ages. Some code were almost 5 years old lol. Should be all clean now. Updated Daz also but less annoying.

Still not on the sandbox part, and I'm super late, but still experimentating on mouse parallax. Not that it's all fancy and all (it's not) but I still try to figure out what can be done (or not, especially with videos).

So far prologue is underwhelming but I'm ok with it, even I would probably trash half of these renders if I had time. I'll try something else in the end, as I'm getting more and more silly.
 

no_more_name

Newbie
Mar 3, 2024
53
14
Why? Why I have to dig that much just for breaking a line?
It's madness. Complete Renpy madness. Please tell me if I'm doing something wrong.

wake-up-meme.gif

Python:
screen confirm(message, yes_action, no_action):
    #tag menu
    modal True
    zorder 200
    style_prefix "confirm"
    add "gui_overlay"

    frame at ComfirmFrameDelay:
        vbox:
            xalign .5
            yalign .5
            spacing 90

            add "images/gui/mainmenu/bar_top.png" at gui_overlaydecor_choicetop:
                yoffset 70

            if message == layout.QUIT:
                label _("Are you sure you want to quit?\n"):
                    style "confirm_prompt"
                    xalign 0.5
                    at gui_inventoryfadeout
      
            elif message == gui.OVERWRITE_SAVE:
                label _("Are you sure you want to overwrite your save?\n"):
                    style "confirm_prompt"
                    xalign 0.5
                    at gui_inventoryfadeout

            elif message == gui.DELETE_SAVE:
                label _("Are you sure you want to delete this save?\n"):
                    style "confirm_prompt"
                    xalign 0.5
                    at gui_inventoryfadeout

            else:
                label _(message):
                    style "confirm_prompt"
                    xalign 0.5
                    at gui_inventoryfadeout

            hbox:
                xalign 0.5
                spacing 300

                textbutton _("Yes") action[yes_action, Hide(None), Return()] at gui_inventoryfadeout
                textbutton _("No") action[no_action, Hide(None), Return()] at gui_inventoryfadeout

            add "images/gui/mainmenu/bar_top.png" at gui_overlaydecor_choicebottom:
                yoffset -70

    key "game_menu" action[no_action, Hide(None), Return()]
 
Last edited:

no_more_name

Newbie
Mar 3, 2024
53
14
Corrected fews glitches in menu here and there. Looks slick now. Feels the Renpy part is done for until I hit another wall. Now I just have to be the monkey pressing the render button until prologue is fully fleshed out. The easiest and relaxing part by a far margin.

Game is fully in 4k, there is no particular reason for it to be, just I have a big screen and it's looking good on it. Probably gonna bite me in the ass but who cares. I found Angle2 to perform better in any situations, GL2 a bit far away even if you play in native 4k.

Game is rather unsual and quite taxing. Multiple 4k images, sometime 4k videos as well (dust particles, rain, film grain, yada yada), all in layers + parallax. I havn't done testing yet, but things gonna be wonky when downsized (2k/1080), GL2 is extremely harsh when downsizing, sharpening with the grace of a hammer. Probably possible to change OpenGL behavior if you are a wizard, but since Angle2 bring acceptable results, ain't gonna bother with it.

Hence a cool button to switch from one to the other :

pythonw_yGN5OvSPhQ.jpg

Redone the title screen with epic music with fog and shit, it uses a different parallax script than the rest of the game:
View attachment pythonw_1CvgSzlAkA.mp4












Main protagonist is female as I've done so many prototype from male POV, I wanted to keep things fresh. It's quite an abomination of a Daz skin. Model has been crash test dummy for years everytime I want to test something.

View attachment pythonw_m75amdk9DI.mp4












Background missing but well.

gwen1.jpg

Also titties from another prototype so you've not completely lost your time reading this.

You don't have permission to view the spoiler content. Log in or register now.
 
Last edited:
  • Like
Reactions: osanaiko

no_more_name

Newbie
Mar 3, 2024
53
14
I'm digging the postwork on the renders.
Thanks!
InGirum- Classic Blue.rar (Lightroom preset)
Quite the opposite I ever did with Daz. Not sure it's really useful as I render with very low gamma (=1, help me 'pop' a render). Gonna look very weird at 2.2, but hey.

That said quite scary thing to say at least.
I have now have hard crash while (really) quick rolling back.
I mean I can annoy the player here and there, but hard crash is huge no-no.
It seems rather random, but couldn't replicate when compiled (so far, if that make sense, make it even weirder).

FSrb60GWIAAUAxb.jpg
 
Last edited:

no_more_name

Newbie
Mar 3, 2024
53
14
Yeah if I build the thing, it doesn't crash whatsoever.

1413263973539.gif

I just don't get it.

Edit:

It was the camera (old show layer). Don't ask me why.

 
Last edited:

no_more_name

Newbie
Mar 3, 2024
53
14


Zero time sadly, every time I try to plan something, it goes to shit for whatever reasons.
Hope I have some time this week end to get work done.

Solved few problems tho. One being game was hard coded to only have one event possible per screen (=location). I was ok with that and worked well so far but tasted sour.

Prologue was around 60 renders, now around 150. Gonna try to share something next week-end.
 

no_more_name

Newbie
Mar 3, 2024
53
14
One thing that restrict the engine is the total absence of .
There is a 3D world and... That's about it.

When I first saw this :

pythonw_9XPxXHpwdg.jpg

I was like... wait a minute, no way *rubs hands*
But then booo. Camera sare just layer transform.
It's funny but quite boring.

Making all kind of projections, even on simple primitive (say a plane) would be sooooo neat.
The weird thing is OpenGL does it all, but didn't made to Renpy itself.

But why you would want camera projection?
Because :

 
Last edited:

no_more_name

Newbie
Mar 3, 2024
53
14
There is one thing I really not understand, maybe I'm drunk or whatever.

Why does show a screen behave differently than call a screen?

I don't get it.
Why?
It is just there to piss off people?
What's the rationale?
Who are these people?
Where do they gather?
So much questions.

FoTAQphaMAEiAdU.jpg
 
Last edited: