I think this adheres to the rules. I've tried to stuff as much as I can into the 20 lines, so users with slower computers may experience problems. Oh, and there's no external media so you can just copy, paste and enjoy! Click to create ripples on the surface. Wait a while and the lights will change colours.
sync on:hide mouse:randomize timer():cls rgb(255,255,255):get image 1,0,0,1,1
create bitmap 1,640,480:set current bitmap 1:for i=1 to 100:ink rgb(255,255,255),0:dot int(rnd(640)),int(rnd(480))
ink rgb(100,100,100),0:dot int(rnd(640)),int(rnd(480)):next i:get image 2,0,0,640,480:set current bitmap 0:make object plain 2,3000,2000
position object 2,500,0,1050:texture object 2,2:set object 2,1,0,1,0,0:make matrix 1,1000,1000,20,20:prepare matrix texture 1,1,1,1
fill matrix 1,0,1:make object sphere 1,20:position camera 500,400,-200:point camera 500,0,500:ballposx#=500
ballposz#=500:dim ripple(2,4):dim light#(3,7):hide light 0:set ambient light 20
for i=1 to 3:make light i:light#(i,1)=int(rnd(1000)):light#(i,2)=int(rnd(1000)):light#(i,3)=int(rnd(16))/4
light#(i,4)=int(rnd(16))/4:light#(i,5)=int(rnd(16))/4:next i:do:lighta#=wrapvalue(lighta#+0.1)
for i=1 to 3:if light#(i,1) 500:light#(i,6)=light#(i,6)-1:endif
if light#(i,2) 500:light#(i,7)=light#(i,7)-1:endif:light#(i,1)=light#(i,1)+light#(i,6)
light#(i,2)=light#(i,2)+light#(i,7):set point light i,light#(i,1),200,light#(i,2):color light i,rgb(abs(sin(wrapvalue(lighta#*light#(i,3)))+1)*127,abs(sin(wrapvalue(lighta#*light#(i,4)))+1)*127,abs(sin(wrapvalue(lighta#*light#(i,5)))+1)*127):next i:if mouseclick()=1 and clicked=0:clicked=1
if ripple(1,4)=0:ripple(1,1)=ballposx#:ripple(1,2)=ballposz#:ripple(1,3)=0:ripple(1,4)=1:else
if ripple(2,4)=0:ripple(2,1)=ballposx#:ripple(2,2)=ballposz#:ripple(2,3)=0:ripple(2,4)=1:endif:endif:endif
if mouseclick()=0:clicked=0:endif:scroll object texture 2,0,0.001:for k=1 to 2
if ripple(k,4) 0:ripple(k,3)=wrapvalue(ripple(k,3)-5):ripple(k,4)=ripple(k,4)+1:if ripple(k,4)=151:ripple(k,4)=0:endif:endif:next k
for i=0 to 20:for j=0 to 20:for k=1 to 2:if (sqrt((((i*(1000/20))-ripple(k,1))^2)+(((j*(1000/20))-ripple(k,2))^2))) (ripple(k,4)*5)-540:height#=height#+sin(2*(ripple(k,3)+sqrt((((i*(1000/20))-ripple(k,1))^2)+(((j*(1000/20))-ripple(k,2))^2))))*((150-ripple(k,4))/5):endif
next k:set matrix height 1,i,j,height#:height#=0:next j:next i:update matrix 1:ballposx#=ballposx#+mousemovex():ballposz#=ballposz#-mousemovey()
if ballposx# 1000:ballposx#=1000:endif:position object 1,ballposx#,50,ballposz#
if ballposz# 1000:ballposz#=1000:endif:sync
sync rate 60:text 0,440,"The Darthster's ripples 'n' lights! Fps:"+str$(screen fps()):loop
I'm going on the principle that if..else..endif, for..next and do..loop are all one command each. It's for dbpro, since db can't hack the massive long line I put in the middle. If you break it down and substitute some variables it should work in db.
Tell me what you think. I get 62fps.
Btw, this is version 2 because the '' operators in the original were deleted by the code tags, so spaces either side of the operators mean it should work now.