-
Notifications
You must be signed in to change notification settings - Fork 9
Developer Section: Plugin
AStagesPlugin is an interface used to extend the functionality of AStages. It allows plugin developers to:
- Register new managers for custom logic.
- Modify existing restriction attributes.
- Create new paths and folders for both internal use within AStages and for the plugin itself.
- Handle restriction updates, including removing or resetting them when necessary during reloads.
This interface provides hooks for synchronizing data with clients, executing code before and after scripts are reloaded, and managing plugin-specific resources, while ensuring proper integration with the core AStages system.
Every AStagesPlugin must define a unique identifier by overriding the id() method. This ID is required by AStages to correctly register, load, and reference the plugin within the system.
The identifier must be a valid ResourceLocation. A helper method, AResourceLocation#fromNamespaceAndPath, can be used to quickly generate one, as it is valid in both 1.20.X and 1.21.X.
The value should be unique to your plugin to prevent conflicts with other AStages integrations.
public class YourPlugin implements AStagesPlugin {
@Override
public ResourceLocation id() {
return AResourceLocation.fromNamespaceAndPath(YourMod.MODID, "astages_plugin");
}
}AStagesPlugin#reloadBeforeScripts: clear restriction caches.
Called before JS scripts are reloaded. Useful for preparing or clearing data before scripts are processed, managers highly use this method. AStages will call this method when necessary, no additional logic is required unless you want custom reloading.
public class YourPlugin implements AStagesPlugin {
public static final CustomManager CUSTOM_INSTANCE = ...;
@Override
public void reloadBeforeScripts() {
CUSTOM_INSTANCE.reloadBeforeScripts();
}
}AStagesPlugin#clientSynchronization: synchronize restrictions to client.
Called to synchronize plugin data with a player's client. This is useful when restrictions need to be updated on the client side, for example to hide item names in tooltips or above the hotbar. AStages will call this method when necessary, no additional logic is required unless you want custom synchronization.
public class YourPlugin implements AStagesPlugin {
public static final CustomManager CUSTOM_INSTANCE = ...;
@Override
public void clientSynchronization(@Nullable ServerPlayer player) {
CUSTOM_INSTANCE.clientSynchronization(player);
}
} AStagesPlugin#reloadAfterScripts: build caches and support client-side command autocompletion.
Called after JS scripts and restrictions have been reloaded.
This method is commonly used to build or rebuild caches based on the restriction values previously added or modified.
AStages automatically invokes this method when reload operations complete.
public class YourPlugin implements AStagesPlugin {
public static final CustomManager CUSTOM_INSTANCE = ...;
@Override
public void reloadAfterScripts() {
CUSTOM_INSTANCE.reloadAfterScripts();
}
}This overload is called when the server instance is available. AStages uses it specifically to update networking-dependent features, such as:
- Client-side command autocompletion for stage IDs
- Autocompletion for simple restriction IDs
- Any feature requiring server data to be sent to the client
The server is required because without a valid server reference the plugin cannot safely send packets—doing so would cause a networking error.
@NotNullParams
public class YourPlugin implements AStagesPlugin {
public static final CustomManager CUSTOM_INSTANCE = ...;
@Override
public void reloadAfterScripts(MinecraftServer server) {
// Build server-dependent caches and send updated autocomplete data
CUSTOM_INSTANCE.someSynchronization(server);
}
}AStagesPlugin#clearClientOnLogin: clear leftover client-side synchronized data.
Called when a player logs into a server.
This method is used to clear any client-side leftover data from previous synchronizations, such as restriction states or attribute values that were cached while connected to a different server.
Without cleaning these values, the client might display outdated or incorrect information after switching servers.
AStages will call this method automatically when needed; plugins only need to implement the cleanup logic.
public class YourPlugin implements AStagesPlugin {
@Override
public void clearClientOnLogin() {
// Some clearing operations
}
}AStagesPlugin#registerManagers: register custom managers for specific restriction types.
Called during plugin initialization to allow the mod to register new managers and associate them with their corresponding restriction types or handling logic.
Managers are responsible for processing, validating, updating, or caching restrictions of a specific category.
Registering a manager here ensures that AStages recognizes it.
@NotNullParams
public class YourPlugin implements AStagesPlugin {
// This line is required because restriction types are registries
// Remember to register it in your mod main class, under mod event bus
public static final DeferredRegister<ARestrictionType> RESTRICTION_TYPES = ARestrictionType.setCurrentDeferredRegister(DeferredRegister.create(AStagesRegistries.RESTRICTION_TYPES, YourMod.MODID));
public static final ARestrictionType YOUR_TYPE = ARestrictionType.create("your_type");
public static final CustomManager CUSTOM_INSTANCE = ...;
@Override
public void registerManagers(ManagerContainer container) {
container.register(YOUR_TYPE, CUSTOM_INSTANCE);
}
}AStagesPlugin#attachAttributes: add new attributes to existing restriction types.
Called to allow plugins to add attributes to pre-existing restriction classes.
Attributes extend the behavior or data of a restriction by attaching additional values or logic to it.
This method is useful when a plugin wants to enhance a restriction type—such as adding flags, counters, conditions, or custom metadata—without creating a new restriction from scratch.
You may provide:
- The restriction class to modify
- The attribute to attach
- Optionally, a default initial value
Once added, all instances of the specified restriction class will include the attribute, and its value will be handled automatically by AStages.
@NotNullParams
public class YourPlugin implements AStagesPlugin {
@Override
public void attachAttributes(AttributeContainer container) {
// Add attribute without initial value
container.addAttribute(AItemRestriction.class, YourAttributes.CUSTOM_ATTRIBUTE);
// Add attribute with initial value
container.addAttribute(AItemRestriction.class, YourAttributes.CUSTOM_ATTRIBUTE, 10);
}
}AStagesPlugin#registerConfigFolders // #registerServerFolders: create under config folder or world-dependent folder structures and access their paths.
Called to create and register server-dependent folder structures inside the world's directory.
This system allows plugins to easily define directory trees and automatically gain access to their resolved paths during runtime.
Each folder is created using:
- An
ADirectoryResourcerepresenting the folder’s name - A
Ref<Path>to store the resolved filesystem path (can benullif you don’t need direct access) - An optional lambda to define nested subfolders
Special cases are roots (only one allowed in each tree) defined using custom AFolder#root method.
This method is essential for plugins that need to store per-world data, configurations, caches, or generated files. (Stage system is based on this folder system).
Once registered, AStages automatically resolves and manages these folders based on the currently loaded world, ensuring correct server-dependent paths.
@NotNullParams
public class YourPlugin implements AStagesPlugin {
public static final ADirectoryResource YOUR_DATA_DIR = new ADirectoryResource("yourdata");
public static final ADirectoryResource SUB_FOLDER_DATA_DIR = new ADirectoryResource("subfolder");
public static final ADirectoryResource SUB_SUB_FOLDER_DATA_DIR = new ADirectoryResource("subsubfolder");
private static final Ref<Path> subSubFolder = new Ref<>();
@Override
public void registerServerFolders(FolderContainer container) {
// Create root folder inside the world directory
var root = AFolder.root(YOUR_DATA_DIR, null);
// Define subfolders
root
.subFolder(SUB_FOLDER_DATA_DIR, null, subFolder -> {
// Nested subfolder, store its resolved path into subSubFolder
subFolder.subFolder(SUB_SUB_FOLDER_DATA_DIR, subSubFolder);
})
.subFolder(...);
// Register root
container.register(root);
}
public static Path getSubSubFolderPath() {
return subSubFolder.getValue();
}
}AStagesPlugin#registerSimpleRestriction: register custom simple restrictions and related things.
See Developer Section: Simple Restrictions for more information regarding this method!
Documentation:
-
Restrictions
- Crop
- Dimension
- Effect
- Enchant
- Item (Old)
- Loot
- Mob
- Ore
- Pet
- Recipe
- Region
- Screen
- Structure -
Addons
- Curios API
- Pufferfish Skill's -
Simple Restrictions (via commands)
Brand new and intuitive way to add restriction! -
Developers
- Plugin
- Restrictions
- Simple Restrictions
- Stage System
- Utils -
Q&A
A place where questions are on the agenda! -
Changelogs
Changelogs since 0.6.0 version! -
What's Happened? (FLOP!)
New code formatting is coming!