James, like many of these demo programs pong is a hacked copy of something else and possibly not the most logical arrangement! As you will have spotted sx,sy,sz are location components of the ball and dsx,dsy,dsz are velocity components in so far as each loop the locations are incremented by these amounts. 'Gravity' simply works by adding a small negative value to dsy each loop. If clashTest() returns True then it also provides components of the normal vector at that location and dsx,dsy,dsz are modified by a standard reflection operation R = I - 2(I.N)N (in words: find how much of the ball's velocity is in the same (but opposite) direction as the normal then add double that amount in the direction of the normal!) To keep it moving I use a factor just over 2. There is also a bit of a bodge in which I 'jump' the ball out by 0.1 radius, even so there are instances where the ball 'sinks' into walls.
If the speed it too high I reduce it.
Then I check what's happening with the mouse to see where the 'home' bat should move (actually this involves moving EVERYTHING ELSE, the point of view remains at 0,0,0 which is rather difficult to get the hang of)
Then I check if the ball has got to either side (x direction) and if it has reverse the dsx value (giving a random boost at one side)
Then I check to see if the ball has reached either end (home or monster's) i.e. in the z direction. There's a bit of extra checking to see if the bat's in the right place and bounce or restart accordingly
Finally the ball position is set to sx,sy,sz In actual fact I could have written ball.x, ball.y, ball.z instead.
Hope that helps figuring it out. Do you get any error message when the program crashes?