#adventure-help
1 messages · Page 13 of 1
why is that?
looking at the code, it only seems to check for virtual components. Everything else is ignored, what a bummer
seems like I gotta make my own MiniMessageTranslator
nvm, it was user error. The translations still used %s instead of arg:0
Hi @gray tundra do you have a question about using adventure?
I need something to help me
When I go to sa specific location or I rtp and when I log out I just go back to sever spawn
you seem to be lost, no idea how that's related to adventure
But does anyone know how to fix it?
Obviously no, we can't help you about something specific to a server like this. You need to get in touch with the support of the server you're playing on. Here it is a tech support dedicated to the "adventure" Java library
Hello, if I use MiniMessage to deserialize text, does that not support click or hover events?
For example I do this
Component test = MiniMessage.miniMessage().deserialize("<hover:show_text:'<red>test test'>TEST</hover>");
// public BukkitAudiences adventure;
adventure.player(player).sendMessage(test);
I receive the text but there's no hover text. The same if I try click links
MM supports hover events just fine
the legacy bukkit platform might have issues -- you don't need that when building a plugin for Paper servers
yeah I included MiniMessage so it works on non paper servers as well
any idea why it's not working tho?
also it's shouldn't be using legacy, I included the latest versions
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.26.1</version>
<scope>compile</scope>
</dependency>```
BukkitAudiences
that's legacy
Our recommendation for projects in the Bukkit ecosystem is to only support Paper servers, they're like 90+% of users anyways
looking thru the docs now but do you know offhand the non-legacy version of BukkitAudiences?
Paper
adventure-platform-bukkit is a legacy library, it's only getting community support at this point
OfflinePlayer implements PlayerHeadObjectContents.SkinSource but it doesn't actually work for ObjectComponents if the player is offline. It just renders as a steve/alex head. Is there some simple workaround to get the client to resolve the player's skin, or should I just cache the ProfileProperty texture (or whatever it's called) in a database?
until that PR is merged, you should just manually build a resolvable profile to the offline player's name OR uuid for it to work properly
Is there a way to implement animated components seamlessly
I looked at virtual components but couldn't figure out how they work
Something for a sidebar or action bar, that ticks every 50ms
just send a new component every tick?
Hey, I saw these tags/badges in the server list. (So without resource packs)
Now I wonder with which type of component is this possible? I thought about heads, but I guess that would be a bit inconvenient for texts.
If you don't have any resource pack to have a custom font, then yes custom heads are the only option left. But Mojang removed this in the latest snapshots for the upcoming update
So are those servers currently using heads for this to display and it'll break next version?
Yes and yes. Which sadly makes it probably not worth it because folks won't be seeing it if running latest MC in a few days
(of course you have their IP, it was poorly worded my bad)
Alright, thanks for this information.
Just looked in 26.1-rc2 myself and sadly its breaking.
Is there any confirmed release date for adventure 5.0? Is it planned for paper 26.1 or will it still support 4.x?
Found this, but it doesn't really confirm it. #adventure-help message
Moved this to #paper-dev message
hello, i want to report a bug.
Minimessage is not able to replace a date tag inside hover events.
<hover:show_text:'<yellow>\uD83D\uDC65</yellow> Genutzt: <gray><uses>/<max_uses></gray>" + "<newline><yellow>⌛</yellow> Läuft ab: <gray><expires:dd.MM.yyyy HH:mm></gray>'><code></hover>
<expires:'dd.MM.yyyy HH:mm'> the mm (Minutes) are not parsed
I think it has something to do with:
fixed by escaping the '
hey how do i fix that the message is not deserialized?
it just sends the raw json code in chat
i use sender.sendMessage(mm.deserialize(...))
Which API's sendMessage?
what is your input?
apologies for late reply, its from net.kyori.adventure.audience.Audience
Then abby's question's gonna be the important one.
hmm
if (args.length != 1) {
String usageKey = isTpaHere ? "tpahere_usage" : "tpa_usage";
sender.sendMessage(mm.deserialize(this.configManager.formatMessage(this.configManager.getMessage(usageKey), "player", sender.getName())));
return true;
oh, also, you said json code, not minimessag code? Is that correct? You fed the minimessage deserializer json?
that plugin uses legacy colors originally, and i switched to minimessage
no
it sends raw json component in chat
Throw in a print to log of the same message (result of formatMessage) I guess
though what's a formatmessage method doing feeding into minimessage deserialize?
its just this
public String formatMessage(String message, String placeholder, String value) {
return this.getPrefix() + message.replace("{" + placeholder + "}", value);
}
You know minimessage has a whole placeholdering system that users are already familiar with, right?
But, anyway, back to this comment: #adventure-help message
i havent used it lol
it has no console log
ill send what happened
You added a logging statement to your code and it doens't print to log? You have bigger problems than adventure
no i didnt
its tpa plugin, no logging needed
Is that your input? That's not minimessage. That's a class being toString'ed.
As for not adding logging, I explicitly said to do so for testing. But since you're now showing this output, that's informative. You're toStringing it.
hmm
Figure it out?
yeah ty
I forgot to tell lol
string + component breaks it
well, yes, +ing with Strings will implicitly call toString on the other object, and Component#toString() produces an info debug output yes
exactly
does adventure have some Gson helpers to easily dump data in chat?
e.g. something to make this easier on the eyes (my /dumpitem command)
Paper has its own item dumper command
/paper dumpitem
that said, I don't think it is much different to that output
oh i could steal it's syntax highlighting good idea
Is there a way I could use § just as a character or escape it somehow without it saying its legacy formatting
That throws only if you use an actual legacy color code.
We use that symbol like a section sign
so §3 means Section 3
I see
Well you could alternatively make a placeholder instead of this symbol and then use replaceText method on the component
Or just use your own tag
there's a chance the client might still interpret that as a color code, even inside of a component
Its worth a shot
that warning should be off by default
does this happen in your test server? Because jmp's run-task gradle plugin enables that warning for its runServer task
No I don't think it's off by default
From my experience it is on
But I haven't checked the code in ages
(Unless you said in is not the case but that it should be changed to be the case, then idk)
Btw he's not talking about the warning, I just realized
It's the MM throwing
isn't that the same thing?
MM has its own thing which can't be disabled
then there is a standard component warning thing for malformed legacy usage
why does MM even have its own thing given that adventure has a warning at the component level anyway
MM throws ParsingException
In 99.9% of the case, when the legacy symbol is found, that's because of an error, so it is good to have it fail I think. In that case, @copper oriole I think you should just switch to something like §.3 or so, to denote paragraph no. 3... But may I ask, are you not using that in a Minecraft context? Because MC client doesn't render the § symbol anyway
In a dialog I have it featured yeah
But have you tested that the in-game dialog renders it correctly?
still like this 😭
You have concatenated multiple components together
With + between their String representation
You can clearly see the concatenation on middle of the fourth line
oh
...children=[]}]}TextComponentImpl{...
use the append method for appending components together
ill just turn everythibg into a component
yes
Yes, when working with components, you should prohibit Strings as they are just source of confusion and bugs
yeah im just kinda new to adventure api
i successfully retired from chatcolor lol
how can I convert strings that contain legacy &0-9/a-f color codes to components?
legacy component serializer
Hi, why can't Components accept null values and convert them to strings like String.valueOf() does?
Because using Component.text(String.valueOf()) for security quickly becomes repetitive.
Why would you want to pass null?
For safety reasons, I have many components and I don't want to get an error because one of them is null; I prefer to display null rather than return an error.
because null is not "null"
Thank you for clarifying...
but like, you should be validating your data, not just silently passing garbage
or at least Objects.requireNonNullElse
Components are supposed to be rendered, and unless you are logging debugging data, rendering null to a user sounds weird
often enough people will go out of their way to localize null to "none" or "N/A" if not outright send something completely different
Yes, but I mean, it's very repetitive, e.g., Component.text(Objects.requireNonNullElse(playerOffline.getName())).
I meant, if I don't know, the adventure is so big, maybe there's a NullableComponent or something.
You could look into ComponentLike and just extract that logic into whatever your playerOffline type is
like if your issue is "im writing the same code over and over again" the solution is to extract that logic into a util function somewhere
the solution isn't adjusting the library design to be worse
I see, but it's quite disturbing and adding a component type, I don't see how that would degrade the library, but whatever.
you could probably PR to Paper a name() method for OfflinePlayer that returns a Component (for parity with Player in a sense), though it'd still be nullable given that you can have an OfflinePlayer object without a name
player.getName was one example among many.
Increasing the surface area of the API to prevent a simple null check just isn't worth it. We have to consider complexity, maintenance, ease of use, etc. Even something as simple as "adding a null-friendly constructor" would introduce additional complexity and the possibility of unexpected behaviour.
i see
in a few places i have code that works around this with ComponentLike, here's a simple example
class MyPlayerObject : ComponentLike {
val username: String?
override fun asComponent(): Component {
return Component.text(this.username ?: "unknown")
}
}
Mais oui, passer player.getName() dans un composant serait parfait (ainsi que OfflinePlayer).
Je peux voir afin de faire une PR mais je veux dire que mon problème ne sera pas réglé des demain ahah xD
oups
baguette
Yes, passing player.getName() in a component would be perfect (as would OfflinePlayer).
I can look into making a pull request, but I mean, my problem won't be fixed tomorrow, haha xD
🤡
I was specifically talking about that case because I realized there was an opportunity for API parity, but yes, it won't solve your problem. Though I don't think you often encounter places where you are manually turning nullable strings into components
or at least I haven't found myself doing that, maybe the null checks were something I just did so I forgot the places where I did
tbf i do it very regularly with offline player usernames, but i don't have as much of a problem with that as kotlin's elvis operator makes that v easy
so i do understand the problem
It's true that I'm looking into it, and the IDE tells me that the null warning often comes from the .getName functions of Player and OfflinePlayer.
I'm going to try to submit a PR, but I never really know how to contribute haha (I'll figure it out after checking if someone hasn't already done it)
Imo, you need to consider why you could get null in the first place. As outlined previously, there isn't a single way to handle a null. Maybe in your case Component.text("null") might be ok, but in most case another text should be used. So I think you should end up with something either like Component.text(Object.requireNonNullElse(offlinePlayer.getName(), "Joueur inconnu")) (i.e. a fallback text), or even a completely other component when it is null (for example to show instead the UUID in italic red styling). So would really benefit from having, as Kezz suggested, a util method somewhere like this:
public static Component offlinePlayerName(OfflinePlayer offlinePlayer) {
String name = offlinePlayer.getName();
return name == null ? /* your fallback here */ : Component.text(name);
}
I'll be as easy to use as Component.text(offlinePlayer.getName()), it'll just be instead Utils.offlinePlayerName(offlinePlayer) that's it
I really need to use ComponentLike so much more often, that looks really useful lmao
I say more often, but in reality I have never used it a single time
Correction: I should start using it, that looks really useful lmao
-# like the paper api smh :P
You do realize I meant in my own code, right
Yes
As in making my classes implement it
Making the transition from getName to a component seems complicated to me, there are so many things that would need to be changed.
And I'm talking about paper taking in component rather than componentlike (though there are reasons why that's the case at least sometimes)
i mostly like it in component joining, here's an example from some code im near atm
listOf(
userProfile,
Component.text(" is currently ", AQUA),
onlineStatus,
Component.text(".", AQUA),
).join().let(player::sendMessage)
Why not just use ```kts
player.sendMessage(Component.textOfChildren(
userProfile,
Component.text(" is currently ", AQUA),
onlineStatus,
Component.text(".", AQUA)
))
The list joining seems obsolete?
because i hate textOfChildren
Why 
it was added against my will and i refuse to use it out of love for the joining api
that works well with kotlin but join API would be very verbose for that use case in java lol
Yeah I was also about to ask, how does that look in Java
player.sendMessage(Component.join(JoinConfiguration.noSeparators(),
userProfile,
Component.text(" is currently ", AQUA),
onlineStatus,
Component.text(".", AQUA)));
Is that really the same code?
didn't need the List.of since there's an overload with a varargs
Your parentheses placement is making me go insane
as always 😛
Yeah I don't think I have ever seen a single code block from you which makes me go "this code is nice to look at"

