Frame Timer Bundle

This is a very simple timer that counts game frames rather than real-time seconds:

Code
{"data":{"behavior":{"v":"2","nodes":[{"inputCount":6,"outputCount":2,"name":"Frame Timer","behaviorType":"logic.NodeGroup","x":180,"y":96,"id":"77e1d1dcee404b44","isMenuItem":false},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":0,"y":0,"group":"77e1d1dcee404b44","id":"77e1d1dc1615f74a","startVal":0,"tag":"(0,0)","roundMode":1},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":96,"group":"77e1d1dcee404b44","id":"77e1d1dc85f34747","portId":"77e1d1dcee404b44i0","tag":"Delay","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":160,"group":"77e1d1dcee404b44","id":"77e1d1dc14425b4c","portId":"77e1d1dcee404b44i1","tag":"Repeat Count","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":224,"group":"77e1d1dcee404b44","id":"77e1d1dc5a70e44e","portId":"77e1d1dcee404b44i2","tag":"Pause","dataType":2},{"expression":"(B%A)==0?1:0","default0":1,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"Frame Delay","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":1080,"y":480,"group":"77e1d1dcee404b44","id":"77e1d1dcb86cba44"},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":1440,"y":448,"group":"77e1d1dcee404b44","id":"77e1d1dcfe23e847","startVal":0,"tag":"Output Number","roundMode":1},{"gateVal":1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter","x":1260,"y":512,"group":"77e1d1dcee404b44","id":"77e1d1dc298a1741"},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":360,"y":416,"group":"77e1d1dcee404b44","id":"77e1d1dc80adf642","startVal":0,"tag":"Reset","roundMode":1},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":1620,"y":352,"group":"77e1d1dcee404b44","id":"77e1d1dd6859e746","portId":"77e1d1dcee404b44o0","tag":"Out#","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":288,"group":"77e1d1dcee404b44","id":"77e1d1dd37f08d41","portId":"77e1d1dcee404b44i3","tag":"Resume","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":352,"group":"77e1d1dcee404b44","id":"77e1d1ddb7e0d541","portId":"77e1d1dcee404b44i4","tag":"Reset","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":416,"group":"77e1d1dcee404b44","id":"77e1d1dd5df2504d","portId":"77e1d1dcee404b44i5","tag":"Start","dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":540,"y":576,"group":"77e1d1dcee404b44","id":"77e1d1dd593c3645","_startVal":1,"dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":360,"y":608,"group":"77e1d1dcee404b44","id":"77e1d1dd20357940","_startVal":0,"dataType":2},{"inputCount":0,"outputCount":1,"name":"Always","behaviorType":"logic.triggers.Always","x":180,"y":640,"group":"77e1d1dcee404b44","id":"77e1d1dda73ce549"},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":1980,"y":640,"group":"77e1d1dcee404b44","id":"77e1d1dd495e254a","portId":"77e1d1dcee404b44o1","tag":"Done","dataType":2},{"expression":"B==A?1:0","default0":1,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"==Repeat Count?","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":1620,"y":416,"group":"77e1d1dcee404b44","id":"77e1d1dd681cd444"},{"gateVal":0,"mode":"greater than","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter","x":540,"y":224,"group":"77e1d1dcee404b44","id":"77e1d1ddc618344e"},{"expression":"Math.round((Math.max(A,0)),1)","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Nearest Positive Integer","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":360,"y":192,"group":"77e1d1dcee404b44","id":"77e1d1dd6744454b"},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":900,"y":512,"group":"77e1d1dcee404b44","id":"77e1d1dd826af149","startVal":0,"tag":"Frame Number","roundMode":1},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":720,"y":544,"group":"77e1d1dcee404b44","id":"77e1d1dd90966b48","_startVal":1,"dataType":2},{"gateVal":1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter","x":1800,"y":448,"group":"77e1d1dcee404b44","id":"77e1d1dd67971b43"},{"expression":"Math.round((Math.max(A,1)),1)","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Nearest Positive Integer Excluding 0","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":360,"y":96,"group":"77e1d1dcee404b44","id":"77e1d1dd0c9ffc4f"}],"links":[{"input_id":"77e1d1dd0c9ffc4fi0","output_id":"77e1d1dc85f34747o0"},{"input_id":"77e1d1dd0c9ffc4fi1","output_id":"77e1d1dc85f34747o0"},{"input_id":"77e1d1dd6744454bi0","output_id":"77e1d1dc14425b4co0"},{"input_id":"77e1d1dd6744454bi1","output_id":"77e1d1dc14425b4co0"},{"input_id":"77e1d1dd593c3645i0","output_id":"77e1d1dc5a70e44eo0"},{"input_id":"77e1d1dc298a1741i0","output_id":"77e1d1dcb86cba44o0"},{"input_id":"77e1d1dd6859e746i0","output_id":"77e1d1dcfe23e847o0"},{"input_id":"77e1d1dd681cd444i1","output_id":"77e1d1dcfe23e847o0"},{"input_id":"77e1d1dd681cd444i2","output_id":"77e1d1dcfe23e847o0"},{"input_id":"77e1d1dcfe23e847i2","output_id":"77e1d1dc298a1741o0"},{"input_id":"77e1d1dcfe23e847i0","output_id":"77e1d1dc80adf642o0"},{"input_id":"77e1d1dd826af149i0","output_id":"77e1d1dc80adf642o0"},{"input_id":"77e1d1dd593c3645i1","output_id":"77e1d1dc80adf642o0"},{"input_id":"77e1d1dd593c3645i1","output_id":"77e1d1dd37f08d41o0"},{"input_id":"77e1d1dc80adf642i1","output_id":"77e1d1ddb7e0d541o0"},{"input_id":"77e1d1dd20357940i0","output_id":"77e1d1ddb7e0d541o0"},{"input_id":"77e1d1dc80adf642i1","output_id":"77e1d1dd5df2504do0"},{"input_id":"77e1d1dd20357940i1","output_id":"77e1d1dd5df2504do0"},{"input_id":"77e1d1dd90966b48i2","output_id":"77e1d1dd593c3645o0"},{"input_id":"77e1d1dd593c3645i2","output_id":"77e1d1dd20357940o0"},{"input_id":"77e1d1dd20357940i2","output_id":"77e1d1dda73ce549o0"},{"input_id":"77e1d1dd67971b43i0","output_id":"77e1d1dd681cd444o0"},{"input_id":"77e1d1dd681cd444i0","output_id":"77e1d1ddc618344eo0"},{"input_id":"77e1d1dd90966b48i1","output_id":"77e1d1ddc618344eo0"},{"input_id":"77e1d1dd90966b48i0","output_id":"77e1d1ddc618344eo1"},{"input_id":"77e1d1ddc618344ei0","output_id":"77e1d1dd6744454bo0"},{"input_id":"77e1d1dcb86cba44i1","output_id":"77e1d1dd826af149o0"},{"input_id":"77e1d1dcb86cba44i2","output_id":"77e1d1dd826af149o0"},{"input_id":"77e1d1dd826af149i2","output_id":"77e1d1dd90966b48o0"},{"input_id":"77e1d1dc80adf642i1","output_id":"77e1d1dd67971b43o0"},{"input_id":"77e1d1dd20357940i0","output_id":"77e1d1dd67971b43o0"},{"input_id":"77e1d1dd495e254ai0","output_id":"77e1d1dd67971b43o0"},{"input_id":"77e1d1dcb86cba44i0","output_id":"77e1d1dd0c9ffc4fo0"}]}}}

