While I didn’t start these patterns with the core library, it is actually a foundation to all of the rousr projects, though it’s more of a jack-of-all-trades than anything with a big heavy hitter. As a result, this entry is more of a “grab bag” of helpful scripts I’ve added to our core library to give you some concepts you may not have considered.
I wanted to make sure I gathered everything I’d need for any project and had a very easy way to access it, so while they don’t follow much of a common theme in total - their common theme is “necessity.” You’ll notice a bit of it is heavy on the idea of “caching” and “re-using data” which are really the main tenets of what the
sr_core library is attempting to abstract. In addition, it aims to eliminate as much project “boiler plate” code as it can.
(Boiler plate code is a term used for tidbits of code you have to add to each and every one of your projects, so why not make it small and as painless as possible?)
ensureFont make use of the
gml_pragma("global", "script_name") functionality to set themselves some global, pre-cached data. Whenever you intend to call
draw_set_font you’d use
ensure instead because it works by setting a global variable to whatever is passed to it. The next time it’s called, if its the same value, it just won’t do anything again. This way we can ensure we’re only switching “contexts” when necessary (no need to make a call if its going to return to the same value), but we can also always retrieve the current set value easily.
They’re small little guys, so here’s an example of
sr_ensure_color is very similar:
The two color functions serve as pretty basic helpers -
sr_color_hex(_hex) takes a hex value (as a number, not a string), and converts it to the BGR format that we all know and love that GMS2 uses. This is enormously helpful when you’re trying to match your mockups from aseprite and need to color some text or use a shader…
But speaking of shaders, there’s also
sr_color_glsl(_gml_color) which returns an array of values from 0-1 that represent the passed color.
These 3 functions help you call variable amounts of arguments in a
sr_execute(_func, _params) takes a an array of parameters, up to 32, and calls
_func passing each one as another argument (essentially, it’s an
More advanced use exists with
sr_callback in that the create allows you to creat a single array object that contains the name of a script and arguments to pass to it - but only executes that little bundle of functionality when you
These two are more just ‘fun’ little functions I tend to use with much of my text. They’re not doing anything fancy, they’re actually rendering the same block of text multiple times, and laying them out according to an outline or shadow pattern. You can pass offsets to customize it a bit, but really, they’re just helpers for me incessantly using these text techniques!
sr_core is included with all of the rousr extensions (some extensions only include the pieces of rousrSuite they need), you may already have it if you use any of our extensions! Of course, the most up-to-date version is up on the marketplace, and it always remains compatible with latest versions of each other extension.
Also included is
sr_ensure_singleton(_singleton_name) which implements an older method I used to implement singletons. It expects that the passed name is actually the name of a global variable, checks if it’s set, and if the calling instance is the same id as the current set value of the global - destroying the old one if it exists.
Some notes here are that this is a pretty bad way to follow the singleton pattern, but it does actually work. Notably, it destroys an existing singleton if one is created - this is probably more of a bug than anything because in use, you’d never want your existing data blown away… or you’d at least want to expect that it is going to happen.
Instead, now what I tend to do is something along the lines of this:
Users of your singleton can always use the
with(TestSingleton) syntax. It gives them the benefit of an automatic “null check” (checking if an instance actually is valid), and also ensures they’re accessing the one true singleton. Since we destroy any duplicates, the
with syntax will still refer to the existing one, and users will be none-the-wiser (unless you want them to be).
One benefit of the singleton pattern is that you can use objects as a “namespace” rather than loading up the global namespace with temps - but you can also manage the lifetime of globals such as data structures that might need to be cleaned up…
But of course, that’s just one use!