What is the best strategy for dynamically lighting my scene?

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
rocket
Veteran
Posts: 373
Joined: Tue Jul 10, 2007 2:54 am
Projects: Starlight Ep0, Ep1
Location: San Fransisco
Contact:

What is the best strategy for dynamically lighting my scene?

#1 Post by rocket » Thu Jul 12, 2007 3:52 pm

Thanks to the tutorial and puzzling through the demo files I've gotten a good start on Ren'Py. I'm still pretty much a n00b though.

I'd like to ask for advice on how to best tackle the problem of using Ren'Py's very rich image processing tools to manage my asset complexity.

Here's the problem:
I want to have scenes with different lighting. Say, a park during the day and a park at night. I want the player to meet characters both during day and night.

The brute force solution is to draw two backgrounds for the park (day and night), and two sets of every expression my characters will have (one for day and one for night). Then depending on the scene I show different images. Ugh.

I can think of some alternate strategies:
1. Draw a semi transparent layer of mood lighting over the background, then draw a different layer over the characters. I'm not really sure the best way to do this, but I think Ren'Py supports layers. I'd have to make sure new characters coming on and changes in character expression remain at the appropriate layer so they retain the "lighting effect", but maybe thats trivial.

2. Use the image manipulation code in Ren'Py to tweak each image. In effect it's like the brute force method, but at least I'm not pre-baking the effects in Photoshop.

3. Somehow override the "show" function so that it checks for a global variable (like time of day, or is_street_lamp_on) and renders the images shown with different image operations to simulate different lighting. Number three seems really appealing because I could trigger the state of a lamp based on previous game actions and still reuse most of the script. But maybe I'm being naive as to how useful it would really be...

Any ideas on the best way to do this?

User avatar
DaFool
Lemma-Class Veteran
Posts: 4171
Joined: Tue Aug 01, 2006 12:39 pm
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#2 Post by DaFool » Thu Jul 12, 2007 4:46 pm

I still use separate images for Night / Day. The reasons are as follows:

1.) It's smaller, actually. 2 x jpgs for one background is more efficient than 1 jpg + 1 tinting png.

2.) Creating a night scene is not as simple as placing a dark tint over a scene. You have to manipulate shadows and lights, and it is best to do that in Photoshop, not with Ren'Py.

3.) Use Dynamic Displayables. If you look at my code for Nettestadt Troll, I just do something like this:

Code: Select all

call setnight
scene nettestadt with fade
"etc etc"
call setday
scene nettestadt with fade
I did not have to bother with separate scene declarations for night / day modes.

Now, I did not use night/day for character sprites (did not have to because they were not placed on top of the background), but I did use Ren'Py image operators im.Sepia for their flashback versions.

I am imagining you *might* be able to get away with a simple im.Composite with a tint layer for sprites, instead of backgrounds. How about taking the original sprite, im.Alpha it to 50%, then take it again, im.Grayscale it, then im.Alpha that Grayscale to 50%, then im.Composite the three together (The alpha original, the alpha grayscale, and the dark tint).

User avatar
rocket
Veteran
Posts: 373
Joined: Tue Jul 10, 2007 2:54 am
Projects: Starlight Ep0, Ep1
Location: San Fransisco
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#3 Post by rocket » Thu Jul 12, 2007 6:07 pm

DaFool wrote:I still use separate images for Night / Day. The reasons are as follows:
1.) It's smaller, actually. 2 x jpgs for one background is more efficient than 1 jpg + 1 tinting png.
Gotcha. That's why I'd rather be able to do it with an image operator or a solid displayable to do the tinting.
DaFool wrote: 2.) Creating a night scene is not as simple as placing a dark tint over a scene. You have to manipulate shadows and lights, and it is best to do that in Photoshop, not with Ren'Py.
Yah, I know ^_^;;;

Actually what I'm trying to do is not simple day and night, I just thought that would be an easy example. Actually it's more like a photography dark room, where everything is either illuminated normally or just strongly tinted a color. It would still be better looking in Photoshop, but the fact is if I display my characters in normal light over a background change it'll really lose the intimate atmosphere, so that why I started down this train of thought.
DaFool wrote: 3.) Use Dynamic Displayables. If you look at my code for Nettestadt Troll, I just do something like this:

Code: Select all

call setnight
scene nettestadt with fade
"etc etc"
call setday
scene nettestadt with fade
I did not have to bother with separate scene declarations for night / day modes.
Okay, Dynamic Displayables looks like what I need! Actually it's exactly what I need since I could have earlier user actions determine the state of the lighting, then when I display the scene, just show the items and characters without regard to the current lighting status.

I have to admit the documentation for them in the Wiki is leaving me scratching my head a bit.