Adventure doesn't have a Player class, does it? Is this about Paper's API?
I mean its ComponentLike discussion from what I understand
a while ago I saw someone made a thing allowing you to input base64 and and send a sprite player head in chat textured via that base64 via their own thing but I can't seem to find it anymore does anyone know where that msg is? (it was in this chat )
ty
Is this how Codec<> is meant to be used? It seems so weird, all this work just to convert between object and stored nbt as a file
PlayerPersistenceService.java by @patent fable: https://pastes.dev/S2xXpT4Z3O
BinaryPersistenceService.java by @patent fable: https://pastes.dev/30ISq2j6r7
PlayerData.java by @patent fable: https://pastes.dev/mbPpycY8aZ
what are you trying to do? just turn snbt <-> nbt?
right so you're just going nbt <-> object right?
yes
so just BinaryTagIO.writer/reader ?
yea
so what's the issue? it's like 1 loc to read/write
I'm just asking if this is how I'm meant to use the Codec class
i mean not really
Then what alternative should I use
it's not a replacement for e.g. dfu codec
yeah but dfu is based on nms right
not adventure
then I have to convert every time
dfu is nms
I don't mind using it but I mind the datatypes being nms
converting every time is basically what you're doing with those codecs, like yeah sure you can do that that's fine
or you can use codecs like vanilla does
i feel like you might be better off just using a proper serialization framework/library/format
Do you have a suggestion, I kind of dislike NBTAPI
only one i know of is kotlinx.serialization has an nbt library
but like, you can just use anything - find yourself a nice clean json library or smth
you don't have to use nbt - it's effectively a proprietary format so you're gonna have a better time using something proper like json or protobuf or sqlite or anything
I generally always liked nbt tho
Are codecs not coming to adventure, like in the way I try to use them
or the way the work in nms
then you're gonna have to deal with the fact there are basically zero good libraries for it
we'll likely have a dfu library yeah, but it won't be a codec clone just working with dfu codecs
I don't think that's a question that can be answered now
I haven't tested it, but I am working quite a lot with the Jackson Java library (through the YAML dataformat), but after a quick Google search, it seems someone made a NBT dataformat for it
It seems to be for kotlin tho
No, Jackson is for Java
did you even read the readme example haha
(but I guess it can work with Kotlin as well, I'm not using Kotlin)
That's lwk strange since the whole thing is coded in kotlin
I didn't know you can mix methods like that
I thought they could just run alongside on the jvm
kotlin just compiles to the same old bytecode as anything else
and like not ineract
this is the lib i was talking about https://github.com/BenWoodworth/knbt
Kotlin is just a JVM language, it can be called by Java code (kind of)
yeah I know I just wasn't aware jvm based languages could "talk" to each other aside from running on the same runtime
That's the whole point of running on the same runtime
right but how does the java compiler track kotlin methods just seems weird that they have to account for the kotlin language, also what is like the order how is that based, since a kotlin class might require a java method and the java class might require a kotlin method so which gets compiled first
But if you never worked with Jackson, you might either want to give it a try to discover/learn that library (outside of NBT/Minecraft context), or just use something else, since it's a big big library, widely used, but not the easiest to use for a beginner I'd say
i mean when stuff is compiled doesn't matter - a method in bytecode is the same method whether it was written in java, scala, kotlin, etc
leaning into #general territory now tho
Right but how can a java class try to use a non-yet-compiled kotkin method
in what world are you depending on something that hasn't been compiled
Kotlin source code is compiled by a Kotlin compiler into JVM bytecode, and Java source code is compiled by a Java compiler into JVM bytecode. Everything is JVM bytecode at the end, and the JVM is not aware of which source code was used to get that bytecode
if you are depending on a library that library was compiled
Before compiling your App, the Library was already compiled
How can I achieve style leakage with components?
I want to inject a color key using #replaceText (color is a string converted by my coloring parser string->component). However adventure "isolates" it making the only colored part the thing I've injected, not stuff after even with reset styling.
Are you talking about legacy color codes?
using minedown with certain things changed but essentially minedown format string to component
and what i'm injecting into is a system message (component)
I don't know Minedown, can you provide an example?
it's a placeholder system
&#rrggbb&text
Why not using MiniMessage?
preference mainly due to the markdown-like format and simplicity (in-built hover etc.)
and backwards support for legacy &f, &b etc.
But is Minedown supposed to be used with adventure components or not?
what i wanna achieve is injecting component in the middle of another component overriding styling past injection point if none is defined
yes, its made for adventure
im using the adventure artifact
And since Minedown is a placeholder system, doesn't it have a built-in way to do that?
no, minedown is a color parser like minimessage
placeholder system is what im making
If you need to have Minedown process the whole string at the end, maybe you should work with strings and not components for your placeholders?
my input is components (thats what packetevents returns for SYSTEM_MESSAGE)
but converting to string (with coloring preserved) would be a good solution, just how?
Idk, you said that Minedown was designed to work with adventure components, so they must have a serializer?
i don't think it has component->string unfortunately
actually...
lemme try something
it has a #stringify method, perfect
appreciate your help
Paper 26 release date?
every time someone asks, the release date gets delayed by 3 months
And it doubles when asked in the #adventure-help channel 😄
multiplied by square of pi when asked in #docs-website
Hello, Component.text() isn't able to resolve minimessage tags right?
No, MiniMessage is a completely own serializer doing String to/from Component conversion. Components themselves don't even know MiniMessage exists
You could almost view MiniMessage as a separate project to the main Adventure API (it basically is)
mmm maybe is ViaVersion, but in Paper 1.21.11-127 I have a strange situation
im trying without viaversion now to see if its that
You are now talking about two different things. Mind saying what you are attempting to do and what is instead happening?
I use Component.text() to componentize a chat input.
To replace this chat input while using Minimessage for example to apply a format
%player% -> <message>
I use Placeholder.component(Component), this way it wont parse untrusted tags
But it seems in 1.21.11 these tags are being resolved. I always did my tests locally in 1.21.8 without viaversion
The tags which actually get resolved depend on the MiniMessage instance and any additional tag resolvers you add to the deserialize method
So you would need to also remove any untrusted tags from the MiniMessage instance you are using
I cannot explain to you why it worked for you in 1.21.8, but MiniMessage (de)serialization is an entirely server-side process which mostly shouldn't be affected by server or client version
it is still working without viaversion, I am trying back in 1.21.8 and explain better the pipeline
mm this is the pipeline
- Component.text(String), the String is obtained by PLAIN serializer on the chat message
- In the moment it needs to be formatted
I have a minimessage instance
the format goes to this minimessage instance, in which I pass the TagResolver which contains the Placeholder.component("message", component)
Okay sure, that's how chat formatting is typically implemented
And what is your problem?
oh I know have a better picture
if user type some minimessage tags like "<red>hello" its not get parsed
but
if he types newline
<gold><newline><newline><b>REWARDS</b></gold><newline><newline><newline>Get Ur playtime reward !<newline><aqua>GET UR KEY <yellow><b><click:run_command:/pay Cawv 1 >→ <u>Click Here<newline>
this get parsed
Huh. Could you send a concrete code snipped?
Preferably to https://pastes.dev ?
No, I understand your problem now, but I cannot really understand how the top one doesn't work whilst the second one does
So you are probably doing something wrong with the component inserting after all
Are you sure that you are using Placeholder.component and not Placeholder.parsed?
yep
Im making now a mini plugin to test it
in order to give a snippet
can we move this chat in a private ticket?
Why not just copy the code from your current code
an cancel everything above?
No, this is public support
allright
to ensure its not my fault mostly
cause code is long
yes its my fault, I replicate the pipeline and I don't have the same issue, so its my fault
sorry for the ping lol
Is there any interface or smth that would contain the player name?
In adventure? From... An audience?
What platform are you using adventure with?
none
im doing a common lib for skins so I need to get the username and since paper & velocity all should support adventure and since it got like everything abstract theres no way there isnt a way to get the username right???
i can get the uuid(from Identity) but i cant get the username
audience#pointers()#get with https://jd.advntr.dev/api/4.26.1/net/kyori/adventure/identity/Identity.html#NAME
danke
it would be nice to have documentation about the new hover event show_item format
format?
it used to be SNBT hover:show_item:<id>:<optional count>:<snbt> but it's now hover:show_item:<id>:<optional count>:<data component key 1>:<data component value 1>:<data component key 2>:<data component value 2>:<...>>
That is a adventure 5.0.0 change which hasn't been released yet
I see Kezz hasn't updated the tag in Adventure 5.0 docs PR however, if you want you can comment on it to let them know
it looks like it's already present in 4.26.1 as well
5.0.0 drops support for SNBT and 4.26.1 supports both
sure :)
Hey, can I somehow get the initial input out of an TextComponent?
For example:
final String TEXT = "<greeen><bold>Test</bold></green>";
final Component component = MiniMessage.miniMessage().deserialize(TEXT);
How would I get TEXT back from the component? The PlainTextComponentSerializer strips the color codes...
minimessage is a serializer too 🙂
it might not be exactly the same, but visually the same
Ah, makes sense... Should have found that one myself 😑 Thank you very much, I appreciate it! 🙏
Hey! The message in Paper's AsyncChatEvent is an Adventure Component. If I'd like to add some replacements/placeholders to the chat, e.g. to replace [pos] with another Component containing player's position, what's the proper way to do that?
I think people just don't do that anymore? Given it messes with signed messages
The first step would be to serialize the message component as plain text. Luckily, players don't type in components, otherwise it would be a bit awkward. You now have a string. You should then replace your placeholder [pos] into a minimessage tag format <pos>, so that they can be parsed by MiniMessage. You can then use a very minimal MiniMessage serializer instance with only your custom components added using Placeholder.component. Make sure your MiniMessage instance has no standard tags, otherwise people will be able to write in color and whatnot. After that, serialize the replaced string message with your mm instance and you have the parsed component you can just set as the message again
does that not break the chat chain
I don't know a whole lot of people who care anyways
I consider chat signing a "nice to have", not something you need to support at all costs
So players can't be reported
Yeah, it it was a public plugin maybe it would be worth considering, but it's only for myself
If it breaks when you have a nice chat format idea, well, whatever
i mean you can also just use Component#replaceText but whatevs
yeah but that's sucky when you have more than one placeholder
For plain text, sure, but not if you want to insert a component
? you provide a component
You can replace by a component
Ah that's cool
maybe i'm missing something but keeping a huge map of 100 mappings from placeholder to replacement is no different than keeping a huge set of 100 minimessage tag resolvers
Set is cooler 
I guess with chat specifically you don't really have to care about component children unless another plugin was modifying message as well
Someone knows why my h tag is not being resolved?
hResolver.build()
unrelated but you can just use Placeholder.styling("h", TextColor...)
what is message ?
Just a string
Thanks, looks a bit nicer now
I mean, the source of "just a string" is generally important
if you're deserialising a component with MM, it will escape the text contents so they're not just blindly parsed
Ohh, whoops that was the problem.
Thanks haha
hey this is a bit of a silly question but Key#key warns me for unsubstituted expression, there are ways to make sure I'm providing a valid key whether via Key#parseable or by catching InvalidKeyExceptions, but outside suppressing the PatternValidation warning is there any other way to safely parse a key without having to deal with IDE warnings?
you can just ignore the IDE warning, it only shows up in the IDE anyway
you can work it around by doing:
@Subst("some:placeholder")
var value = actualKeyToBeParsed;
var key = Key.key(value);
if it really annoys you
I prefer to just disable the inspection, only case where it is useful is when you're parsing a string literal and 90% of the time, you aren't doing that
I see, thank you!
maybe I should just contribute a method that returns an optional 😅
I think the @Pattern annotation should just be removed from that method rather than adding an additional one
the annotation is better suited for methods that are more commonly used with string literals, i.e. Commands.literal("whatever"), Key.key is more commonly used to parse user input and thus can't be statically validated
I get what you mean, but having a second method not only makes it easier when you are parsing a literal, it also forces you to always make sure you're parsing valid keys; additionally it just makes intent clearer since instead of suppressing a warning you are explicitly writing .getOrThrow()
(edited to make it actually readable :p)
Btw I already discussed about this last year
@winter socket lol yeah would be nice
Hello, has Component a sort of way to hide for example a metadata and retrieve it?
whats the usecase here?
I would recommend storing data on actual game objects instead, like itemstacks or entities have PDC for that on paper
Honestly, I wanted to propose if it was possible, a pull req on discordsrv, to specify where a message goes to, this was an idea if it was possible
I know nothing about how DiscordSRV works, but I believe that it does not only send the component. There must be some additional data sent along. It would be really hacky to try to bundle those info inside the component, instead of simply having the component wrapped in a more general object, that can have additional data
basically it listen to AsyncChatEvent and forward the message if it was not cancelled.
Issue is that other plugins have no power to decide where it goes or for example to not send it to discord, without cancelling the event
the proper way would be for discordsrv to fire a "DiscordMessageEvent" or something, pass all the data plus the message there, plugins can listen to that custom event, change change or cancel or whatever, and discordsrv then can look at the event result and look at what to do (if cancelled, nothing, else send message to channel that was set in the event)
yeah thats also a good idea, in their docs I don't see link to API, but yeah
i mean, pretty much just everything under https://github.com/DiscordSRV/DiscordSRV/tree/master/src/main/java/github/scarsz/discordsrv/api
yeah I saw it, but there isn't signature unluckily, to be sure 100% you are intercepting the correct message. Thanks btw
Hi everyone, I'm getting this pointing to a forEach on Bukkit#getOnlinePlayers when running mvn install with 26.1.1:
No access: net.kyori.adventure.text.object.PlayerHeadObjectContents
Any ideas what might be causing that?
Hey! I have an issue with MiniMessage that causes items to not be stackable. From what I've observed, emitted components are different when I parse a MiniMessage string in plugins onEnable and when I do the same later, e.g. in a command.
I'm using MiniMessage.miniMessage()
I'm running Paper 1.21.11. The diff for /paper dumpitem is visible on a screenshot. What might be causing this?
it would probably be more useful to have the text in a pastebin
also, the original source minimessage
did that linearize pr ever get merged?
declaration: package: net.kyori.adventure.text, class: LinearComponents
I don't think so, not sure if it was ever a pull request but I remember someone posting a class that turns a "tree component" into a linear one
I am not sure what that means tbh, like compacting a component?
a component will always be a tree even if the contents is just a single node
yeah but the component children were leaves, they had no children
it copied styles and whatnot
that just sounds like the Component::compact method
does that ensure you'll end up with a depth-1 component?
I don't see any PR's for that, and I don't see why you'd want that
there is ComponentFlattener already for display
god damit
?
Yeah this is me, but I hadn’t time to properly focus on that and make a PR, sorry :/ I wish each day lasted 36 hours lmao, so much things to do… But I’ll try to give a look at it in not too long
iirc I wanted to split components at newline or something similar
it's nice work man, no need to apologize
that's entirely different than what you were asking lol
splitting is much easier once you have a flattened structure to work with
but nobody's been interested enough to PR it
ya but then you have an inefficient representation
I needed it at some point for lores
better to do it correctly
can you suggest an alternative then? an inefficient representation is better than no representation
implement it in a way that preserves the hierarchy
I'd rather just use what exists, having 15 components organized differently really does not make a difference
Hi, is there by any chance a way to center a component?
<center>Hello<newline><center>how are you?
I know <center> doesn't exists, mostly asking if there is a way in the API
no
thank you!
To center a text, is sufficient to append space before and after the text? Counting that the text line is 255 in minecraft?
The underlying technical bottleneck is to compute the width of that text, and the width of its container
Mostly I don't think there is an universal way? since if user change their GUI size in the client settings, they will see also chat bigger or smaller
If you control client-side stuff (namely, the resource pack), you can enforce a specific font (with known size), so if you don't use any special components (only text or server-side translated components), you could compute it. But you'll still be missing info on the container's width
so to do a recap, there isn't an universal way basically, since container's width changes according to user GUI size setting?
It depends on what the container is, but basically yes some can be changed through client-side settings (chat, for example)
thank you! Do you know where I can find more info about it?
About what?
the container width
Where are you displaying your texts?
i mean, you can change the chat width of your client to be wider or narrower and there is absolutely no way of knowing that from the server
Here are the chat-related settings that the client could change
thank you both guys for the help ❤️
Namely, "Chat Text Size" and "Width"
it is better to just not center things in chat
if you want something centered, just use an action bar message
or a title ;o
yeah given the situation I would agree, especially due to users using for example Lunar Client or other clients which alters the chat look
do people actually use those for 26.1
But yes, my recommendation would be to not try to center, as you might succeed for the "default" case, but it'll be screwed up when clients have custom settings or so
yes plenty
I see the value for 1.8, didn't know people would still use them for newer versions lol
26.1 I think has a very small playerbase? but pvp players from what I know yes
and feather client
yeah almost every pvper uses a client
To make a "clean" announcement, I would recommend you to do something like:
Random_User: Hi!
-----
[ANNOUNCEMENT]
> The actual announcement message
-----
Another_User: Yay
With sufficient spacing (1 line before and after) and clear demarcation (horizontal bars above and below), things get rather visible and really don't need any "centering"
or do you define the key urself for jumping
wait am I misunderstanding or does this not allow us to get keybinds of a player? huh am I tweaking 😭
No, it just lets you send a message to the client and the client can replace the keybind with the actual keybind
how do they replace it? wdym like how do they set the keybinds?
The client replaces it when rendering the component
yeah so if the player has left click for jump does it not say Press Left Click to jump!
yep
yes
yep
I mean, the server can't actually know what the keybind is, it just sends a marker the client fills in with the right keybind when displaying the message
But if you only care about displaying it and not knowing it then you're fine
aww so we can't access the information ourselves
🫠
like I wish can we not just like grab the info from chat 🥹
ufhghhhfh
I'm sad 😭
Yeah
No, if you render the message on the server the keybind isn't filled in since the server doesn't have any
See "configurable controls" section on https://minecraft.wiki/w/Controls
Minecraft offers controls tailored for different input methods. While Java Edition is playable only with a keyboard and mouse, Bedrock Edition has a wider variety of control schemes in order to accommodate players across all platforms. These controls can be changed in the options menu.
oof
it's also kinda ugly bc it renders as q not Q
well you can like uppercase it!
idk
wait you cant
cuz u don't have the info
ufhhfufhh
man being able to track player keybinds would open so much information up
especially for servers like mcpvp
cuz you can detect stuff
wait how would that work for mods that allow double bunds
binds*
well ig you wouldn't know
hmm
That's up to the mod to figure out
adventure 5.0 is available in the latest paper 26.1.2 builds already?
no
is there an eta?
is there a simple way to turn a HoverEvent.ShowItem into an ItemStack
nevermind, i found this https://jd.papermc.io/paper/1.21.11/org/bukkit/UnsafeValues.html#deserializeItemHover(net.kyori.adventure.text.event.HoverEvent.ShowItem)
declaration: package: org.bukkit, interface: UnsafeValues
Is adventure v5 abi compatible with v4 for non deprecated usage?
iirc a simple recompile should be needed, at least that was the goal
so every plugin compiled before is broken? lol
no
that is the goal ya
epic 👍
Ok I found the source of what I was saying:
Non-goals
- A complicated update for developers. We want a migration to be as smooth as possible for developers, only requiring the removal of deprecated methods and potentially a recompile.
https://github.com/PaperMC/adventure/issues/1202
So it was "at most" a recompile
So if it's not needed, great
ya no one of the constraints of 5.0 was no ABI breaks if you aren't using anything deprecated in 4.26
I'll keep using v4 then to continue targetting java 8 :)
seems silly, it's been years since mc ran on J8
I maintain an adventure library which supports 1.7.10
oh my condolences
That sounds painful
its fun
I know there are 1.7.10 forks which up the java version used
could just go that direction instead
or was it the 1.8 ones, idk, both are old
yeah p much anyone seriously running outdated versions in 2026 should be using modern java versions
there's all sorts of people in the world, but personally I get my fun in different ways
I mean they only added componrnts in like 1.7.2
Scoreboards were added in 1.5
According to bStats, the number of servers running 1.8.8 or below (and with Java 8) is comically low: https://bstats.org/global/bukkit (yes, there's no "Paper" category on bStats)
if you're going that wide of a version range and at the packet level, I'd look into moving most of my logic onto the netty pipeline given that I believe netty version wasn't updated as regularly (at least not in an abi-incompatible way)
of course, you'd have to transform bytes into Components in order to do that but eh
it already works, whatever
wasn't it fun 😛
very fun
theres a script that runs over 50 different mc server versions to test the reflection
No category, but paper itself reports to bstats https://bstats.org/plugin/server-implementation/Paper/580
Oh nice
how do you beat the convenience of legacy codes with the boilerplate of components 😔
I really dislike legacy codes but they're just so convenient 😭, do people use minimessage outside player input for this?
Yeah, people definitely use it inside their code directly as well
In that way it's similar to what you'd have without adventure where you'd have the boilerplate of ChatColor.GREEN + "My text" versus using "&aMy text". Here the former is also significantly longer.
MiniMessage
hm I didn't know that, it seems odd imo (same 'odd' as using &a instead of ChatColor.GREEN) but that makes sense
You can just use Linear components + NamedTextColor if you want to stick with something close to the old style
Personally I find the builder style component creation much nicer, but that's also an option
How'd I be able to use something similar to dynamic replacements in a minimessage translator
I guess I'd just have to do my logic and then just use an argument
Formatter#number would've been pretty cool
you can just pass it as an Argument
Component.translatable("some.mm.message", Argument.tagResolver(...))
I do think it is odd
I prefer just setting up global translator so that I am not using MM directly in code but just as the message format
otherwise, just using Adventure directly for any hardcoded component
I figured it out eventually myself by reading the source code, but thank you nonetheless!
how should i go about creating a custom component with adventure 5?
Custom as in how?
as in like if i wanted to make a new component
that doesn't really clarify much
like, constructing a component? that didn't change much at all in adventure 5, beyond some changes to click events
no i mean creating a new type of component, like if i wanted to extend textcomponent or something
i know its removed because they dont want you to do you that now, but whats the alternative, and how do i use it
One relatively common incorrect usage was to create custom
Componentimplementations. This is now no longer possible, and you should instead be using theVirtualComponentAPI.
i mean i read that but didnt see the alternative, is it virtual components? but then how do i move from using a new component to virtual components
i mean yes, it indeed states the alternative is using a VirtualComponent
but then how do i move from using a new component to virtual components
thats my entire issue
i can't really tell you how to move whatever you're doing without knowing what you're doing
they dont give you any example
well i basically just extended the main component interface and added like 1-2 new methods
once again, without specifics i can't really tell you much
since TextComponent#toBuilderwill be removed in 5.0, is there any other way to convert a component into a builder? the deprecation message tells me to look at ComponentBuilder<?, ?> toBuilder() but i honestly have no clue what to do with that information 😅
what's getting removed is BuildableComponent, Component retains the toBuilder method, though that does mean that if you are using toBuilder on a specific component subtype (like TextComponent) you'll get that deprecation, but it's fine
ahh alright thanks for clarifying!!
does the PlainTextComponentSerializer.plainText()#serialize] return anything for components that aren't TextComponent?
the flattener used is service-provided, so it depends on the platform
Basic flattener (what that is using) will print out the Key for translations and key binds and such
I guess the text only one just doesn't print anything unless it's a text component?
Hey, I'm experiencing a problem when compiling a project that depends on GriefDefender which depends on net.kyori:event-api, no compilation errors occur because we don't depend on event-api directly but without adding net.kyori:event-api as an exclusion I can't package the jar. Does anyone have a fix for this?
please ping me if anyone responds
"can't package the jar"?
what does that mean?
that sounds more like a question for #build-tooling-help
but if GD has event-api classes exposed in their API without properly declaring a transitive dependency, that's… really all there is to it and until they fix that you'll have to manually add that dependency
If developing for a version of paper that does not have the latest version of adventure, do you reccomend just using the bundled version of adventure for that mc version or to shade the latest version of adventure in (if supported)?
you should use the bundled version, and target a paper-api version that contains the api you want to use
thank you
"Compile the code into a jar"
okay and what does that mean
describe the problem, not what you're doing that surfaces the problem
I thought that this would be enough, but sure.
A dependency(GriefDefender) of the plugin I'm working on(ProjectKorra) depends on net.kyori:event-api version 5.0.0, which is not accessible through the previously mentioned dependency(GriefDefender). Unless I exclude net.kyori:event-api, I can not compile the plugin(ProjectKorra):
[ERROR] Failed to read artifact descriptor for net.kyori:event-api:jar:5.0.0-SNAPSHOT
[ERROR] Caused by: The following artifacts could not be resolved: net.kyori:event-api:pom:5.0.0-SNAPSHOT (absent): Could not transfer artifact net.kyori:event-api:pom:5.0.0-SNAPSHOT from/to spigot-sonatype-snapshots (https://hub.spigotmc.org/nexus/content/repositories/sonatype-nexus-snapshots/): status code: 403, reason phrase: Forbidden (403)```
Are there any workarounds other than excluding `net.kyori:event-api`?
add the repo that that project exists in?
No, sonatype snapshots wherever that moved
that too
<id>spigot-sonatype-snapshots</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/sonatype-nexus-snapshots/</url>
<snapshots><enabled>true</enabled></snapshots>
</repository>```
Looks like phoenix616's repo has a copy of it if it's not accessible from the primary snapshots repo anymore, that all got messed around with so, idr what the official repo for that was
hello everyone, how to use new player component in adventure api? ({"player":"Notch"} in /tellraw)
by using Components
I also reccomend checking out the MiniMessage format to make your life easier
player.sendMessage(Component.object(ObjectContents.playerHead("Notch"))) would be the direct equivalent of your example
hm, i'll try it, thank u!
or
player.sendRichMessage("<head:Notch>");
if using MiniMessage
I've been going through the localization page
https://docs.papermc.io/adventure/localization/
How do people actually handle this in practice?
Do most people go through the resourcepack route, or do they parse the keys manually from files into a translation store?
(obviously this depends on platform, but in regard to paper:) if you want to use the translations on items or in dialogs, then you have to use resource pack translations for those
otherwise, server-side translations are more flexible/you can do more with them
I develop custom plugins for my own server in a monorepo, and for the most part I don't use third-party plugins. I went the resource pack route, but I kinda regret it because I have to use flaky scripts to parse translation keys and their English fallbacks out of my code.
Right, makes sense. So if my use-case is primarily for messages being sent to players, adventures translation store makes more sense?
And additional question is how do people generally structure their files for this?
I haven't seen MM's translation store, will look at it
this is an example of how people usually go about it
well that one is actually using json, it's usually through resource bundles
For the json files being loaded there, do people usually do
resources/langs
en_US.json
...
?
usually people use properties files w/ resource bundles
Huh, what are properties files?
translations_en_US.properties:
some.translation.key=<red>a value
Ah, I see. And you bundle this for all locales in
I'm not asking when it will be done I'm asking if someone even started working on it
I'm not sure entirely, but you could probably check out a list of pull requests
does adventure include scoreboard stuff
I can't figure out where documentation for scoreboard stuff is
I mean its just like vanilla?
So, the Minecraft Wiki
Unless you specifically mean the sidebar and just want to use it to display some text.
In that case I would recommend using some library like FastBoard (which supports adventure nicely), because dealing with teams and objectives yourself just for text display gets annoying quickly
for my project I'm trying to do things manually so I can learn to appreciate abstraction
I've found that beginning with abstractions can hurt my understanding
but yes sidebar
ohh ok so there's no paper-supported way to do it
just raw teams/objectives
I mean that is a paper-supported way to do it
Thats how the scoreboard system works in vanilla.
The sidebar is just one feature of it
alr
then I'm probably going to just make a utility for that and abstract away teams system from sidebar
the raw text without any formatting / coloring
I see thank you ^_^
Im having a ton of problems with ping... I use minekube connect for tunneling. And I was wondering if the high ping was my plugins / server or just minekube?
I think this is not the correct channel
That isnt an adventure question, you would be better off asking in #general or #paper-help
Is it possible to use the <sprite> tag with a custom resource pack? I cant seem to guess my way into the proper formatting.
resources/assets/hideandseek/textures/misc/play_tag.png
<sprite:"hideandseek:misc":misc/play_tag> doesnt seem to work, roughly following the example on the docs, just shows up as a white rectangle
you can add custom sprites, but they need to be defined in the existing atlas folders
aka assets/<namespace>/textures/<atlas dir>, i.e. if you added a sprite to the items atlas then you'd do <sprite:"items":"hideandseek:item/play_tag">
was just about to ask about the atlas part until you edited, was reading about that in the mccommands discord because I figured thered be more examples there and thought I was doing something wrong
ty
you can check the atlases' defintions in the vanilla pack to know where each one points to (and their prefix)
I do wonder if minecraft will add support for custom atlases at some point
Would be nice if you could just simply point to namespace:path/texture but I assume it needs to go through atlases for some reason
well, atlases are in charge of stitching sprites together so that they're performant to display. Otherwise they'd be expensive to render and just overall a lot more bloated than they need to be in terms of vram
though I didn't really understand any of this till this moment given I was just checking out how the whole thing works in mcsrc.dev so you may take that with a grain of salt lol (not that it'd be strange though, it is pretty standard thing to do in game dev)
I also realized that you can do animated sprites after looking through that code, which is cool. Could probably do some fancy effects with that and not spam chat like one usually does for animated stuff in chat (though I am sure the same thing can be achieved by (ab)using shaders, I've seen it before)
how should i use adventures NBT library
do you have a specific question?
well im just getting started migrating all my stuff to adventuers nbt library so i can use their own NBT to Component methods, how should I read <1.20.2 NBT (blank name), or 1.20.2+ NBT (no name data)
the papermc docs have nothing about adventures nbt
did you have a look through the javadocs? it's not a complicated library - do you have any specific issues or examples of what you're trying to do that you couldn't before?
alr let me take a look
and now its the task of migrating all of my nbt stuff
Cannot resolve symbol 'CompoundBinaryTag'
i loaded it in pom.xml?
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-nbt</artifactId>
<version>4.26.1</version>
</dependency>
Make sure you refresh dependencies, check build errors if any
i've refreshed but its doing this
[WARNING] Failed to download adventure-nbt-4.26.1.pom [https://jitpack.io/]
[WARNING] Failed to download adventure-nbt-4.26.1.jar [https://jitpack.io/]
this is the only one i've loaded
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
we don't publish to jitpack
where do you publish to
maven central
because every other adventure library loads
ye thats weird
im also loading from maven central
only nbt doesn't load
Cannot resolve symbol 'CompoundBinaryTag'
import net.kyori.adventure.nbt.CompoundBinaryTag;
then this
kk
let me maven refresh
Cannot resolve symbol 'CompoundBinaryTag' hmm
i dont see any sync errors
i cant help you with ide/build issues
#build-tooling-help if you need it
but that version def exists in central https://mvnrepository.com/artifact/net.kyori/adventure-nbt/4.26.1
Problem with your build setup.
do you know what problem that would maybe be?
almost no one is doing anything in #build-tooling-help xd
no need to cross post, you are going to get the best support about build tooling issues from the build tooling help channel
ye i got it fixed
turns out, i was using the WRONG ADVENTURE VERSIONS
AAAAAAA
alright heres a actual question, how do i turn a Component into a NBT tag and vice versa
why?
can I suggest an alternative that doesn't require such constraints?
what packet?
why are you using packets to send a message to a client?
uh
maybe because im developing a proxy
and i dont have any such thing as paper or velocity api
so theres no way
oh my bad
unless i do the packe
sorry but my knowledge of implementing Adventure is a bit dry
You will have to write your own codec like thing then
you could try the unmerged PR for NBT serializer
u know what im just gonna look at velocity code
Or you could round trip via json I guess, if your nbt I impl can do that
that is also a good idea
exactly what velocity does lol
json = deserialize(binaryTag).toString();
component = ProtocolUtils.getJsonChatSerializer(version).deserialize(json);
how should i SNBT it
actually i prob wont need it
actually yes i will need it
so uh
how
nvm again
alright heres a reasked question
how should I read <1.20.2 NBT (blank name), or 1.20.2+ NBT (no name data)?
i still don't really know what you're asking for
like
i have a ByteBuf
i need to read the <1.20.2 NBT
and the 1.20.2+ NBT
theres 2 versions
is there?
let me check
i swear that exists
oh i hate this stupid mc wiki documentation
theres like 2 seperate NBT pages
@cloud vapor
i don't think that matters?
sure
how do i read NBT then?
public static BinaryTag readBinaryTag(ByteBuf buf, ProtocolVersion version,
BinaryTagIO.Reader reader) {
BinaryTagType<?> type = BINARY_TAG_TYPES[buf.readByte()];
if (version.lessThan(ProtocolVersion.MINECRAFT_1_20_2)) {
buf.skipBytes(buf.readUnsignedShort());
}
try {
return type.read(new ByteBufInputStream(buf));
} catch (IOException thrown) {
throw new DecoderException("Unable to parse BinaryTag, full error: " + thrown.getMessage());
}
}
velociyt just skips it lel
see the javadocs - you're looking for the reader/writer classes
found it in velocity lol
not sure why velocity does it this way, the reader has read vs readNameless specifically for this reason
like, they're passing the adventure-nbt reader but not using it at all lol
is this removable? it's a ClickEvent.runCommand
wait no it's a mm
<b><gold><click:run_command:'/duel accept %s'>CLICK HERE</gold></b> to accept!
its there tho
the popup says otherwise
this is what i use
also check that the command exists, and isn't affected by that paper bug
yeah it exists, and clicking run command runs the command and everything works, i just need to remove this popup
How are you registering the command?
brig api + lifecycle manager
does the command have a requires predicate
yeah, a perm check
yeah that'll do it
see https://github.com/PaperMC/Paper/issues/13590 for more info
aight thanks
does status:accepted mean it will be fixed in a later ver?
you'll have to ask paper devs
wait aren't you guys in the same team now?
it just means it's a valid issue
ohw
PaperMC != Paper
we're in the PaperMC organisation yes, Paper the server software is just part of that, Adventure is another part
ohhhhhhhh
this is the anarchy you get in the lawless lands of kezz maintenance
Should make me a maintainer, then everything would be clearly defined, but change every 3 months

Are there any news on that yet?
No
I'm trying to add custom translations to be shown in dialogs, but they don't render and only the translation key is shown to the user in the dialog. When sending the same translatable component directly to a player, it is rendered correctly - is this intended?
What platform?
Paper, in case that's what you mean by platform.
Paper doesn't render server side translations for dialogs, you'll need to do it yourself
see GlobalTranslator.render
for what is worth, there is a PR pending to fix that, which hopefully will get merged:
https://github.com/PaperMC/Paper/pull/13871
I see, thanks for the help.
Hello. How i can use <head> with "Value"? Custom minecraft heads have no UUID or player nickname.
wdym by Value?
i talking about this value:
so a Base64 encoded texture?
the head tag doesn't support Base64 textures and probably never will. However, I'm pretty sure the API ObjectComponent does support them
MiniMessage is meant to be readable, pasting a giant base64 string doesn't seem readable to me
You can use a component placeholder and build a object component in java I guess
i mean, you can always just add your own custom tag resolver
i.e. #adventure-help message
this message should be pinned ngl
See, I don't think it should be in MiniMessage, that means I also don't think people should write that as an extension
It's just not readable
How I'd do it:
In a config, a map of texture base64 and a nickname:
heads {
"bobby": "9d6bdd07abe3f398720e5f010648c2c194a2ba0f5ef3e27013b0670336eb4f3c"
"sally": "67d6bdd07abe3f398720e5f01048c2c194a2ba0f5ef3e27013b0670336eb4f3c"
}
Then, in the minimessage, you would be able to do like <heads:bobby>
it is perfectly readable lol
no it isn't, you cannot read a base64 encoded texture and understand the resulting displayable content of the component
I think its a matter of taste, because the head tag accepts an UUID, and I cannot myself understand the resulting displayable content of the component when reading an UUID ¯_(ツ)_/¯
So what each of us consider acceptable/readable or not is mainly personal preference, imo
Some may also argue that an HEX color code is not particularily readable either. Does it mean we should remove it from MM? I don't think so
A bit of a stupid question, but do minimessage and adventure add lag, don't run on older server versions, or don't support other server software like Spigot, right?
None of the above
Obviously you can add lag if you somehow decide to create billions of components in the same tick, but that won't be adventure's fault 😅
More info here for compatibility with other platforms and supported versions: https://docs.papermc.io/adventure/platform/
worth noting we will eventually be dropping official support for -platform which provides support for very old (like 1.16 and older) versions and spigot support
(i mean technically, that message uses the texture link and not the much longer base64 value)
Yeah, and it could be shortened to only the hash because this is the only domain allowed by Minecraft's client
I can't find this explicitly written anywhere, but am I correct in assuming you can manipulate different Components in different threads safely so long as you don't actually do anything with them (like send one as a message)?
it'd be hard to imagine otherwise given they're immutable but would like to confirm
the fact they're immutable means you basically get thread safety for free
right, well conceivably there could have been some global data structures that the instance methods require for some reason
though I'd ask before I build an entire plugin around that assumption :)
the biggest trouble you're going to face is thread safety around the consumers of Components rather than the Components themselves
In what config?
In whatever config I'm making for my plugin to read.
Ah.. ok, thx
idk who complained but https://webui.advntr.dev/ is updated to latest adventure again
MiniMessage Viewer is a web interface to help generate and edit MiniMessage strings.
Just a general question, why don’t we move it to paper docs now that adventure moved to papermc?
you want to embed it or what do you mean?
You mean this page? https://docs.papermc.io/misc/tools/minimessage-web-editor/
It is not embedded, but referenced by a link so it’s rather the same
Why don’t we discontinue webui.advntr.dev in favour of integrating it in the paper docs
wouldn't it require a separate subdomain or at least special routing? The thing runs a Ktor server
Idk I am just curious. I don’t say it has to happen.
well I do somewhat agree. It looks odd to be on a special domain rather than a PaperMC one
I never understood that domain, nor can I type it
MiniMessage Viewer is a web interface to help generate and edit MiniMessage strings.
is there any docs on the adventure virtual components?
I think I have a usecase for them but I dont really get how they work yet
My main question would be: How can I render the component and what the heck is Context in VirtualComponentRenderer?
Is it intended that there are no Javadocs for adventure 5.1.1 available? https://jd.papermc.io/adventure/5.1.1/ returns a 404, while https://jd.papermc.io/adventure/5.1.0/ correctly returns the Javadocs.
(I realise 5.1.0 and 5.1.1 are identical in terms of API, but I use one global adventure version property in my pom.xml and 5.1.0 doesn't work due to the publishing issue that was addressed in 5.1.1, but 5.1.1 fails due to the missing Javadocs.)
I'll raise it now!
Do you wanna explain your use case a bit more and I'll point you in the right direction
Generally, context is whatever you want it to be (e.g. a player, a world, etc)
So I do a lot of resourcepack trickery. A lot of it is generated automatically and I have mappings on my server for e.g. cafestube:test_inventory to the font cafestube:inventories and char x.
I now want to have the same for font glyphs (e.g. emojis, indicator icons etc.). However those icons get used in plenty of places like our custom bossbar (custom bossbar text is offset by a few pixels to accommodate for a border), inventory lines (we have custom fonts like inventory_text_0 which is the text in the center of inventory row 0, same for row 1, row 2 etc. with different ascents) etc and they need different ascents for each and every one of them.
Since different contexts might contain different amounts of glyphs because of optimization reasons (e.g. emojis are probably not required in inventories or bossbar), I cant just reuse the same unicodes over and over as they might eventually collide. The idea would be to have a GlyphMap for each context (default, inventory_0, inventory_1, bossbar etc.) and to use a lookup depending on context. Since I dont want to supply the context every time I create and declare a component (or I dont want to declare the context in minimessage for example), I thought I might use virtual components to finalize the component depending on wanted glyph map and fallback to the default glyph map if it isnt rendered.
My other idea would be to traverse the component, look for a font used in glyph maps and if yes, lookup the gylph in the glyph map and replace it with the equivalent glyph of the new glyph map. Dont know which is better, but I think virtual components would be great here. The only issue is that remapping no longer works after serialization but I dont think this is an issue (at least not yet).
-# (Man I wish mojang would just give us API's to do UI stuff 😭)
it does sound like something you could use virtual components for
though you would have to pass the context somewhere
my inventory rendering function could easily do that. Same for bossbar UI api etc. Question is just how I would invoke that? How do I actually render the virtual components? I still dont get that
you don't call the renderer yourself, you just store it in the virtual component with the necessary info
but how do I pass the context?
it is passed the moment you instantiate the renderer
internal class GlyphComponentRenderer(
val key: Key,
val fallbackGlyphMap: String = "default"
) : VirtualComponentRenderer<GlyphMap> {
override fun apply(context: GlyphMap): @UnknownNullability ComponentLike? {
return context.getGlyph(key)
}
override fun fallbackString(): String {
return MetadataProvider.instance.getMeta()
.getGlyphMap(fallbackGlyphMap)
.getGlyphUnicode(key)
.toString()
}
}
I thought I'd do something like this? How do I make it call apply with the glyphmap I want?
I'm not sure how virtual components help you here, they're not a magic bullet. You're wanting to manipulate a component tree based on some context, you're gonna have to provide that context somehow.
Virtual components are best for if you need to operate on a component whilst it crosses the boundaries of another API. For example, MiniMessage uses it because the components enter the Paper API and then the renderer is called after. So the data it attaches to the components need to be preserved whilst the component is outside of your hands.
In your case, you've got control of the components the entire time. You're gonna find it much easier to simply have a custom MiniMessage tag that reads context your pass at serialize time.
Ideally I want to include it in my inventory api etc. in a way where API consumers dont need to care about what they provide, API consumers should just expect it to look like the stuff they provided. So if they provide "glyph:testHi" to two separate API's of mine, my api would just rewrite that with the corrected glyph map.
I'm in control of the API that consumes the components, but I want future me or other developers to not need to care about what they pass in as it should just ⭐ magically ⭐ work. If vanilla stuff like sendMessage is called, it would use the fallbackString, which is the correct thing in that case.
But I don't fully get how to get to a point where apply is called with the context I want. How do I do that? Do I just need a function that traverses the component manually and replaces my virtual ones? How is this applyfunction intended to be called? Thats what the mystery is to me
I don't see why that couldn't work with a TagResolver like the translation argument ones where you provide context at deserialization
you could use virtual components, but it'd be annoying as you'd have to pass the context type somehow, like maybe with a scoped value or something
Me using minimessage here was just an example. We often just pass raw components down when not directly translating for icons and stuff thats just the same across all our languages
the api just sees components, minimessage is provided at api consumer level
thats why I want this to happen with virtual components at an api level
if it makes sense
Whats the point of the apply function having a context then? Why does that method even exist at all if there is no way to have just something like Component rendered = component.renderVirtualWithContext(Class<C> context, C context) or something like that?
because thats what I would have expected looking at the api
just like paper internally calls a translation api on components
I started browsing the adventure repo on github and either the github search isnt helping, or this apply function has absolutely no way to be called?
At that point it could have just been left out for users to declare manually, no?
yeah frankly I've been searching and there doesn't seem to be any uses of it, it could be meant to be used in like, a ComponentRenderer but no idea
Thats the only thing confusing me. This method seems entirely pointless.
I could write my own component renderer but I really dont want to bother with children 😭
and whatever else can hold sub-components
AbstractComponentRenderer also does not seem to have any handling for children 
I would have stolen code, but it seems like virtual components are barely use by anyone
Thinking about it, the idea might have been flawed from the beginning since what if a glyph comes from a TranslatableComponent. My renderer would sit in front of that, so it would skip that glyph then. I will need to consider if that is viable to accept then :/
Is minimessage the same as adventure?
Nope
MiniMessage is a format you can use to represent Components (from Adventure) in a human-readable and editable way
I'm trying to find out if there is anyway to display heads in chat. I have managed to do it, but if there is anyway to use a "value" or Minecraft URL to display them instead of UUIDs of a player.
I don't know if this is a valid question for this support channel...
The object component should allow for that
MiniMessage doesn't because it wouldn't be readable
linking #adventure-help message since it shows you how to construct one with a profile property
found this, and all of those works. However then I need to select a player with that skin
the message i linked shows you how
I see, i'm not a programmer tho. I'm using a plugin called interactivechat which has minimessage built in.
would be cool if it can be pinned given the amount of times it has been asked lol
Is it worth it to change all tag resolver things to be lazily loaded by using a component supplier instead of creating them directly? Or how does this even work?
I am introducing some tag revolvers in my plugin that might not be used, but could be for item generation. Might reduce lag?
Like go from this
Placeholder.component("my_tag", Component.text("something"))
To this
Placeholder.component("my_tag", () -> Component.text("something"))
Like might be used, as it's configurable by the user
I mean, it depends whether you actually performs "heavy" computation to create the component. And then, you would probably want some caching to prevent computing it multiple times (i.e. to compute the component the first time and reuse value the next time). It’s called memoizing
In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs. It works by storing the results of expensive calls to pure functions, so that these results can be returned quickly should the same inputs occur again. It is a type of caching, normally implemented using a hash table, and a typical...
The item has a lot of variables there, so I'm not too sure if momoization would be worth it
But good point
And, yes the computation is kind of heavy
Not at the moment, just a recollection that generating these items is a heavy operation. I agree that I should definitely have more to go on before doing a change. I will profile a bit then update you on that later then.
How do you listen for when it's clicked?
I don't think Paper has an event for it outside of dialogs now that I look at it
it may also not work with the current adventure version Paper implements now that I look at the impl
So do I just need to make it some random command and listen for that?
adventure 4 simply didn't support custom payloads the way mini message's click tag was creating click events
that is usually how people go about it, yes. You could also make a custom tag resolver instead of the built-in one to do whatever you want
though you would still have the trouble of listening to the custom click
But don't you run the problem that a player can somehow discover that command and send it at any time?
yes
hm, PlayerCustomClickEvent might just trigger for it with a null dialog response view
in that case you can just use adventure click callbacks as well
You can use a callback click action
Are there any docs on how to use that?
It's literally just a callback
then you can just use the returned click event in a styling tag
I've never heard of that before. Thank you I will look into it.
That did exactly what I needed. Thank you.
glad to hear it!
did adventure-api 5.1.0 file name get broken inside the repo?
there was some missing things with publishing, which is why 5.1.1 got released :D
Hey, does anyone have examples on setting up i18n for a plugin using mini message translator?
https://docs.papermc.io/paper/dev/component-api/i18n/ i see here's an example, but will this handle custom locale set in the plugin folder? i suppose no
it doesn't no, there's quite a few things you would want to handle yourself, one of them being dumping the translations from inside your jar (or download them from somewhere) into your plugin's data folder
okay
there's other thing you may want to handle, such as detecting the locale from the file name and loading the translations accordingly, reloading of the translation sources, namespacing the translation keys so that there's no opportunity for conflicts in the global translator
Hello. How i can show ender_chest here? i try Look at my <sprite:blocks:block/ender_chest > or <sprite:"minecraft:items":item/ender_chest >, but its dont work
because it's an entity block, not a block
There’s no such sprite. You could use a custom head texture to imitate it, but it’s not supported by MiniMessage
ah, okay... thanks
(But if you can code, you can use custom heads of course)
are you sreu you couldn't use the chest atlas?
Well, you can import the whole chest texture, yeah. But it’s very ugly and nowhere near what you expect it to be
It’s the whole texture, with all faces at once
Not 16x16
well why wouldn't
<sprite:chests:"entity/chest/ender">
work?
no please do tell
I’ve done it
It’s the raw texture image with all faces on a 2D image
oh I get it now
I don’t know the English word for it
yes... but its broken 😄
The full sprite sheet
In French, it’s called the « patron »
I believe that's what an image with individual sprite faces is called
Atlas is technically something else
idk I just call it a texture
true
ask the dev of the plugin to add a custom tag that allows you to pass the head texture hash
that way you can just use a player head with that texture instead
otherwise, use a resource pack
how do i showcase a chest as a <sprite>?
sprite:items:item/chest
iam thinking it should be something with block but iam kinda lost
Just read literally the messages above and you'll understand