One of the recurring problems in developing Marketplace assets is avoiding name collisions.
Before GM:S 2.3+, all defined functions were global. However, now we can use combinations of global variables and structs to introduce namespacing of code entities with little chance of collisions.
Additionally, GM:S 2.3+ adds more flexibility when it comes to assets groups/directories structure. This in particular allows us to apply consistent grouping.
The question becomes - what kind of namespacing/structures can we apply? Should we try to aim for namespacing/structure conventions in the first place? I believe the widespread the convention becomes, the smoother the experience of Marketplace asset users; provided the convention is well-designed in the first place.
Code namespacing
Code shorthands
Assets naming
Directory structure
Summary
Overall, common Marketplace asset conventions might add a little extra work for setting up the Marketplace asset, but also save the time developer needs to figure out the conventions themself.
Additionally, if common conventions become widespread enough, this should lead to more unified experience of Marketplace asset users, with external assets kept in their own section instead of cluttering the main code.
Of course, the conventions outlined above are applicable to GM:S 2.3+ only (though certain aspects - such as shorthand macros - can be applied in earlier versions as well).
Do you think these kinds of conventions are worth pursuing? Would you like to make some changes? Or maybe you'd like to point out some cases that aren't easily covered by the proposed conventions?
I'd love to hear your thoughts. ^^
Before GM:S 2.3+, all defined functions were global. However, now we can use combinations of global variables and structs to introduce namespacing of code entities with little chance of collisions.
Additionally, GM:S 2.3+ adds more flexibility when it comes to assets groups/directories structure. This in particular allows us to apply consistent grouping.
The question becomes - what kind of namespacing/structures can we apply? Should we try to aim for namespacing/structure conventions in the first place? I believe the widespread the convention becomes, the smoother the experience of Marketplace asset users; provided the convention is well-designed in the first place.
Code namespacing
One idea I have is declaring global structs for publishers, which in turn have items for packages, then for modules or however we call them. So, there could be a module like:
That module would be a struct providing functions and/or variables related to "Process" functionality, whatever the Process is in the context of StackFlow package.
Of course, we need to define a struct for
With that in mind, I came up with three scripts for accessing publishers/packages/modules:
As long as we use these scripts consistently (using the same prefixes inside), we can use these scripts interchangeably among packages - whether the user ignores, overwrites or keeps the scripts, the result would be the same.
Note: I assume the scripts (as defined with
global.marketplace_publisher_Alphish.package_StackFlow.Process
That module would be a struct providing functions and/or variables related to "Process" functionality, whatever the Process is in the context of StackFlow package.
Of course, we need to define a struct for
global.marketplace_publisher_Alphish
global, then another struct for its package_StackFlow
variable, then yet another struct for Process
module. And let's not forget the same publisher or package can have multiple packages/modules, yet it only should be defined once.With that in mind, I came up with three scripts for accessing publishers/packages/modules:
GML:
// defines the publisher if needed, returns the publisher; marketplace_publisher_* prefix is added automatically
marketplace_get_publisher(publisher)
// defines the package if needed, returns the package; package_* prefix is added automatically
marketplace_get_package(publisher, package)
// defines the module if needed, returns the module
marketplace_get_module(publisher, package, module)
Note: I assume the scripts (as defined with
function scriptName(...)
rather than scriptName = function(...)
) are all available before any global code is run (see also: this thread). If it's not the case, it complicates the use of these scripts a lot.Code shorthands
Additionally, we could provide macros with shorthands for packages, modules and/or functions. These shorthands would be kept in separate Script assets, so that they can be skipped/removed easily. Something like these:
GML:
// script: shorthands_Alphish_StackFlow_package
#macro StackFlow global.marketplace_package_Alphish_StackFlow
global.marketplace_package_Alphish_StackFlow = marketplace_get_package("Alphish", "StackFlow");
GML:
// script: shorthands_Alphish_StackFlow_modules
#macro Flow global.marketplace_module_Alphish_StackFlow_Flow
global.marketplace_module_Alphish_StackFlow_Flow = marketplace_get_module("Alphish", "StackFlow", "Flow");
#macro Process global.marketplace_module_Alphish_StackFlow_Process
global.marketplace_module_Alphish_StackFlow_Process = marketplace_get_module("Alphish", "StackFlow", "Process");
#macro AetCetera global.marketplace_module_Alphish_StackFlow_AetCetera
global.marketplace_module_Alphish_StackFlow_AetCetera= marketplace_get_module("Alphish", "StackFlow", "AetCetera");
GML:
// script: shorthands_Alphish_StackFlow_scripts
function StackFlow_Flow_push(_controller) {
return global.marketplace_publisher_Alphish.package_StackFlow.Flow.push(_controller);
}
function StackFlow_Flow_pop() {
return global.marketplace_publisher_Alphish.package_StackFlow.Flow.pop();
}
function StackFlow_Process_run(_instructions) {
return global.marketplace_publisher_Alphish.package_StackFlow.Process.run(_instructions);
}
GML:
// script: shorthands_Alphish_StackFlow_scripts_short
function Flow_push(_controller) {
return global.marketplace_publisher_Alphish.package_StackFlow.Flow.push(_controller);
}
function Flow_pop() {
return global.marketplace_publisher_Alphish.package_StackFlow.Flow.pop();
}
function Process_run(_instructions) {
return global.marketplace_publisher_Alphish.package_StackFlow.Process.run(_instructions);
}
Assets naming
The simplest option would be something like prefix_Publisher_Package_*. It should work well enough for items like Scripts, Rooms, Sprites, Objects... - as long as we don't expect the user to type out the asset name directly, we should be good.
It might be trickier if we expect the user to e.g. refer to an Object - for example, something like
In such case, I'd suggest still sticking with the exhaustive naming convention (i.e.
It might be trickier if we expect the user to e.g. refer to an Object - for example, something like
Tween_create(obj_QuadraticTween, 20, 80, 30)
.In such case, I'd suggest still sticking with the exhaustive naming convention (i.e.
obj_Publisher_Package_QuadraticTween
), but also provide a shorthand macro like #macro obj_QuadraticTween obj_Publisher_Package_QuadraticTween
in some kind of shorthands script (e.g. shorthands_Publisher_Package_objects
).Directory structure
To easily separate the Marketplace assets from others and from the user's code, I'd suggest putting all the package utilities into Marketplace > Publisher > Package directory in the Asset Browser.
We can do pretty much whatever we want in our package folder, as long as we follow the assets naming properly.
The
If our package comes with a demonstration example, maybe we could add related assets Example > Publisher > Package. I'd keep it at the same level as Marketplace directory rather than something like Marketplace > Publisher > Package > Example, so that you can easily opt-out from importing the non-essential examples.
Not sure about the shorthands, if we were to include them: should they go into Marketplace > Publisher > Package directory structure, or maybe we could have a separate directory like Shorthands > Publisher > Package?
Having it in the separate directory has the advantage of easily choosing shorthands or opting out from them altogether. Considering the shorthands are the most prone to name collisions, and their macros can block out other variable names, we probably want to have them readily available in the import tree.
We can do pretty much whatever we want in our package folder, as long as we follow the assets naming properly.
The
marketplace_get_publisher/package/module
scripts would go straight into the Marketplace folder, so that they can be easily skipped/overwritten when importing multiple packages following the conventions. If our package comes with a demonstration example, maybe we could add related assets Example > Publisher > Package. I'd keep it at the same level as Marketplace directory rather than something like Marketplace > Publisher > Package > Example, so that you can easily opt-out from importing the non-essential examples.
Not sure about the shorthands, if we were to include them: should they go into Marketplace > Publisher > Package directory structure, or maybe we could have a separate directory like Shorthands > Publisher > Package?
Having it in the separate directory has the advantage of easily choosing shorthands or opting out from them altogether. Considering the shorthands are the most prone to name collisions, and their macros can block out other variable names, we probably want to have them readily available in the import tree.
Summary
Overall, common Marketplace asset conventions might add a little extra work for setting up the Marketplace asset, but also save the time developer needs to figure out the conventions themself.
Additionally, if common conventions become widespread enough, this should lead to more unified experience of Marketplace asset users, with external assets kept in their own section instead of cluttering the main code.
Of course, the conventions outlined above are applicable to GM:S 2.3+ only (though certain aspects - such as shorthand macros - can be applied in earlier versions as well).
Do you think these kinds of conventions are worth pursuing? Would you like to make some changes? Or maybe you'd like to point out some cases that aren't easily covered by the proposed conventions?
I'd love to hear your thoughts. ^^
Last edited: