Skip to content

Add new configuration types and serializers for numeric and boolean values#353

Merged
twisti-dev merged 18 commits into
version/26.1from
feat/config-serializers
May 17, 2026
Merged

Add new configuration types and serializers for numeric and boolean values#353
twisti-dev merged 18 commits into
version/26.1from
feat/config-serializers

Conversation

@twisti-dev
Copy link
Copy Markdown
Contributor

@twisti-dev twisti-dev commented May 17, 2026

This pull request introduces a new set of configuration constraints and types, improves serialization support, and adds bootstrapping state management to the core server instance. The main changes are grouped below:

Configuration Constraints and Types

  • Added a comprehensive suite of annotation-based constraints for configuration validation (e.g., @Contains, @Directory, @MaxLength, @Range, etc.), enabling more expressive and type-safe config definitions.
  • Introduced new configuration types such as BooleanOrDefault, ConfigDuration, DurationOrDisabled, and flexible number wrappers like DoubleOr and IntOr, supporting default/disabled states and enhanced parsing/validation.

Serialization Enhancements

  • Added new serializers for fastutil map collections and improved/adapted serializers for complex types, including a switch to ScalarSerializer.Annotated for component serialization. [1] [2]
  • Provided a utility for registering default serializers and annotation markers to control serialization behavior. [1] [2]

Core Server Improvements

  • Added an AtomicBoolean-based bootstrapping state to CoreInstance, with a public isBootstrapping() method and automatic state update on onLoad(), allowing other components to check if the core is still initializing. [1] [2] [3]

Utilities

  • Added configSizeOrNull() utility function to determine the size of various collection-like types in a null-safe way.

Versioning

  • Bumped the project version from 3.11.2 to 3.12.0 in gradle.properties.

…alues

