Ugh, that thing again… no wonder. (Sorry, that sample is kinda my pet peeve.)
It does generate normal vectors:
normal = GeomVertexWriter(vdata, 'normal')
...
normal.addData3(normalize(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
normal.addData3(normalize(2 * x2 - 1, 2 * y1 - 1, 2 * z1 - 1))
normal.addData3(normalize(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
normal.addData3(normalize(2 * x1 - 1, 2 * y2 - 1, 2 * z2 - 1))
But they always point away from the center of the cube (that the square is supposed to be a side of), while they should be perpendicular to the square in this case. Just one of the reasons I don’t like that sample.
If you’re interested in procedural geometry, feel free to check this out. (Shameless plug, sorry (again) .)
If you’re going with CardMaker, note that it generates its rectangles in the XZ-plane, so you’ll have to do:
playing_surface.set_p(-90.)
Cheers!