I just figured I’d share this since I find it pretty useful to have a timer that stays consistent with the game’s framerate. It’s especially good for weapon fire rates and things like that (which can start to trigger too often with a normal timer when a game lags a lot).
This timer bundle also includes inputs and outputs that I would love to have on the normal Timer behavior (Repeat Count, Pause, Resume, Output Number, and Done).

6 Likes

I’ve been using one of these for a while, really useful

2 Likes

I recently made a new version of this and figured I should share it:
Frame Timer

Frame Timer Code
{"data":{"behavior":{"v":"2","nodes":[{"inputCount":7,"outputCount":2,"name":"Frame Timer","behaviorType":"logic.NodeGroup","x":180,"y":80,"id":"366ec79b25cec045","notes":"You need to connect an Always behavior to the Always input here in order for this to work (but make sure the Always behavior is below any other behaviors that set this timer's properties),\nThis timer counts by frames instead of seconds, so it always is consistent with the game's framerate, not the real life time. \nInputting anything greater than 0 to the Repeat input will set how many frames to wait between Out# outputs.\nSetting Repeat to 0 just disables this entire timer.\nSetting Repeat to -1 makes the timer repeat forever (unlimited output count)","n_o":1,"isMenuItem":false},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":96,"group":"366ec79b25cec045","id":"366ec79bf1e5644d","portId":"366ec79b25cec045i0","tag":"Delay","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":160,"group":"366ec79b25cec045","id":"366ec79b6140e34e","portId":"366ec79b25cec045i1","tag":"Repeat Count","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":224,"group":"366ec79b25cec045","id":"366ec79cf8b1864b","portId":"366ec79b25cec045i2","tag":"Pause","dataType":2},{"expression":"(B%A)==0?1:0","default0":30,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"Frame Delay","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":1080,"y":480,"group":"366ec79b25cec045","id":"366ec79c7fcd2144"},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":1440,"y":448,"group":"366ec79b25cec045","id":"366ec79ce8c59245","startVal":0,"tag":"Output Number","roundMode":1},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":360,"y":416,"group":"366ec79b25cec045","id":"366ec79c521fca40","startVal":0,"tag":"Reset","roundMode":1},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":1800,"y":320,"group":"366ec79b25cec045","id":"366ec79d4489b44b","portId":"366ec79b25cec045o0","tag":"Out#","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":288,"group":"366ec79b25cec045","id":"366ec79d0914884a","portId":"366ec79b25cec045i3","tag":"Resume","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":352,"group":"366ec79b25cec045","id":"366ec79d3934f549","portId":"366ec79b25cec045i4","tag":"Reset","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":416,"group":"366ec79b25cec045","id":"366ec79d20aa644b","portId":"366ec79b25cec045i5","tag":"Start","dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":540,"y":576,"group":"366ec79b25cec045","id":"366ec79dae5faa49","_startVal":1,"dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":360,"y":608,"group":"366ec79b25cec045","id":"366ec79d22fcb948","_startVal":0,"dataType":2},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":2160,"y":464,"group":"366ec79b25cec045","id":"366ec79d8e381a44","portId":"366ec79b25cec045o1","tag":"Done","dataType":2},{"expression":"B==A?1:0","default0":1,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"==Repeat Count?","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":1800,"y":384,"group":"366ec79b25cec045","id":"366ec79d26478a41"},{"expression":"Math.round((Math.max(A,-1)),1)","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Nearest Positive Integer","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":360,"y":192,"group":"366ec79b25cec045","id":"366ec79e3d520747"},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":900,"y":512,"group":"366ec79b25cec045","id":"366ec79e90e8bd46","startVal":0,"tag":"Frame Number","roundMode":1},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":720,"y":544,"group":"366ec79b25cec045","id":"366ec79eb5af0e44","_startVal":1,"dataType":2},{"expression":"Math.round((Math.max(A,1)),1)","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Nearest Positive Integer Excluding 0","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":360,"y":96,"group":"366ec79b25cec045","id":"366ec79eb5b45b48"},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":664,"group":"366ec79b25cec045","id":"366ec79eb7ea3e48","portId":"366ec79b25cec045i6","tag":"Always","dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":1620,"y":328,"group":"366ec79b25cec045","id":"366ec79e5ad34e42","_startVal":1,"dataType":2},{"gateVal":1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":1260,"y":504,"group":"366ec79b25cec045","id":"366ec79e325c7843"},{"gateVal":0,"mode":"not equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":540,"y":200,"group":"366ec79b25cec045","id":"366ec79ea3d4c64f"},{"gateVal":1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":1980,"y":408,"group":"366ec79b25cec045","id":"366ec79e75d40c46"},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":1620,"y":416,"group":"366ec79b25cec045","id":"366ec79e9cd2444a","_startVal":1,"dataType":2},{"gateVal":-1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":720,"y":192,"group":"366ec79b25cec045","id":"366ec79e4e76b242"}],"links":[{"input_id":"366ec79eb5b45b48i0","output_id":"366ec79bf1e5644do0"},{"input_id":"366ec79eb5b45b48i1","output_id":"366ec79bf1e5644do0"},{"input_id":"366ec79e3d520747i0","output_id":"366ec79b6140e34eo0"},{"input_id":"366ec79e3d520747i1","output_id":"366ec79b6140e34eo0"},{"input_id":"366ec79dae5faa49i0","output_id":"366ec79cf8b1864bo0"},{"input_id":"366ec79e325c7843i1","output_id":"366ec79c7fcd2144o0"},{"input_id":"366ec79e5ad34e42i2","output_id":"366ec79ce8c59245o0"},{"input_id":"366ec79e9cd2444ai2","output_id":"366ec79ce8c59245o0"},{"input_id":"366ec79ce8c59245i0","output_id":"366ec79c521fca40o0"},{"input_id":"366ec79e90e8bd46i0","output_id":"366ec79c521fca40o0"},{"input_id":"366ec79dae5faa49i1","output_id":"366ec79c521fca40o0"},{"input_id":"366ec79dae5faa49i1","output_id":"366ec79d0914884ao0"},{"input_id":"366ec79c521fca40i1","output_id":"366ec79d3934f549o0"},{"input_id":"366ec79d22fcb948i0","output_id":"366ec79d3934f549o0"},{"input_id":"366ec79c521fca40i1","output_id":"366ec79d20aa644bo0"},{"input_id":"366ec79d22fcb948i1","output_id":"366ec79d20aa644bo0"},{"input_id":"366ec79eb5af0e44i2","output_id":"366ec79dae5faa49o0"},{"input_id":"366ec79dae5faa49i2","output_id":"366ec79d22fcb948o0"},{"input_id":"366ec79e75d40c46i1","output_id":"366ec79d26478a41o0"},{"input_id":"366ec79ea3d4c64fi1","output_id":"366ec79e3d520747o0"},{"input_id":"366ec79c7fcd2144i1","output_id":"366ec79e90e8bd46o0"},{"input_id":"366ec79c7fcd2144i2","output_id":"366ec79e90e8bd46o0"},{"input_id":"366ec79e90e8bd46i2","output_id":"366ec79eb5af0e44o0"},{"input_id":"366ec79c7fcd2144i0","output_id":"366ec79eb5b45b48o0"},{"input_id":"366ec79d22fcb948i2","output_id":"366ec79eb7ea3e48o0"},{"input_id":"366ec79d4489b44bi0","output_id":"366ec79e5ad34e42o0"},{"input_id":"366ec79ce8c59245i2","output_id":"366ec79e325c7843o0"},{"input_id":"366ec79e4e76b242i1","output_id":"366ec79ea3d4c64fo0"},{"input_id":"366ec79eb5af0e44i1","output_id":"366ec79ea3d4c64fo0"},{"input_id":"366ec79eb5af0e44i0","output_id":"366ec79ea3d4c64fo1"},{"input_id":"366ec79c521fca40i1","output_id":"366ec79e75d40c46o0"},{"input_id":"366ec79d8e381a44i0","output_id":"366ec79e75d40c46o0"},{"input_id":"366ec79d22fcb948i0","output_id":"366ec79e75d40c46o0"},{"input_id":"366ec79d26478a41i1","output_id":"366ec79e9cd2444ao0"},{"input_id":"366ec79d26478a41i2","output_id":"366ec79e9cd2444ao0"},{"input_id":"366ec79e9cd2444ai0","output_id":"366ec79e4e76b242o0"},{"input_id":"366ec79d26478a41i0","output_id":"366ec79e4e76b242o1"},{"input_id":"366ec79e9cd2444ai1","output_id":"366ec79e4e76b242o1"}]}}}

