The logs were asked for while I was working on another task, and the issue was closed at that point. During that time I was trying to resolve the issue on my own by still working at it and the logs were requested post re-install. I can't exactly reverse time.
#development
1 messages ยท Page 6 of 1
i'd prefer it after i show him he's got a fake client
<img width="249" height="257" alt="Image" src="https://github.com/user-attachments/assets/f775c018-461c-4891-a58f-b3f94a83bc0a" />
<img width="1395" height="635" alt="Image" src="https://github.com/user-attachments/assets/b385fa74-89c0-41f9-9aab-a34941881bd2" />
Guess I missed that part, my bad. I just deleted that folder as I'm trying to clean up the mess, so I don't have logs now.
but if the issue is persistent...
not my problem
๐ ๐
Out of curiosity, anyone happen to know whether or not cache contains a list of transports like teleports, doors, stairs, etc.?
I know Shortest Path plugin adds transports manually so I am assuming it's not in the cache, but I'm asking just to confirm there's no way to extract it
does a plugin config only support primatives/enums or is there a way you can use classes
it doesn't support arbitrary classes, no
you can serialize something to a json string
eh i was trying to figure out if there was a way to put config groupings into logical classes, then show the individual config items in the plugin settings
but it doesnt seem like it
ive got like 150 configitems in 1 file and it bugs me
you could make a panel and manage that part of your config from there
I really dont like the state of panels and dont want to contribute to the problem
fair enough
This is blocking an update to bank tag layouts so please add this soon.
Currently it assumes that if the base id is the same as the id in the layout then it is not a variation, which is plainly not true.
The exact id match does not catch this case because that checks the id of the item in the bank, not the id in the layout.
@rancid marten if you could add this before the next update that would be appreciated
I need it for a mass convert feature between btl and bt layouts
the second pr is not necessary
convo was a while ago and apologies for ping but that's 'combat achievements tracker'
You can have your main config inherit multiple separate interfaces and group them that way if you're just looking for a nice way to group related config functions
yeah thats what I was looking to do after I realized my first desire of serializing and deserializing classes into config fields wouldnt work. ill try that
ty!
almost could have an hasLayout() but I guess it runs infrequently
yeah I had the same thought
I'd be willing to do something like https://github.com/Adam-/runelite/commit/1e9cbbd37bf6c440bf97dbf23fb617b6bba6db4d - I think it is the same as what you have now, can you test it?
@broken summit just making sure you see this
kinda surprising that generating 141 tabs every time I withdraw an item doesn't cause me issues
only costs 1-1.5ms
Test is running great on Intel Mac. Looks great as well!
<img width="2334" height="1692" alt="2026-02-18_18-12-24" src="https://github.com/user-attachments/assets/fce95e4d-7696-4aef-a5f3-3f83c374fb5c" />
<img width="2334" height="1692" alt="2026-02-18_18-12-20" src="https://github.com/user-attachments/assets/dcca6355-4b4a-4a6c-99b5-ab757c9e6795" />
<img width="2334" height="1692" alt="2026-02-18_18-12-15" src="https://github.com/user-attachments/assets/a0f766e1-24b7-4819-a503-09e9ec7956dc"...
@naturedamends The issue I've worked out is twofold. First, I believe my original instructions are incorrect and not what I was actually doing at the time. The options I gave in that post did make the launcher use the proxy, but when the launcher launches the client, that client doesn't inherit those options. The correct way to do that is by setting an environmental variable, like `export JAVA_TOOL_OPTIONS="-DsocksProxyHost=127.0.0.1 -DsocksProxyPort=1080...
Various fixes, adjustments, and additions using original 2005 and OSRS sprites.
- Remove the changes to sprite id
- I was under the impression that we only changed sprites that were directly in the game frame and sprites that would have been changed in 2005. Because otherwise, everything else is subjective to how the style should look.
So, just want to check since it's been a while and I swear this used to work:
Made a PR for the hub, and it failed the check. Fixed the issue and force pushed the branch like I used to do, and the PR just isn't updating with the new contents of the branch at all (even though the commit on the PR no longer exists as far as I can tell).
Am I doing something wrong? or has the submission process changed in the past couple years
https://github.com/runelite/plugin-hub/pull/10651
sounds like a github issue to me. never heard of this
first time I am seeing this happen
yeah I'm super confused
maybe just try this
https://stackoverflow.com/a/76590821
there was some issue in PR merge queue so maybe that broke it
I thought I'd tried that last night, but apparently not. it seems to have worked, thank you!
Is there any way to get these stack variants in my plugin without dumping them from cache to a file and loading from there?
i dont think they're going to add a new coin stack so you can probably just hardcode them
I need all stackable objects. I could hardcode it but I'd like a general solution.
mmm
I don't see one ๐
and the RuneLite ItemVariant mapping does not handle stackable variants AFAICT
yeah you're right, I don't see it either
If I PR a change to add stackable variants to wherever item_variations gets generated would that get approved?
Can you look into how bank layouts does it? Doesn't that map for variants
Maybe not
Looks like that uses ItemVariationMapping which isn't aware of stack variants
I think stack variants are only used for visuals of stack count > 1 so probably most plugins don't need to be aware of them
Probably nothing?
I think that is your answer as to why it's not done for core
That wasn't my question, but I guess the answer to my actual question is "no"
that is sort of the defacto answer for "can i pr x to core in the name of hub plugin y" but it's not wrong to ask imo
you can generate images of an item with a certain stack count
I think the only awareness core has of stackables is in generating images of them (eg for loot tracker) and the ItemManager has a thing for doing that by quantity, built from the cache i think
but I doubt that's uesful to you
oop beat me
barely XD
only cause I paused to look up if it does it straight from cache
I assume it gets it from the client
where did you look this up? wouldn't that be closed source code?
whatever this is
oh I meant client.createItemSprite
oh interesting ItemManager::getImage can take quantity and stackable bool
oh right itemmanager is using createItemSprite
It's been a frustrating experience to have useful things right there but not exposed by the API because it wouldn't be useful to "enough" plugins when there seems to be plenty of stuff in the API that is practically useless and I can't find anyone using it at all.
I don't know if anyone has ever asked for this
oh btw I saw your plugin on reddit. that thing has legs it seems XD
No, probably not for this; I'm not that bothered by this one even. It's more stuff like this https://github.com/runelite/runelite/discussions/18055
but it would be nice in general to have this stuff available unless there's a good reason not to expose it IMO
Yeah it's been popping off. Theoatrix even made a short on it which is pretty cool ๐
Everytime I do bank options my game tanks FPS ๐ must be nice only having 1-2ms Though I feel like potion storage is at fault ๐
this thing I'm talking about is every time you withdraw an item
not just on bank options
Sorry I meant withdrawing too, but also depositing (albeit deposit doesn't feel nearly as bad as withdraw)
I should profile it next time I get on
Is it new since the recent changes?
Not that many tabs, like around 10 IIRC
What I'm talking about nah
Sorry for the confusion if that's what you both thought
Do you have a code example showing this issue? Maybe something I could just paste into jshell?
if a ConfigChanged comes in on the swing thread is it guaranteed to be from an actual user input on the config page?
I want to open a modal dialogue in this
And I'm paranoid that somehow something like plugin presets might somehow f this up and have it open at weird times.
no
I own the zulrah loot locator plugin, and I was recently approached by someone who is interested in making the same kind of plugin for locating where loot will spawn at leviathan. I suggested that these features should be part of the same plugin (toggleable in config), so there isn't a unique loot locating plugin for every boss.
Does rebranding/renaming a plugin come with any special hoops/obstacles to navigate?
basically don't change the plugin class simple name or the hub manifest filename. you can change other things like the display name or whatever
gotcha, thanks for the heads up
Be aware if you change the plugin name you should set a configName on the plugin descriptor to ensure it references users' existing configs
also while i do appreciate you putting the effort in to adding it as a feature for your existing plugin, if i'm understanding what your plugin currently does, you might need to make the levi one off by default
otherwise we're gonna get a ton of traffic about some weird square appearing in the fight
yea that sounds reasonable
do these two bosses actually use like the same algorithm for this
if the default is to only show below 0 hp surely they will notice that the loot always spawns on that tile?
no not at all, it's just the exact same feature - a tile indicating where loot will spawn once the boss is dead
yea it's currently set by default to only appear once the boss is dead
can that be changed? cuz the example gifs show it changing spots
but I would be inclined to just have it off by default like felan said
thats why i said that
yea the example gifs were set with a higher value so you could see it working in real-time, but by default it does not do that
mmm
I kinda hate the idea of zulrah on by default and levi off by default, that's just weird especially to new users.
but that's your choice I suppose
yea that is weird ๐ญ
i suggested it because of sote wall hider
could check what the hp threshold is and disable it if it's > 0 maybe.
adding a bunch of new bosses on by default
where did my walls go ????????????????????????????????????????
and 1 square is enough to confuse people, see default radius markers
more people should just utilize update messages for their plugins
not implementable afaict if you didn't already mark that your plugin was previously installed.
that's something I wish runelite had natively though
onPluginUpdated() something like that
add text to the tiles that says "this tile is brought to you buy the Loot Locator plugin"
Anyone know off the top of their head if a plugin's #shutDown is ran
- When a user gracefully shuts down RuneLite
- When a user forcefully shuts down RuneLite (eg. power out)
- _I'm assuming it doesn't run?
Oh...
onclientshutdown
TIL. Thanks.
won't help with power cuts ofc.
Mhm, got it
onComputerLostPower when?
plugin that accepts graceful shutdown command from my UPS before my OS does
import java.util.precognition
is there a way to ship out different defaults depending on if the user already had the plugin installed vs. fresh install?
no, unless you stored in the config that it had previously been installed
Unironically would be nice for Plugin Presets plugin o7 Though I reckon it has something to do with having the file always open, and when a PC shutsdown it gets corrupted.
If someone installs a plugin but never changes from the default and then that config option is removed, does it still exist via ConfigManager?
really not that hard to send update messages https://github.com/Zoinkwiz/quest-helper/blob/64a2adcbc36ef6b2e1b15459583be3da44b02bff/src/main/java/com/questhelper/managers/NewVersionManager.java#L37
you have to first update the plugin to have taht system
Wait, is that storing the entire UPDATE_CHAT_TEXT string as the version
then update it again with the new stuff you wanna announce
Instead of just storing 4.12.1 lol
I guess its one less variable to change code wise and you'd only save some storage space
I bet this works ๐ฎ
I think defaults are stored in the config file
I don't know of a way to reproduce a visual problem in jshell. I made a small plugin showing it; just open the panel and click the buttons in order and you should see it: https://github.com/jhughes/runelite/tree/animatedmodelcacherepro
This is what I'm not sure about. Do we persist them in the config file on plugin install?
If so easy way to check for legacy users would be remove/rename a config option and check for old key in manager.
And then do what Pine showed moving forward if you want actual update messages
[ https://github.com/MosheBenZacharia ] [ @deep adder 229844694287253506 ] mozerine#0
if you write it manually instead of via the config file i don't see why it would write a 'default' value, and the method i showed would work either way
I was gonna say, yes if you launch the client, all plugin configs will have some value written--whether that's the default, or a user-defined value
launching with a fresh profile will write default configs for all installed plugins (by default, only core plugins)
[ https://github.com/Lazyfaith ] [ @ebon wraith 188137636748066817 ] lazyfaith#0
LMAO I was looking through the game's textures to see what all is available. I can't wait to replace the fire cape with some random king's portrait.
I think those are from the magic tree. Will probably look cool on a cape
roof cape
So there is not an "animated model cache" so idk totally whare you are having a problem with
Interesting.. I saw some references to it from a while ago and I thought maybe it was implemented. Do you understand the problem I'm seeing with animations not respecting color replacement? Whatever color replacements+equipment are in place the first time the animation plays seem permanent as if there is a cache.
its because the player model is cached and then after that you are modifying the item configs
Shouldn't playerComposition.setHash fix that though?
no
PostItemComposition is more close to what you would want but it still wouldnt work correctly if your plugin is started after the player is already logged in
My actual plugin uses PostItemComposition and sees the same problem even if it starts up before login
are you sure?
Pretty sure, yes. What does playerComposition.setHash actually do then? It causes my changes to the item composition to reflect on the player for the idle, walk, and run animations, but not skilling animations.
it computes a hash derived of all of the player kit/equipment which is used to look up the player model from the model cache
you are modifying the item compositions themselves though which is different, the player hash just includes the item id
So color replacements are not part of that hash then?
Well every time I've looked at playerComposition getColorTextureOverrides it's been null
if you use PostItemComposition and apply the recolors there and then start your plugin before login, there is basically no chance it is broken
this is an entirely separate color override system and isnt what this code you submitted is using
if i were to fix this i would take this route though
Yeah that's right; the only way it fully works right now is to use PostItemComposition and restart the client.
idk if you would need to restart, you just need to logout i think
but like this cant be right
For most animations it seems to snapshot the colors of the item compositions the first time the animation plays and cache that. That lines up with what you're saying regarding setHash's behavior.
For idle, walk, run animations, setHash does cause the player model to change
I may have confused you with the way I worded that. As long as I don't change the colors everything works fine. It sees the same problem if the user changes any colors.
I can expand the ColorTextureOverride api a little to make it so this works I think
it is a little tricky since the overrides only work if the existing item also has an override of the same length
I'd be super happy if you do that!
I updated my repro plugin to split the cache reset and playerComposition.setHash into separate buttons. Based on what you said, "Step 5 Set Hash" shouldn't do anything because I didn't change any equipment, and yet it clearly applies the changes I made to the itemComposition in step 4. Is that a bug?
is getColorTextureOverrides() non null for you?
No, it's null for every step
but again youre not using the post item comp event
oh let me add that
these inconsistencies happen when the player model cache is updated with a model prior to you changing the item composition in a way which affects the model
also the player model cache isnt exposed and is neither of these caches you are resetting
I think everything you're saying makes sense except the current setHash behavior changing the idle, walk, and run animations.
Adding a postitemcomp event to recolor these items to black will not allow me to dynamically change their color so the repro won't work
it does, you just need to reset the item comp cache
but, again, it wouldnt reset the player model cache
err.. I can dynamically change the color yes, but it won't demonstrate any different behavior is what I mean.
So do idle, walk, and run animations use the player model cache differently than other animations like mining? It seem so strange that these animations have different behavior with setHash.
no, they dont
also this has nothing at all to do with animations
it gets an unanimated model from the cache and then animates it after that
whether its walking or mining or w\e is not relevant
the mining anim is a different model though because the player has the pickaxe
or well it is if the player doesnt have the pickaxe wielded
Will the player model hash be the same for a player wielding a bronze pickaxe and when playing the animation HUMAN_MINING_BRONZE_PICKAXE?
Yeah it doesn't appear to be the same in my testing. I think everything you've said makes sense and aligns with what I see; I really appreciate the explanation.
So to summarize potential fixes for my issue:
- I need a way to reset the player model cache after changing an itemComposition's colors if I want consistency.
- PlayerComposition ColorTextureOverride API expansion would allow me to change colors per-player and would be nice to have, but wouldn't actually fix my issue without access to the player model cache
you wouldnt need a way to reset the player model cache if i improve the colortextureoverride api
since the overrides are hashed in setHash
I think
oh gotcha
yeah
/**
* Get the {@link ColorTextureOverride} for a kit slot
*/
@Nullable
ColorTextureOverride getColorTextureOverride(KitType kit);
/**
* Create a {@link ColorTextureOverride} for a kit slot.
* The ColorTextureOverride is initialized with the overrides from the provided item.
*/
ColorTextureOverride createColorTextureOverride(KitType kit, int itemId);
/**
* Remove the {@link ColorTextureOverride} for a kit slot
*/
void removeColorTextureOverride(KitType kit);
I made this
That sounds perfect!
Is there any way to replace an npcs attack/block/death animations? Seem to only be able to get idle and walking working.
just setAnimation() it right?
give this a try once its done deploying
I found the issue, setAnimation() was indeed correct, it was just that the animation check was targeting the old npc id and not the new one I believe
[runelite/static.runelite.net] New branch created: wiki-data-2026-02-20
763e923 Update wiki data - RuneLite Wiki Scraper
first time contributor; what's the turnaround time on the tests for a new plugin? i'm not asking about it being on the plugin hub, but it's been at the RuneLite Plugin Hub Checks for ~24h now. I guess i just don't know the process
Which pr?
10657
You have a new github account which requires a maintainer to manually run the action
ok, thanks. i didn't see anything about that
Does it not say anything in your end that it requires us to approve it to run?
I clicked the run button now though
i saw an approval i just thought that was for adding it to the repo
Yea i could see that being confusing
but thanks for the quick support guys. hope to keep contributing in the future
If you're not familiar with the gh process, which most people doing hub dev are
not super familiar with working with others' projects, no. i just use it personally for version control mostly
King cape is so silly XD
were you able to check out the new api?
How do I tell if it's released yet? When I tried last I got an error
In your build.gradle change the version to latest.integration
I switched to latest.integration and I get the same error: java.lang.AbstractMethodError: Receiver class oj does not define or inherit an implementation of the resolved method 'abstract net.runelite.api.ColorTextureOverride createColorTextureOverride(net.runelite.api.kit.KitType, int)' of interface net.runelite.api.PlayerComposition.
add --refresh-dependencies
Ok that fixed it. Yes it looks to be working!
I'm able to recolor items mid animation and it shows up on equipment as expected. I'll keep testing it but so far so good.
Thanks so much, Adam! ๐
does onNpcSpawned actually mean every time an npc is drawn on screen for the first time, not actual spawning
yeah, it's when the npc is sent to the client
I believe I've managed to get to the cause of this issue with some assistance from Claude & Ruffled (117 HD) and @IComplainInComments's tipoff.
It appears that the macOS window server is holding a reference to the back buffer IOSurface and occasionally re-reading it while it's being rendered into despite the CALayer's contents pointing to the front buffer. I came to this conclusion by:
- Using [apitrace](https://gi...
Type
Incorrect behavior
Operating System
Windows
OS Version
10
Bug description
An unsuccessful devtools.highlights load from config renders the script inspector unusable
Screenshots or videos
RuneLite version
RL 1.12.18-SNAPSHOT
Logs
2026-02-19 23:28:55 PST [AWT-EventQueue-0] ERROR net.runelite.client.RuneLite - Uncaught exception:
java.lang.NullPointerException...
Now that this typo is fixed, PMD is identifying that the blacklist/highlights fields can be final. Apply that, and this should be good to go
changing these fields to final causes a build error
\IdeaProjects\runelite\runelite-client\src\main\java\net\runelite\client\plugins\devtools\ScriptInspector.java:213: error: variable blacklist might already have been assigned blacklist = new HashSet<>(Lists.transform(Text.fromCSV(DEFAULT_BLACKLIST), Integer::parseInt)); ^
Same error for highlights
Hmm, I guess that'll need a couple of // NOPMD: ImmutableField comments after lines 86 and 87 instead then. This appears to be a PMD bug as it doesn't account for that, I'll open an issue on their repo for it.
https://github.com/pmd/pmd/issues/5046
seems to have been fixed in later versions.
next we need projectile recolor. i cant be having my blue shadow be firing orange projectiles
I was talking in 117hd discord about the possibility of rendering text in-game natively instead of using the client's text rendering engine. This could be useful to render arbitrary size text, so you could use custom size scaling. Or when playing with stretched mode, most of the scaling algo's leave the text looking a bit blurry unless you're integer scaling.
My very rough first draft idea for the api is like this:
- have the client go through most of its regular text rendering composition stuff
- as soon as the bounding box of the text is known, call a hook/callback
- the callback, if registered can override the content of the text widget. It receives the bounding box of the original text and the desired string
- the callback renders a different output in place of the original text widget
- alternatively, the callback returns a widget with the custom rendered text but idk if you can have an arbitrary bitmap or whatever as a widget
This would require somehow having information about what text is being rendered and override the normal rendering process, so I think this would need to go into the injected client and be exposed through the api, so perhaps that already makes this infeasible, but I thought I'd just pitch the idea anyway lol
I have thought about this before, basically the hard part is you have to then scale all of the client's rendering too
not just the text
since they are all written to the same buffer
Yeah I realize there's two parts to this
which is also the same thing we use for overlays, so those have to be hidpi aware too
Let's say you only allow the same size box to be drawn, you couldn't scale up anymore, but you could change the font, I suppose
changing the font would mostly be just swapping out some sprites and a tiny bit of metadata
But you're still stuck with the client's glyph rendering right
yeah
if you wanted more complex glyph rendering you would have to swap out the client's font metrics stuff too
Does stretched mode render the regular interface and then scale it up by some fixed factor based on the size of the client?
yes
It's not just graphics scaling tho, it also scales input boxes and stuff..?
So does it create bitmap widgets?
ah wait it already has such widgets to work with, it just makes every widget larger and then populates the content with the upscaled version of what was there before
it scales down input going in, and scales up the image buffer coming out
it doesn't touch widgets at all
then what is changing the widget sizes
nothing changes the widget's size
My inventory becomes twice as large when I enable stretched mode
so somewhere, the size of clickable things is also adjusted right? I'm missing something here I think lol
no, the widget is the same size
if you call getWidth on it, it will return the same value regardless of if stretched mode is on or off
in resizable mode, the canvas is the same size as the game window (minus the sidebar) right?
so what happens when you enable stretched mode..? does the canvas become smaller by the stretched mode factor, so every click is also mapped like that?
the canvas is, but the pixel buffer the game draws to is not if you are stretched
so the pixel buffer is sized down and then whatever goes into the buffer gets upscaled?
yes
and then gpu/117hd render over the viewport, actually rendering the game at the real window size
but the ui buffer is still downsized and upscaled?
yes, they upscale the ui texture in a shader
and stretched mode with the original client renderer just upscales the whole output buffer?
yes, it rasterizes the tris at a downscaled resolution, then its upscaled with java2d
where downscaled = vanilla native res
good stuff, that works quite differently from what I thought
and native is a fixed res even in resizable mode?
no that doesn't make sense haha
its canvas size * scaling factor
which is capped at 2x?
with some checks to make sure it doesn't get under the canvas min size
I don't think its capped at 2x
the injected client decides that factor right
its mostly just set by the plugin
but the injected-client is what actually handles it
oh I understand now lol, setting the scaling to 100% basically means, halve the game res, then upscale the output back to the original window size
yes
so you could put it to 200% and it would divide by 3(ish)?
yes
but capped by the minimum client size I guess
so on 4k you could scale a lot more before you reach the cap
yes
okay thanks alot I did learn much just now haha
So does the vanilla client use three fixed sizes (regular, small, bold) for font rendering?
ah thanks
they are all just bitmap fonts
You could natively render text into the (bounding box that would be created by the vanilla text renderer) * scaleFactor
it wouldn't layer correctly
hmm
so you need to tell some module to "render this string please, but make sure it fits into this size", and immediately draw the output into the buffer
that doesn't help you get a different size/dpi awareness
Instead of what the client would've rendered there. If I understand the flow more or less
Yeah but you could antialias it
wait no because the upscaling happens after
REEEEEEEEEEE
yeah
introduce z-buffer
or delegate composition to the upscaled version
i.e. build all widgets in an ordered list, then upscale each one, then draw. And flag text widgets to add antialiasing when rendering takes place
that would be way slow
also would not layer correctly since most of the client cannot deal with alpha
also there is stuff like items and the minimap that are render to texture that you have to deal with
Not sure I follow
the minimap and items are drawn to an intermediate buffer, then copied to the actual backbuffer
so you have to decide if those should be scaled / how that works
are those intermediate buffers the same size as the backbuffer?
nope
but the logic stays the same right
also did you mean items as in, inventory?
yeah
minimap I get, you "paste" the texture into the minimap bounding box right
its the way it is so it can be rotated
and mask parts that are outside the target
but if you upscale it centered on the player (how the rotation is done also), that would do it
upscaling is linear anyway
still not sure what the item(s?) buffer is for
its createItemSprite
because you need to do the upscaling individually?
yes
you would need to clear the lowres buffer, draw to it, then composite it onto the real buffer for each thing you draw
i'm not a graphics programmer but what if you paste all of the buffers into one big one and upscale them all at once, excluding the text ones
then its more expensive to upload to the gpu
then it wouldn't layer correctly
I meant more like
put individual sprites/textures next to each other
you'd need to have a variable size buffer tho
idk if that is possible
imagine an inventory in a game like diablo
items have a size and you put them next to each other in a 2d grid
upscaling them at load time would be okay, but there is still the problem of the hundreds of things that are not just a texture
upscale the whole 2d grid, then cut each part
right that could work too
the cost of upscaling is basically per pixel, so batching them together is worse since you are now upscaling whitespace
I'm beginning to understand why it's just a single buffer upscale and a mouse click translation ๐คฃ
if you upscale on gpu, could you apply the shader to multiple textures at once?
Good debugging! A few notes from looking into this.
- Chrome doesn't use IOSurfaces to pass to a CALayer like we do, it just uses them to frames between two processes with different gl contextes, which is why it doesn't need to doublebuffer
- I did try to use IOSurface(Un)Lock, but that has no effect. According to a GTK comment it doesn't really lock anything, but manages copying the buffer to/from the gpu
- Firefox has
SurfacePoolCAwhich does basically what you describe, so I'm interes...
like a cube and the upscale works on each slice, but parallelized basically
you would also have to composite it on the gpu
and now you are paying gpu transfer cost for overdraw too, which there is a lot of
I think I'm underestimating the cost of switching the data between cpu and gpu
my idea was something like:
- rasterize every widget,
- take the dimensions of largest texture (this could be optimized probably) and create a cube buffer of x * y * z (z is probably bounded by max gpu parallelism)
- fit all smaller textures into the cube, minimizing whitespace where possible, also need to keep some open space between them to prevent bleeding
- upload the buffer to the gpu, upscale the whole cube, or cubes if everything does not fit into the z layers
- download the buffer(s) and do compositing
- this is the final frame buffer, upload it to wherever it needs to go to display it
or maybe you could upload another buffer that contains the necessary composition info and skip the extra download/upload cycle
you basically cannot do an operation on the gpu then copy the result back to the cpu in a single frame
today in #development: ririshi learns basic concepts about graphics and discovers the same things that abex just said, repeating exactly what he said a few minutes later because he came to the same conclusion
and uploading all of that data every frame is way too slow
maybe if you keep separate buffers for well known things, so again basically like you said, load items and fixed 2d textures and upscale them once
then somehow inform the gpu to copy certain boxes from those pre-scaled buffers when compositing
but that doesn't solve the 100s of non-texture widgets
some of those might be static which means you can draw them once to save time?
basically the only way I could think of making it work is to just implement 99% of the whole ui renderer on the gpu
with all of the annoying buffer management that goes with that
then virtualize the gpu so you can also run the game on just the cpu again
I guess that's what software gl is for
might as well write the whole client to run on the gpu instead
who needs a cpu in 2026 smh
Seems to be working for me. Same RL version (1.12.17). Make sure the
Tanoption is checked for tanning in: Configuration ->Menu Entry Swapper -> UI swaps<img alt="Image" width="243" height="354" src="https://private-user-images.githubusercontent.com/22647380/549642930-2d3dfa18-053d-4a70-9e05-ba39b4a3ce4e.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzE1OTQwNDksIm5iZiI6MTc3MTU5Mzc0OSwi...
Hey looking for some advice - deving my first plugin.
-
The functionality I'm going for is private messages decaying over time. I've got this functionality working, however it lives in onClientTick. Is this appropriate? The only alternative I can think of it making a thread of each pm.
-
When private messages are using split chat, I'd like for the messages to stay in the chat box but be removed from the text coving the game window. With my current implementation it deletes both. I'm just wondering where I might start looking for implementing this.
you could probably use onGameTick or @Schedule, or a ScheduledExecutorService method
For 2 you might have to just hide the individual message widgets in the split pm box instead of actually deleting the message from the client (assuming that's what you're currently doing)
for 2, you probably have to look at clientscripts, maybe start here https://github.com/runelite/cs2-scripts/blob/5d5a7f977ce01ea4ec86c4e8d7c7d8b231f90005/scripts/[proc%2Cpm_filtertest].cs2#L2
Yeah I'm currently deleting the message, I'll take a look at the widget and clientscripts ty
46f59f0 update snailman-mode to v1.1.2 (#10656) - adamk33n3r
48aaae0 update tictac7x-charges to v0.6.10 (#10663) - TicTac7x
I want to differentiate between two objects in a "onMenuOptionClicked" event that have the same event.getId(). ObjectID.PMOON_TELEBOX_3X3. It seems that the param1 is different for them. Is that a good way of doing it?
They are entrances that lead to different areas of Neypotzli and I just want the one that is the exit
I've never really understood what the param0 and param1 means really
That should work then right?
sounds good
Thanks!
Using --insecure-write-credentials is the offical way to do runelight plugin development with Jagex accounts?
Yes
that's why the github wiki says to use it
Aight thaks wanted to double check before I leaked my creds.
it's the INSECURE way, but also the only way
just don't reveal the credentials file that is created with that command and you're fine
the best thing is to remove the file when you're done coding
Where does it save it so that I can delete it?
isn't it mentioned in the guide
.runelite/credentials.properties
read that carefully
Ok I'm very confused now. When I first login and click the entrance, it has param0=63 and param1=44. I then walk around, going through different entrances. When I return to THE SAME PLACE, the SAME entrance now has param0=71, param1=52. What the hell???
this also happens to the other doors, but once you enter a door once it seems to find the correct params
Seems to be some kind of login thing that gets calibrated once you enter some other area? I have no idea why it does this. Does anyone know?
it is a scene coord, so its relative to the scene base
you want to LocalPoint::fromScene it
then WorldPoint::fromLocal or fromLocalInstance if you expect to deal with instances
Man this one I'm not so sure of, I have tested it and it seems to work, but I wonder if there's any better way of doing it.
String menu = event.getMenuOption();
MenuEntry entry = event.getMenuEntry();
WorldView wv = client.getWorldView(entry.getWorldViewId());
int level = wv.getPlane();
Scene scene = wv.getScene();
Tile[][][] tiles = scene.getTiles();
final Tile tile = tiles[level][entry.getParam0()][entry.getParam1()];
LocalPoint localPoint = tile.getLocalLocation();
int localX = localPoint.getSceneX();
int localY = localPoint.getSceneY();
int deltax = localX + wv.getScene().getBaseX();
int deltay = localY + wv.getScene().getBaseY();
//1439 and 9612 are 'magic numbers' that are the non-relative x and y axis of the entrance I want to block, meaning that the other entrances are not blocked.
if (menu.equals("Pass-through") && event.getId() == ObjectID.PMOON_TELEBOX_3X3 && deltax == 1439 && deltay == 9612) {
event.consume();
client.addChatMessage(ChatMessageType.GAMEMESSAGE, "", "[Prevent Misclicks] Leaving the cave disabled" +
" since you have " + amountSulphurAsh + " sulphurous essence in your inventory!", null);
}
I get an non-relative position when doing localX + wv.getScene().getBaseX(), and this number is constant no matter where it loads. What do you think, is this a decent solution?
It was surprisingly difficult for me to get this to work, I feel like I'm missing a piece of information since it probably isn't that difficult really.
I looked at the code for objectindicators for inspiration but couldn't quite crack it. I know you get a tileObject. Perhaps you could use that?
what about the api abex mentioned
I use it in the code, localpoint is from tile, which is from scene.getTiles()
but I can't use a localpoint, I need to use a non-relative point
that's why I use two relatives, since it makes a non-relative
I'm sadly not familiar with that notation, I tried doing localPoint. but couldn't find anything returning a worldpoint
any ideas why my VSCode keeps reformatting my code to some strange format?
Kinda feels like, whenever im switching pc and pulling it gets like this for some reason
I need to manually format selection everytime
WorldPoint::fromLocal
<class>::<method>
post passing checks for a new plugin, what's needed to get review/approval?
Wait for a reviewer to review the plugin
Depending on queue/plugin size it might take a while
is there a way to see the queue status?
The open PR list is the queue, effectively ๐
kk ty
sort by least recently updated, pretend all the "Plugin added" ones aren't there, that's the queue I think :L
Wow this is actually so awesome. It turns out what I did is literally calculating the worldPoint ๐คฃ
worldX: 1439 worldY: 9612
Thanks everyone!
You can also check early if event.getId() == ObjectID.PMOON_TELEBOX_3X3 and return early if it isn't. No need to do any of the coordinate calcs if it isn't the right object.
hey that's a good point
less processing power is good
And just to double check my understanding, this "worldPoint" is unique where? Is every point on the map for example unique according to the worldPoint? So x=1000, y=1000 is at exactly only one place (assuming no instances since they might have some weird logic)
You can see the 1439, 9612 worldpoint is here
Oh is that a specific tool you're using?
Awesome!
I see know what abex is writing,
LocalPoint localPoint = LocalPoint.fromScene(entry.getParam0(), entry.getParam1(), wv);
WorldPoint worldPoint = WorldPoint.fromLocal(client, localPoint);
This is what they mean. Didn't understand it :(
Type
Incorrect behavior
Operating System
Windows
OS Version
Windows 11
Bug description
- You're on profile A
- Click "view tag tabs" and right click top left "new tag tab"
- Type in a name but DON'T press enter yet
- Switch to profile B
- Press enter
You will now see that all Profile B's tag tabs are overwritten, and they all happen to be empty too.
Screenshots or videos
Here is a video demonstration & explanation of the problem:
my guy invented a new bug
it's your favorite, no logs!
yeah but this one came* with a fun video
should i attach logs to it
ig that's probably an ez repro if you can do it
I don't think it's my (btl's) fault fwiw
yea it's very easy to reproduce
do u think it could be related to having 2 runelite clients open at the same time?
ok so it happens but I dont' have to hit enter
or at least it did when I only had 1 tag tab. not sure if that's related
and some of my old tag tabs contain the few items I added to that test tag tab
A lot of thecode which accepts input like that will do things like capture config -> wait for input -> use captured config after
id assume is what is happening
this seems so extreme edge case im not sure i care though
it's really weird - not only does it overwrite your tags, but all of them are empty too ๐
I can't imagine tripping this bug in any real situation
i just encountered it naturally
I was setting up turael skipping on my alt, and I'm like: "Oh I want to reference my ironman turael tag tab", so I switched to that profile to look at it and withdraw my custom set of items for this alt account. Then, I went to create the new tag tab so I clicked "new tag tab", but then I stopped myself. "Wait, I shouldn't create it on this profile, this is my ironman profile". So I switched profiles and hit enter.
I bet the code is called at a weird time
since I never had to hit enter, it just closed itself (the prompt)
maybe the ondone is called at a very strange time during profile change somehow, without my input?
the prompt doesn't close itself for me ๐ค
well now mine doesn't either ๐ (different account)
@shy pine swing question for you - why does removing contentsPanel from NotificationPanel (and making the scroll pane's view just mainPanel) cause the vertical spacing between the config options to increase?
is there any visual indication of where u can drive ur boat on the world map, i'm trying to see what misc area(s) u can drive in from
is it this slightly darker water
Not really, different waters have different hazards which are different colors on the map
mmmm
someone opened an issue (on the wiki xd) that u can't see misc favor if u drive in
which is correct since it only checks the two land regions
You can sail around all sides of the island, but you can only get to the land via the docking point
thats the sailing icon right
Yep
so probably just 10299
probably not unreasonable to add, since it's only 1, i just didn't want to add 12 new region ids to the plugin
i guess the issue report itself says "go past the pier" grumble
On a laptop this weekend made in the 1930's so I can't test, but looks like mainPanel and contentsPanel are using different layouts (DynamicGridLayout vs BorderLayout). mainPanel has a vertical gap of 5 while you didn't have any vertical gap or insets on contentsPanel. That's my best guess at least
all of contents panel is nothing but main panel
so it seems like i could remove the contents panel, but if i do it all breaks
Oh hmm
i think the contents panel is artifically lowering the max size of main panel which is causing it to just layout stuff to be smaller
Oh perhaps contentsPanel, because it lays out mainPanel as Borderlayout.North, it's not space-filling (vs BorderLayout.Center would be)
it seems like there should be a less stupid way to do this but I cant figure it out
Try adding the scrollpanel with a North layout and see if it corrects?
JScrollPane scrollPane = new JScrollPane(contentsPanel);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
add(scrollPane, BorderLayout.NORTH);
topPanel is already there though i could try south maybe
If that doesn't work, could have a parent panel aligned to north with both topPanel and scrollPanel as children. Though even that is scuffed.
Usually at this point I break out GridBagLayout but that's also not super clean
a bunch of our config evidently relies on this trick
Added Egniol potion functionality for the dose indicator in the prayer plugin.
Anyone know how I can force a music track to play again when setting client.setMusicVolume(>0) after having set client.setMusicVolume(0) previously?
(Currently fixing https://github.com/alowaniak/music-replacer after some updates, and I don't think it previously had the problem where going from an overrridden track to a "native" track didn't make it play.
Have shuffled things around a bit and also previously relied on MusicPlugin's granular sliders, although I can't find anything special in its old version regarding 0 volume)
They added new varbits and varplayers on Wednesday for audio volume. Not sure if it has anything to do with your issue but may be worth looking into
varbits and varplayers are only readable though right? or can I write 'm to mimic/force behavior?
I'm using the VarPlayerID.OPTION_MASTER_VOLUME and VarPlayerID.OPTION_MUSIC (they're 0-100 afaict) to get the volume, and then play replaced music on that volume and set client volume to 0, and if there's no replacement I set client volume to "effectiveVolume" * 255 pretty much
But I think because when the track starts the client volume is 0, then after setting it higher it will still not play
This moves the Mac implementation from a two buffer approach to a pool of buffers, this is unfortunately required because the macOS compositor seems to keep a reference to the IOSurface presented via CALayer's contents after the contents have changed.
@abextm this is just an initial draft for you to take a look at, I've been running it for a few hours without any issues, the pool grew up to 5 IOSurface's.
I intend to drop the IOSurfacePool debug stats logging commit before merge :)
Not sure wherever or not this change warrants another file so I don't need to shove the whole pool impl in rlawt_mac.m ?
I also wasn't 100% sure if the dynamically growing pool was worth it or wherever or not a fixed size might be good enough, my v...
Is it possible to use the config panel elements (labelled checkbox, labelled dropdowns, etc) in my plugin panel without redefining them in my plugin?
Or even just the styling
Do I need IntelliJ for Runelite development or can I also run it with VS Code?
You can do it with VS Code but IntelliJ will make it much easier
Not important at all, but OOC why are we required to use RuneLite's Gson instance instead of initializing our own?
iirc it is because that is a verified hash in the sense of the maintainers deem it secure to use, rather than having to ensure each new dependency/version added by a new plugin doesn't have a glaring vulnerability in it
default gson likes to reflect into the jdk which doesn't work on newer versions of java, so the gson instance we provide has a thing to make it always fail
howdy. I reused the camera zoom slider tooltip to make the new volume controls have a dynamic tooltip. Any thoughts on this?
how is that better than the vanilla tooltip?
vanilla isnt there while you're moving it
jaflex pleae
the old slider had this function and the new one PMO cuz I can't find % quickly
Thanks ๐
๐ If only Jagex bothered to simply make it/add an input field
jagex trying to copy runelite always ends up like this lol
Vanilla client 2026-2-11 update to volume control removes the dynamic tooltip for volume percentages. This adds it back, but using the tooltip mechanism from the camera zoom slider.
Vanilla (2-21-2026):
With changes from this PR:
https://github.com/user-attachments/assets/85bb7914-1f0b-4802-a6cb-0ba77c89d528
in any case, if you're interested ^ ๐
slayerPluginService.getTargets() seems to return an empty list for aquanites. dont have time to dig in much further than that right this minute https://static.runelite.net/runelite-client/apidocs/net/runelite/client/plugins/slayer/SlayerPluginService.html#getTargets()
they arent getting highlighted by the native slayer plugin nor better npc highlight (which just hooks into the native slayer plugin anyway) so pretty sure its upstream from me
related to this? https://github.com/runelite/runelite/pull/19854
potentially
This, and 63763c82a0735a5452cc3d11beb3bf7295cee7db, are both confirmed in the cache by referencing dbrows 9415 and 9405 respectively.
mere seconds after I figure out how to check it myself ๐
I'd just done that recently for the shellbane gryphon so it didn't take me long
though I didn't know you could just search the dbtables view like that
would've saved me a bit of scripting I guess
we're all learning things today
Before the total additions scare the maintainers off, a quick breakdown:
- Plugin itself is about 300 lines (plus 99 lines of imports and copyright statements)
- 500 lines are a new UI component,
DragAndDropTabbedPane, to mirror the existing dragging behavior inDragAndDropReorderPanebut forJTabbedPane* (see notes) - 1200 lines for unit tests
- changes to support the plugin are about 100 lines
- All unit tests (new and old) and checkstyle passes
I finally learned eno...
Hey all, finally wrapped up my changes for implementing draggable plugin tabs. I worked super hard to make sure I followed all the previous conversation about storing configs (or not storing them in a txt file as someone else tried), following all the patterns I could within the codebase, avoiding reinventing anything already created and using created classes/utils.
I tried to make this as robust and high-bar of an implementation as I could. I'm open to adjusting anything any maintainers have or answering any questions. I'm currently going through and leaving comments to help clarify anything for reviewers. Thanks all.
This is definitely a feature I am interested in adding, I would have to spend probably an hour+ looking at this to figure out if works like how I want it to work and I don't have the time to do that atm. Ill try and check it out later though
did you ever look at #18720's version? https://github.com/runelite/runelite/pull/18720
That is a ridiculous amount of tests
i think the tests are just ai slop
like, idm them we can delete them later
how much of the actual impl is slop vs how much do you understand?
maybe I should look at 18720 too
i would note re 19910 - it definitely shouldnt be a plugin like this, but that is relatively easy to change
I think that one happened around the time there was a fair amount of discussion about desired behaviour in here
ie what should happen re-arranging around disabled panels
Yeah I think that was the case as well
When looking for a pattern for storing/retrieving gson'd lists from configManager, I found and followed the pattern from ChatCommandsPlugin.java for this deserialization. I was originally trying to serialize the List<NavigationBtn> but ended up switching to List<String>. I could do a split on the delimiter instead of this version, if that would be better.
Apologies, left a logging statement in from debugging. Will remove.
This is purely for debugging and can be removed. This helped identify when there were differences in the custom order as expected and displayed. Generally, this would occur during startup when this plugin would load and get the current state of plugins and cause the order to be sorted for only the 5-10 plugins loaded at that moment. This was solved by the onPluginChanged() method above.
I will admit the test are AI slop and I acknowledge in the PR body that they can be removed if unnecessary. In my day job, we don't introduce features without unit tests. I'm totally flexible on this and I'm completely open to any adjustments necessary.
I saw your comments referenced by a comment in https://github.com/runelite/runelite/pull/18406 about your desire for proper order insertion behavior when in a custom order.
how much of the actual impl is slop vs how much do you understand?
I understand everything I wrote. I started with the code from 18406 as a starting point (see my first commit) and took the feedback in that PR body to adjust this. Like not using a local txt file to store the config, so I learned what configManager is and does, how to store the custom tab order in configManager, how to serialize/deserialize looking at other 1st party plugins (ChatCommandsPlugin.java), etc. Some of the complexities around load order and event firing were very foreign to me (as I'm newer to runelite/java development patterns, as I am a python/devops/cloud dev by day).
I chose to make this a plugin so the behavior could be toggled on and off. I did this when testing it while playing when using 18406's original implementation and realized I wanted to be able to turn on and off the behavior to respect Adam's valid concerns.
I'm sure I've done some things wrong, but this is an earnest effort I spent way too much time testing troubleshooting, and pulling my hair out over and this isn't just one giant AI slop commit
I cant speak for how correct this is atm but it definitely just shouldnt be a plugin
That's completely fine with me. Is your preference toggleable in core runelite config? Like I said, I'm completely open to whatever changes I need to make
at the very least it would be just a setting in the "runelite" config to enable/disable dragging, more ideally having a way to control if it is enabled or not could be like a context menu on the sidebar or something?
looks like atm when disabled it resets to default order, which is probably not wanted
This seems to think there are some times when pool->front is !IOSurfaceIsInUse but also it shouldn't be picked as the next buffer and it instead picks a different buffer, why is that?
Also I don't quite get the reasoning to pick appropriately-sized buffers in prefer to non-appropriately sized buffers, what is that trying to do? It seems like it would maybe save a buffer recreation sometimes but those happen almost never, so it seems like it is not worth trying to do this?
I think a bunc...
I went through a few different iterations, one had it keeping the custom ordering when turning the plugin off. But I went with the current behavior because it means plugin off = custom sidebar off. Otherwise, the path to getting default tabs was to reset my custom order settings, which didn't feel intuitive. And wanting to keep my custom order when disabling the plugin didn't make sense from a user perspective.
it should probably be two tiers: on/off and locked/unlocked maybe
Having a user go "I don't want custom tabs anymore, turn off" and then they stayed in custom order once turned off seemed like an antipattern
I also had another config option of "use custom sidebar" with just a bool, but then when consolidating my implementations, I realized that was redundant as the plugin itself is in an on/off state
idk how sacred the default order is really, but thats just my opinion
maybe a reset context menu or something, but I don't see much use case for being able to go back and forth freely between re-ordered and default
ha, I did also have a "reset" button too and realized I could just hook into the plugin's reset() method
which may not be that intuitive, tbh
so if you do desire to reset your custom order back to default, hit the plugin's reset button
(that said i'm 100% gonna try and see if Plugin Presets can be used to do different orders for different activities)
I appreciate everyones thoughts and feedback. I had so many different ideas on how to implement everything that I tried it all, tested it, found which I didn't feel were right, tweaked some more, and had like 3 different branches of the implementations. If you all are interested, you can clone my original repo and try the three different branches to see which you liked better
there's really not any reason to have a live slider because it will destroy performance
drag and drop is already kind of bad when you drop it on world selector
my vision
first op is confusing maybe
Disable dragging perhaps
If you look at my PR body, I ran into that. I tried sliding like DragAndDropReorderPanel but when dragging icons of plugins with large panels like Configuration and World Hopper, it slows down. So that led me back to my first implementation of a dragged Swing Icon of the tab. It prevents reloading of the plugin's panel until dropped. I also made it prevent selecting a tab when attempting to drag and only open the tab when not dragging to drop. This keeps the behavior the same as stock, but prevents the rapid changing of the panel contents when reordering the sidebar
i'm telling you this because I ran into in a poc
even without your tests it's like 5x more code than I had so I didn't read it
The point of ai tests is surely just a check-box, right? To say you have tests without actually testing anything. In fairness I don't think "TDD" people ever wanted to solve real problems.
The good thing about keeping that stuff plugin hub is that code style and lack of care doesn't enter core...
Quick Question about Model::getAABB how is it calculated/what does it represent.
Am I right to assume it should be a AABB around the vertices of the model, given a orientation?
I'm seeing weird results when using it, so want to confirm that this API is what I want or if I should Min/Max the vertices myself.
(I'm leaning towards the latter).
Note: Dynamic Renderables getAABB seem providing a more correct valid bounds
Ideally AABB needs to be conservative, since I'll be using it for occlusion queries to determine if a Zone is visible for 117 plugin.
Am I right to assume it should be a AABB around the vertices of the model, given a orientation?
yes
the aabbs basically aren't broken because if they were then clickboxes would be broken
Is it a potential threading issue then?
I had to do the following in drawDynamic on the RenderThreads to fix some clickboxes:
if (renderThreadId >= 0)
client.checkClickbox(projection, m, orient, x, y, z, tileObject.getHash());
yeah you cant do that
Type
Incorrect behavior
Operating System
None
OS Version
No response
Bug description
I'm not 100% sure if this is a RuneLite issue, but I think it could be fixed by RuneLite.
Color replacements are not applied to stack variants for stack sizes != 1. If I recolor an item with stackable variants, say irit seeds, that color is only visible when the stack size is 1.
ItemComposition itemComp = client.getItemDefinition(ItemID.IRIT_SEED);
itemComp.setColorToReplace(...
I'd also love this, just FYI HDOS got it done: https://x.com/HDOSdev/status/2025321532457976204
This seems to think there are some times when pool->front is !IOSurfaceIsInUse but also it shouldn't be picked as the next buffer and it instead picks a different buffer, why is that?
We were double buffering before so I presumed to keep that, although I also wasn't sure if IOSurfaceIsInUse could return false & then later return true for the same CALayer's contents if something like the mouse moved over the area - I just tested this and it seemed safe to remove at first but I still had...
Type
Incorrect behavior
Operating System
Linux
OS Version
Fedora KDE Plasma 6.18.12-200.fc43.x86_64
Bug description
The indicators for the Emote / Hot and Cold / Maps clue steps, that the Clue Scroll plugin shows are a little bit inaccurate. What I mean is that the indicator is performing correctly, but the actual area where you can perform that action is bigger.
Now, I have been using tile markers to manually mark the exact area where you can do that, but it is quite ...
If we were to display these areas (which I'm not sure we do), we would want to be sure to have accurate areas for everything shown. While we have that information for hot-cold clues because they have a consistent area around the center--and having accurate centers is necessary for the narrowing algorithm, so we have been on top of correcting those--but the same is not at all true for emote clues and other dig area clues. Additionally, reviewing updates to clue locations on a large scale is di...
5c12173 gpu: do not reuse zones with incompatible roofs - abextm
cs2 scripts are all only interface stuff right?
I'm trying to figure out how to start music again after having done a client.setMusicVolume(0) and then client.setMusicVolume(>0) and I found 3932 fires whenever a music track changes (and if music track changes it starts playing)
So I thought maybe doing a runScript(3932) would fix it, but doesn't seem to
Also tried ::setvarp music/master and queueChangedVarp, but they all also don't seem to start the music
kinda at a loss tbh, can't really find anything else that might trigger a restart (as if a player had muted and unmuted sound)
you have to invoke a cs2 to tell the server you want to play music again but idr which one
hmm I would've thought it would be 3932 then since I see that one popping up whenever mute->unmute and changing music track
But programmatically muting and unmuting via shell and then running runScript(3932) doesn't make it play
9238
Would that just be client.runScript(9328) ? Or does it need args?
I also don't see it pop-up in the script inspector (And can't find a 9328 in https://github.com/search?q=repo%3Arunelite%2Fcs2-scripts 9328&type=code)?
*Oh wow, I mistyped it
So a mega-thread where everyone can contribute with the complete area of the Emote/Map clues would not be of any help, like the mega issue #9601?
I understand that it would be a really daunting task, since there is A LOT to modify, besides centering the Hot and Cold clues. But I believed that Emotes and Map clues do not have a narrowing algorithm. So wouldn't it be just a matter of hard coding the area?
So you would like something more "true", as in what the game provides as the real area (re...
So a mega-thread where everyone can contribute with the complete area of the Emote/Map clues would not be of any help, like the mega issue #9601?
I wouldn't think so, since centering hot-cold clues directly lead to better solutions, where finding the center of other clue areas has minimal impact on players.
So you would like something more "true", as in what the game provides as the real area (real data), instead of player driven information through trial and error, since that is not a...
Are all these errors an issue in the current runelite repo?
No, we don't have those errors
It looks to me like you might be missing lombok integration in your ide
oh my fork is still behind it seems
I don't think that's the issue, we've used lombok for a very long time
Okay, I see. It makes sense. Thanks!
Will try to fiddle around with a custom separate plugin.
Important: I did not get the whole Runelite repository running in IntelliJ, this PR is related to my comment in the pull request to make this small feature a whole plugin (https://github.com/runelite/plugin-hub/pull/10696). I did get my own plugin-repo running in IntelliJ + was able to test it. It would seem better to just add this small functionality to the existing Runelite 'Key Remapping' plugin, but I didn't get that working in IntelliJ to properly test it, since I got all kinds of errors...
Hmm could be, I'm still very new to making plugins. I made a PR with the described information related to it. I didn't get these kind of issues with my own plugin repo, but that is like 100 times smaller than the whole Runelite repo
poolNextBack allocating a pool and passing it to poolEntryMatchesSize() is relying on AWTContext being calloc'd to have surface == 0. But despite this you are still zero initing most of the rest of the restructure for no reason. This is confusing.
Please do include a setting for world hopper:
[ ] Display packet loss
So that I can have display current ping enabled but I do not want to see the packet loss (unless I check that box).
Thanks this feather would be great for when servers have alot of packet loss but are playing fine and I don't need the anxiety of staring at the number in the top right corner but I do want the other information such as ping, basically just make Display current ping only display current ping and have a sep...
https://github.com/runelite/plugin-hub/pull/10548 Am I just waiting on someone to review this? been sitting for 2 weeks. want to make sure I am not missing something
you dont have to do anything, if there was something to be done i think some one would've commented on it
theres just a queue for reviews/new stuff.
does that plugin basically exist already
just the tag part, not highlighting, but yes
the tag plugin is barely maintained and only half works
fix it maybe
they dont respond to pull requests
take it over
Sorry I have no idea why that closed...
poolNextBack allocating a pool and passing it to poolEntryMatchesSize() is relying on AWTContext being calloc'd to have surface == 0. But despite this you are still zero initing most of the rest of the structure for no reason. This is confusing.
Agreed, should be should be cleaner now - thanks!
no thanks, I have a working plugin im not fixing someone else's work
Have you asked the wiki people if theyโre fine with your plugin hitting their api? Usually theyโre not ok with plugins hitting dynamic apis directly
its the same way the other plugin hits it
It hits it one time not constantly and caches all ids in the category
I think if its on manual search like that they're okay
Fair
The person that usually reviews new plugins is away for a bit, hence the long wait time
there's 1 open pull request on it and its a draft. They added a new collaborator to the repo a few months ago when it broke last time
like i said. I have a working plugin that I will maintain. im not fixing someone else's work. if it doesnt get approved so be it.
But thereโs no further action required from your part yet
dupe plugins are discouraged but not disallowed
not truly dupe either My focus is on the highlighting for easier bank organization. his is the bank tag feature.
i added that feature so you dont need both plugins
The plugin is still mostly the same but it doesn't matter
every time you update a submission you push it to the end of the queue, looks like this wS updated 4 days ago
so its kinda far down
think ill have some time tonight to make progress but idk
@random narwhal can you give this rlawt build a test? https://github.com/runelite/rlawt/actions/runs/22285974929 particularly make sure the retina scaling stuff is ok / working the same as before
and I guess anything else you have (external displays?). and screenshots.
thanks Adam, if anyone has any issues with it feel free to give me a ping ๐
Is there a way to specify search labels for the plugin hub? Also, where does the plugin icon go for display in the plugin hub (website and search in runelite)?
Right now I have the default little plug icon and search only results in my plugin if you use one of the three words in the name
icon.png in the root of the plugin's repo, and hub tags in runelite-plugin.properties
Is there a required icon size for that display? I believe the in game icon is 48x48
How to develop plugin-hub plugins: https://github.com/runelite/plugin-hub/blob/master/README.md
step 10
@desert fulcrum can you update ground object hider to also not work in hmt sote region?
apparently it's being used to cheat the maze there
I noticed the PR backlog is getting pretty massive. How do you typically recruit new reviewers? Would there be any interest in adding some sort of PR static analysis to look for red flags in code to speed up reviews?
the more we merge, the more people pr--quite the conundrum
Not everything in the pr queue needs to be core with hub existing too, wonder how much of it can be closed due to that
i think they mean the hub
the hub quue is also getting bigger lol
More core plugins just means more for Adam to care about outside of core making it work lol
Oh
I was referring to hub actually, but same question for core I guess
yeah it's a big job
Thankless job and he does it well
I love rikten but seems like they are doing basically everything
What is wrong with a queue that takes a bit
Doesn't seem very sustainable
we have other people that sometimes do stuff but basically everyone has a life
Well I have bug fixes waiting around for days ATM and that's been unpleasant
there seems to have been an influx of plugins lately too
i'm not sure if it's alwys this extreme
it's always like this
oh dang. the ai submissions seem really rough to sift through
There is
i woudln't want that to be my job
Yikes
You can see when rikten started but also when Claude coders showed up.
i guess y'all aren't taking an official stance against vibecoded plugins yet?
As long as they donโt break rules it doesnโt matter if they donโt work well but I think folks are causing some issues with freezing client threads and other stuff that makes reviewers actually check more
i know i've seen the wiki ai policy cited numerous times
I'm wondering if static analysis can help find risks in vibe coded stuff to speed up stuff for the current reviewers. I would take a stab at it if there's interest from reviewers
we already have that at the reviewer level
the bot even yells at you if you are lucky enough
Oh ok then. Glad I asked
go wild
My man
this is just a bad idea, it would cause endless upset and i don't really have an issue reviewing vibe coded plugins
that's fair
i think the pr queue is manageable i just havent had much time to touch it this month. in december/january we were super active on it
Speaking of reviewing is the duplicate plugins on hub not a thing to point out anymore on new ones
is there stuff we can do as plugin developers to make the review process easier?
So many people are just creating new of the same ones that exist with one more feature
that reminds me https://github.com/runelite/plugin-hub/pull/10658 should i wait for this guy to respond or just pr my version dont like the idea of stepping on "his toes"
i think this is just coz its quicker / more easy then getting into core also ๐คทโโ๏ธ
they do it of other hub plugins too
i ask if it's obvious but 99.99% of the time they say "i don't want to contribute to existing" or they get ai to write a dietribe on why their plugin should be separate so idk how worth it that is
everyone wants 100% control of their own thing instead of collaborating
the official stance is dupes are allowed
some of this i get tbh
well yeah we're runescape players, we don't talk like talking to strangers
i guess some people just don't want to compromise when collaborating makes a issue
really the only thing i actively dislike is when people submit monster PRs that sit there for months/ years and then they get upset because they dont seem to understand the world doesn't revolve around their 20000 line plugin
that is just ignorant
but fortunately extremely rare
scared to submit one of my new plugins waiting for backlog to slow down ๐
mhm yes me too thats definitely why i'm procrastinating on my big update
nothing to do with the swing work or fear of changing my data structure
i may need to split the plugin into so smaller feature prs tbh so big atm with all the object placing logic and ui
swing what's not to love
i'm sorry i never learned how to read digital clocks, its taking some time
I'm a dummy and I forgot to add a file to my last PR and now my plugin has a startup error. I'd appreciate a prompt review if anyone is available. Thank you!
https://github.com/runelite/plugin-hub/pull/10702
oh cool I'm purple now
Is there a reason why you are telling people we are "slow to review PRs" when all of your PRs, including the large ones, were all reviewed in a very reasonable time frame https://github.com/jhughes/glamourer/issues/15#issuecomment-3941375073
:< telling people to do config surgery doesnโt work when the cloud sync overwrites it anyways.
This is not some slight on reviewers or something. I'm new here and getting used to the process. It's frustrating for me and my users to have a bug fix that prevents the plugin from loading sit around for days to be reviewed.
I understand reviewers are people with lives and I appreciate that this is volunteer work; I'm not trying to say y'all are doing a bad job or anything.
I'm fine to have new features sit around for as long as necessary, but bug fixes are frustrating to have to wait for. I'm learning that I need to wait to send a PR for a new feature until I have a day to resolve bugs from the previous one or I screw myself
Conversely, it is frustrating for us to merge a hub plugin update just for the author to realize it's buggy and needs fixing, and effectively make it our problem to review it in a hurry
It's quickest and easiest to just revert something that doesn't work, but that's not the route most people want to go when a rollout uncovers bugs
From my perspective rolling back and rolling forward are the same, if I can roll back faster I'd be happy to do that.
As far as I'm aware both require the same review process, is that not right?
Reverts basically don't require review because they roll back to a state which was already approved
I'll be fair and say "hotfix" type updates usually are pretty quick to review as well since they tend to be small, but they are at least some amount, not none
But it still requires review right? It won't auto approve? The fix is literally adding a png file so I'll probably leave it if it's the same
Yes it doesn't get automatically merged
I'll review your pr tonight if someone else doesn't get to it first, I've just got sick kids to look after for a few more hours until it's their bedtime
Much appreciated
it'd be merged faster if the diff was just the png inclusion & no code changes btw
but i'll take a look now
Thanks. Sorry, I will try not to be as much of a pain in the future.
Is it acceptable for injected classes to subscribe to events directly, or should the main plugin class act as a mediator between events and classes?
The developer guide states that events "must be located in the plugin class" but I'm fairly sure that I've seen some popular plugins subscribe elsewhere.
im not home for a week. if someone can pr a fix and test i can update the plugin.
doesn't matter, people do both.
must be included is because people wouldn't know they have to explicitly register with the event bus otherwise
the developer guide says it must be included in the plugin class since you have to do a bunch of advanced stuff to make it work otherwise
and the developer guide is written for people who are brand new
Classes registered to the event bus can subscribe to events, and the plugin class is automatically registered
Okay got it. I'm injecting classes into the main plugin and subscribing/unsubscribing those classes from the event bus in the startup and shutdown methods.
Is that a sensible way to do it?
yes
Great, thanks everyone.
reading some scrollback about duplicate plugins, i noticed someone forked better npc highlight added a feature, but also changed all the metadata to make it a separate plugin. If that ever materializes in a plugin hub submission feel free to tell them they should talk to me about adding features because im happy to discuss design and review PRs. they just havent done any of that at this point
we will do that but we can't exactly force them to
I cant tell you not to accept a 99% duplicate of an existing plugin, im just letting you know im very open to others contributing and havent told anyone they cant
@upper valve why was that a thumbs down?
Time-to-merge for phub PRs has only gone down over time, and yet despite that it has felt like there is an increase in people complaining that their PRs take too long to get reviewed. The number of PRs opened per week has also gone up. While someone might review it ahead of others if you ask a courtesy, it can also be unfair to others who have issues in their plugins waiting to be merged to be skipped over to review yours.
b41a8c2 update chance-man to v3.0.4 (#10627) - ChunkyAtlas
4b836c0 update dizana-alert to v1.2 (#10633) - Servilabs
450866d update uwuscape to v1.02 (#10644) - LunelleVatrinea
540ce20 update flipping-copilot to v1.7.21 (#10643) - cbrewitt
Everything seems to be working as far as I can tell. ๐
(it gave me the usual security warning trying to run the dylib, but that's expected)
Search for Combat Achievement Exporter returned no results.
[ https://github.com/cdfisher ] [ @sharp knot 288504448030867466 ] duralith#0
build fails due to this Error: eckstyle] [ERROR] /home/runner/work/runelite/runelite/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java:74:8: Unused import - java.util.stream.Collectors. [UnusedImports]
I've defo noticed the improvement it's insanely fast now often same day same week, used to wait 2-3 weeks
The team here is doing a great job
Good morning. I wanted to check if you had a chance to read the review comment, and if these changes are appropriate. If so l can go ahead and apply them to the PluginListItem for the core plugins as well.
When using --insecure-write-credentials for testing on a jagex account, is it possible to save these creds so that they dont change when loading up a different jagex account to play the game normally?
But keep them in that file to launch using the same account when running shadow jar's etc?
Just uncheck the option in the launcher
You only need to run it with that once and then the file is there until you delete it
so just remove the arguement after it's added the info for the account you want to use?
Ok cool, because currently its overwriting with whatever account i launch in jagex first
so that makes sense, cheers
There's a few of use playing a group plugin I made but i'm not really interested in submitting it to the plugin hub so we are just launching through a shadow jar to play, I'm assuming this isnt against any TOS as long as the plugin is clean?
Correct, as long as you're not breaking the rules it should be fine
If you zoom all the way in and make your window really small to get your FPS high (like 120+) you should notice the flicker issue is gone hopefully
Hey everyone, first time working on a plugin. Can someone let me know if this seems reasonable what I have so far and if there is anything special needed when updating a default plugin?
that doesnt sound reasonable to me, why would someone playing the minigame not actually want to play the minigame. Introducing a config option like that seems like bloat
To make it more AFK
then turn off the dispenser notification?
They want to only get the dispenser when itโs 1 jump away, but donโt you need to get 2 in a row to get any rewards or is it 2nd one and beyond that give any rewards?
This looks like hub stuff to do tho rather than core
looks like the "initializing" was removed two years ago
Players no longer need to tag two pillars back-to-back to earn tickets.
The idea is to sit beside a pillar and alert if it is right next to me. There's already an external brimhaven agility path plugin, I can see if that guy will accept the change if it shouldn't go into core agility
if they dont want that change you can just make your own hub plugin
they changed it. every pillar gives rewards now
I would definitely go with retrofitting that into the existing hub plugin if that's a viable option (you could also take advantage of their existing pathfinding stuff and ability to block specific obstacle types from consideration when checking if a pillar is 'close enough')
Thank you for pointing that out! Fixed.
unfortunately trends on data have always annual exponential growth, so I would expect claude-written plugin creation to accelerate over time. imo, it may be something to think about if it results in poor UX, increased support tickets and reviewer strain
im pretty anti-ai so my opinion is biased
GitHub
An opinionated version of the example runelite plugin - pajlads/runelite-plugin-template
there are no support tickets lol
lol ik i meant increased activity in the runelite/support channels
I dont think the ux has decreased noticibly from back before ai wrote everything, most people aren't good at coding either
yeah
.. or ux
claude begone
most of the people writing plugins are not industry professionals. nothing really changed other than volume
if anything the ux might be better with ai
fair, though overdependence leads to less comprehension but considering most plugins are tiny it's probably not an issue in that context
i think are you overestimating the average plugin/plugin author lol
the vast majority of the authors are basically runescape players who vaguely can sort of code. they arent software devs
also if a plugin is enough of a problem we can sort of just snap its neck in 2 seconds and move on with our day
weve been able to offset the problem of increased submissions just by adding more reviewers which has sort of worked
at least it is a lot better now than it used to be
Author of the Brimhaven agility plugin here; agreed my plugin is a good place for this to live since the existing pathfinding logic should make it fairly trivial to add ๐
My only concern is that if enabled, users might get double notified because of the existing notification in the core Agility plugin. But if we have this new one off by default, and have a reasonable hint on the configuration option to turn it on telling the user that they'll likely want to turn off the notification in the core Agility plugin, then I don't think that'll be much of an issue.
I can see the appeal for this; lots of people seem to sit in the Agility Arena just spam clicking the obstacle where you don't need to move your mouse, but probably wouldn't be opposed to additional XP from tickets when they're close.
@feral sluice has already reached out in an issue on GH, will orchestrate with them there
I saw in some past discussion that File I/O and networking requires maintainer review. Rikten said this doesn't mean much anymore because all active reviewers are maintainers; is there any reason to avoid these APIs at this point from a PR perspective?
we need to make sure you aren't doing erroneous requests or using data improperly
in the context of reviewer vs maintainer it still requires us to look at it
Will it affect the PR process in any noticeable way once it's submitted? Like if I add I/O once and then don't touch it again am I subjecting myself to longer queues or something?
no
Ok thanks
if I add I/O once and then don't touch it again
you are always in the "requires maintainer" mode once you add those APIs
if more reviewers are later added that are not maintainers they wouldn't be able to look at it as its always gonna be flagged, but currently no
ahh so no real issue now, but could be a problem later
it's not a per PR thing. the scanner looks at your entire plugin every time
Interesting. Thanks for the info. I had someone report that my plugin somehow wiped their config and I'm considering writing occasional backups to a separate file as an extra precaution. Has someone else done something like that before?
it wiped their entire config?
No just one part of my plugin's specific config
I'm using ConfigManager instead of the standard Config system for one part of it
you can backup to a file if you want but if you automatically use that as a source of truth you risk issues for people using multiple devices with synced runelite config
might be time better spent figuring out why it wiped
what does this mean
what it says ๐
Basic config uses net.runelite.client.config.Config
Glamour plates use configManager.getConfiguration
yea but the configmanager is the normal way to interact with the config?
the user facing configurations
Yeah I mean config panel stuff uses net.runelite.client.config.Config. The plugin panel uses getConfiguration and setConfiguration directly.
Everything in the profile properties is cloud synced, correct?
yes (if the user is using a rl account and that profile is set to sync)
but yeah using configmanager is very common so in itself is not a reason for losing data
Is there more info on the cloud sync lifecycle somewhere or just got to read code? I'm curious how it works in more detail?
thats normal, its how tags and such are saved to the config, but they arnt shown in the settings for the plugin
Yeah if my plugin did wipe someone's config it's just shoddy programming on my part. I can make it less shoddy for sure.
i think writing a backup file would add a lot of complexity and potentially break others for the use case above, basically just moving the problem. you're probably best just taking the hit for now and figuring out what happened imo
how much stuff did you write to it?
the server will reject writes over a few hundred K iirc
the actual key size limit is 256k i think
I could see power users going over 100k someday. It's not exactly saving an efficient format
My dev config is at 9KB right now. Almost certainly a power user will cross it :/
I'll probably have to rework this soon and gzip it or something.
you could write the actual content to a separate file instead of putting it in the config
Yeah it would be nice to work with cloud saves though. Any possible issues with saving entries as separate keys and loading them all by prefix?
you could, idk if there's still limits if you write too much overall though
you could also use serializer shorthands
I'm not familiar with this term; what does that mean?
instead of serializing {"somekeyname": value} it serializes {"s": value}
Oh gotcha. Yeah I can definitely serialize a more efficient format.
Whats hte best say to debug a memory leak from my plugin? My plugin is sometimes spiking memory usage from 1200mb to 5000-8000mb.
that is sort of an unanswerable question
Ok, so theres no way to monitor whats using the memory?
take a heap dump and use visualvm or eclipse-mat
Great thanks
Can JDK version or anything other than plugins commonly cause memory usage spikes? It's not constantly increasing but it'll spike after 5-10mins of gameplay and stay there
The dump doesn't show any plugins causing a memory leak
pass -Xmx512M as a jvm arg
java likes to allocate a large heap if you have a lot of system memory
214c3bf update afk-marks-canafis to v1.1 (#10586) - FIrgolitsch
a59a911 update unmutedjingles to v0.22 (#10579) - hootisman
Hi Team - sorry to be a pest or bother. Reached out to a plugin reviewer and was suggested to post here. I'm the developer of the lootbag.gg plugin. Ran into a nasty bug that starts at the plugin level. I understand there's a good bit of other PRs out there. Just wanted to see if you have time to look at a 2 liner change. The plugin is already live and was hoping to get this fix out as soon as possible.
Appreciate the quick response. The plugin tracks trades. Right now, I overlooked on the original pass partial trades. Right now it sends over the wrong information to our backend servers that people are actively using. The fix here is to handle those use cases
66046ea Update embargo-clan-plugin to v1.5.9 (#10713) - Sharpienero
0a6ed32 Update lootbag to v1.0.1 (#10712) - StephenMarkToms
52a16eb Update unmutedjingles to v0.22.2.2 (#10714) - hootisman
Wow there are like 100 open pull requests. I'm curious how often it could happen that when a PR is made everything is fine, but then after a while the master branch is updated by other pull requests resulting in conflicts or that the code in the existing PR needs to be adjusted because some logic in the master branch changed or something. Anyone has experience with something like that happening?
all the time
Do you mean the runelite repo or the plugin-hub repo? Because with plugin-hub nobody should really modify your file so conflicts are rare
I closed the pr the last time that happened.
(it was kind of a bad pr)
I wouldn't update it though
unless someone asked
given there are only 50 open on the hub, and 700 on core, idk which they're talking about lol
That's why I asked, I was like surely there's way more than 100 open on core
please clarify which repo, people are getting distracted
i'd say some AI repo but i dont know any of them
another mention to wake up to ๐
Type
Incorrect behavior
Operating System
MacOS
OS Version
Tahoe 26.3
Bug description
Hi,
Iโm running RuneLite on a MacBook Pro and have never had issues before, but recently Iโve been experiencing an intermittent mouse input problem.
At random times, my mouse clicks will either: Not register at all, or register in the wrong location; sometimes up to 5โ6 tiles away from where I actually clicked.
When this happens, the only temporary fix is fully restarting the RuneLit...
b978234 update random-event-helper to v3.2.0 (#10680) - Infinitay
798ea62 update loot-ledger to v1.1.2 (#10698) - ChunkyAtlas
@trail marten I found a bug in tag layouts (I think?), it's been there forever. If you have two different layouts that have the same name (i.e. one contains the other), then the items from the shorter name will be shown in the same layout as the items from the one with the longer name
that is a bank tags issue
sorry it's the other way around, the shorter name will display the longer name's items
it's not really a bug
you wanna say it's a feature?