#adventure-help
1 messages · Page 5 of 1
woo, who said that? i just asked a simple question no need to be rude saying such thing lol
I’m currently using:
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.21.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.21.0</version>
</dependency>
But for some reason on Minecraft 1.16.5 I’m getting this error:
are you relocating? you probably have a conflict with whatever version the server has
though at the end of the day, this applies
No, I'm not using relocate.
that's your problem
Okay, I'll give it a try. Thanks.
Hi guys, I am getting weird error: https://paste.md-5.net/etaroquqix.md it is caused by MiniMessageHolder
Here is my code:
public interface MiniMessageHolder {
MiniMessage MINI_MESSAGE = MiniMessage.builder()
.preProcessor(new LegacyColorPreProcessor())
.postProcessor(new LegacyColorProcessor())
.build();
}
public class LegacyColorProcessor implements UnaryOperator<Component> {
private static final TextReplacementConfig LEGACY_REPLACEMENT_CONFIG = TextReplacementConfig.builder()
.match(Pattern.compile(".*"))
.replacement((matchResult, build) -> Legacy.component(matchResult.group()))
.build();
@Override
public Component apply(Component component) {
return component.replaceText(LEGACY_REPLACEMENT_CONFIG);
}
}
public class LegacyColorPreProcessor implements UnaryOperator<String> {
@Override
public String apply(String component) {
return component.replace("§", "&");
}
}
public class Legacy {
public static final LegacyComponentSerializer AMPERSAND_SERIALIZER = LegacyComponentSerializer.builder()
.character('&')
.hexColors()
.useUnusualXRepeatedCharacterHexFormat()
.build();
public final static Component RESET_ITALIC = Component.text()
.decoration(TextDecoration.ITALIC, false)
.build();
public static Component component(String text) {
return RESET_ITALIC.append(AMPERSAND_SERIALIZER.deserialize(text));
}
public static List<Component> component(List<String> texts) {
return texts.stream()
.map(Legacy::component)
.collect(Collectors.toList());
}
}
plugins {
`java-library`
id("xyz.jpenilla.run-paper") version "2.3.1"
id("com.gradleup.shadow") version "9.0.0-beta12"
}
group = "pl.karoldronia"
version = "1.0-SNAPSHOT"
val mainPackage = "pl.karoldronia.bounties"
val projectPrefix = "stormcore-zlecenia"
repositories {
mavenCentral()
maven("https://storehouse.okaeri.eu/repository/maven-public/")
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://repo.eternalcode.pl/releases")
maven("https://jitpack.io")
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
dependencies {
// -- paper --
compileOnly("io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT")
// -- configs --
implementation("eu.okaeri:okaeri-configs-yaml-bukkit:5.0.6")
implementation("eu.okaeri:okaeri-configs-serdes-bukkit:5.0.6")
implementation("eu.okaeri:okaeri-configs-serdes-commons:5.0.6")
implementation("eu.okaeri:okaeri-configs-json-simple:5.0.6")
// -- commands --
implementation("dev.rollczi:litecommands-bukkit:3.9.7")
// adventure
implementation("net.kyori:adventure-platform-bukkit:4.3.1")
implementation("net.kyori:adventure-text-minimessage:4.16.0")
implementation("net.kyori:adventure-api:4.18.0")
// -- notifications --
implementation("com.eternalcode:multification-bukkit:1.1.4")
implementation("com.eternalcode:multification-okaeri:1.1.4")
// -- gui --
implementation("dev.triumphteam:triumph-gui:3.1.12")
// -- database --
implementation("eu.okaeri:okaeri-persistence-flat:3.0.1-beta.2")
// -- economy --
compileOnly("com.github.MilkBowl:VaultAPI:1.7.1")
}
tasks.shadowJar {
archiveFileName.set("${project.name} v${project.version}.jar")
exclude(
"org/intellij/lang/annotations/**",
"org/jetbrains/annotations/**",
"META-INF/**"
)
}
can somebody help me solve this error please?
Legacy support is not encouraged here
yea I know, but I think legacy support is not the problem
I am making plugins for some time already and this is the first time when I am making something for 1.17.1 and got this error 🥴
It is an extremely outdated version
Have you tried setting minimessage version to the same one as adventurw api?
Adventure supports all the versions
yes - the same error
Legacy formatting
you can not use minimessage on such outdated version. You need to use adventure-platform and relocate adventure, lacking paper adventure support if you want minimessage
oh wait
yeah, thats it
you need to relocate adventure
just it?
yes, but you are lacking paper methods which support components then
relocate entire net.kyori package?
net.kyori.adventure i believe
that's working!!! Thank you so much!
Is it possible to change Audience Language or resolve a key in a specific language?
Only english is available server side
I mean my own Plugin translation which I Feed into global Translator
Currently it's not possible natively in adventure. There is adventure/#1221 open, which adds support for this though.
Some platforms allow changing the locale of an audience themselves, like Player#setEffectiveLocale(Locale) in velocity for example, but if you're looking for something in paper it doesn't exist iirc
Okay, and is it possible to get the translated component from the global translator in a spezific language?, i guess i can use that: https://jd.advntr.dev/api/latest/net/kyori/adventure/translation/GlobalTranslator.html#render(net.kyori.adventure.text.Component,java.util.Locale)
Hope this pr get implemented 💯
declaration: package: net.kyori.adventure.translation, interface: GlobalTranslator
i have a Formatter.choice and want to display the time in singular and plural accordingly
this is my current MM format
time.day=<time:'1#one day|days'>
time.hour=<time:'1#one hour|hours'>
time.minute=<time:'1#one minute|minutes'>
time.month=<time:'1#one month|months'>
time.week=<time:'1#one week|weeks'>
how do i show the time (number) in case it is not 1
i want 1 to be one day
and 5 to be 5 days
thats my formatter
at the moment no matter what the input is it always renders as "one x"
i analyzed the ChoiceFormat class and it doesnt support inserting the number itself
i use a boolean choice instead now
yeah for singular/plural a boolean choice is much nicer
i just added a boolean choice named "singular"
and a number formatter for time
Trying to send this minimessage string to the player with sendRichMessage <hover:show_text:'test'><green>Your bio has been updated! Hover to see! but for some reason the hover text just isn't showing. It's really puzzling me as in the web viewer it works just fine so I don't think it's the formatting
Any insight would be appreciated!
Which platform / versions?
Paper 1.21.5 is still experimental, no? I know there are some changes in the Minecraft 1.21.5 formats for text events (hover / click), so maybe it comes from here
Might be why, I'll do some further experimentation but it's a weird bug 😭
I fixed it, was doing some weird stuff elsewhere that was affecting it
👍
adventure hover text isn't being displayed when the message is sent through Velocity
on Paper, it works fine
Make sure that you're on the latest version of velocity
i'm on the latest version
client version?
1.21.5
are you using protocol hacks?
not on velocity
Can you test without other plugins on the proxy?
My understanding is that support for the new hover text format was added a few weeks ago, but, I've not toyed around with it in a while
i'll test it right now
i tested with no other plugins on the proxy and the hover text still isn't showing
click events also do not work
it makes sense
what client are you using?
1.21.5, vanilla
I mean, are you using the vanilla client or somethging else
and it works on 1.21.4
and which velocity build?
"Velocity 3.4.0-SNAPSHOT (git-a549880d-b491)"
That is, in fact, not the latest.
is there a command to check the build?
it's easier to get help if you don't lie to us
how can i check the build
i didn't know that meant the build 😅
my bad! didn't realize that b491 meant the build number. thanks for explaining, tho
Does anyone know if it's currently possible to nest MiniMessage translated components? For example: Component.translatable("example.key", Component.translatable("example.argument"))
- Where
example.keyrepresents the string<blue>Info » </blue><green><arg:0></green><dark_aqua> is a complex argument!</dark_aqua> - Where
example.argumentrepresents the stringThis <bold>complex</bold> string
Currently, example.key is translated but example.argument is interpreted literally, resulting in Info » example.argument is a complex argument!
The use case for this would be a wall of text displaying info for the current arena. The titles/descriptions are strings which currently can only be hardcoded in one language via a Component.text() argument.
private Component message;
String json = GsonComponentSerializer.gson().serialize(this.message);
this.message = GsonComponentSerializer.gson().deserialize(json);```
4.21.0
The json string contains the hover and clickevent, but when I deserialize it into the message Component, hover and clickevent disappear. Should I use another serializer?
what if you serialize that this.message again and print it lol
are hover and clickevents in the json payload
if not that's probably a bug that should be fixed
serialize/deserialize should be isomorphic
yes they are
then it doesn't sound like an adventure issue it sounds like somethings up with your client
I sent them via a packet - the json string is with hover&click but after the third line with deserialize() they disappear in the Component where it gets null in the specific hover and click thing
I dont know how I can change something in this path 😄
Hello, could you please help me fix this error?
Error: https://mclo.gs/lMxu6bU
Code: https://mclo.gs/nbKvh00
You can't relocate adventure and then use the native adventure methods in paper
I'm using relocate, but nothing seems to change.
Yes, and I'm telling you not to
surprise, paper doesn't have a method that uses your relocated version of adventure
Unfortunately, that won't work — if I remove it, my plugin stops working on version 1.16.5.
Is it possible to fix it without removing it from relocate?
How can I get the in-game locale code by passing a java.util.Locale ?
I am currently figuring out https://github.com/KyoriPowered/adventure/blob/main/4/api/src/main/java/net/kyori/adventure/translation/Translator.java
What platform are you using?
Paper
Can I somehow add multilanguage support like eng:"bla",otherlang:"bla"?
https://paste.denizenscript.com/View/133865
getting this error when shading adventure 4.21.0 on 1.19.4 paper
Content of Server Log Paste #133865: Unnamed Server Log Paste... pasted 2025/06/08 11:07:28 UTC-07:00, Paste length: 29275 characters across 219 lines, Content: `[11:02:40] [ServerMain/INFO]: Environment: authHost=https://authserver.mojang.com, accountsHost=https://api.mojang.com, sessionHost=https://sessionserver.mojang.com, servicesHost=...
Is the solution to stay on an older version indefinitely?
relocate
It is not possible then, the server doesn't know about all the locales the client has
You could download them manually or smth
Not like that but yes, see the docs for localisation
I'm using the libraries feature, shouldn't it be relocated for me?
No, libraries stuff doesn't relocate, it has no means to accept patterns, etc
hmm, annoying. guess I'll go back to libby/runtime relocations
The parameter of Key#key method is annotated with @KeyPattern, thus every time I want to create a key from an unknown string (from a user, or a config value, for example), I have an Unsubstituted expression warning from IntelliJ. While I understand why, I'd like to know what is, according to you, the best way to create a Key from an unknown string (note that I am perfectly fine with the InvalidKeyException, which is caught later on)
I am aware that I can just @SuppressWarnings("PatternValidation"), but there must be a better solution to such a common use-case, no?
something like
@KeyPattern String str = readKey(...);
Key key = Key.key(str);
should work, or annotating your key-reading method, although these only make sense if you make sure to validate the read string
i jus ignore the warning
But why should I bother validating the string when the Key#key already does?
well thats more documentation thingy, can be helpful if your key is literal
otherwise jus do this
im sorry for ping
or configure intellij to ignore the keypattern annotation altogether 
i'd say that exceptions aren't "normal" flow so unless we had some sort of Key#parseKey method (that was nullable or had a default or smth) then it does make sense for the annotation to be there
happy for a Key#parseKey(String, @Nullable Key) method to be added
that doesn't have that annotation
but yeah, just putting the annotation elsewhere or ignoring it is fine
And I agree. In fact, in my scenario, when the key is invalid, the exception is caught later only to be wrapped in a more precise one, for logging purpose, and then disable the feature that is not properly configured
I do not personally consider this the "normal" flow of execution, am I wrong?
Yeah you're right
which is why it makes sense for that warning to be there, bc something that doesn't match the pattern will throw an exception
Hmm, understandable. I guess the main issue is that IntelliJ is not aware that the exception is caught and this is fine, which explains why I need to tell him to suppress the warning then
yeah i'd just @SuppressWarning for that line/statement
Is there any tag to enable default text shadow generated based on text color without having to specify the color?
You could make one p easily
Inside the minimessage there is no tag for this?
Correct
Seems like adventure-nbt's SNBT reader is flawed
Made an issue here -> https://github.com/KyoriPowered/adventure/issues/1240
Is the fix to just add an if check or is there some other approach I could take?
Your fix looks good to me, although can you add a test just so we don't miss it?
Hopping to bed right now, will do it when I wake up if nobody else gets to it first
It's been a long 14 hours of coding
Done
why does the white not reset the color to white?
<#38a5e3>SizeChanger <#d4cf60>»<white>
it only removes the 2nd hex color?
no wait...
I guess doing the insert of the prefix via
final TagResolver subSectionResolver = TagResolver.resolver("ref", (argumentQueue, context) -> {
final String reference = argumentQueue.popOr("reference expected").value();
return Tag.inserting(parseComponent(reference));
});
is the wrong way?
I mean with Tag.inserting, I thought it would continue the lats color from the component but aparently its the first color of the component?
probably has something to do with how components are structured, if you remove the color of a child component it will get the color of the parent
and what you describe sounds exactly like that
I mean if I do <#38a5e3>SizeChanger <#d4cf60>»<red>t it comes goes to that? is there some way to continue the color of the last component?
show your full code please
and remember that components are trees, if you have two sibling components, the style of each component does not impact the other
are you appending a different component to the minimassge one?
I am inserting it via Tag.inserting
I thought it would just continue the last color... but what would be the best way to continue the last color?
add it as a child of the last child component, not the parent
no idea how that works with Tags though
I guess I could get the last child and copy its color and make an empty parent component that color?
maybe just Tag#selfClosingInserting? kinda sounds like what you want
well self closing would remove all overflowing colors, no?
I'd like the last color to continue
yes, it would use the styling of the part from before your tag
ah, I think your misunderstanding something I'd like the last color of the tag the continue, not before the tag
what is a "last color of the tag"? a tag is something like <red> afaik? Or am I misunderstanding that Tag concept?
if I have <red><ref:some_reference>text
and some_reference points to <gold>this is golden text should be gold now
so Tag#inserting requires a </red> later to stop any parts after it from becoming a child, Tag#selfClosingInserting automatically ads a </red> after the passed Component
I don't think that's how Tags are supposed to work. All Components will be children of your <ref:some_reference> Tag, not of the <gold> Tag
okay.. I guess I need to be a bit hacky then
is there a reason you are not using replacements?
bc each ref could have its own ref
well you could just replace in replacement values too I guess xD
that... works?
I mean, you can make anything work with computers ;)
true true
no idea if Adventure has inbuilt functionality like that, I use my own logic lol
an inserting tag would work literally fine in this example, inserting a component of e.g. Component.text("Hi", RED) will cause subsequent components to be red
unless you explicitely close the tag itself
ofc you can't close it with e.g. </red> because there is no matching opening red tag
well the problem is when the ref has multiple colors
yes because subsequent components become children of the root component
in your exact scenario here - you should be a) using one minimessage string or b) using a preProcessParsed tag
ye ye I know that now too qwq
I just meant "its not really working as I want it to"
on a tangental note, can I somehow get the color where a tag is in the TagResolver?
what do you mean by that?
can you explain a bit more about what you want to achieve?
well rn I want to
get the color the ref should start with (i.e. the color before the tag)
set the tags component color to that
box the tag with an empty component with the color the text should continue in
My point (which was given as far as I see, but) did you just try to close your additional colors in the Component?
you mean like <#38a5e3>SizeChanger </#38a5e3><#d4cf60>»</#d4cf60><red>t ? that only makes the continuation text white
Yeah I mean that :/
yaknow I somehow always hoped that insertion would just append the following text after the last child
yaknow I do wonder what the hell <reset> does tho, since if I use that the following text is white xD
well okay I'll just use the preprocess one, is there some way to not process a matched tag if some requirements are not met? or what exactly does a ParsingException lead to?
What do you mean "not process"? A ParsingException stops the parsing of that tag, and cause a failure in strict mode, and is otherwise ignored (inserting the raw text instead)
raw text as in the tag in plain text form?
Raw text as the exact input text
If the processing of my-tag throws, <red><my-tag>Text will show <my-tag>Text in red
From a tag resolver?
throw ctx.newException("message", args) (or maybe swap the arguments I don't remember)
ah thanks missed that method
closes all currently open tags
obvs only works in one single parse context
do preprocessors proprocess other preprocessor tags?
What?
the preprocessor is run multiple times until the string doesn't change
or up to some arbitrary maximum
huh does the preprocessor of a minimessage instance not get applied to preProcessParsed tags?
It wouldn’t surprise me
no, the pre processor operates on the string before the parse
sad
nah I'm just replacing the legacy color codes with minimessage tags in my preprocessor
Which is bad
...why?
You shouldn’t try to mess with multiple formats
thats why i'm converting it to one format?
idek wht that has to do with pre process tags
And in this case, legacy is what it means, a legacy, now deprecated, format
well I'd like the minimessage instance to also treat preprocess tags the same, as a deserialize string
You should only use MiniMessage, and nothing else
If you really want to shoot yourself in the foot, you can still call the preprocessor yourself before returning preProcessParsed
But it’s just an open invitation for more issues later on
nah not worth it I was just checking I didnt do something else wrong
you should just do that in your pre process tags if you're gonna be cursed
ye
🌳
Hey. Does anyone know, what is going wrong?
I tested it for debugging with an simple command that should actually display the displayname of an item into the chat.
Code:
p.sendMessage(Objects.requireNonNull(MiniMessage.miniMessage().serialize(Objects.requireNonNull(p.getInventory().getItemInMainHand().getItemMeta().displayName()))));
Output: See attached picture. Thanks
In config file: (not the same item, but well...)
? <!italic><!underlined><!strikethrough><bold><!obfuscated><gold>M16A1</gold></!obfuscated></bold></!strikethrough></!underlined></!italic><!italic><!bold><white>
▪ «11»
: 0.1
what exactly is wrong?
I want the item to be serialized as a String to later deserialize it. The config value is peculiar.
guns:
pistol1: 0.1
names:
? <!italic><!underlined><!strikethrough><bold><!obfuscated><gold>M16A1</gold></!obfuscated></bold></!strikethrough></!underlined></!italic><!italic><!bold><white>
▪ «11»
: 0.1
<!italic><!underlined><!strikethrough><bold><!obfuscated>Kugelsichere Weste T2: 0.1
materials:
NETHERITE_HELMET: 1.0
Peculiar how?
If you're talking about all the false style tags, people often create components with a "false" style in order to have a "blank slate" that isn't impacted by e.g. item names being italic by default
On Paper, legacy formatting items also undergo the same conversion when turned to components
Aight, I see. For some reason there is a "?" when I try to save a displayname for a crackshot-item item into the config. Its fine. Thanks for now.
Allright. Never realized it before.
can somebody still help?
show the input string? also what platform/version/etc
Components: https://mclo.gs/Ww8WabE
GSON (de-)encode logic: https://mclo.gs/mStZ6kf
GSON string from Decoder: https://mclo.gs/wOG3ELd
string encode to component: https://mclo.gs/RpUyJvo
net-kyori-adventure-api = "4.21.0"
net-kyori-adventure-text-legacy = "4.21.0"
net-kyori-adventure-text-gson = "4.21.0"
lol guess some of my java applications wasnt up to date
hours of debugging... thanks for the help!!
okay insane so i have the bundle of translations for some languages how do i register them I was trying to use some class
named ResourceBundleTranslationSource but in my IDE it looks like it doesnt exist xd
so ig the way is to go with translation store but how do i do this im so tired ive been trying to learn this
for last 4 hours but there is always some wall im meeting with
what i want to do is just send player message like "key",playerData.getLocale
ig i was close at some point
Give these both a thorough read over and let me know if you've got any questions !
„There are additional methods on the message format translation store to bulk register from resource bundles. You may also want to use Adventure’s UTF8ResourceBundleControl utility class to create your bundle.”
I read that so many times yesterday
But this is too general like what do you mean by there are additional methods
Hello, I was checking in the GitHub Repo and I see in the past this error was reported but was related to people using Gson.
I get this error only in 1.21.5 with papermc 1.21.5 API.
Failed to convert data component value of type class net.kyori.adventure.nbt.api.BinaryTagHolderImpl to type class io.papermc.paper.adventure.PaperAdventure$DataComponentValueImpl due to an error in a converter provided by adventure:platform/paper!
https://mclo.gs/0peJPDX
This happens when I try to render in chat an Item that has a lore, if needed I can provide how I do it.
Tests has been done on:
Paper: This server is running Paper version 1.21.5-113-main@ba7fb23
ViaVersion/ViaBackwards has not been used in the server
com.mojang.brigadier.exceptions.CommandSyntaxException: Expected compound tag at position 26: ...,text:""}]<--[HERE]
Looks like just bad NBT?
As always check you're running the latest versions
yes im running latest papermc available in the website
This server is running Paper version 1.21.5-113-main@ba7fb23
this is the item im trying to render like usually with Component.hoverEvent(source) and as source the itemStack
Can you show some code?
sure
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
here it is, btw its
can you make an MRE to reproduce it?
passing as source the itemstack gives problem, but since its only in 1.21.5 I believe its due to SNBT changes?
there's a lot of fluff there
yes and Ni, I mean mostly theoretical but lemme do it
// REQUESTED MRE
public void doReplaceInChat(@NotNull Component messageFromChat, final @NotNull Player sender){
final String prefix = "[item]";
// Lets think that the message has the prefix and we skip the check if its present just for the sake of this example
final ItemStack itemToShow = sender.getInventory().getItemInMainHand();
final Component replacement = itemToShow.displayName().hoverEvent(itemToShow);
messageFromChat = messageFromChat.replaceText(builder -> builder.matchLiteral(prefix).replacement(replacement));
}```
it means there additional methods, java methods that you can call, .foo(), on the TranslationStore class that you get for a MessageFormat to register a whole ResourceBundle
https://jd.advntr.dev/api/4.21.0/net/kyori/adventure/translation/TranslationStore.html#messageFormat(net.kyori.adventure.key.Key)
https://jd.advntr.dev/api/4.21.0/net/kyori/adventure/translation/TranslationStore.StringBased.html
To recap this happens in 1.21.5 when using as HoverEventSource and ItemStack
@cloud vapor should I open an issue on papermc github?
can you send the output of the /paper dumpitem whilst holding it
https://pastebin.com/MUnzfZak here it is, thank you
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
ah I forgot to say, this happens when item has a lore
if it doesn't have a lore, its fine
idk it kinda just works fine for me, something else is going on on your server, whether it be your code or some other plugin
mmm strange, what version are you running? of papermc
pulled directly from main branch, latest available build too
which is what i see you are running too
can you try with AsynChatEvent? its the only difference I see
and another difference I spot its you are in offline mode I believe? I will test this too
Thanks for helping btw
Simple question, have you actually tested your MRE to confirm you have the issue with it?
Because looking at your original code, you’ve done a lot of simplification in your MRE, of things that could go wrong and cause your original issue
And I’m asking because it looks a little bit like you did your MRE using IA (sorry if not the case, the comments made me think that)
you know, you are right, I have not tested that, mostly cause I noticed this happened when item has lore.
Btw its not IA made, it was written with my left feet xd
i am not in a position to test with my account right now but from what i can see on the server code, that shouldn't matter, you should be using the sync event anyway if you're gonna interact with entities tho :p
but i will test the async event just for you
thank for that
I will clone the itemstack object to avoid possible issues, you are right
will use a future, jump on main thread and get a clone
that'd be fine yeah
thanks for that, at least I can exclude issues related to server code
Does the LegacyComponentSerializer.legacySection() support the font tag? As in we are using it to deserialize the MiniMessage component into a string, however it after inserting the <font> tag it is removed from the string but the font isn't applied, but color fonts work however.
Or do we need to use the bukkit audiances instead to send the component to the player, instead of the player#sendMessage(String) method?
legacy formatting had no concepts of fonts
No, you should really try to avoid as much as possible using legacy stuff
There is a high chance that you're actually doing something wrong if you "need" to do that
Esecially trying to go MM => legacy sounds REALLY wierd
Right, so how would one set the title of a GUI to a format?
Inventory#title iirc?
Changing the title of an open inventory isn't really supported, thus why there is no Component version of that method
The server is doing a hacky thing behind that method that causes problems sometimes, like flickering and desync
ah wait, it's on InventoryView and can only be set on opening :S
you can just reopen the inventory tbh
unless you plan to change the title all the time without user interaction it should be fine
If you really need to, yes reopen, but otherwise you could maybe find a better alternative. What are you trying to achieve?
Ok, thank you
People like to change the title of an open inventory and use a custom font because they're making the title overdraw the entire inventory UI with a custom interface
And they change the title to animate it
I was trying to add a option which allows the placeholders to be updated every few ticks for example
Oh, nothing so fancy then
It would be cool if minecraft added a way to update the title
iirc it used to actually be a thing back when that method was added
thats annoying
inventory gui usage will drop with Dialogs anyways
why would they remove it
Doesn't reopening the inventory cause a flicker?
it only flickers when you close the old one before iirc
That method is reopening the inventory
iirc you can't do what it does without direct packet access though
@stark badger well if it's not used in the game itself then they sometimes clean things up
What it does still causes flickering and desync issues sometimes though
it would be nice if they added what the developer community wanted
They did, and it's called dialogs
They do add things just for developers sometimes but other times they don't want to allow what you want
Or they have some other idea on how to accomplish it that takes longer to implement so it seems like they ignored you then years later an alternative to what you wanted shows up
Dialogs won't be able to display the items from a custom inv, or is there already a way?
you can display anything you want with a resource pack
but yes, if you want to show an inventory an inventory is probably the better choice
Lets hope they won't replace inventory's with dialogs then, it would also be ashame as its been a thing from the beginning of MC
I was not talking about player and block inventory's, I was just replying to your message
inventory gui usage will drop with Dialogs anyways
I think they meant using an inventory to make a GUI, not using it as an inventory
the custom inventory API is literally using block inventories, they can't remove that from the game without removing chests and stuff
but with Dialogs being a thing the usefullness of custom inventories as GUIs that display stuff that isn't item-based (or was shoehorned into being item-based) will decline
Ah, fair point then
Dialogs can show items, iirc
I was digging more, adding some souting to understand in which moment the error is triggered and the error is triggered in the moment paper send the chat message, so not in the moment I apply the replacement code logic (which I reduced to the examples above to test)
The photo with red line is when item has a lore, it seems server isnt able to find an Implementation for the BinaryTagHolder? while without lore it seems good!
I don't know what to think honestly. If there was a problem with the component, the error should have been triggered in the moment I create/replace such component right?
You solution is to binary search through your plugins to find what's causing it
If it's your plugin, well, figure out what weird stuff you're doing outside of simple usages
you think it could be a plugin incorrectly setupping the lore into the item?
Well Emily showed that it isn't an issue with normal setup/usage
The usual check for packet hacks, client version, vanilla client, etc
the strange thing is that this only happens in 1.21.5, previous versions same code works fine.
I will check like you said
I solved, has something changed btw with TextReplacementConfig? it was that
Nothing has changed with that in probably over a year
dont know what to say, thanks for helping btw
For some reason when I serialize a Component containing a showItem HoverEvent, I can deserialize it on the same server just fine. But if I send the serialized data to the Velocity proxy and deserialize in the same manor, I get this error. Is there a better way?
Paper side
Component itemComponent = item.displayName().hoverEvent(item.asHoverEvent());
itemInHand = JSONComponentSerializer.json().serialize(itemComponent);```
Velocity side
``` if (itemInHand != null) {
Component itemComponent = JSONComponentSerializer.json().deserialize(itemInHand);
chatEvent.getSender().sendMessage(itemComponent);
}```
i mean, try/catch and try and print the exception for debugging?
i imagine it's because of problems with versions, since the format for hover events/click actions has changed multiple times
you likely need to adjust the options of the deserializer on the velocity front to match whatever the serializer on the backend has
Ah. You're right, but it's a client/server version mismatch. It's not an issue on the Paper server because I have ViaVer, but on the proxy there's nothing in between.
1.21.5 servers, 1.21.4 client. On a 1.21.5 client it's fine.
viaversion would indeed handle translating the 1.21.5 format to the 1.21.4 format
I wonder if it's at all related to this that was fixed 2 versions ago https://github.com/PaperMC/Velocity/pull/1578
if I use bundle would you recommend me to use only component style of message coding
or to prepare code for hybrid like usage with components and minimessages formats?
"component style"?
and what is "bundle" in this context?
and what do you mean by "hybrid", as in multiple formats in one file?
hahaha so actually i just went with componnet style but for clarification
i meant like for mini messages i can just get bundle with this UTF8resourcebundlecontrol smth like this
while for basic style of resource i can get bundles manually and then save them in TranslationStore
and the hybrid i wanted to do was to get bundles with mini messages and then translate them to components on call
however as its recommended to use translation store on docs then i went with it
yeah you can just use MiniMessageTranslationStore that's fine
all the translation stores give you components out
oh well
that was the response i was looking for then
is there a way to handle component lists with minimessage translator? e.g. for item lores
paper doesn't deal with server sided translations for item stacks
if that's what you're expecting to solve here
public static void loadTranslations(){
MiniMessageTranslationStore store = MiniMessageTranslationStore.create(STORE_KEY, MiniMessage.miniMessage());
for (Locale locale : SUPPORTED_LANGUAGES) {
ResourceBundle bundle = ResourceBundle.getBundle(
BASE_NAME,
locale,
UTF8ResourceBundleControl.get()
);
for (String key : bundle.keySet()) {
String message = bundle.getString(key);
store.register(key, locale, message);
}
}
GlobalTranslator.translator().addSource(store);
}
public static Component translated(Locale locale, String key, Component... args) {
return GlobalTranslator.translator().translate(Component.translatable(key, args), locale);
}
is this correct way of doing this?
https://jd.advntr.dev/api/4.21.0/net/kyori/adventure/translation/TranslationStore.StringBased.html#registerAll(java.util.Locale,java.nio.file.Path,boolean)
https://jd.advntr.dev/api/4.21.0/net/kyori/adventure/translation/TranslationStore.StringBased.html#registerAll(java.util.Locale,java.util.ResourceBundle,boolean)
declaration: package: net.kyori.adventure.translation, interface: TranslationStore, interface: StringBased
iirc you probably want to call #render instead of #translate on the global translator
how?
with the methods linked right above
Are there any intentions on making Sign/Entity Names/Block etc.. being actually translatable as messages? 🤔
are shadows supported by the chat? I can't make it work with MiniMessage, I tried adding explicitly StandardTags.shadow. I'm on latest paper 1.21.4 and also tried custom paper jar with adventure 4.21.0. They work in tab or in display entities.
I have different languages registered and works fine with messages, but when it comes to signs for example, it just displays the key of the translation, which makes me avoid using translatable components directly and just translate them to a fallback lang e.g English and then set sign lines.
So I was thinking what if there was a pre-packet-send translation approach where messages get translated only before getting sent to client, by this, each client gets their own view of the sign lines, same applies for everything else, items, titles, etc..
And best part is, when player A drops item X and player B pick it up, it will be viewed in the lang of player B, that would be awesome and top tier i18n
You'll need to ask the platform you're working on
Yes, they do work on chat. Make sure you're using a vanilla client and not one that's breaking it
Paper 😂
Then go ask paper, this is adventure help :p
Isn't adventure the one that wraps platforms? Not the other way around?
adventure is an abstraction that platforms implement
Adventure doesn't know about signs or entities
Oh ok that makes sense
Are text components with just whitespace characters optimized to be one space character?
If it contains only a single space, iirc there is a shared instance yes
Component.space()
But not any whitespace, for example a tab will remain a tab
Yeah I had a doubt about this
However it should not particularly matter for you, unless you really want to use a lot of space components lol
what prompted this original question, anyway?
hey so i have this question i created this function:
public static Component userError(Locale locale, String messageKey, Component... args) {
Component errorSignature = Component.text("✗ ")
.color(NamedTextColor.RED)
.decorate(TextDecoration.BOLD);
Component messageComponent = translated(locale, messageKey, args)
.decoration(TextDecoration.BOLD, false);
return signature().append(errorSignature).append(messageComponent);
}
and now does this have sense to then do smth like this
error.info.party.leave.leader=You can't leave the party as a leader; <yellow><hover:show_text:'<yellow>click to disband'><click:run_command:'/party disband'>[disband]</click></hover></yellow> it instead.
this.miniMessage = MiniMessage.builder()
.tags(TagResolver.builder()
.resolvers(TagResolver.standard())
.tag("pc", Tag.inserting(this.getMessage(MessageKeys.PRIMARY_COLOR)))
.tag("sc", Tag.inserting(this.getMessage(MessageKeys.SECONDARY_COLOR)))
.tag("prefix", Tag.inserting(this.getMessage(MessageKeys.PREFIX)))
.build())
.build();
I have this minimessage builder with some custom tags added
the tag "<prefix>" is not working.
the values for these tags are fetched from a config,
this is the config content:
primary-color: "<red>"
secondary-color: "<white>"
prefix: "<pc>My</pc><sc>Plugin</sc> <dark_gray>»"
So what's the wrong thing im doing ?
You probably want to use Tag.preProcessParsed(...) instead of Tag.inserting
That fixed it, thanks !
.
i mean, both feel like it would be fine
i dont get the question
actually the quesiton is does this minimessage formatting override message data in function
this is minimessage "You can't leave the party as a leader; <yellow><hover:show_text:'<yellow>click to disband'><click:run_command:'/party disband'>[disband]</click></hover></yellow> it instead."
which is stored in minimessagestore smth
for translation
so like my question is if there is red message like signature| X something went wrong <yellow>click
is it gonna be still red or this yellow from minimessage should override it
ig ill just test it
heres the yml
I feel like you've forgotten something here
yeah its in #paper-dev now
Or it was
i accidentally uploaded it twice
I dont know i get error: class MiniMessageTranslationStore not found during proxy initizlaization
u p d a t e
im on velocity 3.4.0
update to the latest build of velocity
this is latest build of velocity????
what's your build #?
im using snapshot as it is recommended in docs it should use latest build always but i also refreshed dependencies
and it still doesnt find the class
what?
im talking about on your velocity server
you said you got the error during proxy init
also, provide the full error?
im working on it
Hello
Just had a question regarding adventure.
on 1.19.4 the message I'm sending looks how I expect it to be, but for some reason on newer versions (we are using viaversion) it appears to break (breaks differently on different versions). I was wondering why that is and if there is a way to fix it.
Hello, do the new versions support 1.21.5 for hover, click event and everything else? Is support complete for 1.21.5?
yes
hover and click doesn't seem to work in 1.21.5
1.21.5 server and vanilla client?
yes
generally, no idea; would need to see code, etc; as that generally should work
Loading Paper 1.21.5-103-main@2ba1675 (2025-05-29T12:14:46Z) for Minecraft 1.21.5
' <gray>- Type <red>cancel</red> <gray>or <click:run_command:"/{_clan} {_cancel}"><hover:show_text:"<red>Click to cancel."><red>[CLICK HERE]</red></hover></click> to cancel.'
Audience audience = this.plugin.getAdventure().player((@NotNull Player) sender); audience.sendMessage(text);
in 1.21.4 it's ok, 1.21.5 the texts in the chat don't work
a simple text is sent
this.adventure = BukkitAudiences.create(this); onEnable()
you mean, 1.21.4 server and client, and a 1.21.5 server and client?
server and client 1.21.4 is ok
server and client 1.21.5 does not work
No idea, support for that stuff was merged afaik
make sure that you test without other plugins
mojang did change the format fairly substantially in .5, many protocol library fluffery might break it
There are only 4 plugins in this instance started from 1.21.5. I will delete all of them for testing and leave only 1
same thing, only 1 plugin installed
if this is adventure-platform-bukkit, #adventure-platform-mod-help
Break how? What platform? Versions? etc
Hey guys, how do I support ItemStacks automatically? (For example Nexo uses MiniMessage for the items but on my plugin is not compatible)
What do you mean? Support them how?
Explain what you need to do, with examples, because "support ItemStacks automatically" is too broad
Someone told me this is not working because MiniMessage is not supported (item from Nexo)
What isn't working? That looks fine to me
I have no idea what could be the issue because if i hold this item on my hand it works fine but it gets unformatted when in the menu
This is the item:
and MiniMessage spits out components which work fine when put in lore
You're gonna have to share some code or something 😅
I'll get more information on this beforehand, just wanted to know if you guys knew something
Yes it looks, the difference is that it has 2 extra lines which are related to the crate preview menu
Then I don't understand what your issue is
If you have a valid item (with name / lore created with the help of MM or not), which becomes invalid after going through a modification process like your crate plugin, I don't think the culprit is the creation process (which may have involved MM), but rather it seems to be the modification process (your crate plugin, as you mentioned it)
Thats correct, my plugin is designed to give compability to legacy format as well as Spigot but it seems paper has a displayName(MiniMessage) or at least a setDisplayName(BaseComponent)
And i'm using the setDisplayName/getDisplayName that works with a String
The item does not store any MM-related stuff inside, it just have components (which, again, could have been created using MM, but this is just like a "factory" stuff, once it is created, it becomes independent from MM)
Yeah I mean, i was expecting that
But it seems BaseComponent[] doesnt get parsed as expected for the String getDisplayName
Wanting to support multiple formats at once is not recommended
lol
You shouldn't use deprecated methods in new code
And those two you showed here are deprecated
I mentioned previously my plugin is designed to give compability to legacy
Thank you I'll take a look on my side now
Which is not recommended
Just because is not recommended, doesn't mean I shouldnt or can't work with them
I work with them for a reason
Appreciate the time, I'll step out now! 😉
Legacy strings don't have the concept of fonts - you can't use fonts and legacy at the same time
So it's not about compatibility, because fundamentally you cannot get this to work at all using the legacy deprecated methods
1.19.4 Paper (native server version)
1.21.1
how are you sending the messages?
Just player.sendMessage(comp);
so you're not using adventure-platform or anything
Are you sure the components aren't serialized using legacy serializer somehow?
Some parts of it are
Because it really looks like this is the case
Then this is probably the root of your problems
public static void loadTranslations(){
MiniMessageTranslationStore store = MiniMessageTranslationStore.create(STORE_KEY, MiniMessage.miniMessage());
for (Locale locale : SUPPORTED_LANGUAGES) {
ResourceBundle bundle = ResourceBundle.getBundle(
BASE_NAME,
locale,
UTF8ResourceBundleControl.get()
);
for (String key : bundle.keySet()) {
String message = bundle.getString(key);
store.register(key, locale, message);
}
}
GlobalTranslator.translator().addSource(store);
}
public static Component translated(Locale locale, String key, Component... args) {
return GlobalTranslator.translator().translate(Component.translatable(key, args), locale);
}
When i have something like this
error.usage=usage: <0>
and i provide
error.usage, Component.text("/party help")
it still says usage: <0>
i also tried with {0}
ong
context?
I have an iterator that proceeds on each tag it finds, but it seems the tag resolver gets fired twice each time a tag is found
So the iterator literally skips a value for each tag it finds
I will open dis from PC to give more context
so i have this
private TagResolver resolver(Iterator<Component> iterator){
return TagResolver.resolver("n", (queue, context) -> {
System.out.println(context.target());
return Tag.selfClosingInserting(Component.newline().append(iterator.hasNext() ? iterator.next() : Component.empty()));
});
}
and this message
<gold><b>Hey <receiver>!</b></gold><n><n><n><gray>We're glad you're here. Enjoy the show!</gray>
The sysout prints:
[20:42:27 INFO]: null
[20:42:27 INFO]: null
[20:42:27 INFO]: null
[20:42:27 INFO]: null
[20:42:27 INFO]: null
[20:42:27 INFO]: null
Though it should print 3 nulls instead, since it found only 3 <n> tags.
this results in losin X iterations from my iterator, where X is the number of <n> tags
I can get it working by a hacky way, but that's not really what I intend to
so should I go with String#replace 😭?
Tag resolver needs to be pure
In computer programming, a pure function is a function that has the following properties:
the function return values are identical for identical arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams, i.e., referential transparency), and
the function has no side effects (no mutatio...
yep
you can use arguments e.g. <n:1> and so on
it's called multiple times because hasName defaults to checking if the resolve method returns non null for any given name
you can obvs avoid that partially by overriding hasName but note that resolve is still called in the pre process phase of the parse to check if you are providing a preprocess tag
i do want to improve this to cache resolve/name calls, but it's very low prio
I see, that makes sense. Didn't know there is a hasName method exists.
That would be nice
yeah it's easy to miss when you're using tag resolver as a functional interface
@cloud vapor can you kindly accept my friend request? I would like to send you a private message related to a paid request. Hope this is not a problem, thanks in advance
Unless you're offering full-time employment and are okay with a 3 month notice period then I'm not interested, sorry
nope nothing like that, mostly is paid support for adventure
i can give you free support for adventure if you just ask here lol
It would require me to screenshare cause Im not able to explain it. This is why Im willing to pay for your time
def not interested, sorry
no problem with that! thanks anyway
so I did this now:
MiniMessage allowedTagsMiniMessage = MiniMessage.builder().editTags(t -> t.resolvers(tagResolvers)).build();
MiniMessage notAllowedBuilder = MiniMessage.miniMessage();
Component parsed = allowedTagsMiniMessage.deserialize(chatColor + notAllowedBuilder.escapeTags(originalMessage));
tagResolvers containing: color, gradient for people with said permissions (op in this case) and a custom TagResolver, the question is: can i make an exception for escapeTags to allow certain things (colors, gradient) depending on permission
escapeTags takes in a TagResolver which according to the docs 'escapes all known tags in input messages' but if I give it StandardTags.Color it doesnt keep gradient in
actually giving the notAllowedBuilder an empty TagResolver works, damn
im figuring out a way to make a chat plugin with some cases like
- the player should be able to type [i] which gets replaced by <item> that replaced the <item> by a hover component showing their item
- the player should not be able to use colors in chat, unless they are OP
- the player should be able to set a chat color/gradient
Ok, so first things first, for your [i] replacement, I suggest you use a pre-processor on your MM instances (doing basic string replacement of [i] into <item>)
Then, to make players able to use only some tags, depending on their permission, as you tried, I think using a dedicated MM instance for each player (or each "role" or "rank", if it makes more sense in your case) with only the appropriate tag resolvers is the good way. You don't need to escape tags since you removed the resolvers, so for example <b> won't match any known resolver in your bare MM instance, so it will just stay <b> and not become bold (same applies for colors, and other tags)
Finally, regarding the global chat style registered for each player, you cannot just include the raw tag text because you removed the resolver, but you can apply the style directly on the resulting component (with .mergeStyle(...)). However, I understand it is bit more difficult with gradients, so if this is an absolute requirement, you may need another approach
yeah gradients is a must..
i found something good enough for now :p
MiniMessage allowedMM = MiniMessage.builder().preProcessor(chatHoverHandler::replacePlaceholders).editTags(t -> t.resolvers(tagResolvers)).build();
MiniMessage disallowedMM = MiniMessage.builder().tags(player.isOp() ? TagResolver.empty() : StandardTags.defaults()).build();
Component parsed = allowedMM.deserialize(chatColor + disallowedMM.stripTags(originalMessage));
👋
This is my current approach for splitting a sentence into multiple parts: ```java
String text = PlainTextComponentSerializer.plainText().serialize(content);
if (text.isEmpty()) return null;
List<String> sentences = StringUtils.splitSentence(text, MainConfig.SubtitleSettings.MAX_SENTENCE_LENGTH);
`StringUtils.splitSentence(String, int);` splits a sentence into multiple parts, but it only works for strings. My goal is to achieve the same functionality for `Component`s. How would that be done?
I could possibly serialize it into MiniMessage but tags shouldn't get involved in this.
what does StringUtils#splitSentence do? does it like split it after x characters, the first space before x characters?
For example, "Hello, how are you? Hope you are doing good." to:
Hello, how are
you? Hope you
are doing good.
Basically splits without breaking words
so the first space before the xth character?
or whatever number MainConfig.SubtitleSettings.MAX_SENTENCE_LENGTH is, right?
Yeah, like that
I recently made a proof of concept about this, but there are quite a few limitations. Feel free to have a look at what I shared there: #adventure-contrib message
I also have a limited ComponentLineWrapper in the repo I maintain. I should look at your approach and perhaps use that to improve, indyteo ^^
Hello, I have a problem with minimessages. Specifically, I can't deserialize the placeholder in the <click> tag.
This is what the raw text of the message looks like:
<click:suggest_command:'/resident <username>'><hover:show_text:'<username>'><<username>></hover></click>: <message>
I using this code for working with this text:
MiniMessage.miniMessage().deserialize(text, additionalResolver)
There is additionalResolver:
resolvers.add(Placeholder.component("message", message));
resolvers.add(Placeholder.component("username", player.name()));
In the game itself, everything works correctly EXCEPT that <username> is not inserted into the <click> tag! Please help.
This is how it looks in the game:
Pretty sure it has to be a parsed placeholder inside the hover and click.
And one more thing! If I remove the single quotes and write <click:suggest_command:/resident <username>> instead of <click:suggest_command:'/resident <username>'>, then <username> will be inserted correctly, but the <click> itself will break
Pretty sure my reply covers your fix.
I don't quite understand. Should I do something like this firstly?..
MiniMessage test = MiniMessage.builder()
.tags(TagResolver.builder()
.resolver(additionalResolver)
.build()
).build();
test.deserialize(text);
You're doing Placeholder.component when you should be doing Placeholder.parsed for stuff that gets parsed into a minimessage tag.
Oh! It's really works! Thanks a lot!
hi, how can I get a list of compound tags using adventure's NBT?
Found it:
tag.getList("name", BinaryTagTypes.COMPOUND);
small question, is there a way for a TagResolver to actually return a complete empty string? everything I do seems to return in a space being returned anyway
return Tag.selfClosingInserting(Component.empty())?
also adds a space :/
What is your input string?
is it possible to display dialogs with the new update?
I believe it's up to platforms to implement most of the dialog stuff right now because it's still in flux. Paper, for example, is working on API.
........
The exception tells you what is wrong p clearly :p
Yes, but what is the alternative?
MiniMessage
in your case, the <gradient> tag
You can define custom tags in minimessage
If I have %variable% and I want to replace it with the display name of an item stack, how can I do it?
Or just string replace on the MM string before you deserialize it to components
Custom tag would be better though
Just do "my item is <item>" and use tag resolvers
hmm
after this I sound stupid :C
let's hope that what I want to do works
And can I only use < >?
Because what would happen if I want to use the <red> tag for my own use?
Using only <> is a good thing as lots of plugins use minimessage so users get familiar with it
What is this limitation due to?
MiniMessage is all about <> stuffs. It would be silly to make it handle multiple different formats that nobody uses.
planning on making part of a plugin standalone, is there a standard way to get stdout as an audience?
It's not a limitation, it's a conscious decision to make it easier for the end user
it's just an interface, you could implement it and redirect the various sendMessage methods to a ComponentLogger
with the ANSI component serializer if you want colour
How can I customize the formatter for ComponentLogger?
I noticed that adventure loggers use slf4j while craftbukkit uses java.util.logging and i am unsure how to change this
(basically I want to include the thread name, right now it's [21:32:49 INFO]: [plugin-name] log message i want it to be [21:32:49 INFO]: [plugin-name] [Server thread] log message)
is it like a command-line parameter to starting the server?
ah it's the xml files
imma mess around with these ty for point it out
do you maybe know where I can find the default one (for paper or for bukkit/spigot if it's the same)?
you would grab it from the patched server jar or from the github repo
Hi! Is there already a way to abbreviate a component by putting "..." at the end? Kind of like StringUtils.abbreviate from org.apache.
Alternatively, is there a way to figure out the number of characters in the component, I see there's no .size() or something like that
Nothing in the API for that no
I am working on a plugin and want to use dialogs. Is there an ETA for 0.4.24 release?
should have expected that
It doesn't? I was looking arount the commits and it looked like it did. OK
Read the docs for the methods added
As Kezz said, there is no way to do it properly into the API for now, because there are quite a lot of technical challenges to take into account, but you can have a look here: #adventure-contrib message
It is a proof of concept of component wrapping (with some important limitations, but if they does not apply to you, you might want to take inspiration)
You should be able to adapt the wrap method to create an abbreviate method instead
But the same important limitation will apply. Basically, if you want to support anything other than text component, you’re screwed
was the maven repository changed? this URL is 404 but 4.22 works
no clue how that is deployed
https://repo1.maven.org/maven2/net/kyori/adventure-api/4.23.0/ its def all there
oh so it's now on maven central? the adventure-platform-mod repo still uses the original URL
its always been on central?
oh its just manually unzipped into here https://github.com/KyoriPowered/adventure-javadocs
ah no theres some python scripts
obviously it's published using an internet explorer activex browser extension, and someone forgot what button to press /s
idk what one has to do to trigger the action, not really important, zml will see this and do it when time permits
should be updated
translate is not keybind
do components auto serialize w/ jackson objectmapper or do i need to make / register a custom serailizer?
or I guess just have a jsonserializer at all?
is it intended that all virtual components are equal?
they dont override equals so inherit it from text component, which only compares the content, but for virtual components the content is always empty
ah
but the fact that they dont compare beyond that is annoying
cause im using them in the minimessage way as named translation arguments but they are all comparing equal so the bossbar name (which compares the old/new names for equality) doesn't update
The bossbar optimization has been removed in the latest version iirc
would be nice to fix the problem inside virtual component itself instead of simply removing this specific bossbar case, but good to know, thanks 👍
It was removed for another reason (translatable components being technically equals before translation): #adventure-help message
feel free to submit a PR
i'm not entirely sure how to feel about this, i know there is no contract or spec about this but is component == jsonDeser(jsonSer(component)) an invariant we care to maintain?
hm, no, that concept goes sideways the second you construct a component with modern features but have the serializer configured for older versions
i don't really think component equality has ever been something we really consider tbh
Is there a Collector to join components from a Stream? I thought so, but I can't find it anymore. Or maybe I just mix up with Component#join
Component.toComponent()
Ahhhhh I was searching with "join". Thx!
Yeah, I had a hard time finding it as well
Hi, I'm having an issue with the MiniMessage format related to bold text. This is the format I'm using:
<b><gradient:#FFE259:#FFA751>ɪɴғɪɴɪᴛʏ ᴄʀᴀғᴛ</gradient></b> <gray>|</gray> <green>1.21 - 1.21.4</green> <white>Java & Bedrock</white><newline> <yellow>¡Únete a nuestro servidor Survival!</yellow>
The problem is that all the text becomes bold.
If I remove the bold text, everything works fine. This happens with the latest version of Adventure 4.23.0 — with version 4.21.0 it worked perfectly.
<gradient:#FFE259:#FFA751>ɪɴғɪɴɪᴛʏ ᴄʀᴀғᴛ</gradient> <gray>|</gray> <green>1.21 - 1.21.4</green> <white>Java & Bedrock</white><newline> <yellow>¡Únete a nuestro servidor Survival!</yellow>
This only happens in paper, could it be a ProtocolLib problem?
try without other plugins than your motd one
shadowColor is nullable
hi, how can i display to the user to press a key to open his inventory, relative to his client side controls? and, preferably, when is that possible without adventure? ive been managing to stick to the bukkit api so far
You mean, you want to send them a message to hit their key for opening their inv? if so, you need a component because that stuff is configurable
It's not possible with legacy chat, you have to use components or MiniMessage
(the Bukkit project died a decade ago, the Bukkit API only exists in forks called paper-api and the legacy spigot-api)
does that keybind component work inside of itemstack lore?
oh wait im speaking bukkit lang 😨
I don't see why it wouldn't work there
how do I add an adventure component to the lore of a bukkit itemstack?
but how can i add an adventure keybind component to it?
Have you used adventure before?
nope, should i go read the docs :P?
oh yeah TextComponents, sounds familiar to bukkit, is it compatible?
oops i mean net.md_5.bungee.api.chat.TextComponent
What you are referring to are the deprecated bungee components spigot added to spigot-api
i suppose i can set the itemmeta lore to either spigot textcomponent or the newer adventure one?
I mean, we don't provide support for anything that isn't adventure these days
understandably
If you use legacy spigot methods we will try to convert it to adventure internally
you would need to use an component API to do it, and anything using the legacy API will wipe out your thing
I'm kind of lost rn. When havign a setup like:
Component.text("lorem").color(firstColor).append(
Component.text("ipsum").color(secondColor)
);
Everything works fine and the colors are applied correctly. But when instead of a Component#text, a Component#translatable is used, the second color isn't applied and the first one is full through. What could be the cause ofr this and is there a solution?
What platform & version of adventure? Are you using any server-side translations?
Paper 1.21.4 build 226, Adventure 4.20.0 and yes I am using server-side translations. The translations are components too (but I think the color should still be applied after it's translated, atleast I hope that's the case). The use-case is for a customName of an entity
And show code
entity.customName(Component.text("[")
.color(NamedTextColor.RED)
.append(Component.text("Lvl." + level).color(NamedTextColor.BLUE))
.append(Component.text("] ").color(NamedTextColor.RED))
.append(Component.translatable(translationKey).color(NamedTextColor.BLUE))
);```
`entity` is a normal Entity and `level` an integer
For registering translations I use `TranslationStore#register(String key, Locale locale, T translation)` where `T` is a normal Component as my TranslationStore is `TranslationStore<Component>`
is there an easy way I can split Component into List of components? For example split on <br>
there were a variety of issues with the component-based translation stuff that have since been fixed
you may be running into one of 'em
no
Hm, okay. I was gonna update to 1.21.6 anyway when it's out of experimental, hopefully that will fix it then, thanks :)
is there a way to support both Minimessage and legacy color code (&c)
Not healthily. Legacy codes are over a decade dead.
If you have existing configs using legacy, a one-time deserialization to component and then serialization to minimessage is the way to go.
I was thinking of making a simple chat plugin that supports both minimessage and legacy code
It's 2025 - there's no need for new plugins to support stuff that Mojang moved away from in 2013.
Mojang itself doesnt use Legacy color codes?
There are a few spots that still support it because they're slow to remove things, but Mojang has been using components for chat since MC 1.7
OH SHI alright thats uhh a long time ago
You can string-replace the & codes with minimessage tags, if its just for player-facing chat stuff
I've never succeeded in teaching players Minimessage, so I get that 
deserialize legacy, serialize to minimessage, replace \< with < and then deserialize from minimessage again
That doesn't really work the way you think it does. Please don't support bad and incomplete approaches.
uhhh 😅
ik thats bad workaround
I get what you mean but its fine ill not going to start on that project anyway and if i was i'd probably only support minimessage
Legacy and components do not operate the same way, and users will be confused when your string-replace or mixed serializer approach causes formatting to be inconsistent.
After how much time is usually an answer provided for an issue on github?
How to create an persistent bossbar with Adventure? Like how bukkit does it.
https://docs.advntr.dev/bossbar.html isn't already persistent? Never used it
create a bukkit one if you want to use a bukkit one
no component support :(
i think that's a fair reason to close it
but a decision does need to be made about whether or not to deprecate the old boss bars
that would require the adventure bossbars to be persistent, interact with /bossbar and also be used for mobs (e.g. Boss#getBossBar). All three things you can't do with them right now
idk how adventure platform works nowadays, but I remember the concern being there that you can't have those things on e.g. Velocity, so you can't have them in the adventure API
none of those things require adventure api changes
i also dont think persistency in the boss bars really matter
it gets asked about in -dev sometimes, some people seem to want it. And thats how vanilla does it
I suppose the only issue would be that the adventure API doesn't have any way to say if one should be persistent or not
So you would either need all persistent, none persistent, or add some additional API for managing which ones are persistent that is not a part of the actual boss bar API
yeah, Bukkit.makeBossBarPersistent or w/e
we could add a flag for it in adventure but why, it's so easy to just persist them yourself as a dev
In this case persistent doesn't just mean saving them to add again later, it also means vanilla things know they exist
// Converts a legacy string (using formatting codes) to a TextComponent
final Component component = LegacyComponentSerializer.legacyAmpersand().deserialize("&6Hello &b&lworld&c!");
I found this on the wiki, does this still work? It says:
Required type:
net. kyori. adventure. text. TextComponent
Provided:
me. clip. placeholderapi. libs. kyori. adventure. text. TextComponent
you imported the wrong textcomponent class
So I should be using
me. clip. placeholderapi. libs. kyori. adventure. text. TextComponent
?
Because all of my code uses this one net. kyori. adventure. text. TextComponent
Is there a way to convert between the two?
you're importing placeholder api's shaded version of adventure somewhere
the full error should tell you
Ahhh, the LegacyComponentSerializer was the wrong version. thank you both
which java version is adventure built against?
awesome, thanks
https://github.com/KyoriPowered/adventure/blob/1c16bdd2ec4a1f1b115e4c0c5acb0d1376a37f32/build-logic/src/main/kotlin/adventure.base-conventions.gradle.kts#L10
Then why is this set to 17 
A user-interface library, formerly known as text, for Minecraft: Java Edition - KyoriPowered/adventure
A toolchain is just what java version is required to build and run the project - the actual code that is built is Java 8 language level
indra defaults to 8 for the target, which is why you dont see it explicitly being mentioned in that build file
I see, never looked into Indra really
how come the component logger isn't an audience?
it's just an slf4j logger that accepts components
it doesn't make sense to make it an audience, log at what log level? should it use any markers? what format?
If I add Adventure 4.22.0 to my plugin's gradle.build like in this page (https://docs.advntr.dev/getting-started.html), will it override Adventure 4.21.0 currently bundled with Paper and let me access newer Adventure features?
It doesn't seem like my plugin can override the bundled Adventure version because the feature I tried isn't there. Is there a way to check what Adventure version my plugin is currently using once the server starts?
no
So I just have to wait for Paper to update their Adventure version, right?
yes
can also build your own Paper JAR with the updated Adventure, don't know what the side effects of doing this would be
Is there a way to use the built-in date (or any other) formatter with dynamic tag? I think what I did would work, but it looks a bit hacky, so I'd like to have your thought about it...
public static final MiniMessage MM = MiniMessage.builder()
.editTags(t -> t.tag("event_start", (args, ctx) -> {
String name = args.popOr("event name expected").value();
return Formatter.date("event_start", getEventStart(name)).resolve("event_start", args, ctx);
}))
.build();
// Omitted for simplicity
private static LocalDateTime getEventStart(String eventName) { /* ... */ }
As you may guess, there will be a similar event_end tag as well.
There can be multiple events simultaneously and their name is not restricted at all, so I'd really like to keep them as an argument of a single tag resolver
The main advantage would be to not have to duplicate any date formatting logic in my own code, since there's already a tag resolver for that.
Typical usages would be:
<gray>The <gold>mining</gold> event is starting at <red><event_start:mining:'HH:mm'></red></gray>
<green>Summer event will be live between <b><event_start:'Summer 2025':'yyyy-MM-dd'></b> and <b><event_end:'Summer 2025':'yyyy-MM-dd'></b></green>
Well the date formatting logic is literally just calling SimpleDateFormat so I wouldn't worry too much about duplicating it tbh
Hmm, in a way, yes, but in the same time, there's the argument handling logic (which is also not that much I agree, but not much + not much = well, a little bit much)
Furthermore, there is the same question for other resolvers, I guess (number being the first one that comes to my mind, but choice or boolean also maybe)
Example that comes to my mind for the number formatter:
Inserting a score of a player (not from the vanilla scoreboard thing, a score from an hypothetical plugin), for a leaderboard.
Raw text would be:
<gold>1st: <name:1> (score: <score:1>)
<gray>2nd: <name:2> (score: <score:2>)
<#CD7F32>3rd: <name:3> (score: <score:3>)
And the score tag would fetch the value at the given rank, and one may want to take advantage of built-in number formatter tag features (such as localization, decimal management...)
And just while I was writing this example, I realized that it could actually be a cleaver way to ease the creation of leaderboard holograms in my leaderboards plugins, so the example is not that hypothetical (at least, in the next few months, when I'll have time to work on that plugin 😅)
Side question, I just want to be sure this is not my (mis)understanding of English that is fooling me:
https://github.com/KyoriPowered/adventure/blob/main/4/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java#L100
Here the JavaDocs says (L.93):
This replacement is auto-closing, so its style will not influence the style of following components.
However (L.103):
return Tag.inserting(...); // Shouldn't it be Tag#selfClosingInserting instead then?
(Same applies to all the formatters, hence why I think it is just a misunderstanding on my side rather than an actual error in every formatter)
Then let’s make a PR and we’ll see, I guess 😅
where can i see all the translation keys and their english values?
you would need to grab the english locale file
Hey I am working with the localisation feature with MiniMessageTranslator. It works well, but I am encoutering issues with sub-translations.
For example, my.key=hello <value> where value is just a number or player name is ok.
but my.key=You have <time_remaining> where time_remaining links back to time.format.days=<day> days. My MiniMessageTranslator get call for my.key but gets no calls for time.format.days even though its passed through as an argument and is a TranslatableComponent.
Then I end up with "You have <missing: time.format.days>"
Are subtranslations not supported? I couldn't find any info about them on the docs.
thank you, any pointers are appreciated.
This is fixed in Adventure 4.22.0
oh perfect, thank you. 🙏
is there a way to override style of a tag resolver?
I mean
lets say I have this string: <red>Hello <player_name>
player_name is replaced with a compoent of the player's display name.
and I can't make the player's name red
If the component with the display name has colour, then you'd want to strip the colour beforehand or use a plain string tag or smth
private Component getChatMsg(String groupName, Player player, Component displayName, Component message) {
String msg = configManager().getGroupMsgTemplate(groupName);
TagResolver tagResolver = TagResolver.builder()
.tag("player_display_name", Tag.selfClosingInserting(displayName))
.tag("message", Tag.selfClosingInserting(message))
.build();
if (msg == null) msg = "";
return miniMessage().deserialize(msg, TagResolverHandler.finalPlayerTagResolver(player), tagResolver);
}
this is my current code
my answer doesn't change after seeing the code
yk
but how I replace it without making it a component
huh
either remove the color from the displayName component, or plain text the display name and use a string inserting tag
You could make your own <unstyle> tag to strip style from its children (allowing it to inherit the one from its parent then)
It would be fairly simple using Modifying
.tag("player_display_name", Tag.selfClosingInserting(displayName.style(Style.empty())))
well this doesnt work
how can I strip and then insert
Create a custom tag implementing Modifying like I said above.
Let me know if you need help for the implementation (I just tested it, it works, with 1 line of code, or 2 if you consider the tag registration in your MM instance)
and then how I would insert it to the text?
slap it in a text component?
.tag("player_display_name", Tag.selfClosingInserting(Component.text(PlainTextComponentSerializer.plainText().serialize(displayName))))
like that?
cause that doesnt work
idk about the selfClosing part, but, that would work in terms of the component part
"doesnt work"
You're not using malformed components, no?
what is that
what is the strings contents after you run it through the serialiser
Using legacy cruft inside of text components
I guess not
I use <>
wait I think I know how to solve
Show us the output of PlainTextComponentSerializer.plainText().serialize(displayName), just out of curiosity plz
Ok, so it has no style at all, thus if you really executed the code you shown, it should have worked. What is the result (what color is the name)?
white
I am using hex color from a placeholder to set the color - I think thats where the problem comes from
tho the color it self is translated somehow
Its like it doesnt apply to the text after the placeholder
oh
wait
wait
Can you please confirm that this works:
private Component getChatMsg(String groupName, Player player, Component displayName, Component message) {
return miniMessage().deserialize("<red>Hello <player_name>", Placeholder.component("player_name", displayName));
}
What are you talking about?
We learn new things every day - and that's how we build up
I used selfClosingInserting to phrase the placeholders
so its like closing
Yes, but there's nothing after your placeholder
So it makes no difference in the example you shown
wait will try
selfClosing just means it closes itself
e.g. style from that tag won't effect subsequent tags
UNLESS, you shown us something that is not what you really try, which is like asking help on a math question with a different formula: pointless and a waste of time for everyone
please provide an MRE and we can look into it
ok I fixed it
ofc it was papi tags
that means legac haha
so you were inserting legacy into the resulting component or smth
The phrased papi was this text "<#74cafc>"
that would not even have turned into a colour with your old code
I think he inserted (self closed) empty component containing just a color
Thus, it was not affecting the following
Anyway, it was a completely unrelated issue because he did not actually tested the example he shown us
Bruh I did
Clicking components does not work and I updated to the latest version. This seems to only be happening in .6
I don't see anything in changelogs, just curious if this is a known issue or not
I'm not seeing anything in github issues either
cc @tawny marsh
specifically uh click for command suggestions
What platform are you using it on?
can u make custom tags? so for example if I put <hi> it puts "Hi" in the string
private static final TagResolver RESOLVER = TagResolver.builder().tag("hi", Tag.inserting(text("HI"))).build();
private static final MiniMessage MINI_MESSAGE = MiniMessage
.builder()
.tags(RESOLVER)
.preProcessor(str -> "<!i>" + str).build();``` maybe this
would it make it laggy? 👀
If its possible can I use reflect and only keep the resolver for default Minecraft colors
I saw all of these are private classes
💀 it works ig
I swear if there is easy way to do it I will cry
look at the methods?
I did 2 mins ago and my heart is broken
paper 1.21.6 latest release
I’ve had two people complain about it so far
Hi, seem to be running into some weird issue on 1.21.6 with the Translator
Causes a StackOverflow for some reason
I am gonna guess it relates to my system for intercepting packets to translate stuff, but it has not happened on earlier versions 
full log; https://mclo.gs/ufyoImR
tested by removing most fancy formatting and it just complains whenever i try and get the translation string for an argument 
seems to be the same problem as #paper-help message
ok nice, fixed it temporarily by just not registering it for 1.21.6 servers, ill keep an eye on that 
ong what the hell are you doing, they are all public - StandardTags.color()
I saw that very late 😭
are you not just registering a translator that calls itself
probably
Not probably, definitely
should I benchmark it
We already have benchmarks
no its called outside of the class as a static method basically
whenever it enters the translate method and finds a key it just infinitely loops, hence i just dont register it and it works
definitely looks like an issue with the recursive rendering pr
im not going to be able to take a look this weekend, but if you wanna have a little adventure adventure to see if you can figure it out that'd be super!
this pr in particular https://github.com/KyoriPowered/adventure/pull/1226
although i dont know why it wouldn't have been caught in any of our unit tests
in all likelyhood its some combo of some scuff in my packet interception to transform a component + translation being recursive
tried printing out the component and the first here is likely the original one, and after its being kinda funky
okay yeah made a simple plugin that just registers it and it just recursives it with no modifications or anything
Using paper API directly or using adventure-platform-bukkit?
adventure platform bukkit 4.4.0
It doesn't support .6. See blood's PR, and be sure to use #adventure-platform-mod-help in the future 🙂
Will do, thank you!
shouldn't you be returning null instead of the component here, when no translation is done?
afaict it's infinitely recursing because returning a component indicates a translation was done, and translated components may need further translation, so it's passed back to the global translator
should probably remove the recursion there and introduce a limit, though
your translator is flawed yes
i see so returning the same just means it thinks it was translated into another, returning null indicates it should be "the same"?
the translation process will keep checking as long as there are translatables
null means there is no translation
returning null means "skip this translator"
the javadocs are a bit obtuse here since that bit is mentioned only for the string key one https://jd.advntr.dev/api/4.23.0/net/kyori/adventure/translation/Translator.html#translate(java.lang.String,java.util.Locale)
declaration: package: net.kyori.adventure.translation, interface: Translator
but returning null for the TranslatableComponent overload means to call the string one, and the string one returning null means "skip this translator"
that seemed to fix yeah my bad..
guess it worked before cuz it wasnt recursively doing it
thanks
Does adventure support setting the Component name/lore of items? Like I know paper stores it as components, but I would imagine this is only supported on the latest paper versions.
So would it be possible to set the name/lore of items via the adventure lib aswell, or would I need to convert them into minecraft components using the API?
Adventure does not know about items
What is your underlying question? Please provide some context
Im basically trying to set the item name/lore as components using MiniMessage format, but since only the latest versions of paper support it Im asking if there is a way to set the name/lore of items on older versions of paper aswell, for example using Adventure#setLore(ItemStack, Component)
It's not only the latest versions of paper. It's been there for many, many years. Are you talking about super ancient servers (that aren't typically worth supporting anyway) ?
No because adventure doesn't known about bukkit itemstacks
I mean pre 1.19, yeah
Good enough then, I saw adventure has this handy method: MinecraftComponentSerializer.get().serialize() so I might use that
Not worth your time, honestly. Nearly no servers run it, and certainly no servers that actually download new plugins. 
But, if you really want to add component support properly to versions prior to adventure-in-paper (which I think is actually closer to 1.16?) you'd need to poke internals.
yeah paper has had native adventure integration since before 1.19!
Which was in June 2022 (3 years ago), fyi
Was markup support removed from MiniMessage?
I haven't used this library since probably 1.17 so makes sense lol
I don't see anything in the docs so I was wondering
Since the only options now are tags, does this mean that tags have to be in the format of <{tag_name}>, and I can't just add ** for bold?
oh wait I can do a preProcessor to change ** to <bold>, maybe? hmm...
For survey purposes, may I ask why you wish to use markdown when users are getting used to minimessage tags?
efficiency and familiarity purposes
** is a lot easier than <bold>
and familiarity via Discord
MiniMessage is widely used, I would expect most server owners to know it by now
Better to have a dedicated parser for this then
There is minedown if you just want to have markdown support
The preprocessing approach is what that old markdown module used and it was really cursed and bad
do my own parsing on the string to replace markdown with tags, then shove it into minimessage?
Would there be any way to see if the server(paper) supports native MiniMessage support or would I just use reflection to check if its a supported method?
<@&748618676189528155>
too slow
sniped 😦
At least I wasn't that slow 😛
Just check if the class exists
or check the server version
So which version to check for?
And what class?
I mean, CraftMetaItem exists even on bukkit so
uh, the MiniMessage class lol
like Class.forName or just run it and catch a ClassNotFoundException
many ways
MiniMessage itself doesn't support setting item meta, atleast that was what was said here
On the legacy spigot loader another plugin loading in minimessage would cause trouble if you're looking to use methods that take components.
Yea, so I want to check if those methods are available or not
Check if the method exists, then.
I might just use reflection then
If your plugin will only work where supported, could just compile in a use of it in a try/catch during onenable and bail out with a helpful "your server is in ancient history" message (or don't try/catch it and just error out)
We have a multi module plugin, so I want to check which module to initialize
Is there a way to translate the PAPI placeholders inside a Component without recompiling it? Like not having to parse it to a string, translate it, and parse it again to a Compoment
"recompiling"?
Edited my message
This example assumes you know the placeholder you are parsing (Also not what Im looking for)
