#adventure-help
1 messages · Page 11 of 1
would avoid all of that by using the key and then doing:
StreakItem:
Lose:
type: "minecraft:diamond"
Display: "<c:#8cc1cd>Streak: <red><streak>"
Lore:
- "the lore"
Win:
Material: "gold_ingot"
Display: "<c:#8cc1cd>Streak: <green><streak>
ItemStack item;
ItemType type = Registry.ITEM.get(Key.key(type));
if (type != null)
item = type.createItemStack();
else
item = ItemStack.empty();
benefit also that it filters out block types (since they're on a separate registry), so you don't have to worry about things like accidentally creating an ItemStack with a block type
That looks interesting, I'll take a look at that
Tbf, what's even more cursed, it that their JD states the opposite: https://github.com/PaperMC/adventure/blob/main/5/text-minimessage/src/main/java/net/kyori/adventure/text/minimessage/tag/resolver/Formatter.java#L131
This replacement is auto-closing, so its style will not influence the style of following components.
Still, this is an interesting one. When you append something to <red>Text, you expect it get inherit the red styling, while when you append it to <red>Text</red>, you expect the red styling to get closed and thus not inherited. But that's not true, because in fact the 2 syntax (closed and unclosed) are strictly equivalent! This is a kind of bias from the brain thinking that the append occurs at the "MM-encoded string" level, when in reality it occurs at component level
If you wanted to keep the standard formatter that returns inserting tags instead of selfClosingInserting for some reason, you would've to write: You have <type:won:lost></type> <type:'<green><streak>':'<red><streak>'></type> coinflips
Which isn't pretty, yeah
I had to look at the debug output and couldn't understand what was going on lol, but that makes sense
made a test case and everything
Can someone please help me to find a RedStone Limiter?
I need a 1.21.1 PaperMC plugin to limit the redstone usage cuz there are some players with a big redstone farms and server is lagging even with 10GB ram. Can someone send a RedStone Limiter Plugin link to this thread? Ping me please.
#paper-help but honestly idk if this server is the right place to ask for plugins
how do I flatten a component while keeping its styles? basically to turn the first box to the second
In your example, Component#compact() should do it
oh lol, thanks!
But the example you shown contains no style also 😅
Compacting will preserve the style, but the result won't necessarily be "flat"
yeah it was just an example thing to test why these two components aren't equal
is there another way to do this? (guh did I xy myself)
It'll be a visually identical equivalent component, generally smaller in size to represent in memory
Basically it's hard to test true visual equality
If that's what you want to achieve
But why would you want that
so I should try to flatten both components before comparing?
the short version is that I'm working on some API for in-game players and the expected behavior from players is that visually similar components should be equal
the idea of "components" is not really exposed
Compacting both component could help yes, but there are case where two visually equals components won't be structurally equals, even after compaction
if it helps reduce these cases I'm all for it, a good enough solution, thank you :)
And couldn't you get out by comparing your technical representation (your data model BEFORE it gets turned into visual components for players)?
If you see what I mean
this isn't really applicable in my case but I appreciate it!
what is the correct usage for the atlas? the documentation is incorrect as sprite:item/emerald will correctly display an emerald sprite, but sprite:"minecraft:items":item/emerald displays an empty box
minecraft:blocks atlas works
oh, is it only in 1.21.11? i'm on 1.21.10. nice.
is there any way to tell if a block/item is in the atlas? i know this is something that only the client knows but want to not have to manage a list myself manually
As discussed here, there’s not an easy way, no
follow up to this but i believe doing this would change the title of what im using is there a way to make a copy?
im looking a custom inventory view right now just tryna derive some information from the title
how does one convert BinaryTag to String or Json?
A copy of what? A copy of a component? Components are immutable, any operation "mutating" them makes and returns a copy
oh i see
... you probably don't want to do that
implement InventoryHolder instead, checking titles or generally using components for data storage like that is an anti-pattern
unfortunately im checking an inventory that's from a datapack otherwise i would definitely use this approach
BinaryTagIO iirc
got answer in minestom 🙂
MinestomAdventure has a utility function
Hey, is there an scenario where MiniMessage#deserialize can return something that is not a TextComponent?
(I'm assuming it is returning a TextComponent, tbh idk)
Why?
Because I need a TextComponent, and I have the suspicion that doing something like this may not be safe:
TextComponent firstComponent = (TextComponent) MiniMessage.miniMessage().deserialize(first);
This doesn't tell why
I don't understand what you mean then, could you elaborate please? Why what?
Why do you want a text component?
Sorry
Why do you want to convert the output of MM to a text component?
I need this function
https://jd.advntr.dev/api/4.25.0/net/kyori/adventure/text/TextComponent.html#content()
declaration: package: net.kyori.adventure.text, interface: TextComponent
.. and what do you need the string contents for?
Oh, ok I think I should explain the entire thing I'm trying to do
I'm experimenting a little bit with packets to modify the MOTD of the server
For the PacketType.Status.Server.RESPONSE (in packetevents) I only have a json, which expects a "text" field for the MOTD.
I gave paper source a quick read to see how they handle this and found this:
PlainTextContents.create(((TextComponent) this.adventure).content())
Which is later used in the minecraft chat component
I'm not yet entirely sure if the result of TextComponent#content is what I need for this, but this was part of the experiment ig 
If you want to extract the plain text from a component, you can use the PlainTextComponentSerializer
It'll erase all the style and special objects, and only keep texts
I was expecting to preserve colors, styles and other text features like heads/sprites
I think you could achieve a similar result when starting from an MM-encoded string by using MiniMessage#stripTags, which may be simpler
iirc MOTD does not support components, so you'd have to use legacy encoding (LegacyComponentSerializer)
Wait maybe they use a weird alternative legacy-like syntax for styling
Or it is now possible since recent update maybe
you can use the gson component serializer to turn any component into json which packetevents seems to need, but we've also got some longstanding api in paper for ping responses you should consider using
Actually, this started due to this issue:
https://github.com/PaperMC/Paper/issues/8073
I found a workaround using PacketType.Play.Server.SERVER_DATA and then got the idea to do the same but for PacketType.Status.Server.RESPONSE
Basically doing everything using packets looked like a fun challenge, so I'm now giving it a try 
a really specific and odd use case: what would the best way to add markers into components, invisible to the players (in a tooltip for example) but so that plugins can use them to figure out a "meaning" of that component
I want to use this for lores, and there can be arbitrary other data in the lore, so when parsing the lore I want to mark some lines so when parsing the same lore in the future, the plugin knows which lore lines to find/modify/avoid/whatever
Just don't
Components are visual elements, not a storage system
To store arbitrary data on an item (because you talked about lore), you can use PDC
You can access that data from plugins, and even see it in the vanilla item data if you want to, for debugging purpose
And many more elements supports PDC, not just items
that's exactly true
but in my scenario it does not make sense to store such data on the item :(
let me give somewhat of an example: a "super ender pearl" which requires a player to have at least 100 experience levels to use it
when a player without that much xp is holding it, there appear some lines in the lore saying exactly that, "You need 100 XP levels to use this item"
but when he drops that item to someone who has 100 xp or he gets 100 xp himself that lore must disappear, and the plugin will know exactly which lines to remove, without removing the rest of the lore
sure it can, instead of lore, be a chat message, but that would be just for "using" an item, there's a lot of other possibilities
right now I'm consindering adding a content="" component with a very specific color as a first child of the main component but i'll think about this more tomorrow
You'll find it much easier to simply recreate the lore from scratch when needed
wouldn't it break with arbitrary items for which the user may have manually edited the lore (/data modify ...)?
If you’re allowing players to use that command then you got bigger issues lol
I would recommend just using PDC like teo suggested then just listen to the PlayerInventorySlotChangeEvent to check whether the data needs to be updated
Is it possible to scale the head from the head tag to a other size?
No, but if you put it on a text display of course you can scale the text display. In other contexts (chat, lore, dialog UI…) the size is fixed, like regular texts
Is there any guide about custom audience?
What do you have trouble with? And what are you trying to use custom audiences for?
It seems that I was looking for ForwardingAudience 😅
who is kyori
it's an organisation
how do I display horizontal lines with no breaks in the chat like in this image?
I believe that's just strikethrough on spaces
ah thanks that worked
miniMessage = MiniMessage.builder()
.tags(Placeholder.component("primary", Component.translatable("palette.primary")))
.tags(Placeholder.component("secondary", Component.translatable("palette.secondary")))
.tags(Placeholder.component("error", Component.translatable("palette.error")))
.tags(Placeholder.component("prefix", Component.translatable("prefix")))
.build();
GlobalTranslator.translator().addSource(new LocaleMessageTranslator(miniMessage, this, key));
is there a proper way to do this because i know this wont work and i'm probably not doing it right
You are overriding tags every time
Your MM instance only have prefix
You should use MiniMessage.builder().editTags(tags -> { ... })
Furthermore, I believe you want the style of the prefix to influence the rest of the message, so you should use a Tag.inserting(...) tag resolver instead of Placeholder.component(...)
how do you show items (like pickaxes) on the server list using minimessage? I've tried <sprite:blocks:item/snowball> and it works, but something like <sprite:items:item/diamond_pickaxe> doesn't, and neither does the official example <sprite:"minecraft:items":item/porkchop>
item sprites are in the blocks atlas
thats why snowball works and the other two dont
The example is wrong yes, but things will change in the next Minecraft update, the blocks and items atlas will split
oh crap thats good to know
why items in blocks atlas? mojang, what did you do?? 😭😭
It was experimental, they said it. And now they improved it be splitting the two atlases
(Tomorrow)
anyone know how to get this working
you were told to use editTags before
yes
that was edittags
you're using it, my bad
had a stroke reading the first codeblock due to indentation
what does your LocaleMessageTranslator look like
is there a reason you aren't just using a MiniMessageTranslationStore
why are you calling #build in the consumer?
what platform & version of adventure are you using?
did not know that existed
that was an accident and i have no idea how that compiled
whichever came with paper 1.21.10-R0.1-SNAPSHOT
it's a consumer so it's not like there's a value being returned, so it compiles
ah
issue might just be that you mispelled palette in the language file
oh yea that file says pallet, lol
i mean if it makes you feel better, i also missed that
I missed it the first time, but after looking at the LocaleMessageTranslator class, I assumed something else was wrong since it looked fine so I looked harder
if you want to have the IDE yell at you for keys that don't exist on the resource bundle, you can use the jetbrains annotations thingy and an util method like so:
public static Component tr(
@PropertyKey(resourceBundle = "messages") String key,
Object... args
) {
return Component.translatable(key, args);
}
this will make it error if you use a key that isn't in the bundle messages
also lets you do tab completion on the keys in the resource bundle
im using yaml files for locales which probably isnt the best way to do it but ill keep this in mind
.properties file are commonly used for locale files, but yaml is fine too
the above approach won't work for it but it is what it is
is it possible to save/apply settings immediately when cycling these options? or does it have to rely on another action?
https://docs.papermc.io/_astro/input-multi-options.CgHkNz2V_ZFE0MH.webp
Not really, it’s all client-side until he submit
Is there a way to replace a text inside string white still retaining it as a string? I want to use the TagResolver on a string without trning it into a component
why?
I mean, String.replace?
if you want to use component manipulation then you need the component tree
I mean, you would be better off writing a custom tag for that given that you'd likely need to deal with PAPI expansion fun
is adventure 4.26 not deployed to central?
or rather, is not deployed on purpose? xD I can see it isn't myself I guess: https://central.sonatype.com/artifact/net.kyori/adventure-bom/versions
Discover adventure-bom in the net.kyori namespace. Explore metadata, contributors, the Maven POM file, and more.
I see. I guess I use snapshot for now but imo there should be a manual deploy done to not cause more confusion lol
I switched from TranslationStore.messageFormat to MiniMessageTranslationStore.create to be able to use minimessage in the resource bundles but now all arguments are missing, they show up as {0} ingame too both in chat and in item lores where i explicitly invoke the global translator
Is this supposed to be like that and how do I get the arguments to work?
guess that's it lol thank you
I just looked at the subclasses of TranslationStore in my ide and noticed the minimessage and used it xD
Are color tags like <red> supported in the server.properties motd string?
Have you tried it?
no
nope, there was a PR for it but it got closed (pre-softspoon)
Vanilla won't support it, but plugins might do dark magic to add support to it I guess
Of course its possible with plugins
just use MiniMOTD
When i want to display certain items in chat, can i get the sprite path from an itemStack?
<sprite:blocks:block/diamond_block> will show a diamond block. But <sprite:blocks:block/skeleton_skull> does not show the skeleton skull. I also tried items:item/.. but also not working. Is that even possible?
not really
I know teo send something of a workaround for that in here though, let me see if I can find it
here it is
they didn't send the whole thing it seems which is a shame
ah i see, but I cant find something for the skeleton_skull for example
Isn't it actually skeleton_head or something like that?
at least not skeleton_head
some items simply don't have a sprite, that might be one of them
could be, sadly
Yeah a lot of the variants don't, like you might just have the base head item
is there any other way to display an item in the chat except the sprites?
something that also prints the amount there?
Sprites or custom font
Yeah I know, but I need to finish it before I could share it, and I kinda paused it waiting for the blocks/items split, but now that the 1.21.11 is out I guess I will get back to it
And yes no skeleton skull item or block sprite, but MHF_Skeleton player head thankfully
good idea!
i tried my custom resource pack images with the sprite tag, does not seem to work, intentionally or is it usually working with resource packs?
Have you made an atlas?
You added your textures to the blocks atlas?
yea, the textures are working properly on the items so it must be working
I managed to get them to work when I played with them like a month earlier, so it’s possible, but I can’t tell exactly how I did it, it was pretty exploratory on my side
Did 1.21.11 change how sprites work?
This minimessage tag <sprite:item/salmon> works fine on 1.21.10 clients, but renders "no texture" in 1.21.11 clients
And the other way around, the tag <sprite:"minecraft:items":item/salmon> works fine on 1.21.11 clients, but renders the unknown character square on 1.21.10 clients
Is there a way to print something that can be rendered on both 1.21.10 and 1.21.11?
I think your only way to make something work on both is to ship your own resource pack and only use custom sprites
I have the sprites on the motd, too early to send the resourcepack
I think I'll have to manage it based on the protocol version until I'm able to drop 1.21.10
They separated the blocks and item atlases
Best you can do is just toggle the atlas depending on the version
Reason why it shows no texture now might be because blocks is the default atlas and you’re trying to use an item sprite
final Component homeComponent = Component.text(nameOfHome)
.hoverEvent(HoverEvent.showText(
Component.text(
plugin.getConfigManager()
.getMessage("please-select-home-hover")
.replace("%home%", nameOfHome)
)
)).clickEvent(ClickEvent.runCommand("/home " + nameOfHome));
What am I doing wrong? I'm trying to show text in the hover and when they click have the player run a command. I'm getting Cannot resolve method 'showText(TextComponent)' inside te HoverEvent.showText() block
Technically you should be able to remove the HoverEvent.showText(...) wrapper and do directly .hoverEvent(Component.text(...))
But this doesn't explain why you can't call the method yourself
Thanks alot! Removing it fixed the error.
and it compiled
Oh also do you know if the / in front of the command is required in this case?
ClickEvent.runCommand("/home " + nameOfHome)
Yes you need it
Perfect thx!
Yup, kinda what I was thinking, I’ll give it a try later when ai get the time
Umm
is it possible to do something like this <click:copy_to_clipboard:<code>><code></click>?
essentially copy a placeholdeR?
iirc you want to use a Placeholders.unparsed for that one
hey isnt there like a web demo of adventure?
MiniMessage Viewer is a web interface to help generate and edit MiniMessage strings.
how can you display a players head in minimessage?
is anyone able to get a ClickEvent#suggestCommand to work in a Dialog ActionButton? It doesn't appear to do anything for me, and almost seems like it is not working because it doesn't close the player's open dialog
if they don't work in Dialogs, is there a way to suggest a command to through a bukkit method?
is there a reason you don't use the command template dialog action for that?
ah wait, suggest command, not execute command
does that even work anywhere else than chat
yeah, i am trying to use the staticAction
well, i'm sure it would work if it closed the dialog first
like, for it to work on dialogs or books, it'd have to open chat window for the player
I sincerely doubt mojang accounted for that
guess it is worth a try
has mojang not added a way to suggest a command to the player outside of the specific clickevent
this is so sad
I'm processing text within components, like this:
fun traverse(text: Component, consumer: BiConsumer<String, Int>) {
text.replaceText {
var pos = 0
it.match(".+").replacement { matchResult, _ ->
val everything = matchResult.group()
val prevPos = pos
pos += everything.length
consumer.accept(everything, matchResult.start() + prevPos)
return@replacement Component.text(everything)
}
}
}
Just recently someone reported an issue where the whole server looks to have frozen, here's the stack (I cut out the end of the stack):
https://gist.github.com/Thorinwasher/8b2945cab749fe1078e595ab048fb3e5
- Does there exist a better alternative to traverse components (I need to know the global char-pos, which is a bit of a weird requirement for components)?
Or - Is this an issue with adventure, can this be fixed?
For more context:
- I need to modify the text in multiple ways, to obscure text. It's a game mechanic for making a recipe that can be found in loot more interesting.
- Recipes of the same type should be merge able, where no previous data is lost in the merging
- Therefore the global position is necessary to know, it's both used in the database and in merge processing
Might be this exact trace if the traversing is repeated a lot 🤔
I mean, it's farily hard to say with a truncated log
if all of the other traces are showing it's stuck in the same code then you would generally need to work out why
Nothing there suggests anything is directly wrong, just depending on the input complexity that might hurt
Yep 🤔 , could just have randomly pointed to that stack at that moment of time
Maybe testing with a profiler gives clearer statistics on this, getting server freezes like this seems like it's going to be a bit sporadic though. I get the feeling something could be wrong in the plugin, it's fairly un-optimized. Problem is that all of the text processing is randomly determined by generating a seed (which is used pseudorandomly)
Also now that I think about it, I should initialize the .+ pattern statically (I thought that was a cheap operation to do for simple patterns, might not be)
compiling that pattern won't really be an issue tbh although it is good practice, it also isn't what was caught in that stack trace, but, anything could've been
Oh, yeah that's true 👍
I also don't think matching all chars in a string would be an expensive operation, so the issue might be elsewhere
you could also use the Component#iterator/iterable methods here and checking if the iterator element is a TextComponent
Anyhow, "might" is a bad word to use in programming, bad habit of mine. I definitely need to test this
unless you plan on actually replacing the text, then replaceText is not a good fit for this :d
I think I just used it as I'm unsure what components can have text inside of them, how components render, and so on. But if it's only text components, then that's set
Alright, I will rewrite that to something of the type DFS or BFS then. 👍
yo
so unless i'm missing something v4.26.0 has been released but not published to maven central?
oh
has it been published to a different repo?
no
ha I think I have a fix
I have now released adventure 4.26.1, which is identically to 4.26.0 plus the CI fix
javadocs are still pending, more work needed for that
(cc @lucid torrent)
yo thx
does Component.translatable from a MiniMessageTranslationStore return serialized minimessage or a parsed one? i would like to think its parsed already, but i want to confirm
also how do i have per-player defaults for Component.translatable locale? i want to have something like
Translatable is called, returns in Locale A if player has set from a command, otherwise returns in locale B (locale of the client) and locale C as the overlord fallback
everything i have written till now, first time using adventure for translations:
sorry about the kotlin if you are java-only
I don't think that level of fallback is supported, the expectation is to just use the clients locale, or fallback to whatever the server is set to or something like that
It's not the first time people asks for a server-side client locale tho. Would it be possible to hook a custom Function<Player, Locale> into the translator to allow this?
doing sprite:item/name_tag doesnt seem to work in paper 1.21.11 anymore, it returns the texture not found texture
worked perfectly in 1.21.10
1.21.11 split item textures into a new atlas. If you try <sprite:"minecraft:items":item/name_tag>, it should render correctly.
okay. thx!
(You can shorten a little bit this to only <sprite:items:item/name_tag>)
You could also create your own shortcut <item_sprite:name_tag>
yes that's totally possible right now by setting a custom target - you can use Argument.target(Pointered) as an argument in your translatable component and just make sure you set the Identity.LOCALE pointer to override/set the locale that mm will use for translation
so you'd just make some sort of util function that can create those pointered instances for you
hello I need to serialize String to TextColor.
I'd like the string to jsut be
"&0-9" or "#RRGGBB"
should I do a switch and manually asign either (NamedTextColor) or TextColor.fromHexString(string) for hex string
or is there other magical way
I need to apply the color to components, but first I need to serialize it from the config
Why not just use Minimessage?
because it would make my config super ugly for what I need to do
complex serialization that needs to be human readable and editable
and what would that change if I still need a TextColor not a Serialization
what?
mini message is a human readable format, so im not sure what you mean by that?
it doesnt matter. I'd like to serialize simple String like "&f" or "#RRGGGBB" to TextColor object
ok - and what if you want to specify a non-color style?
"human readable" and "&a" don't belong in the same sentence without negation. 🙁
say, a shadow color? or italics? or bold?
are you going to add separate options for that?
nope not the case
it's why i asked for additional context
i don't know what is the case
but generally, specifying a single color in a config (is your problem even a user-facing config? i don't know, hence why i asked) is an anti-pattern
there is a TextColor#fromCSSHex or similar, see the Javadocs. You can use that for the #RRGGBB format
im aware of that
the other format hasn't been used by the game in like 12 years now and is not user-friendly, just don't
(and if you really want to, yeah what you suggest initially is probably the "best" way)
thanks that's exactly what I needed.
yes
Hi, how to get a shield rendered correctly as a sprite? It's maybe to hacky right? Because u need to tell that it has the normal wood color and no pattern?
shield_patterns has only this entries:
"sources": [
{
"type": "minecraft:single",
"resource": "minecraft:entity/shield_base"
},
{
"type": "minecraft:single",
"resource": "minecraft:entity/shield_base_nopattern"
},
{
"type": "minecraft:directory",
"prefix": "entity/shield/",
"source": "entity/shield"
}
]
I don't think there is a good way beyond some hacky stuff with negative spaces

thats really bad :/
@dapper bay seeing as you shouldn't be using any version older than 1.21.10 anymore it's not really that big of an issue?
a lot of player base is generally in .8/.4/.1
only if you let them
it would be okay if there is support for .8 at least...
well we haven't invented time travel yet
What do you expect then? We're not working at Mojang Studio, they released head components in 1.21.9, so adventure provides support for them since they exist
can i get some feedback from you guys on what i can improve?
i am learning to work with localization
Please ask specific question on which topic you need help, because we don't have time to review an entire project 😅
no worries i was just asking someone to review it for any pointers, only if you have too much free time otherwise no problem
Hello, I'm looking for clarification around comparisons when Virtual Components are involved. Based on the documentation for the emitVirtuals method for a MiniMessage builder, it sounds like you should be able to compare Components deserialized from the same MiniMessage instance. However, this does not seem to be the case.
Considering an example:
MiniMessage mm = MiniMessage.builder()
.strict(false)
.emitVirtuals(true)
.tags(StandardTags.defaults())
.build()
// the following is false
mm.deserialize("<rainbow>Hello").equals(mm.deserialize("<rainbow>Hello"))
Looking through MiniMessage source, it appears that equality checks haven't been implemented. Is it intended or expected that components like this can't be compared? Do I need to compare the serialized (string) output instead?
Feel free to ping me in any replies
I don’t have the time currently to look at your whole question, but maybe this could help you re-think your problem: why would you ever need to compare components…??
Is there a "better" way for comparing the something like the name of an item for example against a string (or component)? For context: this is for Skript. I don't expect that kind of comparison to be common, but it does happen, and I would prefer to preserve compatibility for users.
Yeah we don't support component comparison like that, emitVirtuals is intended for roundtrip serialising of e.g. gradients/rainbows to produce the same output as the initial input
I assume Skript has a way to store data in the PDC or similar of an item
That's how you should be doing comparisons
Yeah that would be the recommended approach for analyzing data ofc
And the supported way yes
Though I'm sure there are users still doing name comparisons
Fair lol
There are still a lot of users doing unsupported things, unfortunately we don't have the time or space to support everything unintended - we provide/point towards better solutions and support those instead
For sure I get that. I think, for compatibility purposes, instead analyzing the serialized content should suffice
I figured I would ask here just before resorting to that
PDC has been around for years and years, that's actually got more compatibility than components tbh
Still a bad idea. Use PDC.
I should clarify this is not for a script I'm writing - this is for the language itself. I'm integrating Adventure/MiniMessage into the codebase, but need to tie up compatibility for existing user code
I'd still suggest a one-time migration to store identifiers into PDC
I would see nothing wrong with breaking compatibility with bad design.
We have the ability to deprecate inadvisable code, so I think we can take that route with eventual removal. I appreciate the insight 🙂
Happy to help 🫡
Is there a way to set a new minimessage prefix? e.g <> to {}?
Because im working on a little gui creator for my projects and every gui is based in XML, and XML doesnt like <> characters
Not really no
So the best way would be by finding things such as {} with a regex pattern and replace it by <> right?
I mean yeah i can escape <> characters in xml, but in big config that looks terrible
I guess, but it could cause unexpected behavior if the user uses a real </>
I imagine there wouldn't be overlap between the xml tags you're using for the gui and the MM tags though, theoretically you could pull it all off looking like xml
Isn't there something like <![CDATA[...]]> which allow for anything inside?
yeah i will find something that looks right haha
Thanks for the help anyway!
Honestly I think I'd find it reasonable to see like (just using html example) <div><span><b>meow</span></div> and have the <b>meow run through MM
Most XML parsers I've used before should let you read contents as strings ignoring the tags when you're at certain places
Hello, can I somehow get a collection of players/receivers from an Audience from an AsyncChatEvent?
Assuming you mean paper's event, the viewers set is, I think, unique players (and maybe the server too? lost track). Further paper api questions belong in #paper-dev
Okay, thanks!
doesnt seem to work for:
sprite:items:item/compass
The items atlas doesn't exactly exist like this, idk what went on, but you can just use <sprite:item/compass> and it should work
Unless I am misremembering, which is very likely, they just kept the items under the default blocks atlas
They split it since 1.21.11
Yeah, there's not a single compass sprite
Each orientation has one

aha
So <sprite:items:item/compass_00>...
thx!
didnt work out, iam still getting the missing texture texture
hmm
aa i see
Don't hesitate to Ctrl + F here
minecraft_textures_atlas_items.png.txt by @sweet hornet: https://pastes.dev/26fLX0aYMi
It's the debug atlas file generated from 1.21.11
(And if you want to see the actual sprites, but just try them out in-game it's easier 😅)
yeah thx, i will indeed try them out ingame
saved that txt
now i can just ez search for it
And because there's no magic, you can find in the vanilla resource pack (assets/minecraft/atlases/items.json) how it is generated:
{
"sources": [
{
"type": "minecraft:directory",
"prefix": "item/",
"source": "item"
},
{
"type": "minecraft:paletted_permutations",
"palette_key": "minecraft:trims/color_palettes/trim_palette",
"permutations": {
"amethyst": "minecraft:trims/color_palettes/amethyst",
"copper": "minecraft:trims/color_palettes/copper",
"copper_darker": "minecraft:trims/color_palettes/copper_darker",
"diamond": "minecraft:trims/color_palettes/diamond",
"diamond_darker": "minecraft:trims/color_palettes/diamond_darker",
"emerald": "minecraft:trims/color_palettes/emerald",
"gold": "minecraft:trims/color_palettes/gold",
"gold_darker": "minecraft:trims/color_palettes/gold_darker",
"iron": "minecraft:trims/color_palettes/iron",
"iron_darker": "minecraft:trims/color_palettes/iron_darker",
"lapis": "minecraft:trims/color_palettes/lapis",
"netherite": "minecraft:trims/color_palettes/netherite",
"netherite_darker": "minecraft:trims/color_palettes/netherite_darker",
"quartz": "minecraft:trims/color_palettes/quartz",
"redstone": "minecraft:trims/color_palettes/redstone",
"resin": "minecraft:trims/color_palettes/resin"
},
"textures": [
"minecraft:trims/items/helmet_trim",
"minecraft:trims/items/chestplate_trim",
"minecraft:trims/items/leggings_trim",
"minecraft:trims/items/boots_trim"
]
}
]
}
Which means basically that every texture from the assets/minecraft/textures/item/ folder is mapped to an item sprite
Which explains why there's a ton of sprites for the compass (and clock)
Idk, check using regex and find the first match that matches a tag
The tag pattern is openly accessible
string.equals(mm.escapeTags(string)) might work
I see, thanks!
And it's finally available!
Feel free to try it out if you need them, and tell me if you see something wrong. I guess next time someone will ask for this I'll give some explanation. For now, I've written a small README, which hopefully helps a little bit.
https://github.com/indyteo/MaterialSpritesGenerator
The complete rules (of which I shared an extract back in the days) are there for the curious 🙂
(Note that I don't need/want any recognition if you want to use the pre-generated mappings, they're freely available in the releases)
Hi, I've already added Adventure as a dependency. How can I make the plugin's inventory title use a custom font?
What API are you writing for? (paper? fabric?)
Paper I would say
Add the dependency to the pom.
No need to add adventure (in fact, best not). Just use Paper API as dependency. There are createInventory methods that take Component titles. For more Paper API help, visit #paper-dev 🙂
Okey, thanks!
which event is that? Also the PlayerCustomClickEvent?
it would be that event, yes, though the callback system is preferable
well I cant use it because I'm using minimessage through a config
so I have to do <click:custom ....
afaik yes
probably something like <click:custom:'namespace:key'> of i had to guess
yea I think so too
lemme test that
serialization is a whole other thing
but right now it does support deserialization
yes, for serialization
not deserialization
and it will be supported for serialization in adventure 5 which is not yet finished
hm I see
if you're doing the code why don't you just make a callback click event and add it as a custom tag or something
so something like action:...identifier in my message strings and replace that in code with a clickable component?
I need to be able to pass dynamic data to it
for instance:
"You got a friend request by PlayerX [Accept] [Deny]" here I somehow need to be able to get the action (Accept) and the player PlayerX as well as the executor
I'd just style that like <accept>[Accept]</accept> <deny>[Deny]</deny> and then have fun tagresolvers for that.
okay but how does the tag resolver know which player to accept or for instance which server to join / clan to join
also its not like im using accept or deny for one thing only
it should be used for multiple systems
I'd be making a resolver that can be aware of the players involved and have the callback already know it 
hm
and what about executing commands?
is it possible to disable that popup
and also replace placeholders inside of <click:run_command:'/friend accept <player>'>
because I already have commands for all actions
I mean, basically yeah you'd make <accept> a tag resolver that adds a ClickEvent to that text that runs that command with the player name on it.
And the command popup doesn't happen if the commands are properly registered and sent to the client, iirc?
Yep
alr yea it actually works without a popup
then I only have one issue left
When I hardcode the clan command argument it worked without a warning popup
but here
You have been invited to the clan <primary><clan></primary> by <primary><inviter></primary>!\n<click:run_command:'/clan join <clan>'><green>[Accept]</green></click>
at tag resolvers Placeholder.unparsed("clan", clan.name())
the issue is here that in the message <clan> gets replaced with the actual clan name "test"
but inside of the click: tag it doesnt
which makes sense cuz its a tag inside of a tag? --------> <click:run_command:'/clan join <clan>'>
is there an easy way to fix that?
So you'd want to use a pre process parsed placeholder
used TagResolver.resolver("clan", Tag.preProcessParsed(clan.name())) instead now
why not just use Placeholder.parsed("clan", clan.name())
funny, what you did is exactly like its impl:
I wouldn't do either, because that's easy for a user to mess up compared to making a tagresolver that auto makes the clickable command, like <join><green>[Accept]</green></join> which is also more readable. Obviously workshop other names like <joinclick> <joincommand> etc.
I created a dynamic TagResolver using the method below and am using the #deserialize method with the created TagResolver, but it is not being parsed in the game
Someone has a idea why?
unparsed is for a literal string, you probably meant to use parsed
Whoops my bad.
Yeah changing it to parsed fixed it xd
thanks lol
Well nvm I did not say anything
Hello, I'm using net.kyori:adventure-api:4.26.1 and there does not appear to be PlainTextComponentSerializer (at least that's how I vividly remember it's called.) I'm outside of any mod/plugin ecosystem (it's a library for a plugin)
Is there a way to convert Adventure's component into a plain string?
adventure-text-serializer-plain separate artifact
also in maven central?
That's where I got the ID to copy/paste, so yes I think so 🙂
thanks
the javadocs for 4.26.0/1 are now on the jd site, sorry for the delay
https://jd.advntr.dev/api/4.25.0/net/kyori/adventure/audience/Audience.html#sendActionBar(net.kyori.adventure.text.Component)
does this trigger System Chat Message packet or Set Action Bar Text packet?
declaration: package: net.kyori.adventure.audience, interface: Audience
that would depend on the platform I would say
im on paper, testing right now
why do you care, its an implementation detail
but on paper it would be a set action bar text packet
im looking to make a mutable component, how would i do that?
For what reason?
adding components to my skript addon, by skript standards you should be able to modify an object so immutability is not amazing in my case
someone else already did it but they wrapped the component in another class, looking to avoid that
was thinking of using the componentbuilder interface
would that be appropriate?
Builder potentially solves your problem. But this feels like a design flaw to expect everything is mutable.
doesn't Skript support components natively with some syntax of their own
it is similar to minimessage but predates it
unless you mean to add getters/property expressions for a given component string, which I guess could be useful
thats the old/current system, adventure implementation is planned for april, im just doing something similar to allow the people using my addon to use the same extensive features while skript doesnt have them
well, its not really like that, i said by skript standards but i really just said that on the spot, it would just be much better if it was mutable in this context
i'll go with builder, thanks!
I would just make a component serializer for their format and add some kind of expression like f%string% if that's allowed
I am a bit confused, how would I create a tag <example> that has access to everything after it?
for instance for text replacement.
Modifying
https://pastes.dev/fgfUzUwdig I am a bit confused, any ideas why this is sending like "duplicated" stuff?
can you show your code?
it's linked
you want to clear the children of the returned component
how do we open urls with mini message?
<click:open_url:'url'></click>test
isnt it this?
ohhhh
thx
ngl i was looking to the doc but
i was searching for "url" in the page
im dumb sorry
Trying to use base64 textures for heads because using the <head:base64> does not work
Not quite sure where to start
The head tag does not yet support base64 textures
I see! Interesting
I was going to use it for chat emojis instead of using the good old fashioned map with unicode characters xD
Any idea when or if?
It will support it as soon as I finally sit down and get named arguments to work, the plan has been to put base64 and other stuff as named arguments
Got it. tysm. Thank you for all the hard work too

Wondering as well if there's a way to retrieve a tag as a Component specifically? Or should I parse it through MM first and just return that
In the short term is is possible to just make your own tag resolver for it though? 🤔
Well that's what I was wondering
There is Component.object
You can construct the object components (like head components) through there
ohh?
Where can I find the docs for this
Nowhere yet really. But you can see an example in the head resolver source code, like for example SequentialHeadTag.java, I've linked some lines where the component is constructed
Wow that's a lot
The JavaDocs are a great place to look too: ObjectComponent
didn't I give you a tag resolver for this a few days ago
tbh I have no idea how to use it. I'm gonna save it and experiment w normal tags first
you just pass it to the serialize method like so: MiniMessage.miniMessage().serialize("<green>Idk <head_texture:some actual base 64 here>", headTextureTag)
you can also build a custom MiniMessage instance that has it built in I guess
Paper
In that case it's already a hover event source.
demn
call itemStack.asHoverEvent() 😉
I better read the docs properly
better yet, you don't even need to call asHoverEvent! you can just do component.hoverEvent(itemStack) :)
Thanks
You aswell
Hii, why head is not displaying on chat?
coupon-send-code-player:
chat:
- '{header}'
- <white>
- <green> <b>[+]</b> Grabbed <yellow>{code}</yellow> <aqua>{template}</aqua> Coupon.
- <green> <b>[!]</b> Gifting is enabled!
- <green> <b>[!]</b> Sent coupon to <b><aqua>{player}</aqua>
- <head:{uuid}>
- <white>
- '{footer}'
sound: coupon.sent-code
where {uuid} replace with player uuid
or i am misunderstood something..
here the code i used
override fun sendMessage(sender: CommandSender, path: String, placeHolder: Map<String, String>) {
val audience = when (sender) {
is Player -> JService.adventure.player(sender)
is ConsoleCommandSender -> JService.adventure.console()
else -> return
}
// Get message
var message = getMessages("$path.chat").apply(placeHolder).joinToString("\n")
if (message.isEmpty()) message = getMessage("$path.chat").apply(placeHolder)
if (message.isEmpty()) message = getMessage(path).apply(placeHolder)
if (message.isEmpty()) message = getTemplateMessage(path).apply(placeHolder)
if (message.isEmpty()) return
// Split into lines
val chatMessage = message.split("\n").map { it.trim() }.filter { it.isNotEmpty() }
// Actionbar
val actionBarMessage = getMessage("$path.actionbar").apply(placeHolder).trimStart()
if (actionBarMessage.isNotEmpty()) {
audience.sendActionBar(JService.applyMiniColor(actionBarMessage))
}
val title = getTitle("$path.title.main", placeHolder)
if (sender is Player && title.title.isNotBlank()) {
audience.showTitle(
Title.title(
JService.applyMiniColor(title.title), JService.applyMiniColor(title.subTitle), Title.Times.times(
Duration.ofMillis(title.fadeIn), Duration.ofMillis(title.stay), Duration.ofMillis(title.fadeOut)
)
)
)
}
if (sender is Player) {
val soundSting = getMessages("$path.sound").apply(placeHolder).ifEmpty { JService.configManager.messages.getString("$path.sound")?.apply(placeHolder) }
val sound = GuiSound.loadSound(soundSting)
sound.playSound(sender)
}
chatMessage.forEach {
audience.sendMessage(JService.applyMiniColor(it))
}
}
is it because of use of audience?
Your issue might be how you use placeholders, it's hard to say without seeing more code. MiniMessage has a custom tag system that you should use instead - see the docs for more info
I just simply replace the text on it
private fun String.apply(placeHolder: Map<String, String>): String {
var message = this
placeHolder.forEach { (key, value) ->
message = message.replace(key, value)
}
message = message.replace("{prefix}", prefix)
message = message.replace("{header}", header)
message = message.replace("{footer}", footer)
return message
}
after all placeholder applied it send the text
I verified that there is no mistake in {uuid}
placeHolder.code = redeemCode.code
placeHolder.uuid = uuid.toString()
the fact the whole line isn't being sent is definitely an indication the problem is on your end rather than adventure/minimessage
but just to double check, vanilla client? correct client+server version for the head object components? updated server version?
1.21.10
looks like you're using adventure platform of some sort, spigot i guess?
you don't need to use adventure-platform if you're using paper, it's possible that could cause issues
but again, there's more questions here :p
also, what does debugging tell you? when you stepped through the code where exactly was the issue?
it is becuase i do give support for spigot as well
same though
when i simple use head tag after "Sent coupon to"
the whole line just got ignore like ""
okay so what was the component that you sent to the player? did you print that?
You're definitely using an up-to-date vanilla client too?
Yea using 1.21.10
Let me check
This one?
ObjectComponentImpl{contents=PlayerHeadObjectContentsImpl{name="47dd2cf1-0521-3481-bd5b-18feed752b3c", id=null, profileProperties=[], hat=true, texture=null}, style=StyleImpl{obfuscated=not_set, bold=not_set, strikethrough=not_set, underlined=not_set, italic=not_set, color=null, shadowColor=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}, children=[]}
that looks fine to me then, definitely either an issue in adventure-platform or you're using some modded/custom client that's breaking things
wouldn't be surprised if adventure-platform was broken on .10
okay great
so when i said vanilla right at the start, that's what i meant :p
sorry for misunderstanding
nw, glad you got it sorted
is it possible to support head texture for cracked player via skin restorer?
alright got it
then what about custom texture support?
nvm i got anwser from old post
how can i support both legacy color codes and minimessage tags
i've tried few things but it didn't work
oh so I can't just use normal head or base64 there yet. OK thanks
it supports a player UUID, if that's what you mean
providing profile info manually is pending on named arguments being supported, (but, that b64 doesn't seem to be anything valid anyways)
you can just create a custom tag
here's one that does just that
(The hash in the Minecraft texture URL: https://textures.minecraft.net/texture/6ee554abe14fda92ef5ec921222fe60c268a8abdf4120d4f283e803de8d3fe0b)
Is it part of the specs that token emitter ends some tag with a forward /?
I mean, is it valid syntax to have like <my_custom_tag:with_arg/>?
(It works, but I've never seen that syntax)
And regarding your case, you might be interested in this custom head tag I've made (but I haven't tested it yet in real world, it's only a prototype as far as now). Main motivation was to have serialization ability.
Example:
private static final MiniMessage mm = MiniMessage.builder()
.editTags(tags -> tags.resolver(CustomHeadTag.RESOLVER))
.build();
// Inside my dummy /mm command executor:
Component component = mm.deserialize(String.join(" ", args));
sender.sendMessage(component);
sender.sendMessage(mm.serialize(component));
Obviously the code is not fool-proof, as there's no validation on the argument, but feel free to improve it.
Showcase:
CustomHeadTag.java by @sweet hornet: https://pastes.dev/9PObbpr7u8
I never understood what the whole serializable resolver and component claiming stuff is for
I know the built-in tags all implement it, but I don't think I've encoutered cases where I needed to implement that functionality on my custom tags
Can this be PR to the official minimessage please?
the base64 texture stuff is waiting for named arguments
I think the named argument version of the head tag implements the functionality already, it is just not merged yet
Oh great, but these textures (not base64) would be useful too probably to be pr there
I'm using custom head textures in some item's name/lore, for example to show zombie head on an undead-related weapon, etc.
Custom head textures uses the profile property textures, which is a base64-encoded value containing (along with some other not-so-useful-in-this-context values) the URL to the PNG texture file on Mojang's servers (which is uniquely designated by a probably random (or maybe md5 or something related) hash). They have no UUID nor player name, only the textures property making them static profiles (as opposed to dynamic profiles).
On the other hand, I have an in-game item editor tool for my staff members to create/modify items (namely, their name/lore). This tool relies on Minecraft dialogs, and components are encoded using MiniMessage so it's more user-friendly for them (than JSON or SNBT, for example).
But with the actual builtin head component from MM, such custom head are lost and turned into Steve/Alex heads if the item is edited, because it gets turned into <head> with no argument, and the profile property is lost.
So, TL; DR, yeah I needed to code a serializable tag handling custom heads based on profile property textures
The named argument version (can't find it anymore, PR closed?) is likely to handle "all" (despite having only one really useful currently) profile properties, and uses their raw value, which is the base64-encoded JSON string containing the URL
And you must admit it's a bit less cluttered to have :
<custom_head:6ee554abe14fda92ef5ec921222fe60c268a8abdf4120d4f283e803de8d3fe0b>
Than (at least, it can be bigger despite other values not being useful):
<custom_head:eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNmVlNTU0YWJlMTRmZGE5MmVmNWVjOTIxMjIyZmU2MGMyNjhhOGFiZGY0MTIwZDRmMjgzZTgwM2RlOGQzZmUwYiJ9fX0=>
So "yes", but it's likely to not be merged unfortunately due to the other plans in mind currently, with the named arguments. But again, feel free to just include my tag in your project and register it in your MM instance once for all
the issue is I wanted to use it with TAB plugin 😅 so not sure if I'm able to make this work well
Ah, idk about that plugin, maybe they have an API where you can edit the MM instance they use? Otherwise that's a whole another issue, about registering tags into a "global" MM instance 😅
Is there a way to create a text Component with gradient w/o using MiniMessage from-string-deserializer?
Something like this
Well, no, that’s a serialisrr specific feature, Minecraft doesn’t support gradients
You would need to modify the component yourself to implement such a feature outside of MM
there is a PR but it kinda got nowhere:
https://github.com/PaperMC/adventure/pull/1063
Can I use sprites with adventureapi? Don't want to use minimessage since components take less lines in the code
yes
If you're hardcoding components, you shouldn't be using mm anyways
look at Component.object(...)
The whole adventure vs minimessage thing is confusing to me
I get why minimessage is useful for the end user, but in the code base I would rather stick to adventureapi
that's the general idea - mm is a frontend for user input and config files and licalization, but if you don't need those its easier to use components directly
It's all adventure components internally though
So in theory you can have icons in rank prefixes now?
Is it possible to change the tooltip style for hover message component in MM?
@rare sage smh i can spell good
mm is just a format for what Minecraft offers, can vanilla chat components do that?
No clue, I’ll go research
it's only possible to change tooltip style for itemstacks iirc
but you can display an itemstack as a hover event?
So if I make an itemstack, I should be able to display it through a hover event?
With the tooltip style
I think so, but you need a resourcepack
I have my custom tooltips ready, but thanks I’ll try to make it with an itemstack
I have a data object with certain meta data and I wonder how I can write a custom component that does certain things before the string is rendered.
I just want to preprocess certain MetaData before I dump it into placeholders for MiniMessage.
im confused, you're writing a component but you want to make a placeholder for minimessage?
can you explain a bit more about what you actually are trying to achieve
I just want to throw in an specific object with the content and at the end I have a component that I can simply send
On the end I want something like this: context.sender().sendMessage(CustomComponent.of(template)); sender().sendMessage is a method in velocity for example
so, just a util method? yeah ofc you can just do that
is there any difference between component.append(component2).append(component3)... with textOfChildren(component1, component2, component3...)? In my plugin the former one sometimes consumes all subsequent components.
in the first case component would be the parent which 2 and 3 will inherit styling from, textOfChildren would be equivalent to doing Component.empty().append(component).append(component2)... and would result in no style being inherited since the parent is empty
so why would it happen that the subsequent components just disappeared
components are immutable, append returns you a brand new component
the first one creates this tree
the second one creates this one
yeah my code is like return component.append(component2).append(component3)...; but still
Actually, not really. C is a child of A, not B
What you described is component.append(component2.append(component3));
You need to give a little bit more code if you want us to be able to help you
thx. but I think I figured it out
Nice
Hey, so currently I have a way of adding custom placeholders via a config in my Plugin, but for some reason, if I create a placeholder called <secondary_color> that returns <red> and then use that placeholder in a text like <secondary_color>Hello, for some reason, Hello does not show up as red, as if the color gets reset after that. If I make the placeholder return <red>A, only the A will be red, then rest is reset? Any chances somebody could look into how I am doing things:
- Processing/parsing placeholders: https://github.com/xMrAfonso/Runway/blob/v2/src/main/kotlin/me/mrafonso/runway/processing/ProcessHandler.kt
- Custom Placeholder handling/creation: https://github.com/xMrAfonso/Runway/tree/v2/src/main/kotlin/me/mrafonso/runway/resolver
I haven't read the code but that just feels like you're making a self-closing inserting tag for everything
if you want a tag that only does styling, you'd use a styling tag, if you want a tag that inserts text and its style can be passed down, you'd use an inserting tag
If making custom color placeholders, I'd vote styling placeholder.
yeah this feels like it is the case: https://github.com/xMrAfonso/Runway/blob/v2/src/main/kotlin/me/mrafonso/runway/resolver/TagResolverBuilder.kt#L66-L76
Hello, why do I get this error on 1.19.2 paper with adventure platform bukkit 4.4.1: https://pastebin.com/EHTdeVWB
AdventureMeta.java:257: this.logger.sendMessage(Component.text(msg));
you need to relocate adventure in your plugin
What for? Currently the lib gets downloaded by the server
conflicts with adventure that is bundled with the server
adventure-playform-bukkit is completely unnecessary when working with paper servers anyways
Is there any other way by not having to realocate the lib in my plugin? I can't deal with the size since we also need the Gson lib which together puts the plugins over 4.5mb
Trying to target paper, but older then 1.19.4
#adventure-platform-mod-help for any other questions with the legacy platform impls
paper has had adventure since 1.16.4
and anyways
Do those support gradients?
I am indeed using that
Unfortunately no, since gradients are just "syntactic sugar" over manually putting a color to each character
How do I make heads or any sprite using adventure
I see minimessage supporting it
cool
Is it possible to add something like https://jd.papermc.io/paper/1.21.11/io/papermc/paper/command/brigadier/MessageComponentSerializer.html to Velocity by copying the source code from the serializer and registering it? I do not know how to do the registering part and wasn't able to find any documentation about it.
declaration: package: io.papermc.paper.command.brigadier, interface: MessageComponentSerializer
declaration: package: com.velocitypowered.api.command, class: VelocityBrigadierMessage
Does minimessage have support for the Player Object component?
I think my need is different to head unless I'm mistaken
I'm basically looking for the minimessage equivalent of {"type":"object","object":"player",player:{name:"playername"},hat:true,color:"#010000",shadow_color:0}
should be the right thing, try and see
head gives me the flat head of my player, my thing returns (I think) a full skin
the head tag is the minimessage equivalent of the string you sent
Just did some testing and it's the colour giving me the skin image. It's some shader stuff with my resource pack (which I have no clue how it works 😅 ) I'm guessing I just use the minimessage head thing with the right colour hopefully, thank you
is there any documentation on how to format minimessage and use the new custom click actions? I tried looking on the docs, and couldnt find much about it, (also searching is a pain since it merges with all of other paper's docs and theres no distinction as to wat product the search results are from)
im guessing its something like this <click:custom:'namespace:key'> but how would i add a payload to this?
in this case it seems to have a key argument and a snbt one for the payload
so like <click:custom:'idk:whatever':'{"idk":"my payload"}'>
remember that that's the 5.x codebase, I think some of the click event types are less fully supported in MM in the released version
ah, you're right. In the main/4 branch, custom isn't supported since its payload type is custom and the method that MM uses only supports Payload.Text/TextCarrier type actions
well, it isn't supported by the built-in tag but you could still make a custom one for it
it special-cased changePage action whose payload type is int, I wonder why that wasn't the case for custom. I guess it just didn't make sense given that code was gonna be reworked anyway
custom click events are just newer so it didn't make it in time for the initial release
makes sense
here's a tag resolver for a custom click tag if you want: https://pastes.dev/YBBsfDdHmg
I mean, that tag is only useful for 4.x, in 5.x you'd just use the click tag
but yeah, should be fine without the serializable resolver stuff
Is it possible to disable the closing tags(</color>) on LegacyComponentSerializer when de-serializing from a String? Without manually replacing them?
what
I know its possible in the MM builder, like miniBuilder.strict(false);
what are you talking about in actual component structure
How to disable strict serializing with the LegacyComponentSerializer.Builder?
there's no such concept with legacy
Oh, well, then how to disable it when Serializing a Component back to a string?
you can't disable it, it is just how legacy generates components
Like I use miniMessage.serialize(legacySerializer.deserialize(String) to translate legacy colors into MM format, but how to prevent the serializer from adding the closing tags
you can't stop it from generating closing tags, since otherwise it'd be a different kind of tree
Didn't you answered yourself here?
&anode A &bnode B &rnode C legacy has no way to indicate that a node is a child of another one, unless you explicitly made a serializer which treated every node as a child of the other, but that wouldn't be how people expect legacy to be parsed
if you don't want the closing tags, you can just remove them after serializing, or make an encoder which acts in the way you want. Former is probably easier
is there a reason you don't like the closing tags though?
Yeah, well, I figured better ask if there was a built in way instead of manually replacing them out of the stringgs
non-strict will only emit tags when it needs to for the sake of maintaining the component structure
(or at least, I think that was the default behavior there)
it is, yeah
They break when a message is like &aGreen\n&cRed, where my code currently formats the colors before splitting the string into multiple lines, causing the <green> tag to appear in the first like, and </green> on the second
if this is for lore, recommendation is to not use new lines at all
if it comes from a config file, just use a string list instead
Well, Im not recoding thhat part. Manually replacing the closing tas it is! XD
newlines inside of components is generally asking for issues
it is fine on chat, just not anywhere else
I semi recall the behavior there being somewhat inconsistent
Yeah, I was already wondering why the serializer escapes the \n
yeah text manipulation of the mm output will cause trouble
it should be a trivial change, I would strongly recommend just doing it the right way
I also don't understand why you are going legacy -> MM -> Component
I think I understood your XY. And if you have a legacy component like §cThis is\na multi-line\ntext!, it's not a question of closing tag being there or not, it'll be a question of the color only applied to the 1st line
Im known to do things more difficult as it should. So we should be fine
its been 5 years of people being too lazy to implement proper componenr splitting
the PR is there, it just seems that it died to relevance
Since a string is easier to manupilate then a Component, especially replacing placeholders in it
could just work with the legacy string if you're doing that
or just drop legacy and use MM x)
I'll publish my PR as soon as 5.x is out (and also I have some time)
-# https://github.com/indyteo/adventure/tree/component-split
wouldn't it be better to get it shipped before 5.x is released
Then what, it needs to be parsed to MM either way, so if its before or while sending the message, it doesn't matter right?
why does it need to be parsed to MM at all
MiniMessage doesn't like legacy colors I noticed
I mean, mojang deprecated legacy colors a decade ago
Well, idk my idea was to wait until they have more time to review PRs, and also 5.x being stable so I don't have to change my code. If every "big" change of 5.x is done, I might do it
and legacy colors inside of components is stupidly inconsistent
Sure thing, I was just bringing the facts
Yeah, so they need to be parsed to MM to make MM even consider them, am I right?
its nothing to do with mm, it's just vanilla
Right...
MM treats them as invalid input, and there is no direct means of transforming legacy to MM due to the nature of the tree
many optuse attempts have been made and I guess they work for simple strings, but, we don't recommend or support such manipulation of legacy strings
Really, mojang deprecated them a decade ago and we recommend that plugin devs follow the rest of the ecosystem and move on too
I like backcompatibility or give users atleast the option to use it
Even if it makes my life a little harder
Well, I better get back to fixing this...
Are there any news regarding dialog support?
development happens on GH, anything that happens happens there
I think paper has its own dialog api for now
TextComponent settingsComponent = Component.text().build();
for (FarmerSetting setting : farmer.getFarmerSettings()) {
settingsComponent = settingsComponent.append(Component.text(setting.name()).clickEvent(ClickEvent.callback(e -> farmer.toggleSetting(setting))));
}
TagResolver settings = Placeholder.component("settings", settingsComponent);
How could I make the output like String.join(", ", list)
so it would be like Setting1, Setting2, Setting3
also this looks kinda ugly, there is probably a better way but im not aware of that
see Component.join
so smth like Component.join(JoinConfiguration.commas(true), components)
If you want the end user to be able to define the format for joining, check the Formatter.joining minimessage tag resolver
not really
I know but I wanna use dialogs in Velocity
Our current plans are focusing on the 5.x update and then we will start exploring things like dialog/waypoints api, especially now that they seem relatively stable
What does that have to do with Adventure?
looks like you're just not shading protocolib - see #build-tooling-help
Helloo, what's the best way to join components?
Is there a way through the TextComponent.Builder?
Normally I use Component.join()
But I have to make a Collection to use that
Is there a way in the builder to append new lines for example in between components?
what's wrong with Component.join? it also takes varargs
There is nothing wrong besides using a Collection instead of a builder
Just wondering if there was a better way
It does the job, I was just wondering hehe
you can use the method that doesn't take a collection 🤔
what are you looking for and how does the static join method not satisfy you?
I was looking for a JoinConfiguration or something similar on the component builder
Just out of comfort really
Because I normally use the Builder and I used to do .append("hello").appendNewLine().append("something").build()
It's fine tho, using Component.join is the best way I see
And doing gradients inside of a Component is possible?
I know with MiniMessage it is possible with <gradient>, but inside components?
there is no api for it, no, there was a pr but it was left unfinished iirc, though mostly done, you could just take a look at it and take whatever useful snippets you might find
kind of a scope creep pr imo instead of getting a basic api working first but w/e
🤣 thanks Emily!
why minimessage gradent with 3 color and 1 to -1 phase it don't make smoth animation (issu on ~4sec, ~8sec, ~12sec),
while 2 color work fine ? (big white number is the phase)
(this is what i mean by 2 color work)
which version
1st is 3 color <- my issu
2nd is 2 color
Version of adventure
4.25.0
Have you tried on latest (4.26.1)?
how could i ? paper is bundled with 4.25.0
component = component.replaceText(builder -> builder.match(matcher).replacement(
parse(player, keyword, decoration + prefix).append(parse(player, keyword, keyword.replacement())
.hoverEvent(HoverEvent.showText(parse(player, keyword, String.join("<newline>", keyword.descriptions()))))
).append(parse(player, keyword, suffix))
)
);
I'm now using this to replace the text matches regex, but how do I know the input text?
nvm figured out
Is it possible to cache the tree/structure of a component?
Usage being that I only have some specific placeholders that I want to be reparsed, so MM doesn't have to parse the rest.
Currently not, but that's something that had been discussed as a possible feature in the future
That reminds me, I should finally finish my adventure PRs
Add this to your PR list, I need it xD
do you
people have brought up wanting it however it hasn't been done simply because MM parsing is fast enough to just not bother
However on the technical side of things it's very well possible to do, so it's quite a valid thing to expose
The MM parser already parses it into a tree, the placeholders get handled only after the MM parsing step
valid I don't know, I have seen Kezz being rather opposed to the idea before
though if it comes down to just exposing a method to turn a Node.Root (or whatever it is that deserializeToTree returned) into a Component, then that's probably fine
It's technically pointless as it's fast anyways, but it's not a particularly intrusive change
Kezz indeed doesn't see a need, but isn't opposed to it being added
I've talked about it a while back
Never said it wasn't, but squeezing some extra performance by caching doesn't sound bad either lol
Yeah my opinion too
how can i append a child to a component, but make the result not inherit the styles from the parent?
these guys are making everyone bold
Children inherit style, you can't change that. But if you have, say, compA and compB, instead of compA.append(compB), you can write Component.empty().append(compA).append(compB)
(There are slightly more optimized ways to create an empty component from a set of children, but this is for you to get the idea)
Component.textOfChildren(...) is one optimized way to do so
thank you
exactly what i needed
Uhm what would be the best way to make an inserting tag that the content inside would not be parsed by custom tag resolvers, only default MM? For context, I am parsing a string with MM and custom tag resolvers, but I want to make a "blocker" tag, which an user can then use so that inside that tag, the content will not be parsed with the custom tagresolvers. It's mainly to avoid people using tags they aren't supposed to.
Not entirely sure if I understand you correctly but I think what you are looking for is Placeholder#unparsed
that sounds like a weird requirement
usually when it comes down to not letting users use tags they're not meant to, you just build a MiniMessage instance with the tags they can use
interestingly, the Context#deserialize methods which take a TagResolver seems to combine the Context's TagResolver with the one you pass, so you can't really use that
you'd have to make a MiniMessage instance that you use separatedly and deserialize the MM with that
Yeah this ^
So whatever is inside the tag, I'd use a different MM instance?
well, since I am using this in packets, changing placeholders in items for example, there is no way to know if the item name was edited by a player or by a plugin, so I am trying to prevent abuse, like players adding the placeholders themselves when they are not allowed.
yeah see this is why it's best to do stuff not at a packet level haha
if you just have an arbitrary string then it's not at all possible to differentiate between user and plugin generated text
well the whole concept of the plugin cannot be done without packets xD
exactly why I want to create a tag where server owners can block any parsing of such
yeah we had that in mm years ago but it just doesn't work
bc what's stopping the player from just closing the tag
Well, in that case, what are the options? a self closing tag which takes text as param which would be the "restricted" part?
what if they just <pre:" at the end
the only option is a single tag that prevents parsing for the entire rest of the string without being closed really
it's why we removed this kind of tag from mm years ago, it just doesn't work
FYI context would be that in a chat plugin for ex. it would be pre:"%msg%" or whatever
well that also works tbf
how would that be implemented though?
inserting and self closing tags wouldn't work
modifying probably
you might find it easier to fork mm and add a custom parser directive tag ig
yepp
🍴
by this you meant a modifying tag or modifying MM?
modifying tag yea
Wait couldn't I simply use escapeTags on the input? Or would that also escape the "default" MM tags?
escape tags will escape any tags known to that minimessage instance
I see, one of the kinda solutions I found was to simply get the string, split it at <restricted> and simply use a diff. instance for the second half
that should work fine
Running into this again now, is there any existing way to do this? Would a PR be accepted (and if so, should it be the default or an additional option)?
Because currently, saving a list and then loading it can give a different list (it wraps it on saving and doesn't unwrap on loading)
And e.g. Mojang's implementation seems to unwrap on loading by default
Does anyone know when strikethrough works with spaces and when it doesn't
I have it sometimes working and others not
FRChat.getServerColorGradient(" ").decorate(TextDecoration.STRIKETHROUGH) shouldn't this work as a long dash line?
It might get trimmed, i.e. all heading and trailing white-spaces being removed, which is, in your case, your whole string. So you might need to add a non-white-space at the beginning and/or at the end. I think that a simple dash - should go "under" the strike-through, making it unnoticeable
I will try that, I didn't know there was an auto trim there
That was it indeed! Sadly coloring doesn't affect the strike line XD
Do you guys know of any character wide enough to look like a full line?
You mean something like that: ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯? ⎯
it doesn't really matter, just strike through a - or smth
Strikethrought is not colored tho
Yeah like that
But does it look like that on minecraft? XD
I did the mix and it worked, thanks guys 🙂 I did the dashes + strikethrough
yeah it is
it's coloured whatever the text colour is
Hey is there a way to convert the Adventure Component to a minecraft Component
iirc there are static methods in the internal PaperAdventure class
what exactly is strict() in MM?
javadocs only say it puts it in strict mode
what does that do
I understand ya'll do this on your free time and all obviously, and I don't want to be annoying and rush you to reply, but I brought this up for the first time months ago, and would appreciate it if anyone from the team could weigh in if you've got time - unless I'm doing something wrong, this seems like a pretty major issue...
Here is example code to replicate this problem: https://pastes.dev/DtYWadXEDv
Which results in this:
[13:54:24 INFO]: [Plugin]
API Data: BinaryTagType[CompoundBinaryTag 10]{tags={"list"=BinaryTagType[ListBinaryTag 9]{tags=[BinaryTagType[IntBinaryTag 3 (numeric)]{value=5}, BinaryTagType[StringBinaryTag 8]{value="hello"}], type=BinaryTagType[BinaryTag 127]}}}
Post Write: BinaryTagType[CompoundBinaryTag 10]{tags={"list"=BinaryTagType[ListBinaryTag 9]{tags=[BinaryTagType[CompoundBinaryTag 10]{tags={""=BinaryTagType[IntBinaryTag 3 (numeric)]{value=5}}}, BinaryTagType[CompoundBinaryTag 10]{tags={""=BinaryTagType[StringBinaryTag 8]{value="hello"}}}], type=BinaryTagType[CompoundBinaryTag 10]}}}
[13:54:24 INFO]: [Plugin]
NMS Data: {list:[5,"hello"]}
Post Write: {list:[5,"hello"]}
I'm happy to work on a fix & PR myself, just want to know what's going on with this first and how you'd want it handled/fixed
I'm not really sure what the issue is?
NBT Lists with multiple types are wrapped on save ([1, "t"] -> [{"":1}, {"":"t"}]).
For the NMS part, Mojang wraps them on save and then unwraps them when loading, resulting in the same list as expected.
But Adventure NBT only wraps them on save, which means that when reading you basically get a completely different list; ListBinaryTag#unwrapHeterogeneity does exist, but it's not called automatically, and for a deep nested compound with lists inside it it can be very annoying (and sometimes expensive) to handle, as you have to basically recreate the entire thing due to the immutability.
I believe that part of the general expectation over this stuff is that it should follow vanilla behaviors
Yeah that's what made sense to me as well, just wanted to get confirmation before PRing anything into list loading logic
public void onChat(@NonNull AsyncChatEvent event) {
var prefix = TagResolver.resolver("prefix", (args, ctx) -> Tag.inserting(getPrefix(event.getPlayer())));
event.renderer(ChatRenderer.viewerUnaware((player, playerDisplayName, message) -> {
return
MiniMessage.miniMessage()
.deserialize("<prefix> <name></prefix> <dark_gray>» <gray><message>",
prefix,
Placeholder.parsed("name", player.getName()),
Placeholder.component("message", message));
}));
}
final Component getPrefix(Player player) {
LuckPerms lp = LuckPermsProvider.get();
PlayerAdapter<Player> adapter = lp.getPlayerAdapter(Player.class);
CachedMetaData metaData = adapter.getMetaData(player);
String prefix = metaData.getPrefix();
return MiniMessage.miniMessage().deserialize(prefix);
}```
why doesnt my color of my prefix continue over to my username
actually, do you want the username to also be a gradient or just the last color of the prefix's gradient (purple)?
just to continue so your username is the last color of your prefix
hm, wonder if one could just use LinearComponents thing for that
@EventHandler
public void onChat(@NonNull AsyncChatEvent event) {
var prefix = getPrefix(event.getPlayer());
event.renderer(ChatRenderer.viewerUnaware((player, playerDisplayName, message) -> {
return Component.textOfChildren(LinearComponents.linear(prefix, playerDisplayName), Component.text(" » ", NamedTextColor.DARK_GRAY), message);
}));
}
public Component getPrefix(Player player) {
LuckPerms lp = LuckPermsProvider.get();
PlayerAdapter<Player> adapter = lp.getPlayerAdapter(Player.class);
CachedMetaData metaData = adapter.getMetaData(player);
String prefix = metaData.getPrefix();
return MiniMessage.miniMessage().deserialize(prefix);
}
can you try this
scrapped the whole MiniMessage stuff since it made the whole thing more confusing than it needed to be, unless you're gonna put the format string into a config it isn't necessary anyway
alr to back to normal components
welp i dont think there is lot more we can do now it dont work
well, if anything you can do this:
@EventHandler
public void onChat(@NonNull AsyncChatEvent event) {
var prefix = getPrefix(event.getPlayer());
var style = prefix.children().getLast().style();
event.renderer(ChatRenderer.viewerUnaware((player, playerDisplayName, message) -> {
return Component.textOfChildren(prefix, playerDisplayName.style(style), Component.text(" » ", NamedTextColor.DARK_GRAY), message);
}));
}
I don't find it to be particularly clean but that's probably the only thing that's gonna work properly lol
I also don't know whether it'd be better to use mergeStyle or applyFallbackStyle
ima just try that
if that dont work
ima go sleep
its like 1 am already
it works
...
now i can go sleep gn
<hover:show_item:diamond_helmet:1:{"minecraft:enchantments":{"minecraft:aqua_affinity":1}}> this mm tag doesn't work, am I wrong?
You’d need to test but fairly sure that’s invalid
yep it output just default diamond helmet
Oh, the layout is correct, idk about the tag though,
it's wrong maybe but I don't think it's wrong SNBT format afaik lol
try putting the tag argument in-between single quotes (')
it doesn't seem to be working
oh is docs outdated?
then how should I use it?
from that code, an example of it would be <hover:show_item:'diamond_sword':1:'minecraft:enchantments':'{"minecraft:sharpness":5,"minecraft:looting":3}'>
for what's worth, you can just serialize a component into MM to get what it'd look like, i.e.:
var item = ItemStack.of(Material.DIAMOND_SWORD);
item.addEnchantment(Enchantment.SHARPNESS, 5);
item.addEnchantment(Enchantment.LOOTING, 3);
MiniMessage.miniMessage().serialize(Component.text("Something").hoverEvent(item));
// returns <hover:show_item:diamond_sword:3:enchantments:'{"minecraft:looting":3,"minecraft:sharpness":5}'>Something
Hi - is there a non-deprecated version of player.sendTitle(); e.g. with components?
That'd be player.showTitle()
-# See JavaDocs link below this message
Got it, thank you!
is there any (hacky works for me) adventure implementation for hytale?
and how complicated would it be to implement one myself
Somebody at work tossed one together, not public though
I think somebody in this discord also tossed one togther too somewhere, you'd need to search
will do
I think I went through like 2k messages at this point I don't think there is
is text in hytale even remotely similar to components in minecraft
they mostly use json for everything so I assume it is in some sense, though I am sure they have a different set of features for things like click and hover events
Both using json just means they both can have properties 🤔
features? in hytale? lol
you cant even have colored name tags
but yeah, I do want an adapter for it eventually, its on my list
for MM
its #4 on my shit I wanna do list rn ^^
i glanced at it and it looked like it was fairly componenty, and somebody at work said the same and said they could probably get adventure working for it
I thought somebody had posted one in a channel somewhere on here but, idk, discord search is useless and my memory is tragic
I did saw somebody using minimessage in hytale already, ye
you just need to translateadventures component class to hytales message class
I mean, as long as they figure out a component serializer for whatever hytale uses, it works fine
and I think they only did color
I use a lot of TranslatableComponents, I wonder if those will be able to be used
might require to expose the Plugin/Server methods to give own logic to handle choosing Locale
if you use translatable components for server-side translations, all it'd take is rendering the translations before converting it to hytale in the hytale component serializer
Maybe there's no way to actually get them in "vanilla", but when exploring the player data files we can see this:
"DisplayName": {
"DisplayName": {
"RawText": "indyteo",
"Bold": null,
"Italic": null,
"Monospace": null,
"Underline": null
}
}
Which suggests that some styling is intented to be supported
I guess it's still work in progress then
Or maybe they tried with the display name then scraped the idea idk
Either way, considering the early state of all this, I wouldn't invest much time to this 😅
people still need to remember that it's just an unfinished early access and the game has a lot of development ahead still
Can someone give an example of using a sprite with adventure not minimessage? It's a new feature so it's hard to find any public plugins that do this
final Component component = Component.object(ObjectContents.sprite(
Key.key("items:item/diamond")
));
That's the Adventure™ way of working with object components
those are drawn from whatever resource packs the client has
so for vanilla items you can look into the builtin resource pack
And if you want to automatically get the best (which may be subjective, but well, at least one) sprite for a given item, I’ve made mappings from Paper Material to sprites components
player:levelForXp
or
player:level_for_xp
or
player:level-for-xp
What is dev recommend
_ seems to be what vanilla uses these days
thx!
Is it possible to use Adventure to set the name or lore of the Component type for an ItemStack while only introducing the Spigot dependency?
Or any another way?
convert the Component to BaseComponent using gson
thx
@boreal orchid is Component.object a 21.11 thing?
working in .8 and don't see it in adventure
it was introduced in 1.21.9 I think
Hello, I'm working on a special anvil GUI that allows players to rename items using MiniMessage formatting codes. Currently I just deserialise the rename text and apply it to the resulting item, but I want there to be limits, i.e. I only want to allow colour codes, and some formatting codes, like <bold> and <italic>, but I don't want to allow things like <newline>. What would be the best way of doing this?
Create your own MiniMessage instance with only the tag resolvers you want/need
ty!
also, is there an equivalent to String#isBlank for components?
or would I need to serialise it to plain text and call isBlank on the resulting string?
There's not, because some components are dynamic (score, NBT...) and cannot be determined whether they're blank or not. However, in your case, since you filter which components are allowed, you know you only have text components, so yeah either plain text serialize and check if the result isBlank, or traverse the tree yourself and cast each component to TextComponent, and check if the content isBlank
How do I do this? Are there docs/examples I can refer to?
the way I currently get my instance is simply with MiniMessage.miniMessage(). I can't immediately see other methods that allow me to specify tag resolvers or something
MiniMessage.builder()
Is there a way I can include a literal <red> tag (for example) in a string and have it not be parsed by MiniMessage? I'm writing an in-game book as a reference for MM tags that players can use
I plan on the book just being a string list in a yml file, and each line will be deserialised
escape it with a \
Is there a way I can have tag aliases in my MiniMessage instance? For example, I could have a <grad> tag that works exactly the same as <gradient>? I'm allowing MM tags to be parsed in a special anvil GUI, and the character limit of anvil GUIs is proving to be a problem, so I want to create shortened versions of all the tags I can if possible
you can simply register a custom tag resolver with the alias
myMMBuilder.editTags(builder -> builder.tag("grad", (args, ctx) -> StandardTags.gradient().resolve("gradient", args, ctx))
I'll give it a try thank you!