Fixing a CG Gallery unlock bug. Thumbnail of a Kahlua steamer with cocoa powder sprinkled on top.
CG Gallery unlock bug
The recent Android build/update also introduced a bug where CGs weren’t unlocking properly in the gallery. Some investigation into how images are indicated as being seen revealed that the new layeredimage
syntax was not playing nicely.
Images are defined in the format of image_name attribute1 attribute2 ...
. Ren’Py keeps a dictionary of seen images in persistent._seen_images
with key-value pairs of (image_name, attribute1, attribute2 …):Boolean, where the Boolean is True/False depending on whether the image has been seen.
Code for unlocking gallery images is simply gallery.unlock(image_name)
. Before the layeredimage optimization conversion, we were doing gallery.unlock('cg1')
and the like. This worked out alright because the code for showing the image in-game was scene cg1 with Dissolve(.3)
. In both the gallery unlock code and the in-game code, the image being viewed is cg1
. After the optimization update, we had to change in-game cg code to scene cg1 attribute1 attribute2 with Dissolve(.3)
.
We originally thought that Ren’Py was looking up whether just image_name
was seen by the player, not image_name attribute1 attribute2
was seen by the player. An example (inefficient) code for this kind of lookup is:
image_definition = ('image_name', 'attribute1', 'attribute2')
image_seen = False
for key in persistent._seen_images.keys():
if image_definition[0] in key:
image_seen = True
Instead, Ren’Py is doing a very basic lookup.
image_definition = ('image_name', 'attribute1', 'attribute2')
image_seen = False
if image_definition in persistent.seen_images.keys():
image_seen = True
So we needed to change the gallery unlock code to include all the image attributes: gallery.unlock('cg1 attribute1 attribute2')
. And order matters. gallery.unlock('cg1 attribute2 attribute1')
would not work because it’s a different tuple.
Base seems to be a special keyword for layeredimages
In one of our layeredimages, we had an attribute base
.
layeredimage randal:
always "something"
group base prefix "base":
attribute 1 "base1"
attribute 2 "base2"
group eyes prefix "eyes":
attribute neutral ...
We expected that if we did scene randal base_1 eyes_neutral
, then the corresponding tuple would be ('randal', 'base_1', 'eyes_neutral')
. This was not the case. Instead, the tuple was ('randal', '1', 'eyes_neutral')
. This caused a bit of trouble with figuring out why one of the CGs wasn’t unlocking properly. A quick fix was to change the prefix to “pose”.