- introduce BelowZeroToEmpty annotation to treat negative numbers as empty
- implement BooleanOrDefault type for optional boolean configuration
- add DoubleOr and IntOr interfaces for optional numeric values with default/disabled states
- create serializers for new configuration types to handle serialization and deserialization
🔧 chore: update version to 3.12.0 in gradle.properties
```
@twisti-dev twisti-dev self-assigned this May 17, 2026
…onstraints

- implement serializers for BukkitConfigurationSerializable, ItemStack, Location, Material, and others
- introduce new constraints like Contains, Directory, DisallowValues, and more
- enhance configuration handling with custom serializers for better data management
@github-actions
Copy link
Copy Markdown
Contributor

⚠️ API/ABI changes detected!

This PR contains changes that modified the public API. To update the reference ABI dumps:

./gradlew updateKotlinAbi
git add **/api/**
git commit -m "Update ABI reference"
git push

After updating, the CI will pass. Make sure the changes are backward compatible.

- introduce ConfigDuration data class for handling duration values
- implement parsing and formatting for duration strings
- update DurationOrDisabled and duration constraints to use ConfigDuration
- add ModernSerializerTestConfig for testing new configuration types
@github-actions
Copy link
Copy Markdown
Contributor

⚠️ API/ABI changes detected!

This PR contains changes that modified the public API. To update the reference ABI dumps:

./gradlew updateKotlinAbi
git add **/api/**
git commit -m "Update ABI reference"
git push

After updating, the CI will pass. Make sure the changes are backward compatible.

- introduce Contains, Directory, DisallowValues, EndsWith, ExistingFile, MaxDuration,
  MaxLength, MaxSize, MinDuration, MinSize, Namespace, NegativeNumber, NoDuplicates,
  NotEmpty, StartsWith, and WritablePath annotations
- each annotation provides specific validation logic for configuration fields
@github-actions
Copy link
Copy Markdown
Contributor

⚠️ API/ABI changes detected!

This PR contains changes that modified the public API. To update the reference ABI dumps:

./gradlew updateKotlinAbi
git add **/api/**
git commit -m "Update ABI reference"
git push

After updating, the CI will pass. Make sure the changes are backward compatible.

@twisti-dev twisti-dev marked this pull request as ready for review May 17, 2026 20:57
Copilot AI review requested due to automatic review settings May 17, 2026 20:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the Surf config system with new scalar serializers, wrapper config types, constraint annotations, and additional Paper/Bukkit serializers/registry support, alongside a version bump.

Changes:

  • Added multiple new core scalar serializers (e.g., Key, UUID/URI/URL, regex/pattern, path/file, text color) plus wrapper config types (BooleanOrDefault, DurationOrDisabled, IntOr/DoubleOr).
  • Introduced many new Configurate constraints (numeric/string/collection/path/duration/key) and registered them in SpongeConfigSerializers.
  • Added fault-tolerant/bridging map serializers (generic map + fastutil maps) and expanded Paper-side serializer registrations (Bukkit types + Paper registries).

Reviewed changes

Copilot reviewed 63 out of 63 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/VectorSerializer.kt Adds Vector serializer
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/registry/RegistryValueSerializer.kt Registry value serializer
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/registry/RegistryEntrySerializer.kt Registry entry base serializer
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/PaperSpongeConfigSerializers.kt Registers Paper serializers
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/NamespacedKeySerializer.kt NamespacedKey scalar serializer
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/MaterialSerializer.kt Material scalar serializer
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/LocationSerializer.kt Location node serializer
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/ItemStackSerializer.kt ItemStack Base64 serializer
surf-api-paper/surf-api-paper-server/src/main/kotlin/dev/slne/surf/api/paper/server/config/serializers/BukkitConfigurationSerializableSerializer.kt Fallback Bukkit CS serializer
surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/PaperPluginMain.kt Updates test plugin wiring
surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/config/ModernTestConfig.kt Adds new test fields
surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/config/ModernSerializerTestConfig.kt Adds serializer/constraint test config
surf-api-paper/surf-api-paper-plugin-test/src/main/kotlin/dev/slne/surf/surfapi/bukkit/test/command/subcommands/ModernSerializerTestConfigCommand.kt Adds reload command
surf-api-paper/surf-api-paper-plugin-test/src/main/java/dev/slne/surf/api/paper/test/config/TestConfig2.java Adds wrapper type field
surf-api-paper/surf-api-paper-plugin-test/src/main/java/dev/slne/surf/api/paper/test/command/SurfApiTestCommand.java Registers new test command
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/type/number/IntOr.kt Adds optional int wrappers
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/type/number/DoubleOr.kt Adds optional double wrappers
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/type/number/BelowZeroToEmpty.kt Adds numeric compatibility annotation
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/type/DurationOrDisabled.kt Adds duration-or-disabled type
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/type/ConfigDuration.kt Adds duration parsing/formatting type
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/type/BooleanOrDefault.kt Adds boolean-or-default type
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/UuidSerializer.kt Adds UUID serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/UrlSerializer.kt Adds URL serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/UriSerializer.kt Adds URI serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/TextColorSerializer.kt Adds TextColor serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/SpongeConfigSerializers.kt Registers new serializers/constraints
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/RegexSerializer.kt Adds Regex serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/PatternSerializer.kt Adds Pattern serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/PathSerializer.kt Adds Path serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/KeySerializer.kt Adds Adventure Key serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/FileSerializer.kt Adds File serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/EnumValueSerializer.kt Adds enum serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/collection/map/WriteKeyBack.kt Adds map key normalization annotation
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/collection/map/ThrowExceptions.kt Adds strict map mode annotation
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/collection/map/MapSerializer.kt Adds tolerant map serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/serializer/collection/map/FastutilMapSerializer.kt Adds fastutil map bridge serializer
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/WritablePath.kt Adds writable path constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/Trimmed.kt Adds trimmed string constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/StartsWith.kt Adds prefix constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/Range.kt Adds numeric range constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/PositiveNumber.kt Adds positive constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/NotEmpty.kt Adds non-empty constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/NotBlank.kt Adds non-blank constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/NoDuplicates.kt Adds no-duplicates constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/NegativeNumber.kt Adds negative constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/Namespace.kt Adds key namespace constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MinSize.kt Adds minimum size constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MinNumber.kt Adds minimum number constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MinLength.kt Adds minimum length constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MinDuration.kt Adds minimum duration constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MaxSize.kt Adds maximum size constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MaxNumber.kt Adds maximum number constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MaxLength.kt Adds maximum length constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MaxDuration.kt Adds maximum duration constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/ExistingFile.kt Adds existing-file constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/EndsWith.kt Adds suffix constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/DisallowValues.kt Adds disallowed values constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/Directory.kt Adds directory constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/Contains.kt Adds substring constraint
surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/CollectionConstraintUtils.kt Adds size helper
surf-api-core/surf-api-core/api/surf-api-core.api ABI dump updated
surf-api-core/surf-api-core-server/src/main/kotlin/dev/slne/surf/api/core/server/CoreInstance.kt Adds bootstrapping flag
gradle.properties Bumps version to 3.12.0

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6fcd2dba9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

twisti-dev and others added 3 commits May 17, 2026 23:18
- introduce ItemStack, Location, Material, and GameRule types in ModernSerializerTestConfig
- register new serializers for ItemStack and Location in PaperSpongeConfigSerializers
- change registryKey visibility to protected in RegistryEntrySerializer
- improve error message in RegistryValueSerializer for missing values
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@twisti-dev
Copy link
Copy Markdown
Contributor Author

@copilot adress all the feedback on the comments that are still unresolved and fix them

… FastutilMapSerializer, ItemStackSerializer

Agent-Logs-Url: https://github.com/SLNE-Development/surf-api/sessions/17b51bf8-8b45-42c0-8bff-7ef2c688ffa1

Co-authored-by: twisti-dev <76837088+twisti-dev@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 17, 2026

@copilot adress all the feedback on the comments that are still unresolved and fix them

Addressed all unresolved review comments in commit c50eafb:

  • MinNumber/MaxNumber: Changed to throw SerializationException(type, ...) instead of IllegalArgumentException, consistent with PositiveNumber, NegativeNumber, and other constraints.
  • EnumValueSerializer: Now throws SerializationException with the allowed constants listed, instead of logging and returning null.
  • MapSerializer: deserializePart/serializePart now accept and pass AnnotatedType to the serializer APIs instead of stripping it down to raw Type, preserving type-use annotations.
  • FastutilMapSerializer: Replaced the unconditional as AnnotatedParameterizedType cast with a safe as? check. Added a new PrimitiveToPrimitive subclass for non-generic fastutil maps (e.g. Int2IntMap, Long2LongMap) that would have caused ClassCastException at runtime.
  • ItemStackSerializer: Wrapped Base64.decode() and ItemStack.deserializeBytes() in try-catch that rethrows as SerializationException with a clear message.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • configurate.aoeu.xyz
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@twisti-dev twisti-dev requested a review from Copilot May 17, 2026 22:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 61 out of 61 changed files in this pull request and generated 4 comments.

Comment thread surf-api-core/surf-api-core/api/surf-api-core.api
…version

- use runCatching to safely convert string to Path, returning null on failure
…alization

- add try-catch block to catch InvalidPathException
- throw SerializationException with detailed message on failure
@twisti-dev twisti-dev merged commit de6ff77 into version/26.1 May 17, 2026
7 checks passed
@twisti-dev twisti-dev deleted the feat/config-serializers branch May 17, 2026 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants