Want to add custom properties or functions to a instance in workspace, and interact with it the same way as normal? Look no Further
SuperAPI (Codename: Super hAPI)
I like making compilers, so I hacked up a way for anyone to extend any given class.
You can create multiple extensions for the same class from different modules, and really just build out your API how YOU think it should be.
A good example is I would personally extend DataStores to utilize ProfileService.
When you have a common API across all your games or projects, with the boiler-code already made by you previously, your production speed goes up.
This bring API composition closer to the developers, and really gives the ability to share APIs to multiple developers/customers, or across multiple experiences in a way that is Packaged, Portable, and separate from production-code.
EDIT: THIS IS A PROTOTYPE AND PRE-PRODUCTION
Pitch
Summary
You can use this to aid developers in developing plugin APIs, build APIs, tool APIs, and in-game APIs. Any number of things may be done with this! I will be using this to developer itself.
ALSO: Anything visible via the wiki will generate a Luau representation accurately. Anything not publicly disclosed by Roblox (Such as internal-to-roblox type definitions for QFont, QDir, Array, Dictionary, Variant, Objects to name a few. Default Type annotations were provided. “Broken” types [as far as Luau is concerned] like “CoordinateFrame?” and “float?” have been converted to “CFrame?” and “number?”)
If You have any ideas to commit, please post below! I’d like to build this out, and if it functions well, I’d like to release this plugin to the community!
The Plugin Would have a type introspection catalog, built-in insertable or removable pre-extensions, type generator, and ultimately a easy-search/edit menu as the main component.
The idea here is you can Package a self contained API (and attach metadata) and distribute it to anyone using this framework to enrich their development experience seamlessly… and on the base Coding level that’s compatible with Intellisense.
Extending a Type
Extensions are placed under the designated API
Module, in a folder named Extensions
.
Extensions must be immediate children of the Folder. Namespace collisions between publicly available extension modules are NOT resolved by this plugin, as that is more in the scope of user Interaction with their libraries, and developer interaction with their type identification.
All extensions are scanned via the plugin to find type definitions with the following format.
Example- Extending Instance
export type Extension_CLASSNAME = EXTENSION -- Example Format
export type Extension_Instance = { -- Example with Extending "Instance"
PrintHelloWorld: ()->nil
}
Notice: A Module may contain multiple type Extensions in the same Script.
Initializing The Extension
The Module’s return must be named “module” within the source, and be a table.
local module = {} ... return module
The extension must have an initializer.
The Following format and example applies for Instance:
module.init_CLASSNAME = function(this: WRAPPED_CLASS) return PROXY end --Format
module.init_Instance = function(this: Instance)
local proxy = require(...pathToProxyModule).proxy()
--proxy.members, proxy.getters, proxy.setters, proxy.__metadata
return proxy
end
Editing the proxy.members
allows you to add properties and methods
Editing the proxy.getters
allows you to assign a property to return the value from a function
Editing the proxy.setters
allows you to assign a propert-set-action to go through a function-call.
Members
The following assumes we are implementing PrintHelloWorld
from the above extension example.
module.init_Instance = function(this: Instance)
local proxy = require(...pathToProxyModule).proxy()
local proxy.this = this --Assign this to maintain wrapped object.
local members = proxy.members
function members.PrintHelloWorld()
print('Hello World') -- You can now call this from the wrapped Object.
--Intellisense will also show you the function suggestions!
end
return proxy
end
Getters/Setters, and __metadata
We are assuming we are just editing the proxy
variable in this example:
module.init_Instance = function(this: Instance)
local proxy = require(...pathToProxyModule).proxy()
local proxy.this = this --Assign this to maintain wrapped object.
local members = proxy.members
local getters, setters = proxy.getters, proxy.setters
proxy.__metaData = {GeneratedBy = "ExtensionDeveloperName"}
proxy.getters.CheckIsPart = function() return this:IsA'BasePart' end
--print(object.CheckIsPart) --will return the function calls return.
proxy.setters.InGame = function(isInGame:boolean)
if isInGame == false then
this:Destroy() --pointless, but just for example
end
end
return proxy
How You can help
Right now this is a private plugin until I can get some community feedback about:
- What should be included Extensions to the plugin for optional use? A UI Suite is a good start.
- A Standard type library for optional inclusion (with full implementations for data only), examples including: Array, Dictionary, Stack, Map, Hash, any number of class structures for processing data.
- What are some securities that are wanted before release of this plugin?
Thanks for reading