It seems I use ConditionSwitch in the init block to set up all the variations of images I want associated with a distinct name. So I could easily do this for my background and all the characters who will show up in that room.

Code: Select all

init:
    image Violet = ConditionSwitch(
        "developing == 'true'", "Violet_Red.jpg",
        "developing == 'false'", "Violet.jpg",
        )
    image Jade = ConditionSwitch(
        "developing == 'true'", "Jade_Red.jpg",
        "developing == 'false'", "Jade.jpg",
        )
I can also use the image compositing as you describe to set all those up.

Code: Select all

init:
    image Violet = ConditionSwitch(
        "developing == 'true'", im.Recolor("Jade.jpg", 255, 0, 0, 255),
        "developing == 'false'", "Violet.jpg",
        )
    image Jade = ConditionSwitch(
        "developing == 'true'", im.Recolor("Jade.jpg", 255, 0, 0, 255),
        "developing == 'false'", "Jade.jpg",
        )
Three questions:
1. What the heck does the actual DynamicDisplayble function do? I cant understand the documentation at all.
2. How is ShowingSwitch really used? Again I don't get it.
3. Is there anyway to generalize my definition of images so I don't have to copy and paste that complex ConditionSwitch statement for every character state? Something like a way for me to define a function that takes a file name and produces a ConditionSwitch statement with the right image name and one version of the image tinted red. That way I could also change the tint I apply to all images in one place. Can I do this in Ren'Py script? Do I have to create a Python function (and learn Python first)? Can I even use a function in the init block to do the kind of thing I'm talking about?

Thanks again!

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#4 Post by PyTom » Thu Jul 12, 2007 6:42 pm

rocket wrote: 1. What the heck does the actual DynamicDisplayble function do? I cant understand the documentation at all.
It takes a python function as an argument. When necessary, the function is called with two arguments: the amount of time the displayable has been shown for, and the amount of time any displayable with the same tag has been shown for. The function is expected to return a tuple containing a displayable, and the amount of time that displayable is good for. (All times are in seconds.)
2. How is ShowingSwitch really used? Again I don't get it.
Basically, you give it image names, and displayables, and it becomes the first displayable corresponding to a shown image.
3. Is there anyway to generalize my definition of images so I don't have to copy and paste that complex ConditionSwitch statement for every character state? Something like a way for me to define a function that takes a file name and produces a ConditionSwitch statement with the right image name and one version of the image tinted red. That way I could also change the tint I apply to all images in one place. Can I do this in Ren'Py script? Do I have to create a Python function (and learn Python first)? Can I even use a function in the init block to do the kind of thing I'm talking about?
Sure, you can define a python function to do this.

Code: Select all


init:
    python:
        def if_developing(a, b):
            return ConditionSwitch(
                "developing", a,
                "not developing", b,
                )
     image Violet = if_developing("Violet_Red.jpg", "Violet.jpg")
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
DaFool
Lemma-Class Veteran
Posts: 4171
Joined: Tue Aug 01, 2006 12:39 pm
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#5 Post by DaFool » Thu Jul 12, 2007 7:11 pm

