Quake Strogganoff Spotlight: Framer
Tired of frame functions? Looking for an alternative? Framer to the rescue.
NOTE: I highly recommend checking out an article from the original author NumberSix for more in-depth information.
And here’s an example of a basic standing loop used for the Brain enemy from Quake 2, which is sort of like if Johnny Five was created by David Cronenberg:
void() brain_stand1 =[ $FRAME_stand01, brain_stand2 ] {ai_stand();};
void() brain_stand2 =[ $FRAME_stand02, brain_stand3 ] {ai_stand();};
void() brain_stand3 =[ $FRAME_stand03, brain_stand4 ] {ai_stand();};
void() brain_stand4 =[ $FRAME_stand04, brain_stand5 ] {ai_stand();};
void() brain_stand5 =[ $FRAME_stand05, brain_stand6 ] {ai_stand();};
void() brain_stand6 =[ $FRAME_stand06, brain_stand7 ] {ai_stand();};
void() brain_stand7 =[ $FRAME_stand07, brain_stand8 ] {ai_stand();};
void() brain_stand8 =[ $FRAME_stand08, brain_stand9 ] {ai_stand();};
void() brain_stand9 =[ $FRAME_stand09, brain_stand10 ] {ai_stand();};
void() brain_stand10 =[ $FRAME_stand10, brain_stand11 ] {ai_stand();};
void() brain_stand11 =[ $FRAME_stand11, brain_stand12 ] {ai_stand();};
void() brain_stand12 =[ $FRAME_stand12, brain_stand13 ] {ai_stand();};
void() brain_stand13 =[ $FRAME_stand13, brain_stand14 ] {ai_stand();};
void() brain_stand14 =[ $FRAME_stand14, brain_stand15 ] {ai_stand();};
void() brain_stand15 =[ $FRAME_stand15, brain_stand16 ] {ai_stand();};
void() brain_stand16 =[ $FRAME_stand16, brain_stand17 ] {ai_stand();};
void() brain_stand17 =[ $FRAME_stand17, brain_stand18 ] {ai_stand();};
void() brain_stand18 =[ $FRAME_stand18, brain_stand19 ] {ai_stand();};
void() brain_stand19 =[ $FRAME_stand19, brain_stand20 ] {ai_stand();};
void() brain_stand20 =[ $FRAME_stand20, brain_stand21 ] {ai_stand();};
void() brain_stand21 =[ $FRAME_stand21, brain_stand22 ] {ai_stand();};
void() brain_stand22 =[ $FRAME_stand22, brain_stand23 ] {ai_stand();};
void() brain_stand23 =[ $FRAME_stand23, brain_stand24 ] {ai_stand();};
void() brain_stand24 =[ $FRAME_stand24, brain_stand25 ] {ai_stand();};
void() brain_stand25 =[ $FRAME_stand25, brain_stand26 ] {ai_stand();};
void() brain_stand26 =[ $FRAME_stand26, brain_stand27 ] {ai_stand();};
void() brain_stand27 =[ $FRAME_stand27, brain_stand28 ] {ai_stand();};
void() brain_stand28 =[ $FRAME_stand28, brain_stand29 ] {ai_stand();};
void() brain_stand29 =[ $FRAME_stand29, brain_stand30 ] {ai_stand();};
void() brain_stand30 =[ $FRAME_stand30, brain_stand31 ] {ai_stand();};
void() brain_stand31 =[ $FRAME_stand01, brain_stand32 ] {ai_stand();};
void() brain_stand32 =[ $FRAME_stand02, brain_stand33 ] {ai_stand();};
void() brain_stand33 =[ $FRAME_stand03, brain_stand34 ] {ai_stand();};
void() brain_stand34 =[ $FRAME_stand04, brain_stand35 ] {ai_stand();};
void() brain_stand35 =[ $FRAME_stand05, brain_stand36 ] {ai_stand();};
void() brain_stand36 =[ $FRAME_stand06, brain_stand37 ] {ai_stand();};
void() brain_stand37 =[ $FRAME_stand07, brain_stand38 ] {ai_stand();};
void() brain_stand38 =[ $FRAME_stand08, brain_stand39 ] {ai_stand();};
void() brain_stand39 =[ $FRAME_stand09, brain_stand40 ] {ai_stand();};
void() brain_stand40 =[ $FRAME_stand10, brain_stand41 ] {ai_stand();};
void() brain_stand41 =[ $FRAME_stand11, brain_stand42 ] {ai_stand();};
void() brain_stand42 =[ $FRAME_stand12, brain_stand43 ] {ai_stand();};
void() brain_stand43 =[ $FRAME_stand13, brain_stand44 ] {ai_stand();};
void() brain_stand44 =[ $FRAME_stand14, brain_stand45 ] {ai_stand();};
void() brain_stand45 =[ $FRAME_stand15, brain_stand46 ] {ai_stand();};
void() brain_stand46 =[ $FRAME_stand16, brain_stand47 ] {ai_stand();};
void() brain_stand47 =[ $FRAME_stand17, brain_stand48 ] {ai_stand();};
void() brain_stand48 =[ $FRAME_stand18, brain_stand49 ] {ai_stand();};
void() brain_stand49 =[ $FRAME_stand19, brain_stand50 ] {ai_stand();};
void() brain_stand50 =[ $FRAME_stand20, brain_stand51 ] {ai_stand();};
void() brain_stand51 =[ $FRAME_stand21, brain_stand52 ] {ai_stand();};
void() brain_stand52 =[ $FRAME_stand22, brain_stand53 ] {ai_stand();};
void() brain_stand53 =[ $FRAME_stand23, brain_stand54 ] {ai_stand();};
void() brain_stand54 =[ $FRAME_stand24, brain_stand55 ] {ai_stand();};
void() brain_stand55 =[ $FRAME_stand25, brain_stand56 ] {ai_stand();};
void() brain_stand56 =[ $FRAME_stand26, brain_stand57 ] {ai_stand();};
void() brain_stand57 =[ $FRAME_stand27, brain_stand58 ] {ai_stand();};
void() brain_stand58 =[ $FRAME_stand28, brain_stand59 ] {ai_stand();};
void() brain_stand59 =[ $FRAME_stand29, brain_stand60 ] {ai_stand();};
void() brain_stand60 =[ $FRAME_stand30, brain_stand1 ] {ai_stand();};
And all of that is handled by this one line below:
framerloop($FRAME_stand01, $FRAME_stand30, brain_stand_frames, 0.1, ai_stand());
This translates to: first frame, last fame, function name called by th.stand, next think / framerate, and the ai_routine for each frame. Framerloop just means this function will repeat. Also, if instead of 0.1, you did 0.05 it would be 20 FPS and 0.033 would be 30 FPS… I think.
As you can see from the above function, framer makes short work of what is otherwise a very tedious task. Bonus.
That’s pretty much it folks, I just wanted to send some praise for something that should get more attention.
Happy modding!