Once again, this still counts by game frames instead of by seconds, so it will always output consistently relative to the game’s framerate (I’m pretty sure this is how the old timers worked but now they are changed to output based on the real-world time regardless of the framerate).

I have also made a special version of this frame timer that is set to Repeat Forever, and the code is more optimized because then the repeat count part is unnecessary:
Frame Timer Repeat Forever

Frame Timer (Repeat Forever) Code
{"data":{"behavior":{"v":"2","nodes":[{"inputCount":6,"outputCount":1,"name":"FrameTimer RepeatForever","behaviorType":"logic.NodeGroup","x":180,"y":80,"id":"3671b0e757c1ea48","notes":"You need to connect an Always behavior to the Always input here in order for this to work (but make sure the Always behavior is below any other behaviors that set this timer's properties),\nThis timer counts by frames instead of seconds, so it always is consistent with the game's framerate, not the real life time. \rThis version of the Frame Timer will repeat forever---it has no limit on how many times it will output once started. (So there is no Repeat input or Done output.)","n_o":1,"isMenuItem":false},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":96,"group":"3671b0e757c1ea48","id":"3671b0e76e9d2a40","portId":"3671b0e757c1ea48i0","tag":"Delay","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":160,"group":"3671b0e757c1ea48","id":"3671b0e7dc9b084c","portId":"3671b0e757c1ea48i1","tag":"Pause","dataType":2},{"expression":"(B%A)==0?1:0","default0":30,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"Frame Delay","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":900,"y":256,"group":"3671b0e757c1ea48","id":"3671b0e8c5d37b4c"},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":1260,"y":216,"group":"3671b0e757c1ea48","id":"3671b0e868d37a40","startVal":0,"tag":"Output Number","roundMode":1},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":360,"y":288,"group":"3671b0e757c1ea48","id":"3671b0e841480142","startVal":0,"tag":"Reset","roundMode":1},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":1440,"y":240,"group":"3671b0e757c1ea48","id":"3671b0e80c48c848","portId":"3671b0e757c1ea48o0","tag":"Out#","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":224,"group":"3671b0e757c1ea48","id":"3671b0e83f0a7641","portId":"3671b0e757c1ea48i2","tag":"Resume","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":288,"group":"3671b0e757c1ea48","id":"3671b0e821805647","portId":"3671b0e757c1ea48i3","tag":"Reset","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":352,"group":"3671b0e757c1ea48","id":"3671b0e85d6ab64e","portId":"3671b0e757c1ea48i4","tag":"Start","dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":540,"y":336,"group":"3671b0e757c1ea48","id":"3671b0e88c59fb40","_startVal":1,"dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":360,"y":376,"group":"3671b0e757c1ea48","id":"3671b0e8dfd4394e","_startVal":0,"dataType":2},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":720,"y":296,"group":"3671b0e757c1ea48","id":"3671b0e8a95eaa4e","startVal":0,"tag":"Frame Number","roundMode":1},{"expression":"Math.round((Math.max(A,1)),1)","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Nearest Positive Integer Excluding 0","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":360,"y":96,"group":"3671b0e757c1ea48","id":"3671b0e9fd549344"},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":416,"group":"3671b0e757c1ea48","id":"3671b0e9d65c1b40","portId":"3671b0e757c1ea48i5","tag":"Always","dataType":2},{"gateVal":1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":1080,"y":272,"group":"3671b0e757c1ea48","id":"3671b0e9bdf59847"}],"links":[{"input_id":"3671b0e9fd549344i0","output_id":"3671b0e76e9d2a40o0"},{"input_id":"3671b0e9fd549344i1","output_id":"3671b0e76e9d2a40o0"},{"input_id":"3671b0e88c59fb40i0","output_id":"3671b0e7dc9b084co0"},{"input_id":"3671b0e9bdf59847i1","output_id":"3671b0e8c5d37b4co0"},{"input_id":"3671b0e80c48c848i0","output_id":"3671b0e868d37a40o0"},{"input_id":"3671b0e868d37a40i0","output_id":"3671b0e841480142o0"},{"input_id":"3671b0e8a95eaa4ei0","output_id":"3671b0e841480142o0"},{"input_id":"3671b0e88c59fb40i1","output_id":"3671b0e841480142o0"},{"input_id":"3671b0e88c59fb40i1","output_id":"3671b0e83f0a7641o0"},{"input_id":"3671b0e841480142i1","output_id":"3671b0e821805647o0"},{"input_id":"3671b0e8dfd4394ei0","output_id":"3671b0e821805647o0"},{"input_id":"3671b0e841480142i1","output_id":"3671b0e85d6ab64eo0"},{"input_id":"3671b0e8dfd4394ei1","output_id":"3671b0e85d6ab64eo0"},{"input_id":"3671b0e8a95eaa4ei2","output_id":"3671b0e88c59fb40o0"},{"input_id":"3671b0e88c59fb40i2","output_id":"3671b0e8dfd4394eo0"},{"input_id":"3671b0e8c5d37b4ci1","output_id":"3671b0e8a95eaa4eo0"},{"input_id":"3671b0e8c5d37b4ci2","output_id":"3671b0e8a95eaa4eo0"},{"input_id":"3671b0e8c5d37b4ci0","output_id":"3671b0e9fd549344o0"},{"input_id":"3671b0e8dfd4394ei2","output_id":"3671b0e9d65c1b40o0"},{"input_id":"3671b0e868d37a40i2","output_id":"3671b0e9bdf59847o0"}]}}}

The biggest difference with these is that the Always trigger is no longer inside the bundle, so (after supplying it yourself) you can actually make sure that it will input only after all of the other trigger behaviors that set the timer’s properties. In other words because Flowlab evaluates triggers from left to right (with triggers that share an X coordinate being evaluated from top to bottom), the Always must be evaluated after the other triggers that set this timer’s properties, so now you can be sure that that is actually happening because the Always is outside of the bundle with the rest of the triggers.

3 Likes

@thebrickccentric
Um… would it be possible to make a fps timer in the corner of the screen that displays how much fps the game is running at?

2 Likes

Galactic made it already

It’s basically just an Always → (+)Number
And then a timer set to 1 second resetting the number

Thx

That’s a cool example, but it doesn’t output every frame and it’s only accurate to the whole frame.
If you’re looking for the fps of the screen rendering the game, then the performamce metrics output that (there’s no way to output it through code since the code is capped at 30 fps while the screen’s rendering is not).

If you want an fps counter that outputs the actual fps that the code is running at (every frame, and is accurate to many decimal places), then here:

{"data":{"behavior":{"v":"2","nodes":[{"inputCount":0,"outputCount":0,"name":"FPS Accurate Counter","behaviorType":"logic.NodeGroup","x":-270,"y":-264,"group":"","id":"41a074f906b7e545","isMenuItem":false},{"inputCount":0,"outputCount":1,"name":"Always","behaviorType":"logic.triggers.Always","x":-810,"y":-296,"group":"41a074f906b7e545","id":"41a074f963783043"},{"inputCount":4,"outputCount":4,"name":"Label","behaviorType":"logic.hud.Label2","x":90,"y":-200,"group":"41a074f906b7e545","id":"41a074fa965f074f","text":"0","textColor":0,"fontName":"oduda","scale":10,"textAlign":"left","maxWidth":0,"xO":78,"yO":150,"pin":false,"alpha":100,"kerning":0},{"inputCount":4,"outputCount":4,"name":"Label","behaviorType":"logic.hud.Label2","x":90,"y":-328,"group":"41a074f906b7e545","id":"41a074faba1c7041","text":"FPS:","textColor":0,"fontName":"oduda","scale":10,"textAlign":"left","maxWidth":0,"xO":7,"yO":149,"pin":false,"alpha":100,"kerning":0},{"inputCount":1,"outputCount":4,"name":"Clock","behaviorType":"logic.components.Clock","x":-630,"y":-304,"group":"41a074f906b7e545","id":"41a074fae47c9142","fs":true},{"expression":"B-A","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"Time Difference","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":-270,"y":-296,"group":"41a074f906b7e545","id":"41a074fa285df548"},{"inputCount":2,"outputCount":2,"name":"Toggle","behaviorType":"logic.logic.FlipFlop","x":-450,"y":-296,"group":"41a074f906b7e545","id":"41a074fb7a8c7248","loop":false,"initialState":0},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":-90,"y":-352,"group":"41a074f906b7e545","id":"41a074fb78a2e747","startVal":0,"tag":"Previous Time","roundMode":1},{"expression":"1/A","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Per Second","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":-90,"y":-224,"group":"41a074f906b7e545","id":"41a074fb1e8aea41"}],"links":[{"input_id":"41a074fae47c9142i0","output_id":"41a074f963783043o0"},{"input_id":"41a074fb7a8c7248i1","output_id":"41a074fae47c9142o3"},{"input_id":"41a074fb78a2e747i1","output_id":"41a074fa285df548o0"},{"input_id":"41a074fb1e8aea41i0","output_id":"41a074fa285df548o0"},{"input_id":"41a074fb1e8aea41i1","output_id":"41a074fa285df548o0"},{"input_id":"41a074fa285df548i0","output_id":"41a074fb7a8c7248o0"},{"input_id":"41a074fb7a8c7248i0","output_id":"41a074fb7a8c7248o0"},{"input_id":"41a074fb78a2e747i0","output_id":"41a074fb7a8c7248o1"},{"input_id":"41a074fa285df548i1","output_id":"41a074fb7a8c7248o1"},{"input_id":"41a074fa285df548i2","output_id":"41a074fb7a8c7248o1"},{"input_id":"41a074fa285df548i0","output_id":"41a074fb78a2e747o0"},{"input_id":"41a074fa965f074fi0","output_id":"41a074fb1e8aea41o0"}]}}}
1 Like

I’ve made a new (and slightly improved) version of the frame timer bundles…
Here’s the normal version:

{"data":{"behavior":{"v":"2","nodes":[{"inputCount":7,"outputCount":2,"name":"Frame Timer","behaviorType":"logic.NodeGroup","x":-180,"y":-32,"id":"cfd3efb195a58f40","notes":"Made by thebrickccentric\n\nIMPORTANT: You MUST connect an Always behavior to the Always input!","n_o":1,"isMenuItem":false},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":96,"group":"cfd3efb195a58f40","id":"cfd3efb1307d8f4e","notes":"Delay - This is measured in frames. 0 delay means that Out# will output on the same frame that Start is input, 1 delay means that Out# will output on the next frame after Start is input, 2 delay means that Out# will output on not the next frame but the one after that, etc.","portId":"cfd3efb195a58f40i0","tag":"Delay","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":160,"group":"cfd3efb195a58f40","id":"cfd3efb1de6e5847","notes":"Repeat - This is how many times you want the timer to output before it stops. 0 Repeat just disables the timer (nothing will output), 1 repeat means the timer will output once, 2 repeat means it will output twice, etc. You CAN input Infinity to the Repeat input if you want the timer to repeat forever.","n_o":0,"portId":"cfd3efb195a58f40i1","tag":"Repeat Count","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":224,"group":"cfd3efb195a58f40","id":"cfd3efb12c07f545","notes":"Pause - Pauses the timer, but does not reset anything.","portId":"cfd3efb195a58f40i2","tag":"Pause","dataType":2},{"expression":"B%(A+1)==0?1:0","default0":1,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"Frame Delay","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":1080,"y":480,"group":"cfd3efb195a58f40","id":"cfd3efb3a045e34f","notes":"CHANGE THE DEFAULT DELAY HERE (by changing the value of \"A\")","n_o":1},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":1440,"y":448,"group":"cfd3efb195a58f40","id":"cfd3efb4f9a8874d","notes":"Count how many times the timer has output.","startVal":0,"tag":"Output Number","roundMode":1},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":360,"y":416,"group":"cfd3efb195a58f40","id":"cfd3efb4799c1445","notes":"Reset all internal values","startVal":0,"tag":"Reset","roundMode":1},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":1800,"y":256,"group":"cfd3efb195a58f40","id":"cfd3efb4b502df4a","notes":"Out# - This activates only after the same amount of game frames have passed as the value of the Delay input. It counts how many times it is activated and sends that value. The first output is 1, the second output is 2, the third output is 3, etc.","portId":"cfd3efb195a58f40o0","tag":"Out#","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":288,"group":"cfd3efb195a58f40","id":"cfd3efb4f4e41145","notes":"Resume - Starts the timer again right where you left off when Pause was input, and does not change or reset any of the timer's internal values.","portId":"cfd3efb195a58f40i3","tag":"Resume","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":352,"group":"cfd3efb195a58f40","id":"cfd3efb43ecb2b4e","notes":"Reset - Stops the timer from outputting any more, and resets all of the timer's internal values to their default state.","portId":"cfd3efb195a58f40i4","tag":"Reset","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":416,"group":"cfd3efb195a58f40","id":"cfd3efb4fe9b6346","notes":"Start - First, this resets all internal values in the timer. then it begins counting the amount of game frames that pass. Once the amount of frames passed is equal to the Delay input's value, the Out# output will activate.","portId":"cfd3efb195a58f40i5","tag":"Start","dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":540,"y":576,"group":"cfd3efb195a58f40","id":"cfd3efb5461a024d","notes":"Pause / Resume Switch","_startVal":1,"dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":360,"y":608,"group":"cfd3efb195a58f40","id":"cfd3efb588c7184a","notes":"Start / Reset Switch","_startVal":0,"dataType":2},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":2160,"y":704,"group":"cfd3efb195a58f40","id":"cfd3efb58ba07d44","notes":"Done - This outputs only after Out# has activated the same amount of times as the Repeat Count. It sends a value of 1.","portId":"cfd3efb195a58f40o1","tag":"Done","dataType":2},{"expression":"B==A?1:0","default0":1,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"==Repeat Count?","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":1620,"y":416,"group":"cfd3efb195a58f40","id":"cfd3efb52fd83a43","notes":"CHANGE THE DEFAULT REPEAT COUNT HERE (by changing the value of \"A\", set to -1 to make the timer repeat forever)","n_o":1},{"expression":"Math.round(Math.max(A,0))","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Nearest Positive Integer","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":360,"y":192,"group":"cfd3efb195a58f40","id":"cfd3efb52bc37a45","notes":"This ensures that the Repeat Count amount is always positive or 0 and is a whole number (not a decimal, we can't count decimal amount of outputs)"},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":900,"y":512,"group":"cfd3efb195a58f40","id":"cfd3efb567a78946","notes":"Count how many frames have passed","startVal":0,"tag":"Frame Number","roundMode":1},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":720,"y":544,"group":"cfd3efb195a58f40","id":"cfd3efb5aeab024d","notes":"0 Repeat Count Switch","_startVal":1,"dataType":2},{"expression":"Math.round(Math.max(A,0))","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Nearest Positive Integer Excluding 0","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":360,"y":96,"group":"cfd3efb195a58f40","id":"cfd3efb63ce6c94e","notes":"This ensures that the Delay amount is always positive or 0 and is a whole number (not a decimal; we can't count a decimal amount of frames)"},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":664,"group":"cfd3efb195a58f40","id":"cfd3efb6eb4e5a4f","notes":"Always - REMEMBER TO CONNECT AN ALWAYS BEHAVOR TO THIS INPUT; IT IS HOW THE FRAME TIMER COUNTS FRAMES!","portId":"cfd3efb195a58f40i6","tag":"Always","dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":1620,"y":224,"group":"cfd3efb195a58f40","id":"cfd3efb60c8d2d49","notes":"This is so that the final output always happens before \"Done\" outputs","_startVal":1,"dataType":2},{"gateVal":1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":1260,"y":504,"group":"cfd3efb195a58f40","id":"cfd3efb6b6196347","notes":"If the amount of frames passed is equal to the set delay, then output"},{"gateVal":0,"mode":"greater than","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":540,"y":200,"group":"cfd3efb195a58f40","id":"cfd3efb60d60ee4b","notes":"If the Repeat Count is 0, then the timer is deactivated"},{"gateVal":1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":1800,"y":464,"group":"cfd3efb195a58f40","id":"cfd3efb6fda49145","notes":"Pass=Out# has been output the same amount fo times as the Repeat input value, so the timer is done"},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":1980,"y":688,"group":"cfd3efb195a58f40","id":"cfd3efb6b9bff642","notes":"This is so that \"Done\" always outputs very last","_startVal":1,"dataType":2},{"inputCount":0,"outputCount":1,"name":"Always","behaviorType":"logic.triggers.Always","x":-360,"y":96,"group":"","id":"cfe77207e879b546"}],"links":[{"input_id":"cfd3efb195a58f40i6","output_id":"cfe77207e879b546o0"},{"input_id":"cfd3efb195a58f40i6","output_id":"cfe77207e879b546o0"},{"input_id":"cfd3efb63ce6c94ei0","output_id":"cfd3efb1307d8f4eo0"},{"input_id":"cfd3efb63ce6c94ei1","output_id":"cfd3efb1307d8f4eo0"},{"input_id":"cfd3efb52bc37a45i0","output_id":"cfd3efb1de6e5847o0"},{"input_id":"cfd3efb52bc37a45i1","output_id":"cfd3efb1de6e5847o0"},{"input_id":"cfd3efb5461a024di0","output_id":"cfd3efb12c07f545o0"},{"input_id":"cfd3efb6b6196347i1","output_id":"cfd3efb3a045e34fo0"},{"input_id":"cfd3efb60c8d2d49i2","output_id":"cfd3efb4f9a8874do0"},{"input_id":"cfd3efb52fd83a43i1","output_id":"cfd3efb4f9a8874do0"},{"input_id":"cfd3efb52fd83a43i2","output_id":"cfd3efb4f9a8874do0"},{"input_id":"cfd3efb4f9a8874di0","output_id":"cfd3efb4799c1445o0"},{"input_id":"cfd3efb567a78946i0","output_id":"cfd3efb4799c1445o0"},{"input_id":"cfd3efb5461a024di1","output_id":"cfd3efb4799c1445o0"},{"input_id":"cfd3efb5461a024di1","output_id":"cfd3efb4f4e41145o0"},{"input_id":"cfd3efb4799c1445i1","output_id":"cfd3efb43ecb2b4eo0"},{"input_id":"cfd3efb588c7184ai0","output_id":"cfd3efb43ecb2b4eo0"},{"input_id":"cfd3efb4799c1445i1","output_id":"cfd3efb4fe9b6346o0"},{"input_id":"cfd3efb588c7184ai1","output_id":"cfd3efb4fe9b6346o0"},{"input_id":"cfd3efb5aeab024di2","output_id":"cfd3efb5461a024do0"},{"input_id":"cfd3efb5461a024di2","output_id":"cfd3efb588c7184ao0"},{"input_id":"cfd3efb6fda49145i1","output_id":"cfd3efb52fd83a43o0"},{"input_id":"cfd3efb60d60ee4bi1","output_id":"cfd3efb52bc37a45o0"},{"input_id":"cfd3efb3a045e34fi1","output_id":"cfd3efb567a78946o0"},{"input_id":"cfd3efb3a045e34fi2","output_id":"cfd3efb567a78946o0"},{"input_id":"cfd3efb567a78946i2","output_id":"cfd3efb5aeab024do0"},{"input_id":"cfd3efb3a045e34fi0","output_id":"cfd3efb63ce6c94eo0"},{"input_id":"cfd3efb588c7184ai2","output_id":"cfd3efb6eb4e5a4fo0"},{"input_id":"cfd3efb4b502df4ai0","output_id":"cfd3efb60c8d2d49o0"},{"input_id":"cfd3efb4f9a8874di2","output_id":"cfd3efb6b6196347o0"},{"input_id":"cfd3efb52fd83a43i0","output_id":"cfd3efb60d60ee4bo0"},{"input_id":"cfd3efb5aeab024di1","output_id":"cfd3efb60d60ee4bo0"},{"input_id":"cfd3efb5aeab024di0","output_id":"cfd3efb60d60ee4bo1"},{"input_id":"cfd3efb4799c1445i1","output_id":"cfd3efb6fda49145o0"},{"input_id":"cfd3efb588c7184ai0","output_id":"cfd3efb6fda49145o0"},{"input_id":"cfd3efb6b9bff642i2","output_id":"cfd3efb6fda49145o0"},{"input_id":"cfd3efb58ba07d44i0","output_id":"cfd3efb6b9bff642o0"}]}}}

Here’s the Repeat Forever version:

{"data":{"behavior":{"v":"2","nodes":[{"inputCount":6,"outputCount":1,"name":"FrameTimer RepeatForever","behaviorType":"logic.NodeGroup","x":-630,"y":-16,"id":"cfd57d4de4a70f42","notes":"Made by thebrickccentric\n\nIMPORTANT: You MUST connect an Always behavior to the Always input!","n_o":1,"isMenuItem":false},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":160,"group":"cfd57d4de4a70f42","id":"cfd57d4edbc8494f","notes":"Delay - This is measured in frames. 0 delay means that Out# will output on the same frame that Start is input, 1 delay means that Out# will output on the next frame after Start is input, 2 delay means that Out# will output on not the next frame but the one after that, etc.","n_o":0,"portId":"cfd57d4de4a70f42i0","tag":"Delay","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":224,"group":"cfd57d4de4a70f42","id":"cfd57d4e08392c4f","notes":"Pause - Pauses the timer, but does not reset anything.","portId":"cfd57d4de4a70f42i1","tag":"Pause","dataType":2},{"expression":"B%(A+1)==0?1:0","default0":30,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":2,"version":2,"tag":"Frame Delay","inputCount":3,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":900,"y":480,"group":"cfd57d4de4a70f42","id":"cfd57d4e1926944f","notes":"CHANGE THE DEFAULT DELAY HERE (by changing the value of \"A\")","n_o":1},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":1260,"y":448,"group":"cfd57d4de4a70f42","id":"cfd57d4e83a2f84a","notes":"Count how many times the timer has output.","startVal":0,"tag":"Output Number","roundMode":1},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":360,"y":416,"group":"cfd57d4de4a70f42","id":"cfd57d4e36820a43","notes":"Reset all internal values","startVal":0,"tag":"Reset","roundMode":1},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":1440,"y":464,"group":"cfd57d4de4a70f42","id":"cfd57d4e045cad40","notes":"Out# - This activates only after the same amount of game frames have passed as the value of the Delay input. It counts how many times it is activated and sends that value. The first output is 1, the second output is 2, the third output is 3, etc.","portId":"cfd57d4de4a70f42o0","tag":"Out#","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":288,"group":"cfd57d4de4a70f42","id":"cfd57d4e354e914a","notes":"Resume - Starts the timer again right where you left off when Pause was input, and does not change or reset any of the timer's internal values.","portId":"cfd57d4de4a70f42i2","tag":"Resume","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":352,"group":"cfd57d4de4a70f42","id":"cfd57d4e47f25544","notes":"Reset - Stops the timer from outputting any more, and resets all of the timer's internal values to their default state.","portId":"cfd57d4de4a70f42i3","tag":"Reset","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":416,"group":"cfd57d4de4a70f42","id":"cfd57d4e4ae0514c","notes":"Start - First, this resets all internal values in the timer. then it begins counting the amount of game frames that pass. Once the amount of frames passed is equal to the Delay input's value, the Out# output will activate.","portId":"cfd57d4de4a70f42i4","tag":"Start","dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":540,"y":576,"group":"cfd57d4de4a70f42","id":"cfd57d4ec49d9b42","notes":"Pause / Resume Switch","_startVal":1,"dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":360,"y":608,"group":"cfd57d4de4a70f42","id":"cfd57d4f9bff7941","notes":"Start / Reset Switch","_startVal":0,"dataType":2},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":720,"y":528,"group":"cfd57d4de4a70f42","id":"cfd57d4f3eac9e43","notes":"Count how many frames have passed","startVal":0,"tag":"Frame Number","roundMode":1},{"expression":"Math.round(Math.max(A,0))","default0":0,"default1":0,"default2":0,"default3":0,"default4":0,"default5":0,"params":1,"version":2,"tag":"Nearest Positive Integer Excluding 0","inputCount":2,"outputCount":1,"name":"Expression","behaviorType":"logic.logic.Expression","x":360,"y":176,"group":"cfd57d4de4a70f42","id":"cfd57d4fb2cdd648","notes":"This ensures that the Delay amount is always positive or 0 and is a whole number (not a decimal; we can't count a decimal amount of frames)"},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":180,"y":664,"group":"cfd57d4de4a70f42","id":"cfd57d4fb0a69a49","notes":"Always - REMEMBER TO CONNECT AN ALWAYS BEHAVOR TO THIS INPUT; IT IS HOW THE FRAME TIMER COUNTS FRAMES!","portId":"cfd57d4de4a70f42i5","tag":"Always","dataType":2},{"gateVal":1,"mode":"equal to","inputCount":2,"outputCount":2,"name":"Filter","behaviorType":"logic.logic.Filter2","x":1080,"y":496,"group":"cfd57d4de4a70f42","id":"cfd57d4fc4da4a49","notes":"If the amount of frames passed is equal to the set delay, then output"},{"inputCount":0,"outputCount":1,"name":"Always","behaviorType":"logic.triggers.Always","x":-810,"y":112,"group":"","id":"cfe79d3672293148"}],"links":[{"input_id":"cfd57d4de4a70f42i5","output_id":"cfe79d3672293148o0"},{"input_id":"cfd57d4de4a70f42i5","output_id":"cfe79d3672293148o0"},{"input_id":"cfd57d4fb2cdd648i0","output_id":"cfd57d4edbc8494fo0"},{"input_id":"cfd57d4fb2cdd648i1","output_id":"cfd57d4edbc8494fo0"},{"input_id":"cfd57d4ec49d9b42i0","output_id":"cfd57d4e08392c4fo0"},{"input_id":"cfd57d4fc4da4a49i1","output_id":"cfd57d4e1926944fo0"},{"input_id":"cfd57d4e045cad40i0","output_id":"cfd57d4e83a2f84ao0"},{"input_id":"cfd57d4e83a2f84ai0","output_id":"cfd57d4e36820a43o0"},{"input_id":"cfd57d4f3eac9e43i0","output_id":"cfd57d4e36820a43o0"},{"input_id":"cfd57d4ec49d9b42i1","output_id":"cfd57d4e36820a43o0"},{"input_id":"cfd57d4ec49d9b42i1","output_id":"cfd57d4e354e914ao0"},{"input_id":"cfd57d4e36820a43i1","output_id":"cfd57d4e47f25544o0"},{"input_id":"cfd57d4f9bff7941i0","output_id":"cfd57d4e47f25544o0"},{"input_id":"cfd57d4e36820a43i1","output_id":"cfd57d4e4ae0514co0"},{"input_id":"cfd57d4f9bff7941i1","output_id":"cfd57d4e4ae0514co0"},{"input_id":"cfd57d4f3eac9e43i2","output_id":"cfd57d4ec49d9b42o0"},{"input_id":"cfd57d4ec49d9b42i2","output_id":"cfd57d4f9bff7941o0"},{"input_id":"cfd57d4e1926944fi1","output_id":"cfd57d4f3eac9e43o0"},{"input_id":"cfd57d4e1926944fi2","output_id":"cfd57d4f3eac9e43o0"},{"input_id":"cfd57d4e1926944fi0","output_id":"cfd57d4fb2cdd648o0"},{"input_id":"cfd57d4f9bff7941i2","output_id":"cfd57d4fb0a69a49o0"},{"input_id":"cfd57d4e83a2f84ai2","output_id":"cfd57d4fc4da4a49o0"}]}}}

Note: you can still make the normal version repeat forever by sending Infinity to the Repeat input, or setting the default value inside the bundle to -1. (The Repeat Forever version just cuts out some of the code that would be used to check if you’ve reached the repeat count)

Also, these and the FPS counter bundle now have their own game:

2 Likes