Quake Strogganoff Spotlight: Framer

Sun, Mar 1, 2020 3-minute read

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!