Ceremony Integration
Ceremony Integration
Section titled “Ceremony Integration”Glamour leverages the Ceremony library for robust Pokemon state management and persistence. This page explains the integration and what it means for server administrators.
What is Ceremony?
Section titled “What is Ceremony?”Ceremony is a comprehensive Pokemon state management infrastructure library that provides:
- Cross-Mod State Registry: Central registry for Pokemon effects shared across multiple mods
- Persistent State Storage: Player-scoped Pokemon data that persists across restarts
- Effect Interfaces: Standardized interfaces for sendout, ambient, and other effect types
- State Management Patterns: Generic data structures for extensible persistence
- Clean Extension APIs: Kotlin extensions for accessing state data
How Glamour Uses Ceremony
Section titled “How Glamour Uses Ceremony”Effect Registration
Section titled “Effect Registration”Glamour registers all particle effects in Ceremony’s PokemonEffectRegistry:
// Sendout Effect RegistrationPokemonEffectRegistry.register( id = "glamour:confetti_burst", effect = SendoutEffect { pokemon, world, pos -> // Particle spawning logic })
// Ambient Effect RegistrationPokemonEffectRegistry.register( id = "glamour:sparkle_aura", effect = AmbientEffect { pokemon, world, pos, interval -> // Continuous particle logic })// Sendout Effect RegistrationPokemonEffectRegistry.register( "glamour:confetti_burst", new SendoutEffect() { @Override public void execute(Pokemon pokemon, World world, BlockPos pos) { // Particle spawning logic } });
// Ambient Effect RegistrationPokemonEffectRegistry.register( "glamour:sparkle_aura", new AmbientEffect() { @Override public void execute(Pokemon pokemon, World world, BlockPos pos, int interval) { // Continuous particle logic } });Benefits:
- Effects are accessible to other Ceremony-compatible mods
- Centralized registry prevents ID conflicts
- Standardized interfaces ensure consistency
State Persistence
Section titled “State Persistence”Applied particle effects are stored using Ceremony’s PokemonStateDataObject:
// Glamour's state adapterclass CeremonyParticleStateAdapter : ParticleStateInterface { override fun getAppliedEffects(playerUUID: UUID, pokemonUUID: UUID): AppliedEffects? { // Retrieves from Ceremony's state system return ceremonyState.get(playerUUID, pokemonUUID) }
override fun setAppliedEffects(playerUUID: UUID, pokemonUUID: UUID, effects: AppliedEffects) { // Stores in Ceremony's state system ceremonyState.set(playerUUID, pokemonUUID, effects) }}// Glamour's state adapterpublic class CeremonyParticleStateAdapter implements ParticleStateInterface { @Override public AppliedEffects getAppliedEffects(UUID playerUUID, UUID pokemonUUID) { // Retrieves from Ceremony's state system return ceremonyState.get(playerUUID, pokemonUUID); }
@Override public void setAppliedEffects(UUID playerUUID, UUID pokemonUUID, AppliedEffects effects) { // Stores in Ceremony's state system ceremonyState.set(playerUUID, pokemonUUID, effects); }}Benefits:
- Effects persist across server restarts
- Data survives when Pokemon are stored in PC
- Effects transfer with Pokemon during trades
- No separate database management needed
Data Structure
Section titled “Data Structure”Glamour uses Ceremony’s AppliedEffects data structure:
data class AppliedEffects( val pokemonUuid: String, val sendoutEffect: String?, // Particle ID or null val ambientEffect: String? // Particle ID or null)public class AppliedEffects { private final String pokemonUuid; private final String sendoutEffect; // Particle ID or null private final String ambientEffect; // Particle ID or null
public AppliedEffects(String pokemonUuid, String sendoutEffect, String ambientEffect) { this.pokemonUuid = pokemonUuid; this.sendoutEffect = sendoutEffect; this.ambientEffect = ambientEffect; }
public String getPokemonUuid() { return pokemonUuid; } public String getSendoutEffect() { return sendoutEffect; } public String getAmbientEffect() { return ambientEffect; }}This maps directly to Ceremony’s native state format for seamless integration.
State Management Flow
Section titled “State Management Flow”Applying a Particle
Section titled “Applying a Particle”- Player selects particle in GUI
- Glamour creates
AppliedEffectsobject - State saved through
CeremonyParticleStateAdapter - Ceremony persists to its data store
- Effect immediately available for rendering
Loading Effects on Server Start
Section titled “Loading Effects on Server Start”- Server starts and loads Ceremony
- Ceremony loads all persistent state
- Glamour queries state through adapter
- Effects reapply automatically when Pokemon spawn
Pokemon State Lifecycle
Section titled “Pokemon State Lifecycle”Player applies particle ↓Glamour → Ceremony State Storage ↓[Server Restart] ↓Ceremony loads state ↓Pokemon spawns → Glamour queries Ceremony → Effect rendersCross-Mod Compatibility
Section titled “Cross-Mod Compatibility”Because Glamour uses Ceremony’s registry, other mods can:
Query Glamour’s Effects
Section titled “Query Glamour’s Effects”val effect = PokemonEffectRegistry.get("glamour:confetti_burst")PokemonEffect effect = PokemonEffectRegistry.get("glamour:confetti_burst");Trigger Glamour Particles
Section titled “Trigger Glamour Particles”val sendoutEffect = PokemonEffectRegistry.getSendoutEffect("glamour:sparkle_aura")sendoutEffect.execute(pokemon, world, pos)SendoutEffect sendoutEffect = PokemonEffectRegistry.getSendoutEffect("glamour:sparkle_aura");sendoutEffect.execute(pokemon, world, pos);Check Applied Particles
Section titled “Check Applied Particles”val state = ceremonyState.get(playerUUID, pokemonUUID)if (state.sendoutEffect == "glamour:confetti_burst") { // React to Glamour particle being active}AppliedEffects state = ceremonyState.get(playerUUID, pokemonUUID);if ("glamour:confetti_burst".equals(state.getSendoutEffect())) { // React to Glamour particle being active}Configuration Independence
Section titled “Configuration Independence”While Glamour integrates deeply with Ceremony for state management, particle configurations remain independent:
- Particle JSON configs are loaded by Glamour
- No Ceremony configuration needed for basic usage
- Ceremony handles only the persistence layer
Database Backend
Section titled “Database Backend”Ceremony supports multiple database backends:
SQLite (Default)
Section titled “SQLite (Default)”{ "database": { "type": "sqlite", "path": "ceremony_data.db" }}MySQL/MariaDB
Section titled “MySQL/MariaDB”{ "database": { "type": "mysql", "host": "localhost", "port": 3306, "database": "ceremony", "username": "user", "password": "pass" }}MongoDB
Section titled “MongoDB”{ "database": { "type": "mongodb", "connectionString": "mongodb://localhost:27017/ceremony" }}Note: Configure in Ceremony’s config, not Glamour’s. Glamour automatically uses whatever backend Ceremony is configured with.
Performance Characteristics
Section titled “Performance Characteristics”State Reads
Section titled “State Reads”- Cached: Ceremony caches state in memory
- Fast Access: No database query on every particle render
- Lazy Loading: State loaded only when needed
State Writes
Section titled “State Writes”- Async: State writes happen asynchronously
- Batched: Multiple writes batched for efficiency
- Non-Blocking: Particle application doesn’t wait for database
Memory Usage
Section titled “Memory Usage”- State cached per-player, per-Pokemon
- Inactive Pokemon states unloaded from memory
- Configurable cache TTL in Ceremony
Troubleshooting
Section titled “Troubleshooting”Effects Not Persisting
Section titled “Effects Not Persisting”Symptom: Particles reset after server restart
Causes:
- Ceremony not properly installed
- Database connection issues
- State write failures
Solutions:
- Check Ceremony is installed and loaded
- Verify database configuration
- Check server logs for Ceremony errors
State Conflicts
Section titled “State Conflicts”Symptom: Multiple mods fighting over same Pokemon state
Cause: Other mods also using Ceremony state
Solution: Ceremony’s state system is designed for this - each mod gets its own namespace. Check for mod conflicts in logs.
Performance Issues
Section titled “Performance Issues”Symptom: Lag when applying particles
Causes:
- Database write contention
- Ceremony cache misses
- Slow database backend
Solutions:
- Use faster database (SQLite for small servers, MySQL for large)
- Increase Ceremony’s cache size
- Enable async writes in Ceremony config
Advanced: Custom State Extensions
Section titled “Advanced: Custom State Extensions”Servers running custom mods can extend Glamour’s state through Ceremony:
// Custom state extensiondata class CustomParticleData( val intensity: Float, val color: Color, val metadata: Map<String, Any>)
// Register custom state objectceremonyState.registerCustomState( namespace = "mymod:glamour_extended", dataClass = CustomParticleData::class)// Custom state extensionpublic class CustomParticleData { private final float intensity; private final Color color; private final Map<String, Object> metadata;
public CustomParticleData(float intensity, Color color, Map<String, Object> metadata) { this.intensity = intensity; this.color = color; this.metadata = metadata; }
// Getters public float getIntensity() { return intensity; } public Color getColor() { return color; } public Map<String, Object> getMetadata() { return metadata; }}
// Register custom state objectceremonyState.registerCustomState( "mymod:glamour_extended", CustomParticleData.class);This allows custom mods to add additional particle metadata without modifying Glamour.
Developer Notes
Section titled “Developer Notes”Why Ceremony?
Section titled “Why Ceremony?”Glamour uses Ceremony instead of implementing its own state system because:
- Battle-Tested: Ceremony is proven in production
- Cross-Mod Compatible: Other mods can interact with Glamour
- Robust Persistence: Handles edge cases (trades, PC storage, etc.)
- Performance: Built-in caching and optimization
- Maintainability: Don’t reinvent state management
Integration Points
Section titled “Integration Points”Glamour touches Ceremony at three points:
- Effect Registration:
PokemonEffectRegistry.register() - State Read:
ceremonyState.get() - State Write:
ceremonyState.set()
All other Glamour logic is independent.
Ceremony Versioning
Section titled “Ceremony Versioning”Glamour requires Ceremony 3.0.7 or higher.
Compatibility Matrix
Section titled “Compatibility Matrix”| Glamour Version | Ceremony Version | Compatible |
|---|---|---|
| 1.0.x | 3.0.7+ | ✅ Yes |
| 1.0.x | 3.0.0-3.0.6 | ⚠️ Partial |
| 1.0.x | 2.x.x | ❌ No |
Always use the recommended Ceremony version for best results.