Aw, man, ConditionSwitch (Ren'Py 6.3.0) would have greatly simplified my code. I totally did not know about it.

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#6 Post by PyTom » Thu Jul 12, 2007 7:44 pm

Actually, ConditionSwitch is new in 6.3.1.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
rocket
Veteran
Posts: 373
Joined: Tue Jul 10, 2007 2:54 am
Projects: Starlight Ep0, Ep1
Location: San Fransisco
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#7 Post by rocket » Thu Jul 12, 2007 9:25 pm

PyTom wrote: Sure, you can define a python function to do this.

Code: Select all

init:
    python:
        def if_developing(a, b):
            return ConditionSwitch(
                "developing", a,
                "not developing", b,
                )
     image Violet = if_developing("Violet_Red.jpg", "Violet.jpg")
AWESOME. I just taught myself Python in 30 minutes. http://hetland.org/writing/instant-python.html ^_-

So I could in theory do:

Code: Select all

init:
 python:
  def developing_light(a): 
   return im.Recolor(a, 255, 0, 0, 255)

  def if_developing (a):
   return ConditionSwitch(
    "developing", developing_light(a),
    "not_developing", a
   )

 image Violet = if_developing("Violet.png")
Which should allow me to at a later date redefine developing light to use more complex compositing techniques if needed.

In this case "developing" and "not developing" are assumed to be global variables, is that right? That means also that the function is interpreted in real time, is that right? I'd thought of Ren'Py as something that was precompiled because of the init blocks where all the assets are defined, but I guess I was wrong.

The other two answers leave me as stumped as before, but I suspect as I learn more about this all it should become clear. In my headlong rush to produce something I fear I lack context and experience.

Thanks for the help!

User avatar
Criptych
Regular
Posts: 87
Joined: Sat Jun 23, 2007 9:19 am
Projects: ALICE.NET
Location: The other end of the internet.
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#8 Post by Criptych » Thu Jul 19, 2007 9:31 am

rocket wrote:In this case "developing" and "not developing" are assumed to be global variables, is that right? That means also that the function is interpreted in real time, is that right? I'd thought of Ren'Py as something that was precompiled because of the init blocks where all the assets are defined, but I guess I was wrong.
Just to clarify some things about Python (and programming in general), at least as I understand them:
  • Yes, "developing" is a global variable, in the context of your script. However, "not developing" is an expression that works just how it sounds-- it's True when NOT "developing," i.e. when "developing" is False.
  • Yes, Python (and thus Ren'Py) is "precompiled," but functions by their nature (in any programming language) produce different results with different input.
  • Init blocks provide a way to define assets, including functions, before the script itself begins. It's pretty much unrelated to the compilation step.
Hope I didn't confuse you more. n_n"
Computers are useless. They can only give you answers. —Pablo Picasso

Image

User avatar
rocket
Veteran
Posts: 373
Joined: Tue Jul 10, 2007 2:54 am
Projects: Starlight Ep0, Ep1
Location: San Fransisco
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#9 Post by rocket » Thu Jul 19, 2007 3:08 pm

Criptych wrote:
rocket wrote:In this case "developing" and "not developing" are assumed to be global variables, is that right? That means also that the function is interpreted in real time, is that right? I'd thought of Ren'Py as something that was precompiled because of the init blocks where all the assets are defined, but I guess I was wrong.
Just to clarify some things about Python (and programming in general), at least as I understand them:
  • Yes, "developing" is a global variable, in the context of your script. However, "not developing" is an expression that works just how it sounds-- it's True when NOT "developing," i.e. when "developing" is False.
ROTFL! *wipes tears from his eyes*

Ah, yes! Sorry, sorry! I'm still not quite used to this whole "natural language" thing of Python's. My programming brain is ... er... programmed... to see something that looks like English and naturally assume it must be a variable or function definition. If it had been "!developing" I would have grokked it immediately.
[*]Yes, Python (and thus Ren'Py) is "precompiled," but functions by their nature (in any programming language) produce different results with different input.
[*]Init blocks provide a way to define assets, including functions, before the script itself begins. It's pretty much unrelated to the compilation step.[/list]
Hmm... from the script errors I get (run time errors on image definitions and text tags not being properly formated or closed) it seems that (at least when the .rpy is run from the launcher) the script is parsed as it is executed. I don't know if it is all pre-cached or not (thus precluding a script from writing to itself) but it seems that the script.rpy is not really 'compiled' and then 'executed', but maybe more 'interpreted' (putting those defs in quotes 'cause I'm not quite sure of the technically correct usage).

Anyhoo, my point was merely surprise and pleasure that something in the script.rpy could show a displayable that is... well... dynamic... but moreover dynamic based on the state of the system in a way that could change itself without another explicit show. I mean, it seems I could do:

Code: Select all

  show darkroom
  show Violet
  "Violet" "Lets make out while everybody thinks we're developing photos!"
  $developing=true
  "Violet" "Smooch!"
And the lighting would change on Violet without me having to do a new "show".

I think...

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#10 Post by PyTom » Thu Jul 19, 2007 11:41 pm

It's sort of half-and-half. We first compile the script into a tree of renpy.ast.Node objects, and then we run those node objects. So gross errors, like syntax errors, get noticed early. There are more subtle errors, like forgetting to close a text tag, that we don't notice at the gross level, and wait until runtime to deal with. Lint checks for some, but not all, of these errors.

Repeat after me: "Lint is not a substitute for thorough testing."
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
DaFool
Lemma-Class Veteran
Posts: 4171
Joined: Tue Aug 01, 2006 12:39 pm
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#11 Post by DaFool » Tue Jul 24, 2007 3:39 pm

And the lighting would change on Violet without me having to do a new "show".

I think...
It does technically work with DynamicDisplayables, but on 6.3.0 for me at least, the change seemed draining and wasn't instantaneous enough.

User avatar
rocket
Veteran
Posts: 373
Joined: Tue Jul 10, 2007 2:54 am
Projects: Starlight Ep0, Ep1
Location: San Fransisco
Contact:

Re: What is the best strategy for dynamically lighting my scene?

#12 Post by rocket » Sun Aug 12, 2007 9:33 pm

meh...

The change worked fine and fast for me (now that I've finally coded it) but...

There's no transition, so I think I'd be better off with a "show image" "with transition" pair.

Ah well... that's what you get for trying to be clever ^^;;

Post Reply

Who is online

Users browsing this forum: _ticlock_