Posts like this always catch my interest, player's specualting about the mechanics of the game can lead to some interesting takes. ;) I completely agree with your first point - from a logical perspective, having logs cut FASTER due to the number of players being around the tree cutting, would be silly. I'd imagine the structure to be more similar to a random 'roll' which is influenced by your Woodcutting level than that. Now, I arrive at a point of specific interest to me. Your argument that the trees cannot use a random number of logs to distribute to players in order to determine when the tree falls. Immediately, this flagged as being something odd. Game Servers require a vast amount of processing, which is why primarily you use dedicated machines for the task. Furthermore, your argument is memory usage - YES, excessive memory usage is bad. However, a random number initialised upon construction isn't excessive. The standard Integer Java Data Type requires 4 Bytes of Memory from the machine. Your argument of 10,000 trees and 169 Worlds (May be wrong there), would result in 40,000 bytes per machine (assuming worlds are dedicated) and 6,760,000 bytes overall. A meagre 6601kb distributed over 169 Worlds (Machines), I don't know about you, but if that's something to worry about I think a much higher priority is worrying about Jagex's Server Machines than that. ;) As for your 'getting logs faster' method, well - I'm not completely doubting it. But I feel that simply stating it is far too many assumptions. It makes common, logical sense - yes, and in that respect I'd have to agree with it. But - when you're trying to argue a point, I'd highly advise looking into the probability of a tree falling due to 1 player cutting, and a tree falling due to N players cutting. Compare these using a variety of test-runs and see what comes out. Furthermore, I'd have to add that your point about Dragon Hatchet vs Rune Axe, although you've stated that it's false, casts a LOT of doubt on your post for me. I've set that aside to write this argument, as that would be highly-biased, but just thought I should mention it somewhat. Now - as this has really piqued my interest, I thought I'd digress from developing Java Games for a while to write a little test program for your findings. I'll create a post later or edit this one once it's done with the source, and the test results for clarity. Then we can see, partially, which stands out more. :) Cheers, Ronan. Edit: Well, here it is - my apologies if it seems a little rushed, some of the code may be a bit inefficient in places, but it gets the job done. ;) [hide=Constant.java]/* * Constant.java * * Created on 01-Jun-2009. * * This is part of the Woodcutting Test Application developed by Ronan Turner * in order to test basic randomness of a variety of possible methods implemented * in Runescape for the Woodcutting Skill. */ package game; /** * The Constant class defines constants used throughout this application. * Primarily - tree maximum log values. * * @author Ronan Turner. */ public class Constant { /** * Define Constants. */ public static final int NORMAL_MAXIMUM = 1; public static final int OAK_MAXIMUM = 10; public static final int WILLOW_MAXIMUM = 20; public static final int YEW_MAXIMUM = 30; public static final int MAGIC_MAXIMUM = 50; public static final int MAXIMUM_NO_TREES = 4000; }[/hide] [hide=Game.java]/* * Game.java * * Created on 01-Jun-2009. * * This is part of the Woodcutting Test Application developed by Ronan Turner * in order to test basic randomness of a variety of possible methods implemented * in Runescape for the Woodcutting Skill. */ package game; import java.util.ArrayList; import java.util.Iterator; /** * The Game is where everything is initialised and set going. * * @author Ronan Turner. */ public class Game { /** * Define instanced variables. */ private ArrayList worlds; /** * Constructor for the Game Class. Creates an ArrayList of worlds, ready to * process. */ public Game() { worlds = new ArrayList(); for(int i = 0; i < 1; i++) { worlds.add(new World()); } processWorlds(); } /** * Process all the Worlds. */ public void processWorlds() { Iterator iter = worlds.iterator(); while(iter.hasNext()) { World world = (World)iter.next(); world.processWorld(); } } /** * The Main Method, used to start the Java Application. */ public static void main(String[] args) { new Game(); } }[/hide] [hide=Magic.java]/* * Magic.java * * Created on 01-Jun-2009. * * This is part of the JavaGames package used as an educational * learning application. Created by Ronan Turner. */ package game; /** * Magic defines the mighty, magnificent magic trees... * * @author Ronan Turner. */ public class Magic extends Tree { /** * Constructor for the Magic Tree. */ public Magic() { super(Constant.MAGIC_MAXIMUM, "Magic"); } }[/hide] [hide=Normal.java]/* * Constant.java * * Created on 01-Jun-2009. * * This is part of the Woodcutting Test Application developed by Ronan Turner * in order to test basic randomness of a variety of possible methods implemented * in Runescape for the Woodcutting Skill. */ package game; /** * Normal indicates a Standard, Normal Tree in Runescape. (Lowest level). * * @author Ronan Turner. */ public class Normal extends Tree { /** * Constructor for the Normal Tree. */ public Normal() { super(Constant.NORMAL_MAXIMUM, "Normal"); } }[/hide] [hide=Oak.java]/* * Oak.java * * Created on 01-Jun-2009. * * This is part of the Woodcutting Test Application developed by Ronan Turner * in order to test basic randomness of a variety of possible methods implemented * in Runescape for the Woodcutting Skill. */ package game; /** * Oak defines your standard Oak Tree in Runescape. * * @author Ronan Turner. */ public class Oak extends Tree { /** * Constructor for the Oak Tree. */ public Oak() { super(Constant.NORMAL_MAXIMUM, "Oak"); } }[/hide] [hide=Player.java]/* * Player.java * * Created on 01-Jun-2009. * * This is part of the Woodcutting Test Application developed by Ronan Turner * in order to test basic randomness of a variety of possible methods implemented * in Runescape for the Woodcutting Skill. */ package game; import java.util.Random; /** * The Player class emulates a player in that the player is assigned to a tree, * has an 'inventory' of logs, and can chop the tree. * * @author Ronan Turner. */ public class Player { /** * Define Instanced Variables. */ private int invLogs; //Stores the number of logs this player has. private int swings; private Random random; //Create an instance of the Random class. /** * Constructor for the Player. */ public Player() { random = new Random(); swings = 0; invLogs = 0; } /** * Chop Tree Method. This uses a standard 'dice-roll' method to determine if * the player gets a log. * * @return Returns true if a log was chopped. */ public boolean chopTree() { swings++; int roll = random.nextInt(10) + 1; if(roll == 1) { invLogs++; return true; } else { return false; } } /** * @return Returns the number of logs this player has. */ public int getLogs() { return invLogs; } /** * @return Returns the number of swings. */ public int getSwings() { return swings; } }[/hide] [hide=Tree.java]/* * Tree.java * * Created on 01-Jun-2009. * * This is part of the Woodcutting Test Application developed by Ronan Turner * in order to test basic randomness of a variety of possible methods implemented * in Runescape for the Woodcutting Skill. */ package game; import java.util.ArrayList; import java.util.Iterator; import java.util.Random; /** * Tree acts as an overall superclass for all trees in Runescape. * * @author Ronan Turner. */ public class Tree { /** * Define Instanced Variables. */ private Random random; //Create an instance Java's Random Class, used for pseudo-random generation. private ArrayList players; //Holds a Random Number of Players chopping this tree. private boolean alive; //Determines if this tree can be chopped. (Is available). private String type; //Shows the type of tree. private int rollChance; /** * The Constructor for the Tree Class. * * @param max The MAXIMUM number of logs available to this tree. (Constant for each type of tree). */ public Tree(int rollChance, String type) { players = new ArrayList(); random = new Random(); this.type = type; this.rollChance = rollChance; for(int i = 0; i < random.nextInt(10) + 1; i++) { players.add(new Player()); } alive = true; } /** * Decreases the logsAvailable by 1 each time it's called. Used to indicate * a Player has 'chopped' a log. * * @return Returns true to indicate succesfull chop. */ public void chopLog() { int roll = random.nextInt(rollChance) + 1; if(roll == 1) { alive = false; } } /** * @return Returns the ArrayList of players. */ public ArrayList getPlayers() { return players; } /** * 'Processes' this tree. It gets each player to chop the tree, until the * tree dies. */ public void processTree() { while(alive) { Iterator iter = players.iterator(); while(iter.hasNext()) { Player player = (Player)iter.next(); if(player.chopTree()) { chopLog(); } if(!alive) { displayInfo(); return; } } } } /** * Display Information about this tree upon death. */ public void displayInfo() { String playerSwing = ""; String playerLogs = ""; int totalSwings = 0; int totalLogs = 0; for(int i = 0; i < players.size(); i++) { Player player = (Player)players.get(i); playerSwing += "(" + player.getSwings() + ") "; totalSwings += player.getSwings(); totalLogs += player.getLogs(); playerLogs += "(" + player.getLogs() + ") "; } System.out.println(""); System.out.println("=========================="); System.out.println("Tree Type: " + type); System.out.println("Players: " + players.size()); System.out.println("Swings: " + playerSwing); System.out.println("Logs: " + playerLogs); System.out.println("Av. Swing/Log: " + (totalSwings / players.size())); System.out.println("Av. # Logs: " + (totalLogs / players.size())); System.out.println("=========================="); } }[/hide] [hide=Willow.java]/* * Willow.java * * Created on 01-Jun-2009. * * This is part of the Woodcutting Test Application developed by Ronan Turner * in order to test basic randomness of a variety of possible methods implemented * in Runescape for the Woodcutting Skill. */ package game; /** * Willow defines those poor, abused, weeping-willows of Runescape. * * @author Ronan Turner. */ public class Willow extends Tree { /** * Constructor for the Willow Tree. */ public Willow() { super(Constant.WILLOW_MAXIMUM, "Willow"); } }[/hide] [hide=World.java]/* * World.java * * Created on 01-Jun-2009. * * This is part of the JavaGames package used as an educational * learning application. Created by Ronan Turner. */ package game; import java.util.ArrayList; import java.util.Iterator; /** * The World class creates a 'World', this emulates a Runescape World by having a * large number of trees in the world. * * @author Ronan Turner. */ public class World { /** * Define Instaced Variables. */ private ArrayList trees; //Trees is an ArrayList used to store all the trees created. /** * Constructor for the World Class, 'Creates' the world. The trees are in * proportion: (15:10:8:5:2) (Norm:Oak:Willow:Yew:Magic) */ public World() { trees = new ArrayList(); int split = Constant.MAXIMUM_NO_TREES / 40; for(int i = 0; i < split*15; i++) { trees.add(new Normal()); } for(int i = 0; i < split*10; i++) { trees.add(new Oak()); } for(int i = 0; i < split*8; i++) { trees.add(new Willow()); } for(int i = 0; i < split*5; i++) { trees.add(new Yew()); } for(int i = 0; i < split*2; i++) { trees.add(new Magic()); } } /** * Process this world. This iterates through the list of trees, and gets * each player associated with the tree to keep cutting it until the tree is * dead. */ public void processWorld() { Iterator treeIterator = trees.iterator(); while(treeIterator.hasNext()) { Tree tree = (Tree)treeIterator.next(); tree.processTree(); } System.out.println("World processed."); } /** * @return Returns the ArrayList of trees. */ public ArrayList getTrees() { return trees; } }[/hide] [hide=Yew.java]/* * Yew.java * * Created on 01-Jun-2009. * * This is part of the JavaGames package used as an educational * learning application. Created by Ronan Turner. */ package game; /** * Yew defines the highly-coveted Yew Trees of Runescape. * * @author Ronan Turner. */ public class Yew extends Tree { /** * Constructor for the Yew Tree. */ public Yew() { super(Constant.YEW_MAXIMUM, "Yew"); } }[/hide] [hide=Tree - Max Logs Based. (Tree.java)]/* * Tree.java * * Created on 01-Jun-2009. * * This is part of the Woodcutting Test Application developed by Ronan Turner * in order to test basic randomness of a variety of possible methods implemented * in Runescape for the Woodcutting Skill. */ package game; import java.util.ArrayList; import java.util.Iterator; import java.util.Random; /** * Tree acts as an overall superclass for all trees in Runescape. * * @author Ronan Turner. */ public class Tree { /** * Define Instanced Variables. */ private Random random; //Create an instance Java's Random Class, used for pseudo-random generation. private ArrayList players; //Holds a Random Number of Players chopping this tree. private int logsAvailable; //Stores the number of logs available for this tree. (This instance) private int startingLogs; //Stores the starting number of logs available. private boolean alive; //Determines if this tree can be chopped. (Is available). private String type; //Shows the type of tree. /** * The Constructor for the Tree Class. * * @param max The MAXIMUM number of logs available to this tree. (Constant for each type of tree). */ public Tree(int max, String type) { players = new ArrayList(); random = new Random(); this.type = type; for(int i = 0; i < random.nextInt(10) + 1; i++) { players.add(new Player()); } logsAvailable = random.nextInt(max) + 1; //Generate a Random # between 1 and max. startingLogs = logsAvailable; alive = true; } /** * Decreases the logsAvailable by 1 each time it's called. Used to indicate * a Player has 'chopped' a log. * * @return Returns true to indicate succesfull chop. */ public void chopLog() { logsAvailable--; } /** * @return Returns the ArrayList of players. */ public ArrayList getPlayers() { return players; } /** * @return Returns the number of starting logs. */ public int getStartingLogs() { return startingLogs; } /** * 'Processes' this tree. It gets each player to chop the tree, until the * tree dies. */ public void processTree() { while(alive) { Iterator iter = players.iterator(); while(iter.hasNext()) { Player player = (Player)iter.next(); if(player.chopTree()) { chopLog(); } if(logsAvailable <= 0) { alive = false; displayInfo(); return; } } } } /** * Display Information about this tree upon death. */ public void displayInfo() { String playerSwing = ""; String playerLogs = ""; int totalSwings = 0; int totalLogs = 0; for(int i = 0; i < players.size(); i++) { Player player = (Player)players.get(i); playerSwing += "(" + player.getSwings() + ") "; totalSwings += player.getSwings(); totalLogs += player.getLogs(); playerLogs += "(" + player.getLogs() + ") "; } System.out.println(""); System.out.println("=========================="); System.out.println("Tree Type: " + type); System.out.println("Logs: " + startingLogs); System.out.println("Players: " + players.size()); System.out.println("Swings: " + playerSwing); System.out.println("Logs: " + playerLogs); System.out.println("Av. Swing/Log: " + (totalSwings / players.size())); System.out.println("Av. # Logs: " + (totalLogs / players.size())); System.out.println("=========================="); } }[/hide] Hmm, well - apologies for such a long post, I would of uploaded the files to my host, but I'm not sure if these forums like the posting of links to outside files, even if they are txt / java. Anyway - if you have a better suggestion, please, feel free to reply and i'll get it sorted as soon as possible. ;) This application creates a 'World', within that world a fixed number of trees are created, these trees are created in proportion to each other. (Normal, Oak, Willow, Yew and Magics are created.) After this creation, a random number of 'players' are assigned to each tree. Upon finishing construction, the application 'processes' all the trees. Processing involves iterating through the trees, and having all players cut the tree sequentially - the players have a random chance of successfully chopping the tree and receiving a log. With the first version - if a player receives a log, the tree then performs a 'roll' to determine if the tree dies or not due to that player. With the second version (Trees based on Max Logs), the tree will subtract one from the logsAvailable variable, if that hits 0 - the tree dies. In the second version, the logsAvailable is a random number created upon construction. This application provides 2 very feasible methods for the Woodcutting mechanics - both implementable as you can see. These 2 methods are the Maximum Logs Available per tree and a Random Chance of the Tree Dieing upon Chopping. Two out of the three methods described by the original poster - one proposed as not efficient. The methods are interchangeable by replacing the code within Tree.java, with the code in Tree - Max Logs Based. No other changes should be necessary. The application is entirely customisable, with a bit of playing around, one can run quite a few different test scenarios. For example - the results i'm about to post can provide insight into the logs gained via one player chopping a tree and the logs gained via multiple players chopping a tree. The application could be extended in order to implement regrowing trees - but i'll leave that to anyone that's interested enough to do it. ;) The following are two test results from the application, I've uploaded them as a .txt file as they're each just under 40,000 lines long, I don't think that would work great in a hide tag. :lol: Output from Maximum Logs Tree: http://rturner.byethost3.com/output2.txt Output from Random Death Roll: http://rturner.byethost3.com/outputDeathRoll.txt I'll leave this up to the readers to decide which one has a greater likeness to the Woodcutting mechanics in the game. All I'd say is that there are some interesting results there - and the tests were carried out using the same test data, only different methods, so it should of been a fair test. However - you're welcome of course to compile the source and try it for yourself. ;) Now, I just thought I should mention the inconsistencies of the application. The primary difficulty is that there are a lot of assumptions made based on the game's mechanics, such as the Player's random roll to determine if a log is chopped. I also haven't implemented any possible relation about different grades of Hatchets. Furthermore, I'm using Java's Random class. This is a standard, pseudo-random generator, and like most random generators - it's not entirely random. ;) This is a flaw which is difficult to overcome, as any 'Random' generator, has to follow a set pattern to generate the random number. Java's pseudo-random generator uses the System Time to influence random numbers, as such - there is a bit of an inconsistency with the actual game in that all trees are processed very quickly after each other, resulting in possible influences to the random numbers generated. Within the game, all trees aren't chopped down simultaneously, so it doesn't hold the same flaw. Anyway, this little application's primary aim is to show the readers and the original poster that the two methods are highly possible implementations, and perhaps put some insight into the mechanics in contribution to this post. Enjoy, Ronan. :)