#adventure-help
1 messages · Page 2 of 1
that's what adventure is
no, is not
representing isn't wrapping
you have a fundamental misunderstanding of not only minimessage but adventure
good point here
lets not get wrapped up in semantics lol
minimessage is just a serialization format, you can only use minimessage features in the context of minimessage serialization
yes
and?
false.
how is that false lmao
String representation -> component serialised to string lmao
Not to be rude but can you read the whole sentence
and for developers to extend
to extend with custom tags lmao
no way currently
what
not during deserialization
but using Components
again, you can only use minimessage features in a minimessage context
the core of minimessage/adventure.
minimessage does not exist outside of minimessage
These are used during deserialization - you can add them to a custom MiniMessage instance or add them on the deserialize call e.g. deserialize("string", tags)
adventure can exist without minimessage, you want to make use of minimessage features without minimessage
alright, but I still want to serialise them, as tags
how?
without deserialisation first.
as stated earlier, currently serialization of custom tags is not public api
thank you.
once it is, you can use Virtual components to your heart's desire
You can still use it tho, it's there just not public api
Go and look at any of the standard tags and just copy what they do
Gradient tags are an example of how you can do it with virtual components
"don't know how something works? go look inside it"
Can you chill on the sass a bit
I wonder how does a nuclear reactor works..
alright
Giving you examples is not a bad thing
okay, I'm exaggerating a bit, but it's a feature requested by many.
it really isn't, i haven't seen a single person ask for it even before we added the internal api for it
I've also seen people try to duplicate minimessage tags, just because of using custom tags..
or placeholder api effectively
because as zml said, it takes years and devs know...
I would def want to see some examples of that - please do share! Would be good to help us see what our final custom tag serialization api might look like
trust me devs are very good at asking for even impossible things lol
As for PAPI, we have had this example available for years https://docs.advntr.dev/faq.html#how-can-i-use-bukkits-placeholderapi-in-minimessage-messages
Right but that isn't duplicating MiniMessage tags like you said
what?
I said you're duplicating minecraft components, not tags
and your point was cross-platform support
which is fair.
you said "I've also seen people try to duplicate minimessage tags"
whatever that means anyway
ooohhhh
I'll give you an example
and adventure "duplicates" minecraft components because you can use it outside of a minecraft environment altogether
adventure would be a whole lot less useful for a lot of people if it required a minecraft environment running for it to work
this guy did it before you guys
you love to see it.
okay and?
Right, but unless I'm missing something nothing there isn't possible on MiniMessage?
also worth mentioning that minimessage has existed for far longer than it was integrated in adventure, or before adventure was even named adventure!
In fact from what I'm seeing all it looks like is a clone of the format for use with BaseComponents (which, fwiw, just use the BungeeComponentSerializer from adventure-platform-something)
you keep linking text files without an explanation of what your intention is
what about that file is impossible with minimessage?
the custom tags
which isn't public api
What custom tags?
oh boy
It's over a decade old, lmao
Fuck am old
he has a plugin-prefix value
Dark ages
you can have a plugin-prefix tag
someone needs to update it to use the new non array bungee components 
where
But you could just do that with e.g. a static Placeholder.component("plugin-prefix", myPrefix)
I already do
Stick it in some static custom MiniMessage instance and then you could literally just call deserialize("<plugin-prefix>My message")
then what's the problem?
I have to use this instead of components.
I have to use String instead of Component.
yes
again, if you want to use minimessage features, you have to use minimessage
you cannot use minimessage features outside minimessage
we're just going in circles; unless you have something useful to contribute to this conversation, I reckon this is over
them, when minimessage will replace its strings with components, for custom tags, everyone will use adventure.
that is my whole point.
You can use custom styles in placeholders tho, just expand that to e.g. Placeholder.component("plugin-prefix", Component.text("MyPlugin", TextDecoration.BOLD)
Custom tags already support components
again with the "everyone"
and your words are not making any sense
MiniMessage is a string format that represents components, in a string form
so if you wanna use minimessage strings you have to use strings
I am talking about serialisation/deserialisation
You can use components in custom tags in deserialization and, using internal api, in serialization
None of the code you linked even touches serialization of custom tags so I'm not sure why you're complaining it's missing
I could use Gson insteaf of MiniMessage, and still won't be able to use components with custom-tags
because json format does not have a concept of tags altogether
Yes GSON doesn't support tags it's not intended as a user-facing format
tags are a minimessage feature exclusively
custom tags specifically
you cannot use custom tags outside of minimessage because custom tags are a minimessage feature
the json format is defined by mojang, not adventure, so the json format adventure uses cannot have custom breadcrumbs
Nor would you want to use them outside of MiniMessage because the entire point of parsing a string-based format is that you get access to the whole string for parsing, that isn't easy (or possible in some cases) with pure components
The string is tokenised and then converted into components - any tokenising step would just butcher the existing component tree if it used components as input instead of strings and wouldn't make any sense
alright, this explains it then
yet it could have, custom tags, but not like anyone could imagine.
Again it wouldn't make sense for it to have custom tags. Mixing two different text formats together is not a good idea and would be wildly complex for no real benefit
You'd have to tokenise a tree from inside another tree which is just wild
no, silly
Hm?
I'm thinking about TypeAdapters
The JSON representation of components is a tree
I don't see how type adapters would help
yeah, I know
The point is that fundementally you're going from two intermingled trees into one tree which is leagues more complex than going from one tree to one tree
think outside of the trees, dummy
Pls stop calling people dummy or silly
Yeah I've already warned you to chill with the sass don't make me go and learn how to use my newly gifted mod tools haha
I'm not sassy
and sorry if I really am
But still, I'm not sure how thinking outside of the trees helps you actually get outside of them on a code level
so
TagResolver.Single
that is used in Placeholder class
could be serialised, right?
to json
No - it's code and serializing code is bad
not code..
but the values being used
the placeholder
you have Placeholder.parsed(key, placeholder)
that fits in the tree
yeah
You can already serialize a component created by deserialzing some MiniMessage string into json
that's one of the nice things about components are that they become their own IR for stuff like that
Oh you mean you have a core set of multi-version and multi-platform modules that you use as templates for your projects?
Yes
Can I somehow send a Component message from player A to player B (private messages) that will be hidden for player B if player B has ignored player A in the ESC menu?
I know yo can use identities but it looks like all methods related to this are deprecated
I used to use methods like Audience#sendMessage(Identity, Component) but now it's deprecated and I doubt it still works
declaration: package: net.kyori.adventure.audience, interface: Audience
Chat signing broke that, kind of
iirc it is still possible since /msg can still be signed but I'm not sure how to wire that up or if that's special treatment for that command
that was around the time they were figuring that stuff out, those methods basically existed for, like, 2 versions
Sad
Yeah you'd need to just send a full signed message to the player
Using the API, how do i figure out if there is a set shadowcolor?
(assuming its not the default shadowcolor ofc)
also is there no ShadowColor#default() to do such check
Ooh, minimessage translation support is out
It's tempting to switch from my custom messages.conf file to using the adventure stuff
hold off for now - gonna add a translationregistry which should make it even easier to use
will do :)
you really should switch tho it's VERY cool even if i do say so myself
My current method is a bit.. weird (at least to me) so I definitely do want to switch. Right now i just read in a hocon file of messages and then have a method with a TagResolver... parameter that converts the string to minimessage
only works with one language 
tbh working with one language is fine
i imagine 99% of devs that end up using this sytem will only use one language
but it just lets you do cool stuff like this without having to think twice
player.sendMessage(Component.translatable("my.key", Argument.component("name", player.displayName())));
Yeah, that's my main reason to switch
Right now my version of that would be
player.sendMessage(plugin.getConfigController().getMessage("my-key", Placeholder.parsed("name", player.getName()));
having it be cleaner and be able to use all the translatable stuff makes my life easier lol
yeah i think the nicest part is letting people not have to worry about the hassle of it all
like any dev could now have a full translation system with just a few lines of code
Do someone know why the showItem method with the HoverEvent in a chat message isn't showing my ItemMeta ? it's just an ItemStack with the basic ItemMeta.
what is hand here?
the ItemStack in the hand of the player
and what software are you using? server version? client version? any protocol hack mods/plugins?
paper 1.20.4, same for my clients, I don't have any strange clients or else
Did you know you could actually just write Component.text(...).hoverEvent(hand)? I don't think this is the cause of your problem, but just seeing your code is a little bit complicated for a "simple" task
nah, I need to replace the "[i]" in the chat, not the whole message
no indyteo is right, you should be doing that
1.20.4 paper is not supported unfortunately
The version of Paper you are developing with is outdated and unsupported.
Old versions may not contain useful APIs to solve your problem and may have numerous bugs and/or exploits. If you wish to receive support, please ensure you are developing with the latest supported version.
?
If I do this, the whole message will have an hover event on it
I need to have it on the "[i]" part of a message
would the audience be passed to minimessage translator somehow here?
yeah, would be super useful to be able to get the specified on server (or detected by getLocale) language and get the correct string for this language
sure, when I'm on my pc later
oh yeah that's handled automatically by the platforms
ill open an issue about the target tho dw
wdym?
okay
translating into the correct locale is automatic
I'm not really sure how minimessage translator works yet, but do you mean that it's language/locale scoped or something?
I must do it now 😏
It's just something you can plug into the GlobalTranslator
so you don't have to worry about what the players' locale is as that's handled automatically
ok, so basically I just need to provide the files with translations for locales to the minimessage translator and it would automatically get the correct string from the correct file?
yep!
nice 🙂
oh right, I just need to build my own registry
I've got a PR open that should get merged soon that adds a way of handling that too
oh fun
I'll just.. borrow that code for now until it's merged :)
edit: oh i see which one it is. nvm
so you can load it straight from a directory of .properties files
I was considering looking into how moonshine works but it seemed like a lot of implementation was needed just for locale
what would be the best way to handle lists of components (e.g. for lores) while using minimessage translator?
yeah moonshine is good if you love implementing interfaces
the way i do it is just have a list of e.g. mylore.1 mylore.2 etc and just render until the translation doesn't exist anymore
how can I detect if there is no translation anymore?
good question, ive opened an issue :p
What is moonshine? Impossible to google for
I did find some interesting alcoholic coffees though
got a PR to add a TranslationStore#contains(String, Locale) method - so you basically just while loop to make your list and then stop when that is false
I love moonshine but I can't understand it 
pretty sure ItemStack.displayName() already has the hover event for you, but idk if its in 1.20.4
Is there any way to apply color/formatting to the alternate text in lang_or?
MiniMessage components don't work and trying to use section codes results in the tag breaking...
rip
Best you could do is make your own lang_or that checks in the global translator
Not really worth it. A minor inconvenience, but nothing too problematic for me
It’s making the same bug
idk, i dont have anything like that
From where do I get ComponentLogger, I tried to use adventure-api but it wasnt there.
What platform are you using?
paper and velocity but I need it in my common module
text-logger-slf4j
adventure-text-logger-slf4j
thanks
Can someone tell me why hand.displayName(), return an ItemStack with the default ItemMeta ? in paper 1.20.4
That sounds like a paper issue rather than an adventure issue, but paper doesn't support 1.20.4 anymore.
even if paper isn't supporting 1.20.4 anymore, can someone help me anyway pls
not supporting means no help. Would highly recommend just updating
I cant update it
The version of Paper you are developing with is outdated and unsupported.
Old versions may not contain useful APIs to solve your problem and may have numerous bugs and/or exploits. If you wish to receive support, please ensure you are developing with the latest supported version.
^ as you've already been told
What exactly is the benefit of the ComponentLogger vs the plugin Logger ?
you can log colored text with it
How do I get ComponentLogger in paper? I tried casting but that didnt work
Plugin#getComponentLogger(), or just ComponentLogger.logger() or whatever the static method was
Plugin#getComponentLogger() didnt see that, thanks
What will the component logger log when receiving a translatable component? The raw translation key (or the fallback if present)?
afaik it runs through the flattener, so, it's going to depend on what translations are available on your platform
if no translations are available, it will be the key that's logged afaik
idk if it uses the fallback, I'd guess it does? 
And would it be possible to feed him with Minecraft's translation file (like the en_us.json) so he can log values instead?
You'd need to add stuff to the global translation registry, but, yes
that wouldn't be side-effect free, however
i.e. you'd impact other plugins, etc
It would be cool if the component logger was able to do it from its side, like a client (or an audience)
on Paper it is set up to run through the server's translations too
Definitely don't add the translations to the GlobalTranslator - that would mess with a lot of things
Hey there, does anyone have experience with the TextReplacementConfig? I've been trying for hours to get it to work, but it seems that it just won't.
component = component.replaceText(TextReplacementConfig.builder()
.matchLiteral(placeholder)
.replacement(replacementComponent)
.build());
The component "replacementComponent" has a different color associated with it. The text is replaced correctly, but the color of "replacementComponent" is overriden
It seems like the .replacement only replaces the text and not the full component with its color
It would make sense given the names .replaceText(...) / TextReplacement...
I agree, but I do also think that if it accepts a component it should actually replace it 1:1 and not only a fraction (text) of the component
It replaces text, hence text replacement :p
What are you trying to do? there might be a better solution
dang it :/
The messages of my plugin are stored in a seperate file and accept variables like "Player {0} joined word {1}". I've got two TextColors which represent the default and a highlight color (default = the whole text and highlight = {0} and {1}). I am trying to replace the {0} and {1} with the text AND highlight color
If that sentence makes any sense
Maybe try translations
The text is replaced correctly but without the color formating, which, makes sense if it actually only replaces the text
huh?
Are you using MiniMessage? Are you able/willing to use it?
I am using it yes
I know there is built-in translation support in MiniMessage, so I guess you could try to use this system (with a single language, it's ok, but it'll handle your "placeholders")
I never used it myself tho
But Kezz will probably be able to help you more about this
good to know, but wouldn't that use something like i want to achieve with TextReplacement under the hood? So there should be something available?
Idk, however if you want you can also define a custom tag like <highlight> that sets your highlight color
And perform the replacement in the raw text, before
If you're using MiniMessage, use MiniMessage :p
It has an entire custom placeholder system and even in soon to be released snapshot builds it has an entire translation system with built in automatic placeholder support
No, MiniMessage is a string parser - so it tokenizes the strings and then turns it to a component afterwards, there no work done on components directly
MiniMessage ❤️
how can I set a default font globally
You can't
You can ofc just replace the default font in a resource pack, which I assume you're using anyway
so
I'll put an internal <font></font>
font:minecraft for minecraft and font:default for resourcepack defaults?
font:default is setting my custom texture and font:minecraft or font:whatever goes to minecraft
what
a font is a namespaced key, minecraft:default is the namespaced key of the default font, if you have a custom font you'd use my_namespace:cool_font
when using minimessage, you pass the whole namespaced key to the font tag, <font:minecraft:default> or <font:my_namespace:cool_font>
you can replace the default font in a resource pack, by putting it as the default font in the minecraft namespace, then that will just be the default font for everything
so probably if I don't specify namespace it will be minecraft
yes minecraft:default it setting my custom texture
minecraft:default and default set my custom txture, anything else set the minecraft default texture hahaha
if you replaced the default font in a resource pack, yes of course
awaiting the minimessage translation system 
It'll come when it comes, we all work in our free time and taking time to review stuff is hard
Testing out the PRs and dropping a comment is always good !
Could someone link to that pr
I am to blind to find it 😂
Nvm I think it is the translation store pr
why are CompoundBinaryTag#get*(key, defaultValue) methods notnull? using a null as defaultValue works according to the implementation
using null as defaultValue seems to be against the specification
Would you need the default values being nullable?
that sounds like a bug then
I'm not against making the param nullable and using @Contract for the nullability like we do in other areas
Just wanna make sure there's a good reason
but making the param nullable implies making the return type nullable
Using @Contract you can refine the nullability in certain case (for example, _, !null -> !null means « when the second parameter is not null, the method returns not null »
you are still widening the return type
I assume right now the default value is always not null?
Thus, adding the possibility of passing a nullable default value, that could lead to nullable return, only adds an eventuality. The return value will still be not null when the given default value will be
The return type wouldn't widen for existing API users
while not a binary incompatible change, api wise it's still widening, i can only imagine the 3 kotlin nbt users coming to complain their code no longer compiles after updating
I don't need it anymore, but I was writing an implementation of a maplike class with backing CompoundBinaryTag and it was just easier to simply do compoundTag.getString("key", null) instead of compoundTag.get("key") != null ? compoundTag.getString("key") : null when return value of my maplike's getString method is nullable
Well the get method doesn't return null anyway so
it does
But I don't really think using CBT in for a map is a good idea
yeah, true, that's why I dont need it anymore 😳
Oh right that not getString
nobody cares about kotlin users
They're used to breaking changes
just don't tell jroy i said that i have a reputation to uphold
so real
can anyone help me with showItem for hover event?
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply.
how do i get Map<Key, ? extends DataComponentValue> dataComponents from items?
i got BinaryTagHolder but that doesn't display anything about item, display name, lore, etc
so i assume i need to get those data component values
i know about getData in ItemStack, but that returns Valued and not DataComponentValue
if you're using paper you can just use ItemStack#asHoverEvent()
is there a way to do a simple if else with MiniMessage tags? example <<a_boolean>:<if_true_>:%else%>
ctx.getTagResolverList().add(Formatter.booleanChoice("self_profile", isSelfProfile()));
how the tag would be like? it will parse other tags?
Just <tag_name:true_value:false_value>
it will support tags yes
ok
Maybe unusual question, but what would be the format for a JSON component to have a text shadow color applied? The MC wiki seems to be outdated on this info.
uhh I think the MC changelog was linked somewhere
maybe in the original shadow colour PR
I'm getting a Component with a Block's Name by using Component.translatable(Block#translationKey())
My question now is, how I could obtain the actual text for a player? I want to calculate the text width returned, but I'm unsure what I would need to do here to achieve this with a translatable.
You can't compute server-side something that is client-side
The actual string is defined by the user locale, and possibly the resource pack
I mean, the english (and only the english) default lang file is present in the server, so you can use the Translator (I forget the exact class name) to set it for english only, with all of those above caveats too
The best you can do would be to take the English (or any other language, probably the one most of your users will use) translation files and compute the result, but yeah that won't be exact for all players
What is the final goal?
I just mentioned it
(Why do you need the width?)
To apply specific amounts of characters that will display custom images based on a resource pack
Could someone explain what tag resolvers are?
They are how you resolve custom tags in MiniMessage
Give the docs a read and if you have any other questions we'd be happy to answer 🫡 https://docs.advntr.dev/minimessage/api.html
so basically like placeholders right?
Yeah basically
ah okay thanks
By default, Gson escapes HTML characters such as < > etc.
there's a method on GsonBuilder called disableHtmlEscaping to turn that off
ty
What's the easiest way to check if a component is Component.empty()?
==
That's easier than I honestly expected...
Tho, if I now would apply a font to an empty component, would it still be considered empty?
well it won't be the empty instance because it doesn't have an empty style
^ it would no longer be Component.empty()
Does the shadow component not work in chat? I tried displaying <!shadow>Test in the action bar- works great. But displaying it in chat shows "Test" with its shadow still there.
Should work fine
works fine for me
What platform/version? Any protocol hacks e.g. via version?
Any custom clients or client modifications?
Using 1.21.4 Paper (and client is on Fabric 1.21.4 with no mods installed). ViaVersion is installed, yes.
try without via and on vanilla
Oh wait, ViaVersion isn't installed on this server. I'll try changing to vanilla
Ah, it was the profanity filter I was using. I guess it's stripping the !shadow away but not color or other text format. Thanks for pointing me in the right direction!
Most likely used an outdated adventure version or worse, bungee chat stuff
Open an issue so they can fix
Well actually the weird thing is, it's only using text.replaceText(builder -> builder.match(pattern).replacement(maskWord(word)))
text is a MiniMessage Component
if we aren't accounting for shadow in style merging and such? feels like a big oversight if true
No, it's a plugin I made. I didn't shade it
I see
Can you try to recreate a simple reproduction case and open an issue with that please? So somebody can take a look and this isn't lost
Yeah
I looked into it deeper and it's something wrong with packetevents, not MiniMessage.
Thanks for the update!
serializing ItemStack.asHoverEvent() creates a component with § colors inside that is impossible to deserialize again
how can i serialize asHoverEvent so that it is in correct minimessage format?
Thanks
Can you show your code and a toString of the component you get from asHoverEvent as well as a /paper dumpitem for that same item?
sure
First is the console error the second is the dumpitem
private Component getItemNameComponent(@NotNull ItemStack itemStack) {
if (itemStack.getItemMeta() != null && itemNameProvider.hasItemName(itemStack.getItemMeta())) {
return LegacyComponentSerializer.legacySection().deserialize(
replaceAmpersandCodesWithSection(itemNameProvider.getItemName(itemStack.getItemMeta())))
.hoverEvent(itemStack.asHoverEvent());
}
if (itemStack.getType().isAir()) {
return Component.text(plugin.config.nothing_tag);
}
return Component.translatable(itemStack.getType().translationKey())
.hoverEvent(itemStack.asHoverEvent());
}
This is the method
message.txt by @tepid fable: https://pastes.dev/qSAC9MN8Le
message.txt by @tepid fable: https://pastes.dev/8U7dX9D2a5
ok but it works. why does it work in normal minecraft and then it doesn't serialize correctly?
Because the clients text renderer still has logic for parsing the legacy cruft
it's just unsupported by them and us
it has many dozens of side-effects and we generally just do not support it
I thought that that stuff would be escaped out and MM would just ignore it on the reverse, however
is there any way to translate those legacy into minimessage?
Depends on the input, generalyl you'd go component > MM
There's no reason to still be using legacy formatting in your code or configs in 2025. Time to migrate! 🙂
Got it thank you. i agree but many plugins are still outdated af
i hate MMOItems
it's such a bad plugin
hey hi I'm having trouble with advanture api
<hover:show_text:“<gray>ѕᴏɴʀᴀᴋɪ ѕᴏʜʙᴇᴛᴇ ɢᴇçᴍᴇᴋ ɪçɪɴ ᴛıᴋʟᴀ”><click:run_command:/wlook command odulcu_ferhat_sifir><bold><gold>ѕᴏɴʀᴀᴋɪ"</click></hover>
I'm doing something like this, I normally work in 1.20.1, I changed the server version to 1.21.1 and only <gold> started to work, run_command does not work or I cannot click on it.
AdventureManager.java by @remote marten: https://pastes.dev/9LoKYAXBt9
NPCMessage.java by @remote marten: https://pastes.dev/wvd7VOW35v
are you using viaversion or some other protocol hack?
make sure you're testing with the same client & server version
Formatter.booleanChoice("test", value);
works: <test:A:B>
doesn't work: <test:<green>A:<gray>B>
please help
thank you
how can I stop minimessage from escaping non-resolved tags when serializing to a string?
You can't, that's just how it works in order to allow for proper round-trip serializing
Why do you not want non-resolved tags to be escaped? Sounds like a bit of an xy
so I have a method that takes a string and returns a component, basically a converter.
But the input string can contain §, & and minimessage text, and I want to convert all of them
That's not something we support or recommend at all, it's unfriendly to users and hard to maintain a system that works like that. I'd recommend a one-time migration of your config/lang files/etc to use MiniMessage so you don't have to worry about it at all
and it's janky, but this is what I'm currently using
val converted = LegacyComponentSerializer.legacySection().deserialize(text)
val converted2 = LegacyComponentSerializer.legacyAmpersand().deserialize(LegacyComponentSerializer.legacyAmpersand().serialize(converted))
val back = MiniMessage.miniMessage().serialize(converted2)
MiniMessage.miniMessage().deserialize(back)
Yeah im converting my stuff to minimessage rn but I need a temporary fix
The suggested temporary fix is a simple one-time migration
im currently doing that but I got a lot of stuff depending on this and I just want to see if it works
but thank you anyway
is it possible to get a raw String from a Component?
What do you mean?
like get the text content
There are three or more different strings you could get from a Component
plain text, JSON, minimessage, etc
plain text
Do Component#color and Component#decoration modify the instance or do they only return a modified copy?
So would this code work?
Component component = Translation.component(this, key, variables)
if (color != null)
component.color(color)
if (decoration != null)
component.decorate(decoration);
return component;
Components are immutable, any method that "modifies" a component just returns a mutated copy
alright, thank you
Hello can someone explain my why Component#replaceText doesnt work for me?
Component prefix = gamePlayer.getSelectedPrefix().getPrefix().replaceText(TextReplacementConfig.builder().match("%user_name%").replacement(player.getName()).build());
Component prefix = MiniMessage.miniMessage().deserialize("gradient:#BAC06F:#E47AEB%user_name%</gradient>");
thats my prefix where i want to replace the %user_name% with the players name.
Is there a reason you aren't using MiniMessage's tag system?
e.g. Component prefix = MiniMessage.miniMessage().deserialize("<gradient:#BAC06F:#E47AEB><user_name></gradient>", Placeholder.unparsed("user_name", player.getName()));
In fact the reason your code isn't working is because it would never work at all. When you make the MiniMessage string the %user_name% will be split and colored individually to apply the gradient - meaning you can't use the text replacement system because each character will be in its own component with its own color, and the text replacement system doesn't match across components. So you actually need to be using MiniMessage properly here in order for it to work 😅
Ahh i see now it works thank you!
np! 🫡
will the minimessage translation system support having messages that use placeholders like <my_placeholder> instead of the {0} argument system used by the current internationalization system
Yes
You can see the draft documentation here https://kyoripowered.github.io/adventure-docs-previews/pull/205/minimessage/translator.html
e.renderer(ChatRenderer.viewerUnaware((source, sourceDisplayName, message) -> Component.text().append(miniMessage().deserialize(prefix)).append(Component.text((plainText().serialize(sourceDisplayName)))).append(miniMessage().deserialize("<white>:<reset> ")).append(message).build()));
Why does this not color the username?
because you're appending the display name to the empty component which has no styling
but I put the prefix in front of it
which has color in it
wait, does the color of a previous component not transfer to the next one?
components only inherit styling from their parent
so how do I fix this?
you can try appending the display name to the prefix component
do I really have to serialize the display name to minimsg, append the prefix in front of it and then deserialize it back to a component?
huh
does that mean there is a difference between appending components directly and using the builder?
other than performance yk
No, the issue is just what you're appending to
I would suggest using mini message entirely - it has a built-in custom tag system that allows you to easily add your own placeholders so you can avoid having to do all this appending
See this page and the dynamic replacements page for more information https://docs.advntr.dev/minimessage/api.html
hey, <!shadow> does not seem to work. It does not get parsed or anything, it stays as <!shadow>. I am on Fabric 1.21.1
Any idea why and how to fix or workaround?
did shadow even exist in 1.21.1
no it didn't, it was added in 1.21.4 - hence why you're not able to get it to work
Ah, I see, any way to remove shadows from text in 1.21.1?
Not in vanilla Minecraft
is there in modded? as I am running fabric
And your fabric mods added shadows?
I don't know about modded, hence why I said "vanilla"
no, I want to do some custom ranks, with fonts, and they double down with the shadow and look weird
hence I want to remove the shadow
Why are you running in 1.21.1 and not latest?
The reason I asked what I asked is because, as kezz said, shadows weren't added until 1.21.4. So, where are the shadows coming from, as it wouldn't be in a 'clean' fabric install.
Shadows are part of Minecraft vanilla tho
shadows were always a thing, the ability to specify a custom shadow colour wasn't
isn't minecraft text shadowed by default?
It's the option to customize (and therefore disable) them that was added
The ability to toggle that shadow was always a thing? 
no?
Okay, so the answer is "on 1.21.1 this cannot be disabled without some sort of mod shenanigans, and wouldn't be part of adventure"?
That's it
with the default shadows
do you have an example of what kind of "rank tags" you have in mind?
i mean in game
If you look closely, you'll see the shadow
all servers I've seen using those kind of tags have always had the default shadows
I see
maybe adding a ticker border would mask it somewhat
Let's be honest, I don't even see the shadow as a problem on your screenshot
But that's a whole different conversation, and I don't want to question your design choices
yeah, I was alligning it so I was zooming it and checking per pixel
pixel-perfection in such a low-graphics-quality game is a route to madness
this is a better representation of what I was looking at
yeah, thought it was as simple as adding <!shadow>
anyways, thanks for the help guys
We'll say it adds a little depth to your design 😂
you can remove them using core shaders @mild oracle
huh, interesting, does this require optifine or iris for rendering?
nope, just a resource pack
Alright that will be very useful, thanks
I notice that 1.21.4 paper that MiniMessage#deserialize(String) does not throw an IllegalArgument Ex if the String contains § Is this really the cause or are my exceptions bugged 😂
You're working on fabric, just mixin them away lol
it should
Yeah I did that but it disabled all shadows on all text, and it was fine, but this way would work better as I can selectively disable shadow on just some of the text
You're making the mixin, just put an if statement somewhere on the content or w/e
I did not manage to get that working as the render function was receiving the entire line of text and was computing the shadow for the entire line, and I wanted something like [no_shadow] [shadow} [no_shadow] {shadow]
Hello there
I wanted to ask few questions
1a) Since which Adventure/MiniMessage version shadow is supported
1b) Since which MC version shadow display thing for chat and message formatting will be seen by the client? 1.2?.? (and higher)
2b) What is matrix formatting called, i mean how to call it in MiniMessage, i tried [matrix] and [magic], both does not work
thank you very much,
kill me but i cannot see anywhere matrix format or however it is it's name...
ok obfuscated
apologizes
hello mrs,
this works:
<friend_online_status_ordinal_choice:'0#OFFLINE|1#ONLINE|2#AFK'>
this doesn't:
<friend_online_status_ordinal_choice:'0#<red>OFFLINE|1#ONLINE|2#AFK'>
am I missing any quote?
Isn't it up to whatever added the friend_online_status_ordinal_choice tag whether or not MM tags get parsed in there?
can't say im that familiar with the syntax for choice format, but probably consult the jd for it
<white>Status: <friend_online_status_ordinal_choice:'0#"O<red>FF"|1#ON|2#AFK'>
tagResolverList.add(Formatter.choice("friend_online_status_ordinal_choice", friend.getOnlineStatus().ordinal()));
I'm not really sure what else to say at this point, you might have to consult the javadocs for choice format to see exactly what format the strings should be in
I'll take a look
on it
fixed it:
<white>Status: <friend_online_status_ordinal_choice:0#'<red>OFFLINE'|1#'<green>ONLINE'|2#'<gold>AFK'>
nice spot!
Hello
so i did not use adventure since 4.14 (maybe it's even earlier version)
was it there ever net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer or not and if yes what happened with it?
seperate module?
well i had adventure shaded into a plugin, and this was also there with few more bungeecord classes
Yes
as part of a seperate module
yes
is there the same thing for velocity?
why would there be?
velocity already has native support for adventure and bundles in the defacto serialisers
there is no platform specific stuff that we'd need to deal with translating to, implementing our own text component representation would of been dum
ok so, how can i utilize this in a velocity plugin
I am new to velocity and to adventure to be honest
i don't see anywhere usage for velocity on docs.advntr.dev
Because it's natively supported
velocity classes implement the Audience interface
so you'd just get the player and use the standard adventure methods
ok alright will come back here after i play around even if i don't know, thanks a lot for that infos
Just a question, isn't title duration based on ticks? Why Duration is needed here
Duration is available everywhere, too
and is easy to convert into the platform requirements
If you want "standard" ticks - see Ticks.duration
#this works:
lore=\
<test1:\
0#'\
A\
<test2:\
0#'\
A\
'|1#'\
B\
'|2#'\
C\
'>\
'|1#'\
B\
'|2#'\
C\
'|3#'\
D\
'>
#this works:
lore=\
<test1:\
0#'\
<red>A</red>\
<test2:\
0#'\
A\
'|1#'\
B\
'|2#'\
C\
'>\
'|1#'\
B\
'|2#'\
C\
'|3#'\
D\
'>
#this doesn't work:
lore=\
<test1:\
0#'\
<red>A</red>\
<test2:\
0#'\
<red>A</red>\
'|1#'\
B\
'|2#'\
C\
'>\
'|1#'\
B\
'|2#'\
C\
'|3#'\
D\
'>
do I need to escape any quote or tag when choice inside choice?
seems to be correct but maybe put all of them into one line
thats even more confusing than online line
lore=<test1:0#'<red>A</red><test2:0#'<red>A</red>'|1#'B'|2#'C'>'|1#'B'|2#'C'|3#'D'>
the problem is in the quotes, but I have no idea how to fix that
I guess you already tried \' or \\'?
yes \' and \\'
And " or even maybe SQL-style ''?
Hey !
I'm having a little problem with my resolver tag. It works perfectly as long as there is no null management.
Here, val uuid = PlayerVoteData.getRank(place) the uuid is nullable. When the value is not null the resolver tag works perfectly but as soon as it is null, it stops and I don't even get the debug message println(‘DEBUG: Fetched UUID: $uuid’)
Is there a solution for managing nulls in a resolver tag?
private fun topLeaderboardPlaceTagResolver(): TagResolver {
return TagResolver.resolver("vote_leaderboard") { args: ArgumentQueue, _: Context? ->
val placeStr = args.popOr("Missing place id node").value()
println("DEBUG: Parsing place: $placeStr")
val place = placeStr.toIntOrNull()
if (place == null) {
println("DEBUG: Invalid place format")
return@resolver Tag.inserting(Component.text("Invalid place"))
}
val uuid = PlayerVoteData.getRank(place)
println("DEBUG: Fetched UUID: $uuid")
if (uuid == null) {
println("DEBUG: No player found at this rank")
return@resolver Tag.inserting(Component.text("No Player"))
}
val username = PlayerDataManager.getUsername(uuid) ?: "Unknown"
println("DEBUG: Resolved username: $username")
Tag.inserting(Component.text(username))
}
}
MiniMessage would not stop the execution of code if a variable was null. There's no way that debug line wouldn't be hitting. I'd suggest checking to see if you're swallowing any exceptions and/or stepping through with a debugger to see what's happening in more detail.
Hi!
I'm using Kyori's BossBars for the first time and, coming from the Bukkit version of BossBars, I noticed that there is no removeAll() method (at least it seems like it).
Am I missing something or does it actually not exist and the only way is to remove it individually for each user?
Thanks!
Yeah you just have to remove it individually per player!
why doesn't Audience extend BBV anyway if it has show/hideBossBar & BB has add/removeViewer(Audience)?
tbh i'm not sure why we have BBV in the first place
Sad, but thanks bro sadge
Sorry if I'm in the wrong place, but I was just curious if anyone knew if the mini message tag <font> supports .ttf files?
Couldn't get my font to work with it but I may have just done it totally wrong
it's just a reference to a resource pack font
Gotcha, I'm guessing I just did something wrong somewhere lol, this just shows square icons <font:a.ttf>TEST</font>
well what's the font named in the resource pack?
a.ttf, I'm trying this out through ItemsAdder
I see, so that's just how IA does it I guess
Hi guys, why does this not work?
I used MiniMessage.miniMessage().deserialize, should i be using something else?
"<red>Hello World" works
Specifically
Oh! I was using the wrong format, makes sense now, thank you!
Also what components are indeed shaded into paper? If i just want to support paper, what can i call in terms of MiniMessage?
I'm getting this:
"ClassNotFound net.kyori.adventure.platform.bukkit.BukkitAudiences"
If you just target paper, don't bother with platform-bukkit
Adventure and MiniMessage are included in paper, you can just call player.sendRichMessage("<rainbow>woohoo");
Gotcha, is there any dependency i can use to get what you guys use for paper? (Assuming i don't need dpeendency to paper?)
Oh, and is this supported 1.16.5+?
1.17.1+
Idk when we added MiniMessage
Generally nobody uses those old versions anyways
So dw about it
Since when did your name not have an e
Lol who was that
So i'm currenrtly using this with no dependencies to know if Paper is active (with Adventure), do you guys recommend this?
try {
Class.forName("io.papermc.paper.adventure.PaperAdventure");
return true;
} catch (ClassNotFoundException e) {
return false;
}
Will this guarantee that there is a sendRichMessage?
You would want to look for MiniMessage specifically
This is a hook just for paper, not sure if i need anything else?
Paper had adventure in 1.16 iirc but didn't get MM until 1.17.1
Because sendRichMessage method is on paper, i just want a way to check if sendRichMessage without Checking via further reflection
Was changed yesterday evening, lol
Although I think from 1.16 to 1.17 adventure had some API breaks anyway? At least the bits MM interfaces with did
Yeah i understand, i'm just focusing on the method you mentioned, the sendRichMessage
sendRichMessage depends on MM
So does this apply to every case of MM?
You could just look for that specific method
My questiton is if i can use that code i shared to make sure sendRichMessage is available
i'd recommend using sendMessage with a component and doing the MM parsing yourself
that way you cover more versions
No you cannot
That would return true on versions of Paper that don't have MiniMessage
Yeah well, I was looking to avoid shading MM on my plugin if is already present on Paper
Thats what originated my original question
Unless you pull in your own copy of adventure and minimessage and relocate them that won't work either, you can't use minimessage with the bundled version of adventure in paper 1.16
if you want to check if that specific method exists you can use reflections on the CommandSender class
Just stop caring about old stuff and you can just always use adventure and MM 😄
Not everything that is easy has the best outcome
There are less than 2000 servers on 1.16
I'll use what you mentioned (the commandsender, thanks)
How high is the chance that they want to use your stuff? Lol
Yeah i just want to avoid edge cases which would lead to extra maintenace in the future
When did my nephew get turned in to a meme?
To compare, there are 100k servers on 1.21
well... that edge case is "users running outdated versions"
if you dont support outdated versions at all you cant run into edge cases
If you don't know the vision, better not to argue
I already mentioned above in other convs
Thanks anyway, what you mentioned will help me 🙂
What?
That kid looks a lot like my nephew did 10 years ago
'quick' question; I have a lot of translations I want to convert to MiniMessage, so I'm using a development build of adventure (4.20.0-SNAPSHOT) to take advantage of the MiniMessage translation system.
Now there is an issue; I can't use a ResourceBundle to add all my translations to the MiniMessageTranslationStore, since it does not implement TranslationStore.StringBased. What's the recommended way of adding the all the translations to the MiniMessageTranslationStore? I haven't tried anything yet, and I want to make sure I'm doing it correctly beforehand.
Pushed a fix for this now, thanks for pointing it out!
merge commits 
great, thank you!
now why tf did that build fail
the previous build failed too
kotlin
let's yeet it now
lol
ok unfortunately i do not have time to fix the build today but ill check it out tomorrow for ya
that’s fine, thank you
it's probably just changing the deprecation warning level
shouldn't the text be gray when using this method on a Component when using 2.20.0-SNAPSHOT?
my translation of command.gamemode.set.self is Your gamemode has been set to <gamemode> and I'm sending it with this code:
val arg = Argument.component("gamemode", text(to, YELLOW))
player.sendMessage(translatable("command.gamemode.set.self", GRAY, arg))
see the image for what I actually receive
nb. I've compiled paper with the dev version of adventure as well, which is the reason it 'works' in the first place
(of course with a MiniMessageTranslationStore)
afaict it's because this method doesn't copy the translatable component's style
https://github.com/KyoriPowered/adventure/blob/364dc1ad808a433065ca5df9c396d5d80c389791/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/translation/MiniMessageTranslator.java#L139
is that intended behavior?
i mean probably not? probably just missed
hot damn another good spot
yeah it really should be applying the style from the component
can you open an issue for this and assign me? ill get to it monday
thank you for testing and playing with it btw! how are you finding the new api? still time for suggestions or improvements
so far (almost) everything seems to work as expected, and pretty intuitive as well. I haven't experimented a whole lot though, so I can't really give good suggestions or improvements
Very nice, glad to hear that!
please do let me know if you've got any comments or issues at all tho! :D
Will do, ty!
assigned
Would it be possible to limit the number of characters in a component? Or alternatively process the component to remove any characters over my limit?
I am basically just trying to display an item's display name on a sign, I previously was just setting the line with a String and taking a substring and adding ... if the name went over the limit of 15. But when gradients and hex colours get involved that isn't really feasible anymore
There's no API for it, but you can look at the component flattener to get a good truncation system working
I'm not quite understanding what the ComponentFlattener is doing. Is it just ensuring everything is on the same level instead of components in components as such?
It's effectively an iterator through a component tree that gives you access to pop/pushed style and plain text via the FlattenerListener that you implement
ohhh
So you could use it to fetch the style and text of a component, stop after you hit 15 characters and break out
that's reasonable! thank you :)
can I use equals to compare two components if they have the same contents and decorations
.equals yes
Is this the kind of thing you were meaning? Or have I gone really wrong aha
edit for anyone looking back on this: i just missed updating the remaining limit and also added a check in the pushStyle and component methods to ensure the limit was not below or equal to 0
yeah i think that looks good
Yeahh that worked great, thanks for the advice and support, it's greatly appreciated!
Yeahh I could see it being handy in other scenarios too
how can I make a TranslatableComponentRenderer render child TranslatableComponents when the top-level component is also a TranslatableComponent? This statement specifically makes that not work, so what's the correct way to do this?
^ pulled from TranslatableComponentRenderer.usingTranslationSource
XY: I'm trying to implement my own Translator so I don't have to use the GlobalTranslator so I can translate stuff when building ItemStacks for usage in inventory menus (and I saw people recommend usage of a separate Translator instead of the GlobalTranslator)
It should be deeply rendering anyway
I wouldn't recommend implementing your own Translator anyway, use a TranslationStore - you don't have to register it to the global translator
oops, my bad I was confused. I am actually using the MiniMessageTranslationStore and using that to create a TranslatableComponentRenderer
should I not do that?
I was doing it this way since translate only takes a TranslatableComponent
Actually I think you're right, it should be calling this.optionallyRenderChildrenAppendAndBuild on the resulting component
how have component translations ever worked lol
¯_(ツ)_/¯
oh i see it's nested translatables that's the issue
yes
appending two translatables to a ComponentBuilder works fine
it's just that it doesn't work when the top-level component is a translatable
Using this registry implementation and this properties file team.red = <red>Team Red mapsetup.stage.9.name.success = <grey>The spawnpoint of arg:0 <grey>has <green>s...
I can get to that tomorrow unless you want to make a pr - we need to add proper component translation to the renderer
rather than the current system of overriding and calling super
I'll leave that to you, you know way more about this than I do. Thank you for these quick fixes 🙂
Not at all! I'm sorry these bugs all snuck through haha
We really should have better unit tests for that
adds the volkswagen dependency
<@&748618676189528155>
(67eae3f26ed5010734cf1c4c) // @severe gate (@danehcan / 1163918666409181235) has been banned by @green monolith (276788573666017280)
Reason: Steam scam
#dev-announcements finally legacy color codes can be removed 
finally exit(1) when a § is encountered
unfortunately the legacy serializer will be sticking around for a while yet
even though we discourage using legacy in any projects, it's still very useful for converting from legacy to something like minimessage
-# riley why no french nickname?
Some projects that work from 1.8 to 1.21 heavily depend on adventure. For instance, Packetevents is the most used packet library and is compiled with java 8. Adventure 5.0 will def kill all old minecraft versions that were supported well
No but most servers won’t run java 21
modern minecraft doesn't run on anything below java 21, and below java 17 for older minecraft versions. we've been on java 8 for many years now (nearly 10!), and we can't stay on it forever when so few users are running it
idk modern library and 11 years old version doesn't really match
Yeah
adventure 4.x won't be dropped instantly once 5.x comes around, either. we'll likely continue supporting it for a fair amount of time before it goes away
Tip & Tail 
1.8 forks (which is the only "reasonable" way to do 1.8 at this point) work with java 21.
Using java 8 to run software is throwing free performance gains out of the window
And a security risk
Man i wish Adventure 5.0 was real and not some april fools joke
Oh shi
What’s adventure
a library for rich text representation
Why do you want it to be real? There are barely any api changes for you.
https://docs.advntr.dev/
a library which wraps minecraft's chat components
is built-in in PaperMC, so you can use it's API right away
it also has mini message which allows you to use XML-like syntax for styling your text
Hi guys, I'm getting this when trying to use sendRichMessage that might contain MiniMessage components as well as standard bukkit colors, how can I allow a message to be sent to the player that contains both Minimessage parsing and standard bukkit colors?
standard bukkit colors
are literally not a thing
MM does not support using legacy colors, it breaks the entire concept of the tree and creates a whole bunch of headaches
best you can do is try to convert them, but, depends on where it's coming from, etc
I would assume this would only convert the legacy instead of also supporting MM components?
We can't be migrating to MM as we also support multi-version, so do you think a parser would work? So it converts &4 to <red>?
Is there anything currently right now that allows me to support both MM and bukkit colors? (both at the same time, even if there is a parser in middle, it doesnt really matter)
No
that will break the tree
I mean, if you want to do a blind find and replace, go for it
Just expect inconsistent output and 0 support
Alr thx 🙂
MiniMessage is version agnostic so I'm not sure what your issue is here
It "supports" any Minecraft version
is there a way to add a dynamic placeholders (with player support)? So it would be updated automatically instead of setting it every time as an update
Create a tag resolver
Example:
this.miniMessage = MiniMessage.builder().editTags(t -> t
.tag("random", (args, context) -> {
Component c = Math.random() < 0.5 ? Component.text("Yes!") : Component.text("No :(");
return Tag.selfClosingInserting(c);
})
).build();
MM ♥️
But you cant access the player there, no?
Hmm, I'm no sure what you mean by "the player"?
A (mini)message can be deserialized in any context, even where there's no player
I know there's a concept of "pointered" that can be passed in the .deserialize method, but I never played with it so I don't really know more
If you pass the player on deserialize you can access it using context.targetAsType(Player.class)
well, I want it to update
if a player is at X and he moves to Y, the text will update (from X to Y)
Can you explain a little bit more what are you trying to achieve? This looks a bit like an XY problem (no pun intended)
sure
if a player is at XYZ: 5,64,9
the text will be 5,64,9
if he moves to a different locatio - XYZ: 20,90,80
The text will be updated to 20,90,80
And I dont want it only for locations
kinda like how you can update it manually, I am asking if there is a built in option
Minecraft has no mechanism for automatically updating any form of text
You'll have to do that yourself
you listen to the move event and change the text, action bar, scoreboard, tab list header/footer, wherever
What "text" are you talking about? Actionbar? Bossbar? Scoreboard entry? Either way, as Kezz said, you have to run the update logic manually (every tick or second, on specific event such as PlayerMoveEvent...) in order to recompute the value
Is there a way to add a list of tag resolvers?
or something like that
ok got it
TagResolver.resolver()
and I add to it the others, right?
TagResolver.resolver(resolver1, resolver2, etc)
List<TagResolver> a = new ArrayList<>();
TagResolver.resolver(a);
nice
or use the deserialize method that accepts a varargs of resolvers
TagResolver fineBlockPosResolver = TagResolver.resolver(
TagResolver.resolver("block_x", Tag.selfClosingInserting(Component.text(player.getLocation().getBlockX()))),
TagResolver.resolver("block_y", Tag.selfClosingInserting(Component.text(player.getLocation().getBlockY()))),
TagResolver.resolver("block_z", Tag.selfClosingInserting(Component.text(player.getLocation().getBlockZ())))
);
Is this ok or there's a better way?
-# P.S - Why am I the only one asking questions?? 😭
TagResolver fineBlockPosResolver = TagResolver.builder()
.tag("block_x", Tag.selfClosingInserting(Component.text(player.getLocation().getBlockX())))
.tag("block_y", Tag.selfClosingInserting(Component.text(player.getLocation().getBlockY())))
.tag("block_z", Tag.selfClosingInserting(Component.text(player.getLocation().getBlockZ())))
.build();
hmm
either is fine tbh
Placeholder.component makes a tag resolver for you a bit simpler
same end result though
Sorry if this is the wrong place to ask. I'm interested in using the MiniMessageTranslator which was added in 4.20. I was wondering if there's a timeline for that version's official release, and if it aligns with Paper 1.21.5, would the bundled version be bumped to 4.20, or is 4.18 (as per "1.21.5-no-moonrise-SNAPSHOT") the decided version for the 1.21.5 release?
how do i use a boolean choices
the docs only touch number choices
i tried <value:'enabled','disabled'>
<value:'enabled|disabled'>
<value:'true#enabled|false#disabled'>
figured it out <value:'enabled':'disabled'>
Well, paper 1.21.5 will at least require 4.20 for hovers and clicks to work properly
That doesn't exist tho
Generally we bump adventure whenever possible
how would i dynamicly replace the text of lore? i have a system for custom items and it needs dynamicly updating lore based on nbt(Item Components), time of day(day/night), etc.
i'm defining the lore in MiniMessage format
Use placeolders and reparse the MiniMessage
thanks! whats the best place to re-parse the message? it feels less then performant to re-parse very tick on all items
true! thank you!
I just wanna very quickly verify this. There is no sane way to create the equivalent of a <gradient> tag with the API, right? I am like 99% sure of that, but I am asking for the remaining 1%. (So explicitely without the usage of MiniMessage)
I am not asking for myself — I would personally just use MiniMessage — but I am asking out of curiosity
I mean, depends on your input/output
like, replaceText lets you return some component, you'd just need to deal with generating the gradient components yourself
Let's say I have a String: This is very nice looking text.
I want that to turn into a gradiented Component, which is the equivalent of if I were to serialize ```xml
<b>gradient:light_purple:aqua:light_purpleThis is very nice looking text
Just to specifiy it a bit further
Mhm. I suppose yeah. But nothing direct. In that case, my information is up-to-date lol
I mean, I would probably be grabbing code from adventure to emulate that, but, tags are handled purely in their own space in MM
anything else would require you to deal with that component creation yourself
And that's more effort than it is worth lmao
How can I use MiniMessage in a component, and simultaneously use PlaceholderAPI.setPlaceholders, which in most cases includes legacy ampersand color codes, and still render those color codes correctly?
I know you can parse them into a component, using LegacyComponentSerializer.legacyAmpersand(), but say I had this
var ampersand = LegacyComponentSerializer.legacyAmpersand();
var mini = MiniMessage.miniMessage();
String format = "<b><blue>%vault_prefix% EXAMPLE</blue></b>"
// how to correctly parse `format` string with both?
best you could do is abuse replaceText and call into PAPI there and do the translation
Something that I personally have done is that I made a custom Tag <papi>, which takes the placeholder api tag itself as an argument, and then convert the legacy text into a nice component in the tag itself
I believe that's also somewhere in the adventure docs as an example?
Yep, here: https://docs.advntr.dev/faq.html#how-can-i-use-bukkits-placeholderapi-in-minimessage-messages
So, works in the sense that it is able to retrieve the placeholders, however it does not seem to correctly parse the color codes
PAPI is not returning them using the section symbol (§) either, it returns them with an ampersand (&)
then use the legacyAmpersand serialiser
idk if that's consistent however, might want to try to deal with both
works fine
if you are referring to the behaviour of PAPI, yeah i'm unsure about that too, though this is not a plugin I am going to publish so it isnt a big deal for me
PAPI itself has no concept of colored text - the plugins providing the implementation of the placeholder just return a String. Whether they use an ampersand or a section symbol has no meaning to PAPI
in my case, vault_prefix placeholder contains ampersands.
I would probably just convert all section symbols to ampersands and use the ampersands legacy serializer
That's probably because you defined your prefix with ampersands though
older versions of PAPI used to parse ampersands using ChatColor.translateAlternateColorCodes method, so it consistenly returned strings containing section symbols, as far as I read so far
and then they decided it was out of the scope of PAPI to handle color, which is valid
Yeah, checks out
so the color doesnt spill, which makes it not function correctly in the context of a vault prefix in my use case
where the prefix would be, eg
&cAdmin
and the intention is that you join player name, and the player name is red
Yea, spilling has long been dead
tags can have placeholder args though, I think?
at least, I think that there was a preproccess type tag
well, maybe i just make it possible to put text directly into the placeholder before processing
for my use case
can tag arguments be empty?
eg
empty - papi:vault_prefix:
populated - papi:vault_prefix:electroniccat
ah actually no need for that question, as I can just peek them, and ignore if missing
EDIT - this works for me 👍 thank you guys for the help
I feel kinda blind right now, but wasn't there a tag in Minimessage to not have tags be formatted? Iirc sometheing called <pre>?
Because I can't find any entry in the format docs
don't see it in the source but maybe it's not a normal tag
rip
Sounds like you're including user input in a MiniMessage string - consider using Placeholder.unparsed
Ah yes that'll do it too! We had to get rid of the pre tag because people were just using it completely for user input
Obviously the users could just </pre> and that was that lmao
aw man, I was hoping this would be fixed https://github.com/KyoriPowered/adventure/issues/1157, but oh well
A user-interface library, formerly known as text, for Minecraft: Java Edition - Issues · KyoriPowered/adventure
when is the new version going to be bundled with paper?
Updates to Paper do not have any sort of estimate for when they release, ever. Any and all updates will arrive when they are ready, and the only thing to do is wait for them patiently along with everyone else.
it was more so a question of whether it was going to be with the 1.21.5 release, but I understand
What am I doing wrong?
config
reload: |
<gray> </gray>
<green><bold>RELOAD<reset>
<gray> </gray>
<gray>Reload the <green>config.yml<gray> file to apply changes.
<gray> </gray>
<green><bold>RELOAD CONFIG:<gold><reset>
<green>→ <underlined>Have a nice day!<reset>
https://pastebin.com/JVsm2YU1
Main class
Reloadcommand class
https://pastebin.com/Qqaz7hgf
When executing the command in console i see the text but when executing it in-game I see nothing.
@amber quail #adventure-platform-mod-help if you want to deal with legacy platform-bukkit
BukkitAudiences is only for spigot/bukkit/other legacy servers
did you read the docs?
Ahh yeah now I get why it does not work 😂
Thanks thats enough information for me
Im using a paper server so should not be using the bukkit one at all
Still pretty new to adventure so yeah just found it weird to work in console but yeah I was using the wrong audiences
Works great now
XD
How can I check if a Component is empty (or just contains spaces?)
if you just want to check if it's empty (no style & no content), just compare by reference to https://jd.advntr.dev/api/4.20.0/net/kyori/adventure/text/Component.html#empty()
if you want to check for if it only contains space characters that's different
declaration: package: net.kyori.adventure.text, interface: Component
I will test. I think in my case the number of whitespace characters is predictable
It is either empty or contains one space
So thats enough I guess
I can just use java .equals?
er
what exactly are you trying to do?
vault_prefix, empty = default rank
if (rank.equals(empty()) || rank.equals(space())) check is enough
Isn't vault prefix a string
so in my case, I have started to use a minimessage tag for papi to allow for the rest of my minimessage formatting to work properly
so i can embed the vault prefix into minimessage text
Hi, I have been looking at the adventure Github repository and I have seen that the api module is the one that developers use in our paper plugins. My question is why are there so many modules in the project? For example the text module I understand that they are the implementations of the classes that are in the API. What exactly are those implementations for and I have also seen that there are implementations in the API module. If someone can explain it to me?
there's no text module?
yeah mb. But any module there is a lot
it splits up dependencies, parts of the project some people might not need, and parts of the project that might only be useful for people implementing serializers
okey so you make it in parts to just use/add the ones you need
<@&748618676189528155>
how would i set lore text to white by default? i've remove the italic using .decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE)
.colorIfAbsent(NamedTextColor.WHITE)
tyyy
spotted this on the docs the other day, https://docs.advntr.dev/minimessage/translator.html#minimessage-translator
Is there a typo or something? I'm not sure what you're referring to here
The ()
^^
-public class MyMiniMessageTranslator extends MiniMessageTranslator() {
+public class MyMiniMessageTranslator extends MiniMessageTranslator {
Kotlin, not even once
nice spot, fixed it - thanks!
Hello, I have a question.
I want to create a custom TagResolver#resolver that is closeable and applies the <gradient> effect.
The values for said gradient are hardcoded in my code, they are not available in the argumentqueue.
I have tried and tried but I can not accomplish it. The furthest I achieved was using a Tag.preProcessParsed("<gradient:colorone:colortwo>") but it is self-closing and I don't want that.
How can I do it?
That looks like a special component that you can't replicate with the API so... nope
I guess find/replace the text before you pass it to MM?
pre process parsed tags are not self closing - can you show some code?
u can use this
MiniMessage mini = MiniMessage.builder()
.tags(TagResolver.builder()
.resolver(CustomGradientResolver.hardcodedGradient())
.build()
).build();
Component component = mini.deserialize("<gradient>text</gradient>");
Is it possible to override the locale used for a player (or audience) in the GlobalTranslator? If so, how should I do that? I'd prefer to not have to call render every single time I want something translated to a specific locale
Why do you not want to respect the locale choice of the player?
I will, I just want to be able to add an override if a player wants to have a different 'server' language than their client language for my plugin
Not possible unfortunately no
alr, sadge
is it possible to scale a component's text? or do I need to rely on fonts?
not possible in vanilla - you'd need fonts or shader fuckery
Tho, the aprils fool snapshot and the dev note on the latest snapshot saying they were working on GUIs, we might get something like that in a (near) future
At least I hope so
ye I was asking because the aprils fools snapshot had a changing text scale.
also in the new snap there ui elements on the locator bar are animated
They often experiment things in aprils fool snapshots, however we never know if things will be implemented properly in the following updates. I have a feeling this time the better UI elements (or at least the additional control options) will be, but I’m not working for Mojang
private void actionbarTask() {
String value = Config.getConfig().getString("Editor.message", "null");
Long time = Config.getConfig().getLong("Editor.time", 20L);
if (value.equals("null")) return;
Bukkit.getScheduler().runTaskTimer(this, () -> {
for (Player player : Bukkit.getOnlinePlayers()) {
String parsedText = PlaceholderAPI.setPlaceholders(player, value);
player.sendActionBar(MiniMessage.miniMessage().deserialize(parsedText, Tags.getStandard(), Tags.getGradient()));
}
}, 0L, time);
}
message: "<gradient:<gprimary>:<gsecondary>>Quest points:</gradient> <ascent>%notquests_player_questpoints%"
I have a question about custom fonts / images. We have in the texturepack (ItemsAdder) an image example19.png. If you write in chat :example19: it will render you an emoji, cool. If you do the same in Deluxe Menus it will also render emoji.
The question is how can I do that with Adventure?
How can I use dynamic replacements alongside arguments?
I have this input: <amount> <choice:'0#votes|1#vote|1<votes'>
but MiniMessage#deserialize doesn't have a way to parse the arguments:
kotlin
val arguments = args.map { Argument.component(it.first, it.second) }.toTypedArray()
val parsedChoice = MiniMessage.miniMessage().deserialize(lang.rawTranslation(key), Formatter.choice("choice", choiceInt))
// arguments aren't used```
What are you trying to achieve exactly? Where do choiceInt comes from in your code? And what is args?
I remember now why I don't like Kotlin, it's unreadable outside of the IDE 😦 val makes everything harder, needing to guess the types

You can create a custom <emoji> tag, that's the only way to do it with MiniMessage
Arguments are specifically for use with a MiniMessage translator - you need to use tags, e.g. Placeholder.component(it.first, it.second) - then you can just pass those into the varargs of tag resolvers
Oh I see
The example on the site made me think it required using this method 😅 thanks
The example is specifically for the translation system
I'm shading a few adventure libs into my plugin but I get this error when it runs on paper (no error on spigot):
Caused by: java.lang.IllegalStateException: Key adventure:json/emit/rgb has already been used. Option keys must be unique within a schema.
I'm using these deps. Last time I did plugin dev this wasn't a prob and I'm fairly sure kyori was native in paper by then, so I'm not what's up
net.kyori:adventure-api:4.19.0
net.kyori:adventure-platform-api:4.3.4
net.kyori:adventure-platform-bukkit:4.1.2
net.kyori:adventure-serializer-configurate4:4.19.0
net.kyori:adventure-text-minimessage:4.11.0
net.kyori:adventure-text-serializer-plain:4.11.0
net.kyori.moonshine:moonshine-core:2.0.4
net.kyori.moonshine:moonshine-standard:2.0.4
you're not relocating everything, look at your jar
you are correct, looks like net.kyori.option is not relocated. I never had that one configured. I will test but no doubt that'll fix this
Is it font:myfont:custom_font tag?
I guess you'll have to quote the argument, like <font:'myfont:custom_font'>text</font>
I don't know how ItemsAdder works but you need to find in the resource pack created the name of the font and the text to place
give me a moment
that's the resource pack
the points it that if I write it down on chat it works
:quest_hard:
Search in the resourcepack/menuicons/font/ (not resourcepack/menuicons/textures/font/) folder, it should contain a .json file with the font definition
To find out what text to write inside <font:'menuicons:quest_overlay19'>???</font>
there isn't any only yml file
info:
namespace: menuicons
font_images:
quest_hard:
show_in_gui: true
path: font/quest_hard.png
scale_ratio: 9
y_position: 8
quests_overlay19:
show_in_gui: true
path: font/quests_overlay19.png
scale_rotation: 256
y_position: 13
Then this is not the final resource pack, this is something the plugin is using to generate the pack. And I don't know how the plugin works so I can't help you more if you don't find the final resource pack generated and sent to clients
yea ok wait i will look at the outcome
mhm
no idea
OH
I DID IT
so the Placeholder API do it for you
message: "<gradient:<gprimary>:<gsecondary>>Quest points:</gradient> <ascent>%notquests_player_questpoints% %img_quest_hard%"
You need to add img_ before the name of texture
Hey one question about translations. I am wondering how to add support for localization on my Paper 1.21.4 server. I already have tons of Components created via Component#text or MiniMessage#deserialize. From what I've read GlobalTranslator is the way to go
I am asking because the components I send to players don't get translated automatically at least to my native language they don't
I'd recommend reading over https://docs.advntr.dev/localization.html and https://docs.advntr.dev/minimessage/translator.html
Adventure provides a way to utilize Minecraft’s built-in localization system for client-side translations as well as an additional Adventure-specific system for translating text. Using Minecraft’s ...
That's our "official" way of easily handling both component and minimessage translations
Note that you need to provide the translations via that system, neither adventure, the server nor the client handle any sort of "automatic" translation
I've done a bit of reading on these, but it says all components are automatically sent to the GlobalTranslator, yet when I switch to my native locale it doesnt translate
That vexes me
I mean, the client isn't exactly gonna ship an entire system to automatically translate arbitrary text unfortunately
hmm okay, so there isn't a way to translate my components easily?
You make the lang files, we provide systems to load them and automatically handle creating component in the languages you provide to players
so in reality, translating longer text is not a viable option. But for example adding translations for some items (I have a ton of custom items) is viable?
It's as viable as you want it to be
items don't support server sided translations because that would require modifying the itemstacks themselves, and would bung creative mode