Setting smart component value in script is ignored?

Im working on script for a pixel font that has pixels (‘tiles’) in different sizes. The tiles are smart components with a property ‘size’ that I use for scaling.

In one version of the font the glyphs are build up from a single tile and in another version I use clusters of eight tiles that are all unique.

For the single tile version my code runs perfect but when I run the cluster version the size property seems to be ignored by Glyphs. I cannot find out why.

Here is part of the code for the single tile version that works well:

# add tiles:
            for x in range(0, xIterations): 

                for y in range(0, yIterations + 4): #yIterations + 1 of meer om boven kapitaalhoogte uit te komen

                    tile_x = x * x_increment  # x center positie van een tile 
                    tile_y = y * y_increment +yStart # y center positie van een tile

                    is_even = y % 2 == 0

                    x_offset = 0

                    if is_even: 
                        x_offset += x_increment / 2 

                    tile_width  = tile.layers[0].bounds.size.width
                    tile_height = tile.layers[0].bounds.size.height

                    number_of_hits_negative =  self.hit_points(tile_x + x_offset, tile_y, round(tile_width * 0.5), round(tile_height * 0.5), thisLayerBezierPath) # tile_width en height * iets om blurgebied groter of kleiner te maken
                    number_of_hits = 9 - number_of_hits_negative

                    # print(number_of_hits)

                    tile_component = GSComponent( tile, NSPoint(0,0) )
                    # print(tile_component)

                    if positive_type :
                        tile_component.smartComponentValues['size'] = number_of_hits
                    else:                  
                        tile_component.smartComponentValues['size'] = number_of_hits_negative


                    tile_component.applyTransform( make_translation_matrix(x * x_increment + x_offset, y * y_increment +yStart) )

                    components.append( tile_component )
                  
            thisLayer.shapes = components

And below is the cluster version. The tiles are placed correctly and I get no error messages, just the size is ignored

 # add tiles:
            for x in range(0, xIterations): 

                for y in range(0, yIterations): #yIterations + 1 of meer om boven kapitaalhoogte uit te komen

                    def place(tile):

                        tile_width  = tile.layers[0].bounds.size.width
                        tile_height = tile.layers[0].bounds.size.height

                        tile_x = tile.layers[0].bounds.origin.x + x * x_increment
                        tile_y = tile.layers[0].bounds.origin.y + y * y_increment +yStart

                        tile_x_center = tile_x + tile_width / 2
                        tile_y_center = tile_y + tile_height / 2

                        number_of_hits_negative =  self.hit_points(tile_x_center, tile_y_center, round(tile_width * 0.33), round(tile_height * 0.33), thisLayerBezierPath) # tile_width en height * iets om blurgebied groter of kleiner te maken
                        number_of_hits = 9 - number_of_hits_negative
                        print(number_of_hits)
                        # print("tile_x_center = "+str(tile_x_center))

                        tile_component = GSComponent( tile, NSPoint(0,0) )
                        # print(tile_component)

                        if positive_type :
                            tile_component.smartComponentValues['size'] = number_of_hits
                        else:
                            tile_component.smartComponentValues['size'] = number_of_hits_negative

                        print("size = " + str(tile_component.smartComponentValues['size']))

                        tile_component.applyTransform( make_translation_matrix(x * x_increment, y * y_increment +yStart) )

                        components.append( tile_component )

                    for i in range(0, len(tiles)):
                        place(tiles[i])

                   
            thisLayer.shapes = components

The size value prints correctly to the console but the smart components remain unchanged. What am I missing?

can you compare the content of smartComponentValues when you set it by a script and when you set it manually?

Thanks for getting back so quickly!
The script sets smartComponentValues between 0 an 9 and so does the _smart component ‘size’ property. If I run the script tiles are placed correctly but their size slider is always set to 0. Is that what you are asking?

No, set the slider manually and then print the content of that property. Then set it to something else and print it again. Are both outputs what you expect?

Ah, I see! When I print the value of the single tile it works as expected: when I use the slider to change the size, the print output is correct. And I can also set the size using a script (see below). But with the cluster tiles this does not work. It ignores the size I set in the script and when I change the size using the slider it prints whatever value I set in the script before (even with that line commented out). This what I used to test this in the macro:


font = Glyphs.font

selected_glyph = font.selectedLayers[0].parent
print(f"Glyph: {selected_glyph.name}")
# Iterate through all layers of the glyph
for layer in selected_glyph.layers:
	print(f"Layer: {layer.name}")
	# Iterate through all components in the layer
	for component in layer.components:
	# Get the position of the component
		x = component.position.x
		y = component.position.y
		# Print the position of the component
		print(f"  Component: {component.componentName}, Position: ({x}, {y})")
	# If the component is a smart component, print its values
	if component.smartComponentValues:
		print("    Smart Component Values:")
		component.smartComponentValues['size'] = 5 #comment out to set the slider manually
		print(component.smartComponentValues['size'])

Use the same component that you like to script and set it up manually. Then print that and replicate that with your script.

Fixed it! Had the feeling it might actually be the smart components and not the script so I recreated the smart components from scratch and ran the script again. Now it works. Comparing the two sets of smart components I cannot detect any differences though. I vaguely remember renaming the smart components at some point, could that have broken anything? Thanks for the help! It is greatly appreciated!