Page 1 of 1

Applying a tint to a whole scene in the game

Posted: Wed Aug 13, 2014 6:16 am
by harajukulolita
Hi everyone, I'm sorry if this question has been asked before and I haven't seen it. I wanted to know how to creat a tint for a whole scene in the game. For example, if it were a memory then the whole thing would play out in a sepia or greyscale tint.

I know that this can be done with individual images using the im.Sepia and im.Greyscale operations among others but can how do I apply the sepia or greyscale to the whole scene without defining individual images?

Re: Applying a tint to a whole scene in the game

Posted: Wed Aug 13, 2014 8:46 am
by xela
You can't, scene isn't an image.

I have no idea on how this can be done, maybe a solid with a tweaked alpha channel. That could potentially give the scene a darker look but it's far away from greyscale effect.

Re: Applying a tint to a whole scene in the game

Posted: Wed Aug 13, 2014 8:47 am
by Asceai
Ren'Py currently can't do this in any half-decent way. The only matrix colour operations available are image manipulators. They can't be applied 'live' so you can't e.g. make a Transform that turns everything grey.

Now, to get around the 'defining individual images' part, here's a hack I wrote. It is the very definition of a hack because it uses undocumented internal Ren'Py functionality (specifically, the 'images' dictionary, used to get a list of images) but it creates greyscale versions of every image.

Code: Select all

init 999 python:
  grey_images = {}
  for i in renpy.display.image.images:
    try:
      grey_im_name = i + ('greyscale',)
      grey_images[grey_im_name] = im.Grayscale(renpy.display.image.images[i])
    except:
      pass
  for i in grey_images:
    renpy.image(i, grey_images[i])
So, instead of 'show picture' you can use 'show picture greyscale', instead of 'scene background' you can use 'scene background greyscale' etc.
It'll only work with images that are image manipulators - if you have something like an animated image, this won't work with that - while greyscale versions of the individual frames should exist, the code won't know how to use them.

I don't currently know a good way of delivering the second requirement - making everything greyscale automatically. The simplest way is to redefine config.show to check a flag (e.g. greyscale) and apply the 'greyscale' attribute to shown images if it is set (I use getattr to check it so it won't bug out if you haven't set greyscale yet):

Code: Select all

init python:
  def replacement_show(name, *args, **kwargs):
    if getattr(renpy.store, 'greyscale', False):
      renpy.show(name + ('greyscale',), *args, **kwargs)
    else:
      renpy.show(name, *args, **kwargs)
  config.show = replacement_show
This way you can just set the flag and all subsequent shows will use the greyscale variants:

Code: Select all

label start:
  scene forest_bg
  show girl
  girl "Hi!"
  $greyscale = True
  scene forest_bg
  show girl
  "I remembered this place from my childhood..."
  return
There's numerous downsides to this. First, it won't work with renpy.show(), only 'scene' and 'show' statements. It won't work with anything that isn't specified as an image manipulator, so animations etc. won't work (you'd want to create new versions of them with the greyscale image attribute if you use them in these scenes). You also have to re-show everything in the scene to get them to appear in greyscale - the screen doesn't just go grey automatically.

Re: Applying a tint to a whole scene in the game

Posted: Wed Aug 13, 2014 10:22 am
by xela
For any game that doesn't use "live" displayable atm when stuff needs to be greyscaled, this is an excellent workaround. You could potentially define a number of tints and have it go to back/white gradually... excellent example!

Re: Applying a tint to a whole scene in the game

Posted: Wed Aug 13, 2014 12:20 pm
by harajukulolita
Thank you for the advice, not that I mind spending the time defining each image I'm going to use in the scene but it would just be so much better if there were shorter and practical ways of doing this. I'll give this code a try and see how things work out thank you very much :D

Re: Applying a tint to a whole scene in the game

Posted: Thu Sep 21, 2017 10:23 am
by SONTSE
I run into same problem recently, and found this thread.
Asceai solution does work, but it seems modern RenPy auto-define images from "images" folder bypassing the routine that was hacked by the script above, so they are not affected.
Could you please fix the script to include those auto-defined images?

Or is there more decent way to handle that problem so far?
Thanks!

Re: Applying a tint to a whole scene in the game

Posted: Thu Sep 21, 2017 3:24 pm
by CellHG
Can you not create an overlay/screen with the desire effect as an image?

Then do the show screen to show said overlay?

Re: Applying a tint to a whole scene in the game

Posted: Thu Sep 21, 2017 4:11 pm
by SONTSE
CellHG wrote:
Thu Sep 21, 2017 3:24 pm
Can you not create an overlay/screen with the desire effect as an image?

Then do the show screen to show said overlay?
An effect that operates not a single image (like usual effects do), but composite displayables (e.g. whole layer or screen), or simply applies into everything behind it would be exact thing I love to be pointed at. ^^