Friya

Members
  • Content Count

    106
  • Joined

  • Last visited

Everything posted by Friya

  1. Possible issues (some of the TODOs I wanted to fix before throwing this out there) On some clients you will have a bit of jerkiness at some movement speeds (tweak and see what works for you) When focusing on objects nearby you can get some rather fast camera moves if you traverse over the same point you are focusing on (avoid this by focusing in same direction but at a bit larger distance). If I recall correctly I tested some hacks here just before I paused development -- they may or may not be working Following a moving object needs to be smarter (right now it's just a simple combination of two linear interpolations if I recall) Before I paused development I had a TODO saying this: "Huh. It seems the renderer crashes after we've run a scene a dozen times or so... Is this reproducible?". This is unconfirmed. Following objects underground will not work Due to a limitation in Wurm, "moving/animating time" slowly will never look great with the shadows. Never seen it mid-scene myself, but changing time on the client may be overridden by server at any point (you can probably use the timelock mod to prevent this) Traversing too large distances will get you kicked off server -- should limit creator from sillinesses like this (but for now, I advice restraint) Probably a lot of debug messages in log and the Cinematics tab A conceptually large server component is not completed (not needed to run or use this) Need player/creature name in object notes (my VM crashed, cannot check the Wurm source ... for now) (no idea what I meant with this one) When you first enter the game, automatic activation of Cinematics tab does not visually indicate that it's currently the selected tab. A few of the examples are incomplete and/or missing - ...and a whole heap of features that are mostly extending on already implemented functionality
  2. This is a client mod that will help you create awesome looking videos in Wurm. This is an Alpha release. Real life dealt some bad cards this way and this code's been sitting on my harddisk 99% done for a few months now. I have not halted development of this, merely paused it for a bit. That said, as you may or may not know, I tend to keep my code updated to the best of my ability -- so please post feedback (positive feedback is nice too). I cannot promise I will be able to reply quickly, but I will eventually. All I really ask from you is please share your videos, tips, tricks (at least here) and encourage others to create awesome looking Wurm videos so we can get more people hooked on Wurm. My intention at some point was to create a real cinematic story that would showcase a lot of the features, did not happen, sorry. I'll instead just give you a very, very simple example that sat on the disk. This took about a minute and five mouse clicks in-game to create... (there may be more videos at https://vimeo.com/user61749266 but these were recorded to document progress rather than being a show case) Brace yourself, I have written quite a bit of documentation to get you going. More information and download: http://www.filterbubbles.com/wurm-unlimited/cinematics/ Get started: http://www.filterbubbles.com/wurm-unlimited/cinematics/getting-started.shtml (scroll down) How to create scenes (etc): http://www.filterbubbles.com/wurm-unlimited/cinematics/documentation.shtml (scroll down) How to install: http://www.filterbubbles.com/wurm-unlimited/cinematics/getting-started.shtml#installing I'd write more here, alas, there's no time. Please browse the site above.
  3. Fixed to work with 1.8.* (use link in original post). I realize I may have some unanswered questions and such in this thread, unfortunately real life is rather difficult at the moment so I have just fixed critical issues. In general, it's best to simply check http://filterbubbles.com for updates as I am more likely to just upload a new release there than post here at the moment. (any other code of mine seem to work without updates)
  4. Fixed to work with 1.8.* (use link in original post). I realize I may have some unanswered questions and such in this thread, unfortunately real life is rather difficult at the moment so I have just fixed critical issues. In general, it's best to simply check http://filterbubbles.com for updates as I am more likely to just upload a new release there than post here at the moment.
  5. Intermittent crashes or freezes are horrible, using a "game hoster" or not. Servers have died and been shut down for less. This will at at the very least help pinning down possible problems that may be introduced by a mod, a combination of mods or just plain old server bugs. I wrote this software to assist me in tracking down problems on a server that was getting intermittent freezes -- and it was rare enough that you want to be able to nail it when it first happens -- alas, I was not clairvoyant enough -- so here we have this mod -- a tad bigger than I thought it would become. I share it because I know I will rely on it in the future. It's a bit of a mish-mash of things (*), but I left it all in there as configurable options. It grew out of me eliminating causes of a problem. It was a server where I did not have any access, issue was not reproducible on a test server, and had an absolute crap-ton of mods. Read: I like a challenge (har har). Later on it it also grew into a tool to help me optimize the server code (or at least my behaviour around it). I have to say it's quite pleasant to be able to pinpoint and measure execution cost without modifying actual source code; I may actually start using a similar approach in non-hobby projects. Dumps If you have full control over your environment and have the technical abilities you may want to hook up some external tools to solve a lot of your problems. That said, this program can also output a stack and/or thread dump if it detects slow calls in a monitored area. It may even be easier to use this than other tools. Note that in many cases this will only point you in the direction of the problem. It could still mean you have a lot of work to do from there (i.e. chasing calls down the chain with more monitoring). The server is half-decent at tracking laggy calls itself (albeit a lot less granularity than what is possible using this), aaand provided the call actually finishes! The original usage of the monitor.* properties outlined in the config file below was to distinguish it from a complete freeze or something else (the problem was rare enough that I threw things on the wall to see what stuck). That said, you can monitor execution cost of any method on the server (to pinpoint strange hot areas) -- and attach possible interesting objects from that context ... to really nail it. To do this, use the monitor.* setting below. You can add as many of those as you may need. It's a pretty powerful tool and if I wasn't chasing a bug I'd start looking at a few spots I have taken notes of where I can optimize the actual WU server (optimizing -is- fun). Hard to reproduce exceptions Funnily enough, it turns out this is a great way to pin down intermittent exceptions. If you add a monitor to a call that takes place in a stack trace -- and wait (without much pain), if that call never finishes (i.e. it threw an exception), a warning will be printed in the log (options to include traces as well). To get the detail of which object is the offending one (say a specific creature), add an argument to the monitor (e.g. $0 for this). For a few special cases (like Zone), instead of just grabbing toString() of the object I output e.g. zone X/Y. I intend to add more humanly readable strings of object as I need them, but yeah, it's primarily toString() at the moment. Combine arguments to a monitor with a full thread dump on a slow call and any freezing or hanging problem should become evident rather quickly. Albeit rather spammy if you let it hang too long. A few warnings Monitoring methods will likely not play well with recursive methods, monitor those from the "outside" (never tried it) Monitoring methods that might be called by several threads simultaneously will get dodgy, no doubt (never tried it). Performance impact This mod is written with performance in mind, even if you choose to monitor tight loops it should not affect performance *too* much. The idea is that you can have this running on a live server and just wait for the problem to happen. That said, be aware that it does add a bit of overhead. And might be noticeable in hot tight loops. The cost of having something nice... Searching in spammy logs In order to find warnings in very spammy logs, search for "Hey Friya" (I kept it in there because I could) -- any offender will be tagged with those words. If you find too many "Hey Friya"'s, it probably means your slow call thresholds are too low -- set them higher. (*) the mish-mash: Dump methods calls in a method (in a format for easy copy/pasting for monitoring.* Log a brief version of data stream coming to and/or going from the server Logging of all actions created (read: new Action()), whether by NPC's or Players Slow mod detection; monitoring default mod hooks Monitor if main loop is still ticking Dump all classes modified by Javassist (I do not decompile them for you ) Dump thread info on slow running calls Monitor itself (! okay, this is a lie, but it will output a message every now and then to indicate this) A few more pointless monitoring options (they all sit in the same thread -- hence pointless) Storage of monitored methods executed since entering a hooked method (this helps determine the code path taken through a method) Various options to specify frequency at which things can happen Dump stack-trace on completion of a slow call Dump stack-trace of a monitored call that is still running ... and a few more things. Well, outta here. Cya on the flip side. Example of a properties file: Download latest version (install like any other server mod)
  6. It's funny that you mention it, was just sitting here talking to someone saying that it would only be at a certain speed. So it might only be happening in combination with mods. But yes, definitely -- mods affecting movement speed all over the place. The creature I have seen causing this is not in a 1x1, but I have been betting on it being in a corner of the enclosure. Thanks for taking a look, it does confirm that I'm not barking up the wrong tree.
  7. I've been chasing a bug in Wurm for a little while now. To a client it reveals itself like this when you try to log in: "Waiting for Steam authentication...", and it will hang there. There are probably situations where you see that message and it actually is true, but in the case of this bug it's just an unfortunate side-effect. The server is most likely hanging in a deadlock or an infinite loop. It will not accept any new connections and all connected clients will eventually disconnect due to timeouts. What you will see in the server log are some threads chugging along doing some work (outputting statistics and such), making it seem like it's kind of working. In the case I was asked to help track down, it was not, the mainthread is frozen (deadlocked/infinite loop). You have to restart your server in order to get things going again. So, off I went to find out where... and it SEEMS I have found it, but I'd like a few more eyeballs on it before I call it a day and pat myself on the back. It lies in the movement code of creatures and it's called from a bunch of different places. This code was introduced somewhere between 1.4 and 1.6 (I was out of the loop so don't have source for all version). It probably all came with the introduction of the "Creature Movement Changes" feature. In Creature.takeSimpleStep() we have: ... a little code ... for (int x = 0; x < mvs; ++x) { ... lots of code ... if ((lDiffTileX != 0 || lDiffTileY != 0) && !this.isGhost()) { ... even more code ... if (Features.Feature.CREATURE_MOVEMENT_CHANGES.isEnabled()) { this.turnTowardsTile((short)this.getTileX(), (short)this.getTileY()); this.rotateRandom(this.status.getRotation(), 45); x = 0; this.getStatus().setMoving(false); continue; } ... some code ... } ... even more code ... } ... even more code ... Setting x to 0 in the iteration here ... is potentially lethal. I am curious if anyone with access to the original source code (or author of the code) can shed some light on the intended behaviour and/or state that this can never cause an infinite loop due to the conditions set by: this.turnTowardsTile((short)this.getTileX(), (short)this.getTileY()); this.rotateRandom(this.status.getRotation(), 45); this.getStatus().setMoving(false); I have a hard time wrapping my head around the scenarios and the intentions (hence request for more eyeballs). That said even if it is guaranteed that we will not reset x every iteration, I have to say that this is also terribly nasty programming. ? If this is indeed causing spurious errors on your server a work-around for now: Disable the server feature "Creature Movement Changes" and it should fix the problem until a real patch can be released (since I don't know the intentions of this, I will not release a patch myself). But first and foremost, would like to hear some feedback on this as I have simply run out of patience waiting for the bug to manifest itself on a live server (it's rare enough). TLDR: for (int x = 0; x < mvs; ++x) { if(condition) { x = 0; continue; } } // we might never get here.
  8. Was mucking about in the garden, went inside for a few minutes, come back out to find this...
  9. Hey MystLeissa, There were indeed some things that's moved around in Wurm. I did not spend much time testing things, but I did try bury and devour, both things should now work. Let me know if I'm a dirty stinking liar! The download is the same as in the original post. Edit: PS. I am sorry to hear about the all the vampires dying from soul feed. But hey, we all know they are the evil ones and the slayers are the good ones, right? Right?
  10. Like you suspected, there is a faith requirement (50), deity requirement (BL / WL)... but also a skill requirement of 25 in soul strength or soul depth (depending on Deity). You also cannot have been a champion in the last six months.
  11. Try binding it to all your interfaces, mod here somewhere:
  12. Thanks for getting back with an explanation. This exception really got me curious. Glad it worked out :) oh and let me also give huge praise to Brash for always lurking and having good advice in this corner of the forum :)
  13. Well, okay then. Let's give it one more shot -- with reasoning then. The reason I am suggesting a forced repair of Wurm Unlimited is because a number of things could have gone wrong with your installation. This could be access permissions, diskspace, memory, corruption of a file, anything. So, try breaking your install and let Steam go over your installation -- it's probably the fastest way -- at least faster than trying everything what possibly could have gone wrong. The line in question that is throwing an exception in the modloader has no magic, it just wants to open client.jar. It failing suggests something out of the ordinary is wrong, and frankly it smells like an IO error to me (but no, I have not looked into the newFileSystem() method). Oh, and while running patcher.bat, make sure nothing has a file-lock on client.jar. If you are certain that you know that you've done everything right (and I do think you are doing everything right -- or at least have had no reason to think otherwise). But obviously something has changed on your system, if it worked yesterday.
  14. Well, if nothing is wrong, then I can obviously not help you. The fact that your mods are not working is because your modloader cannot patch your client; this is not a mod problem. The modloader is failing when attempting to access client.jar -- this is not normal, which is why I am asking about modloader, the client folder and your system. But if everything is okay in your Wurmlauncher folder...
  15. This was an interesting one... 1. Are you using the latest client modloader? If not, install that. 2. Do you have free diskspace on the disk where your client is installed? 3. Are you extremely memory constrained on your computer? (as in, little free memory left) 4. Have you tried rebooting your computer, and before doing anything else, run patcher.bat? If the answers to the above are all 'yes', try repairing your WU install in Steam. If Steam says everything is just hunky dory, break the installation by deleting say client.jar (also delete client-patched.jar for good measure)in your WurmLauncher folder, then ask Steam to repair it again. Umm, further questions if the above was not successful: - Can you give a screenshot of your Wurmlauncher folder?
  16. So, anyway... Apparently I left this mod unmaintained for too long... Note, bug: When mucking about on my test-server earlier today I noticed the detection of improved/failed spells was off, I'll post an update for that when time allows. If the wrong message is a bother, just disable the two options for now (that is: showPowerOnSuccessfulCast and showPowerOnFailedCast) . Changes: - Some refactoring and cleaning up - Drunken development bugfix (get player from persistence instead of logged-ins) - Configuration option: Output strength of cast to user when they successfully land - Configuration option: List of spells affected - Configuration option: useLegacyMessages (power in [...], caster in (...)) - Configuration option: showCasterNameBasedOnPower Example of "Show Power On Successful Cast": (you can toggle output of power for both successful and failed casts) Future of this mod: In the spirit of its name, at some point down the line I'll probably add... Support for free casts - high (and/or lucky) cast = caster gets a free cast (think rare) Support for caster names when it comes to runes (and *possibly* imbues) Ability to specify which spell to dispel on an item (other than fixing this annoyance, this is also relevant since you might want to purge names of other casters due to "reward system" below) Rare prayers (don't we all love them) is rewarded: on PVP server -- 3-5 instant casts; on PVE server -- 3-5 free casts A reward system for casters whose enchants are used. Still prototyping on this, the long-term idea is to at least make it viable to have a priest as (almost) a main and remove the need for "everyone is a priest". The ground work for this is done with this mod as it will start keeping track of who casted what. The configuration file contains some information, so pasting it in here for the details: # # Some love for the poor priests. # # I may or may not add more functionality over time. # # -- Friya, 2018 # classname=com.friya.wurmonline.server.priestlove.Mod classpath=priestlove.jar sharedClassLoader=true # # When priest successfully land a cast, they will see the strength of the cast in the event log. # E.g.: Your Courier cast landed with a power of 98. # # Set to false if you want don't want to ruin the surprise. # # Disable this behaviour by setting this to false. # showPowerOnSuccessfulCast=true # # Instead of just seeing that you failed to improve a cast, show just HOW unlucky you were. # showPowerOnFailedCast=true # # Personally I find the use of [ ] to convey the power of spells extremely ugly. But I can see # that it is of interest because of habits. # # That said, if you prefer ugly messages, set this to true. ;) # useLegacyMessages=false # # I like the idea of obscuring names on low-quality things in Wurm proper, but I do not agree # with how it's done. That said, I added it because it felt appropriate. # # You can turn behaviour off for spell-casters by setting this to false. # showCasterNameBasedOnPower=true # # Spells (their class names) that should be supported with names of the caster (typically only # spells that has a power and that can be cast on items). # # If you have custom spells living in the standard package (com.wurmonline.server.spells), simply # add their class name to the list below. # modify.spells.in.com.wurmonline.server.spells=Courier,Nimbleness,LurkerDeep,Opulence,CircleOfCunning,MindStealer,Bloodthirst,SharedPain,DarkMessenger,LurkerWoods,RottingTouch,Frostbrand,Nolocate,LurkerDark,WindOfAges,Venom,FlamingAura,WebArmour,BlessingDark,LifeTransfer # # For custom spells living outside of the default Wurm spells package, add the following # configuration line: # modify.spells.in.<name of the package>=<comma separated list of class names> # Make sure class has a doEffect() method with calls to addSpellEffect() and improvePower(). # # Example: # modify.spells.in.com.awkward.person.spells=SuperSpell,SubtleSpell # # (Note: this is untested, but should just work, I suppose -- if any trouble, just post in the # announcement thread). # Download link in the original post is updated.
  17. Poor priests, always neglected. Always alts. They grind their faith, they grind their channeling, no one will ever know. This will give credit where it's due. Enchants on items will reveal who did the cast. Example: https://i.imgur.com/bKIdXjA.png Given the rather vague name of this mod, I may, or may not, add functionality here. I have ideas, but if you have some as well, I'm all ears. Download *hic* (yes, very untested)
  18. # # A little mod to make my life easier; provides the #goto command for GM's. # I was SO fed up with having to use the wand. # That's it. # # Someone else probably already made a mod for this and I just did not know about it. # # Usage: Type #goto in any tab. # # Syntax: #goto <x y> # or #goto <deed name> # or #goto <player name> # # If the deed is multiple words, use quotes. E.g. #goto "Friya's Fantastic Fellowship" # If there is a deed called Friya and also a player with the same name, distinguish the two by doing #goto deed Friya or #goto player Friya # If going to coordinate, make sure it is within the map boundaries. # You cannot go to invisible GMs. # # - Friya, 2018 # Download And here's the source code for anyone wanting to do ... more. package com.friya.wurmonline.server.admin; import java.util.ArrayList; import java.util.StringTokenizer; import org.gotti.wurmunlimited.modloader.interfaces.PlayerMessageListener; import org.gotti.wurmunlimited.modloader.interfaces.WurmServerMod; import com.wurmonline.server.Players; import com.wurmonline.server.creatures.Communicator; import com.wurmonline.server.players.Player; import com.wurmonline.server.villages.NoSuchVillageException; import com.wurmonline.server.villages.Village; import com.wurmonline.server.villages.Villages; import com.wurmonline.server.zones.Zones; public class Mod implements WurmServerMod, PlayerMessageListener { @Override public boolean onPlayerMessage(Communicator com, String msg) { if(com.getPlayer().getPower() > 0) { // Verbose because I -may- want to add more GM commands. if(msg.startsWith("#goto")) { return cmdGoto(com, msg); } } return false; } private boolean cmdGoto(Communicator com, String cmd) { String[] tokens = translateCommandline(cmd); Location loc = null; if(tokens.length == 1) { tell(com, "Syntax:"); tell(com, " #goto <x y> or #goto <deed name> or #goto <player name>"); tell(com, "Examples:"); tell(com, " #goto 500 500"); tell(com, " #goto \"Friya's Home\""); tell(com, " #goto friya"); tell(com, "Notes:"); tell(com, " If the deed name is multiple words, use quotes. E.g. #goto \"Friya's Fantastic Fellowship\""); tell(com, " If there is a deed called Friya and also a player with the sane name, separate the two by doing #goto deed Friya or #goto player Friya"); tell(com, " If going to coordinate, make sure it is within the map boundaries."); tell(com, " You cannot go to invisible GMs."); return true; } if(tokens.length == 3) { if(isNumericUgly(tokens[1]) && isNumericUgly(tokens[2])) { // #goto x y loc = getCoordinateLocation(tokens[1], tokens[2]); } else if(tokens[1].equals("deed")) { // #goto deed loc = getDeedLocationByName(tokens[2]); } else if(tokens[1].equals("player")) { // #goto player loc = getPlayerLocationByName(tokens[2]); } } else if(tokens.length == 2) { // #goto <player name> loc = getPlayerLocationByName(tokens[1]); if(loc == null) { // #goto <deed name> loc = getDeedLocationByName(tokens[1]); } } if(loc == null || gotoTarget(com, loc) == false) { tell(com, "No idea how to go there... Typo? Coordinate is outside map? Target is invisible? Not a player? Already teleporting?"); } else { tell(com, "The fabric of space opens and you appear at " + loc.getName() + " ... or so you hope."); } return true; } private boolean gotoTarget(Communicator c, Location loc) { Player p = c.getPlayer(); p.setTeleportPoints((short)loc.getX(), (short)loc.getY(), loc.getLayer(), 0); if (p.startTeleporting()) { c.sendTeleport(false); p.teleport(); return true; } return false; } private Location getCoordinateLocation(String sx, String sy) { int x = Integer.parseInt(sx); int y = Integer.parseInt(sy); if(x < 1 || x > Zones.worldTileSizeX || y < 1 || y > Zones.worldTileSizeY) { return null; } return new Location(x + "x" + y, x, y, 0); } private Location getPlayerLocationByName(String name) { Player p = Players.getInstance().getPlayerOrNull(name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase()); // if target is an invisible GM, disallow going to them (caller will give a generic error) if(p == null || (p.getPower() > 0 && p.isVisible() == false)) { return null; } return new Location(p.getName(), p.getTileX(), p.getTileY(), p.getLayer()); } private Location getDeedLocationByName(String name) { Village d = null; try { d = Villages.getVillage(name); } catch (NoSuchVillageException e) { } if(d == null) { return null; } return new Location(d.getName(), d.getTokenX(), d.getTokenY(), 0); } /** * Crack a command line. * * Shamelessly lifted from another mod of mine which shamelessly lifted it from * Apache Commons. See https://commons.apache.org/proper/commons-exec/apidocs/src-html/org/apache/commons/exec/CommandLine.html * * @param toProcess the command line to process. * @return the command line broken into strings. * * An empty or null toProcess parameter results in a zero sized array. */ private String[] translateCommandline(String toProcess) { if (toProcess == null || toProcess.length() == 0) { return new String[0]; } final int normal = 0; final int inQuote = 1; final int inDoubleQuote = 2; int state = normal; final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true); final ArrayList<String> result = new ArrayList<String>(); final StringBuilder current = new StringBuilder(); boolean lastTokenHasBeenQuoted = false; while (tok.hasMoreTokens()) { String nextTok = tok.nextToken(); switch (state) { case inQuote: if ("\'".equals(nextTok)) { lastTokenHasBeenQuoted = true; state = normal; } else { current.append(nextTok); } break; case inDoubleQuote: if ("\"".equals(nextTok)) { lastTokenHasBeenQuoted = true; state = normal; } else { current.append(nextTok); } break; default: if ("\'".equals(nextTok)) { state = inQuote; } else if ("\"".equals(nextTok)) { state = inDoubleQuote; } else if (" ".equals(nextTok)) { if (lastTokenHasBeenQuoted || current.length() != 0) { result.add(current.toString()); current.setLength(0); } } else { current.append(nextTok); } lastTokenHasBeenQuoted = false; break; } } if (lastTokenHasBeenQuoted || current.length() != 0) { result.add(current.toString()); } if (state == inQuote || state == inDoubleQuote) { throw new RuntimeException("unbalanced quotes in " + toProcess); } return result.toArray(new String[result.size()]); } /** * Despite this using an exception for functionality, I am okay with it. It's executed rarely enough and definitely rare enough to trigger the exception. * * @param str * @return */ private boolean isNumericUgly(String str) { try { @SuppressWarnings("unused") double d = Double.parseDouble(str); } catch(NumberFormatException nfe) { return false; } return true; } private void tell(Communicator c, String msg) { c.sendNormalServerMessage(msg); } } /* ------------------------------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------------------------------- */ package com.friya.wurmonline.server.admin; class Location { private String _name; private int _x; private int _y; private int _layer = 0; Location(String name, int x, int y, int layer) { _name = name; _x = x; _y = y; _layer = layer; } String getName() { return _name; } int getX() { return _x; } int getY() { return _y; } public int getLayer() { return _layer; } }
  19. That should just .... work. I use that quite extensively myself. I can't even come up with any idea of what could possibly go wrong? hm
  20. I started dabbling with WU again (we always come back to Wurm! <3) and wanted a bit of new functionality. Sooo.... here's an update to this ... thing. Get some numbers on what is happening with your loot / server You get statistics by typing /lootstats as a GM (power 1+). This will show the stats in the player's Event log as well as in the server log. Any entries not shown when viewing the stats are still 0. That is, a stat will only appear if it's happened at least once. Provided there is activity on the server, statistics will automatically be output to the server log (as INFO) every hour-ish (can be useful for auditing over time, or you know, generate charts). Tracked data points killed.players Total number of times players died on the server killed.npcs Total number of times NPCs died on the server killed.player.[NAME] Number of times a specific player was killed killed.npc.[NAME] Number of times a specific NPC-type was killed killed.ignored Number of suicides or no [valid] players involved in the death of a creature/player or some other reason disqualifying it from giving loot (an invalid player can be e.g. an invisible or invulnerable GM. Think: the target must be 'red' before dying) table.triggered.[ID] Number of times this loot-table was triggered rule.cancelled.[ID].[NAME] Number of times the rule was ignored due to maximum number of items it could drop was set to 0 rule.triggered.[ID].[NAME] Number of times the rule was triggered drop.total Total number of items handed out drop.total.enchanted.[NAME] Total number of this type of enchantment on items drop.total.guaranteed Total number of items handed out that had drop chance set to 100% drop.total.rares Total number of items handed out that were rare or better drop.dropped.[ID].[NAME] [*] The number of items that dropped. This can differ from item.drop.triggered because more than one clone may drop. drop.missed.[ID].[NAME] [*] How many times the item was a valid drop, but RNG screwed the player out of the item :) drop.triggered.[ID].[NAME] [*] Number of times (an) item was dropped mods.calls Number of times external mods utilizing LootTables were notified about drops mods.cancelled Number of times an external mod utilizing LootTables prevented an NPC from yielding loot mods.exceptions Number of times an external mod threw an exception (thus preventing any drop) query.total.lootrules Number of queries to LootRules table misc.players.online Number of players online at the time of printing these stats. Not related to LootTables per se, but can be useful if you want to generate charts (or whatever) based on the periodical output to server log. [*] For some of the drop.* data points, the [NAME] will only be included if the LootItem had a forced name. So, if empty, you'd use [ID] to find out which item it's about. The screenshot gives an idea of what is added. This list will obviously become a lot longer on a live server, for this test I had a small number of rules and spent two minutes killing four creatures (without anything dropping). The link in the original post is updated with latest version. And well, that's it. Enjoy
  21. Hello, I have been out of the Wurm Unlimited loop for quite a while and just happened to end up browsing this section; so I apologize for the somewhat late reply. I think you may be right in your assessment that something is off here. Was the 'random' color set by any chance? I can imagine that would have thrown things off a bit. Regardless, I have thrown together a new release that checks if all three color components are -1, then do not set color under any circumstance. There's a caveat here; I have been unable to test the release as my Wurm Unlimited is currently a bit borked and I have not been arsed to fix it I hope this helps you. The download link is the same as was in the original post in this thread.
  22. I saw this happen in the past myself, but have never actually managed to reproduce it on my test/dev server, so at this point I actually don't really know why that happens sometimes. If you have this issue though (albeit frustrating as heck), you can destroy all those creatures and just respawn them (as any model), as long as you get the exact names correct. If you find out why they lose their position in some scenarios, please do let me know!
  23. Not sure if I've mentioned this, but you can have any Wurm item inserted into the LootItem table (items from mods too). But the important bit here: By default I only insert a *subset* of Wurm's items. Things that are not very plausible as drops like carts, boats, etc are not inserted. Items like GM wands, mission ruler, etc are also excluded. That said, you can easily insert any missing items yourself by looking up the Wurm template ID in the com/wurmonline/server/items/ItemTemplateCreator* classes. 25Jul2017 Some updates to LootItems Ability to set weight of items, you can also add a random factor to the weight. Use 'weight' and 'weightrandom' (this is in grams). As with other random parameters, if weight is set to 1000 (1kg) and you have a weightrandom set to 500, the weight will be a random value between 1000 and 1500 grams. You can of course modify the weight of any item, say, a light weight huge axe or so. Added ability to force an item to rare. Do this by setting 'forcerare' to 0 for normal, 1 for rare, 2 for supreme and 3 for fantastic. This is different from how rarity works on LootItems otherwise, you could always set items to 'can-be-rare' and then it is done through randomness (bones were an exception, they would always be rare or better). This new option will *force* them to go rare, supreme or fantastic. Ability to set colour. This can be useful for almost every item of course, but I set out to add it for the purpose of being able to drop properly configured scale and hide. Please note that some items are simply not affected by colour -- sadly nothing that I can do about that. As is often the case when defining colours, RGB is used, you can get more information about that here: https://en.wikipedia.org/wiki/RGB_color_model The fields added to LootItems table: colorR / colorRrandom (redness), colorG / colorGrandom (greenness) and colorB / colorBrandom (blueness). So, setting colorR to 50 and colorRrandom to 205 will create a random 'redness' between 50 and 255. The final value of each color-component (R, G or must be between 0 and 255 or you may get an unpredictable result. As a side-note, dragon scale and drake hide colours are: Red dragon/drake: 215, 40, 40 Black dragon/drake: 10, 10, 10 Green dragon/drake: 10, 210, 10 White dragon/drake: 255, 255, 255 Blue dragon/drake: 40, 40, 215 To test all three additions INSERT INTO FriyaLootItems(id, itemids, name, dropchance, colorr, colorg, colorb, weight) VALUES(150001, 372, "red dragon scale", 100.0, 215, 40, 40, 100); INSERT INTO FriyaLootItems(id, itemids, name, dropchance, weight, weightrandom) VALUES(150002, 347, "tasty meal", 100.0, 500, 500); INSERT INTO FriyaLootItems(id, itemids, name, dropchance, colorr, colorg, colorb, forcerare) VALUES(150003, 2, "sweet satchel", 100.0, 0, 0, 255, 2); INSERT INTO FriyaLootTables values(123457, 150001); INSERT INTO FriyaLootTables values(123457, 150002); INSERT INTO FriyaLootTables values(123457, 150003); INSERT INTO FriyaLootRules(rulename, loottable, creature, age) VALUES("Test of color, weight and forced rarity", 123457, "troll", "venerable"); The above examples will make all venerable trolls drop: a meal weighing between 0.5 and 1.0kg (named tasty meal) 0.1kg red dragon scale a blue satchel that is forced to become supreme (named sweet satchel) As always when we need to update the database: On your next restart of server, the new fields will be merged into the existing database automatically (no action required from your side). But yes, you do have to restart your server to see the new fields. PS. I know I use 'color' in code and 'colour' in text. I am consistent in my inconsistency.
  24. It would be fairly easy to make, but I consider it out of scope for the LootTables mod since that is really just about 'random loot'. I am also not sure if I feel any temptation to write that mod myself, but if someone is up for the job, I'd be happy to assist with pointers on how to make it happen (and even tweak the LootTables mod if that is necessary).