hipolipolopigus Posted December 3, 2011 Author Share Posted December 3, 2011 (edited) I'm also slightly saddened by the fact that nobody picked up on the rather obvious Bethesda reference after 7 pages! :sad: -Sigh- :rolleyes: Edited December 3, 2011 by hipolipolopigus Link to comment Share on other sites More sharing options...
747823 Posted December 3, 2011 Share Posted December 3, 2011 If you read this, you should prepare yourself for a wall of text. I skipped between parts a lot so hopefully there aren't any half-finished sentences or paragraphs. If there are, sorry. I'm a novice programmer, a 3D modeler, texture artist, 9-year TES player, have played thousands of hours of online games, have been at in the top 1% "skill level" of players in at least one game and top 20% in several. I think I have some useful ideas. Not that the experience matters, but now you know my perspective... take what you will from this. I mostly agree with anyone saying to keep gameplay extremely simple until you've got a fully working model, hopefully without too many bugs and with complete "basic features" that are necessary. I think you can come up with a list (I'll help by making an example one) of things that are necessary for game mechanics, which are required for more complicated things. You could even divide it into multiple levels. I think it's better to fully complete (or at least to a predictably working extent) each level before adding more. I'll split this into 4 levels for now. I'm just pulling these from my head and obviously they're not fixed. PCs = Player-controlled actors. (1) Most basic features to be synchronized, quite obvious:PC positions.PC rotation.PC actions (move input, attack input, etc.)PC animation states (attacking, moving, casting, dead, etc.)NPC actionsNPC action states (2)PC stats: level, skills, skill progress, attributes, resistances, race, sex, perks, armor rating, etc.PC spell lists.PC inventories.NPC stats.NPC spell lists and inventories.NPC locations, rotation, actions.NPC states. (3)PC equipped items.PC face and body shape.PC quest states.NPC trade gold and inventory.Container contents.Outside item locations/physics. More on this below.Time of day.Weather. (4)Server-side saves. More on this below. (5)Any "extra" stuff such as synchronized dialogue and some features that I will mention below. And now some areas I want to talk about in more detail... ---Character creation, saves, etc: Assiociating characters with clients:One character per server. The save file should probably be saved in a specific folder for each user, and a database entry will be made somewhere which associates this directory, and thus character, with a "token" (I don't know if this is the right term, sorry if it's misused...). When a client joins, the client's token is checked against every one in the database, and if there's a match, the associated save is loaded, a new actor is added to the server and client game worlds, the stats are copied and the client is given control of it. It could be IP based obviously. The first time a client joins a server, the IP is associated with the save and the save is auto-loaded when that IP connects. If it doesn't exist yet, client is directed to character creation mode and the new IP is put into the database. Probably the easiest to code. It could be a client-side file containing a unique string saved in the skyrim user folder. When the client joins, it's checked automatically like the IP and the character is loaded. Client can use this on any computer and can create multiple characters, but it requires swapping of the file itself. It could be username/password based. A password and username is stored for every character, and the client enters this every time (but can save it to a file locally to remember what to send.) Then client can play any character they have the password to. Allows multiple character per client. Probably the best idea all-around. Seems easier to code than the client-side file and less likely to fail with an IP change, hard drive failure, etc. Joining/character creation:I'm assuming the last method I metioned for associating saves with clients. When the player starts multiplayer mode, the player has three options: Continue, start new character, cancel. Continue sends a check to the server containing the player's "token". In this case, the name and password. If they match and the match isn't "online", do the load procedure and mark it as online. If not, give a message and go back to the 3 options. If player selects new character, ask for a new name and password. Name is checked against other existing entries. If the name is unique, the game temporarily loads a singleplayer cell. The singleplayer character creation runs in an empty, exitless zone. Completing the character creation sends all of the character data to the server. It saves to a new directory associated with the previously entered username/password. When this is over, the singleplayer stuff is unloaded and the game receives the world data from the server and then cues the load process with the newly created save. More about my idea for a load process below. Saving:I think doing something like this would be good: User presses the singleplayer quicksave input to save, and the server replaces the user save. A new save file should be created automatically every x amount of time (day? hour?), but otherwise the current one is replaced when the user saves. Maybe delete saves that are more than a few days old to keep enough backups in case of problems, but not use excessive space. There need to be server-wide saves every x amount of time as well. The state of all non-PC entities needs to be saved separately from the character saves, which is not the case currently. There should probably be a warning 5 minutes and 1 minute before a server-wide save is occurring. It should also save all characters to their respective files at this time. The purpose of automatically doing this is to keep the state of the world if the server crashes or something else goes wrong. Should probably keep several saves at once too in case of corruption or some other issue. Loading:When a client joins, the client's token is checked against every one in the database, and if there's a match, the associated save is read by the server, a new actor is added to the and client game worlds, and then all data is copied from the save to the new player actor instance and the client is given control of it. If a save is corrupt or otherwise fails to load, server checks previous saves from the same user and loads them instead if possible. Notifies player with a message about what happened. The actor instance is disabled and marked for garbage collection when the client leaves. The active username thing is marked as offline. I think this is how it has to work, because you can't make a new actor for every character in real-time. I'm not completely sure but it will probably work better to just create a new instance of the same actor for every PC, and set everything on the client's instance to be the same as what's in the save file that this client asks for. I'm sure you could figure all of this out yourself, since you obviously have more programming experience than me, but maybe it was useful to read from someone else's perspective anyway. ---Communication: It seems really easy to add a small chat feature to the console. You type "say <message here>" and all players can hear it. Also add things like "chat 1/0" to mute chat, and "tell <playername> <message>". Every time you enter one of these, the server receives it and sends the string to the respective players, and their client prints it in the console. Not necessary, and a low priority of course, but it seems easy enough to implement and would be useful. I don't think there's a need for a custom chat window, but it might be nice if it's not too much work so chat can be read while doing other actions. The console would work fine though. ---Position/heading/movement: Make this client side!It absolutely sucks to have a game where you press an input, wait for the server to register the input, calculate your new position/vector/action/whatever on the server, and then send it back to you and have your client do it. It's also tons of work for the server. Every game I've played that's any good has it. I'll present a comparison of examples for either way. (A) Client side movementGood things: Player's movement feels smooth to himself, even in the presence of lag or overloaded server.Bad things: Player may see other players move unexpectedly if there's lag (B) Server side movementThe good/bad seem to be the exact opposite of the other situation. I think everyone will prefer smoothness of their own movements over accuracy of others' positions. I also have ideas for NPC movement and actions:NPC position of the client who is closest to that NPC is propagated to all clients when position is updated. All clients send their positions for all loaded NPCs to the server, and the server compares how close each player is to each NPC, and sends back all positions from the closest clients. The client adjusts only within a certain theshold (25 game units? something like that - doesn't adjust if something is already very close to the received position, which it should usually be, but may not be). It should probably be this way for the "action" state of each NPC as well. I.e. uses data of PC nearest to NPC for whether this NPC is in combat, with whom, etc. I think this would be great for things like... two players fighting separate NPCs in the same cell. Then players engaging a close NPC with an action will not see that NPC move/behave unpredictably. The PC whose updates are used could also be locked every <some amount of time>, to avoid weird switching in case two players are constantly switching between being the closest to the NPC. And the PC whose updates are used could be always locked if more than one PC is within <some close distance> of the NPC. ---NPC dialogue, dialogue for quests states, trading, etc: I have a few ideas for this. None of them involve all players hearing/seeing the same dialogue at the same time because it seems like too difficult of a goal to think about yet. Many modern games with online play don't even have that feature. (1)Only allow one player to have a dialogue interaction with an NPC at a time. I think it's mostly unnecessary if the players are actually Co-oppingUpdate all quest stages and rewards for all players (in the same party party?) if one player iteracts with an NPC.Advantages: probably easier to code and runs fasterDisadvantages: (2)Allow players to interact with the same NPC and the same time, but don't synchronize dialogue or quest-related stuff, and don't show it to other players. Only synchronize an NPC's trade inventory and trade gold, but only and always when a transaction takes place. (3)Same as 2 but NPC inventories are 100% client side. ---Leveled NPC and loot generation, spawning, etc: If a party exists in a cell, this should probably take the party count into consideration. This could probably be done by a selected client (wheover has the lowest ping?). I can come up with a quick thing that would work pretty wella: average level of players in the partyn: number of players in the partyl: level of enemies to generate l = roundingfunction( a + a * 0.1 * n ) I have no idea if this would be balanced or not but it's just an example. The idea is to increase the level of t For FFA, pick a new random number in the range between the two players' levels for every spawn. If there are multiple parties in the same cell, or a party and Respawn rate should change dynamically with the number of players on the server. I think respawn rates should increase from the default to default times the number of players in the server. This should also have a cap of course if there will be a possibility of more than 8-10 players, because it would be quite dumb to have stuff respawn 2 minutes after you clear a dungeon. ---Hit detection: Make this client side! The client is going to have the other PC and NPC locations, stats, etc. for the moment... calculate things here, not on the server. I know there are drawbacks to this, but I think they are less. I'll give two examples. (A) Client side hit detectionClient calculates a hit based on its own stats and positions of the other characters, and sends them to the server as hits, and the server sends them to other players/NPCs. A cue for the attacking animation and an update on position, rotation, etc. should probably be sent out at this time as well. The problems with this are: possibility to see players hitting someone from weird looking positions, better reflexes needed for blocking in PVP combat... (B) Server side hit detectionPlayer attack inputs are received by the server, and whether they are hits and their damage and other stuff is calculated by the server. The problems with this are... players seeing their weapon make make a hit on their client but not actually doing anything because on the server that wasn't a hit. Extremely frustrating, as I'm sure anyone who has ever played an online game with PVP combat knows... As well as it being extra work for the server. ---Physics: Mostly client-side... Again, I know this causes discrepencies between server and clients, but the physics are not important. The only part they serve in the gameplay is in And I think this is going to be a waste of resources, is probably going to be complicated to write the code for, and would cause potential weird and unpredictable visuals for clients. I'm sure there's a way to kill the physics simulation... have the server receive an input when a physics simulation starts on any client, send this to each other client, and run it on the server at the same time. Set a timer at the beginning for a max simulation length, and when it ends, start checking for the object being slow enough to count as stopped and close enough to a static surface facing upwards to count as stopped. As soon as the object meets these checks, send the position calculated on the server to all clients. There will probably be cases where this causes objects to move unpredictably, but at least it will only happen once instead of constantly during the simulation, and will make the most important part of the simulation work properly: The final resting place of a physicalized object will be the same for all players. Alternatively, you could do what I suggested for the NPC positioning. Skip the server-side simulation completely, and take the "final location" from the nearest PC to that object for the current simulation and propagate it to all of the clients. This should probably have better performance, but I don't know if it will function better than the previous. Also, I don't know how arrow hit detection works, but I think it definitely needs to be from the client who shot the arrow. See bows in Minecraft multiplayer for example of why. They are nearly useless. This might be different in 1.0 though, I haven't played the game in a while.---Sleeping:Bed becomes a player's spawn location after dying, and heals a player but doesn't advance time. A player can clear their spawn location from a menu or with a console command. ---Fast travel: Doesn't advance time. Several ideas for balance... Can use fast travel only once per in-game day.Can use fast travel only after x real life minutes.Party members receive a fast travel invite for the same location when one member fast travels. Ignores the fast travel cooldown. ---Competitive game objectives: This is only a potential idea and should be low priority if you even like the idea. It's "inspired" by the Minecraft factions multiplayer mod, and I think it would be quite fun and easy to implement. Would also create more interesting dynamics between players that extend far beyond... 3 players enter a dungeon togther, kill stuff, and then move to the next one. It is sort of an "addition" which is unrelated to the mechanics but would give a PVP focus and also give a purpose to play for a long time. Now players can take control of holds and there can be player-player politics that are much more dynamic and interesting than the in-game ones. I also think my system is rather easy to implement and doesn't require any huge changes to the game or huge performance decreases. There is no visual representation. Save a "power" stat for every player in each hold. The idea is essentially that a player or group of players can take control of holds. The power level could be a value between 100 and -100 that is 0 by default. The power stat could also be party-wide or faction-wide (if factions existed) for shared control. What having power does for a player in a hold:> Players deal more damage and take less damage. Every 25 positive points could add a 5% increase to all of a player's skills and attributes, and every 25 negative points could incur a 5% decrease to them while in that hold. These could be spell effects that calculated and added to a player upon entering cells from a certain hold. This would probably require an ESP that gives a way of marking cells as part of a certian hold, unless that already exists. I don't know if it does. > Friendly NPCs have a higher chance of fighting on the side of a player with more power should a battle happen near NPCs. 0 or less power = 0 chance, 100 = 100% chance. This gives the defenders a greater advantage when defending at key locations such as cities, because they will have the protection of the citizens of the hold. > Players with negative power in a hold can't open containers in hold. This gives others incentive to defend a hold - they can store their items here when they leave the server or Gaining/losing power:When a player or party wins a fight against any player or NPC in that hold, his/her (or the party members') power level for that hold goes up. Victories over NPCs in that hold could increase the power level by 0.25, victories over players could increase it by 5, and death could reduce it by 10 (this has to be offset because of how many NPCs the player can kill easily). Power gradually goes back to 0 over time. Maybe... 10 points per real life hour? Attacking or defending a hold:Players should probably all have a custom ability that shows the location of all other players in the current hold as "quest markers". Lasts for 20-30 seconds and has a 3-5 minute cooldown. Maybe only available if power is above -50 or something, would have to test balance. ---Overall thoughts:Do not redesign the game! ...and make as many features client-side as you can to save resources and make it feel smoother. It also makes the gameplay a lot smoother if the connection is slow. And don't force a player's position or actions on his own client... The only drawback that I can think of with this is that it opens a bigger window for cheating. I don't think cheat protection should be a priority, as some measures could be a huge performance sacrifice and I presume it's not going to be a competitive experience for most players. I would also expect most servers to be privately hosted for a group of players who all know each other, and there would be no reason to cheat in that case. Also I really hope you change the project name... I just think it sounds stupid and is confusing. Why not just Skyrim Co-op Project? But the name doesn't really matter, I guess. Was going to post this on your mod forum but there was a 10,000 character post limit. Link to comment Share on other sites More sharing options...
hipolipolopigus Posted December 3, 2011 Author Share Posted December 3, 2011 (edited) Holy... f***... I'm reading this right now, I'll post another reply when I'm done o__o Sorry about that post limit >< You're on the Brainstorming team now, whether you like it or not :P You have access to the Design and Development forums. I'l check what the post limit is on your new group, not sure what it'll be :P Edited December 3, 2011 by hipolipolopigus Link to comment Share on other sites More sharing options...
hipolipolopigus Posted December 3, 2011 Author Share Posted December 3, 2011 Now, new post... While we haven't really spearheaded any core mechanics yet (Purely because we don't have access to the CK yet, so we don't know the limits), you certainly seem to have more than a few of your own. Even if we did have access to the CK, I wouldn't want to speculate on end functionality ideals at all simply because things are going to change vastly over the months this project is going to take. I'm going to be writing up my own list of (Hopeful) end result mechanics, although I'll explicitly state that nothing is final and everything is subject to change. You've expressed many interesting ideas here. If you wouldn't mind, please split them up into similarly organized groups and post them in the "Design and Development" forums as separate threads after I've done my own so you can get a feel for the kind of layout I'm looking for in proposals. There's already a few loose ones there (Check out the Mannequin post) when you have the time, they should answer a few questions and resolve a few issues that you've stated (Hit accuracy, etc). Welcome to the team ^-^ Link to comment Share on other sites More sharing options...
nandchan Posted December 3, 2011 Share Posted December 3, 2011 (edited) I'm sorry, I don't really see the advantage of your proposal. Why is a dedicated server bound to fail? It would be a modified version of the client, stripped of character and rendering cycles, and instead receiving/sending the change in players' states. Lucubration is right though, I misunderstood and appearently the plan is to have a hosting player to which the others connect, as nandchan described it as well. I'm not a programmer so I may well be wrong, but I still think a dedicated server is the key to making this work, so please tell me where I'm wrong. The inherent problem here is that the game engine can only really load and calculate a small number of cells at one time, the one the player is in, and the others are all using very stripped down logic. With a centralized server, you'd have to restrict all players to being inside the same cell, but if you use a decentralized server system like I suggested, you could have different players being in different zones. @747823: Concerning your concerns about NPC dialogue, remember that the game (Skyrim) is no longer paused during conversations, and all NPC dialogue is “spoken” via 3D sound effects just like every other random NPC dialogue is, simply sending these “3D sound events” to other players should be trivial. Same for synching weather and so on, because we 1. have a command to forcibly change the weather on each client, and 2. have a command to get the weather on the server - a lot of these are very trivial to implement. (Which is a good thing). I agree that physics should be client-based, but I'm thinking of a system with regular position/movement synching like in WoW (same for character/NPC movement). This allows somewhat smooth movement, and allows the client to smoothly interpolate the positions. So for example, if you run full speed against a pot on the table, your client (which performs hit detection) sends the event to all other clients, which then set their copies to the same position (in the air) and speed (very fast towards the wall), and can thus all calculate the same future (bounces off the wall) locally. What I also disagree with is your ideas for saving/loading - in continuing with my suggested “distributed server” model, I think that when you press F5, your entire current world as you see it locally will be saved, locally - this happens for every player. When you choose to host a new SkyNet session, you decide upon one “initial save” that will be loaded and synched to all other players. So you can, for example, have player A be the highest priority/initial hoster for a while of time, but then if player C continues playing on his own for a while, you can choose to load his save as initial state instead of A's - which will synch that change back to A (and B, D). I do not think an account-based password system is used for this. Since we're offloading calculations to the client-side, we already have a very reduced security system, which will force everybody you allow to join to be somebody you trust (well enough to play fairly). Think about the console etc as well. The most I'd do is sending a request to the initial hoster asking him whether he wants to allow character X with stats Y and inventory Z to join. Finally, I'd like to mention that offloading calculations to the client works well with my idea of a “distributed server”, except in this instance, even portions of cells and individual events are distributed as well. In the case of a collision (eg. player A says pot should be at 15/15/15, player B says pot should be at 20/20/20), the player with the higher hosting priority (as discussed earlier) would override. Note: One way this could be implemented is with each object in the game world additionally being tagged with a “hit” flag. The way this would work: Whenever a client does hit detection on an object and it results in “hit”, the object's “hit” flag is set, and periodically, every object that has its “hit” flag set will get sent to all other clients - until it either expresses no change in position or speed to the last synch, or the client in question receives a synch event for the same object from a different client, in both cases this would result in the local “hit” flag being unset. Similarly, if a client has the highest priority inside a certain cell, “hit” would be used for NPC collisions as well, not just player collisions - so if an NPC walks against a pot and knocks it over, this would count as a “hit”. @hipolipolopigus: I don't really wish to participate in this project more than I already have, it's just my programmer's instinct forcing me to think about this whether I like it or not. Edited December 3, 2011 by nandchan Link to comment Share on other sites More sharing options...
747823 Posted December 3, 2011 Share Posted December 3, 2011 (edited) Holy... f***... I'm reading this right now, I'll post another reply when I'm done o__o Sorry about that post limit >< You're on the Brainstorming team now, whether you like it or not :P You have access to the Design and Development forums. I'l check what the post limit is on your new group, not sure what it'll be :P Haha, alright. I can't promise that I'll be active but if I think of more stuff I'll try to remember to post it. These are of course... just ideas for how things could work, and it's just mine and I'm not suggesting that they are the best or should be used. I hope I didn't make it sound too much like that. I know I'm using "will be" instead of "could be" but it doesn't mean anything. I wanted to clarify something about the "loading and saving" that I felt wasn't clear enough before. The world save will probably just be normal ES saves, but the world one used by the server has no player, This is the only save that is actually used by the game. The "character" saves are just used to store all of the statistical data for player characters, but the actual player characters are just instances of an actor which have been modified after being created and continues to be modified as the game progresses. You can think of it as... spawning 5 of the same actor in singleplayer and using console commands to change their stats, inventories, etc. The reasons I suggest making a new instance when a player connects, deleting it when a player leaves, and storing the data in a separate save are: > So the server dosn't need to do a full world save any time one player wants to save and leave the server. A full world save will affect everyone on the server like it affects the player singleplayer games, so it would be annoying to have this happen any time a player wants to save their character. Players can save and leave without needing a world save > So that the player instance isn't left in the world when the player leaves the server. Also allows the player to have multiple characters which can be switched between. I thought of something that could be problematic... If the server goes crashes with players in it, there will be no chance to delete the player instances and save the world. This means that when the server starts again, all player instances from the last save will still be in the world. Maybe there's a way to delete them all upon starting the server and save the world like that? Obviously exiting without crashing could do that, but doing it at startup is probably good too. About your other post... well yeah, My speculations are based mostly on knowledge of Oblivion. It looks like a lot of things are similar in this game. And like I said, I am only a novice programmer, so I think I'm only able to come up with... "outlines" of things like this. And I'm going to sleep. I'll split everything up and post in the mod forum when I wake up. :) Edited December 3, 2011 by 747823 Link to comment Share on other sites More sharing options...
nandchan Posted December 3, 2011 Share Posted December 3, 2011 More outlandish ideas: It's possible that, in continuing (again) with my distributed server model, we could abolish the notion of a “hosting player” completely - for example, one could allow every player to interact with NPCs, but only if nobody else is currently using it. Since quest stages would be synched, this could allow for, example, one player starting a quest and another player finishing the same, with quest rewards being distributed to all players (the non-accepting players would receive it inside a special “quest reward” crate to 1. force them to actually travel home/outside, 2. prevent over-encumbering them in the middle of combat). While a client is paused (inventory) or in a different cell, synch events for a given cell would be pushed onto a “synch queue”, which then gets executed once un-paused. Since synch events are all provided by the player which triggered them, this basically allows players to be completely unaffected by the “hosting” player pausing his game, and similarly, if one player pauses his game, he needs to be careful or he could still die in the meantime. This has the handy side-effect of removing the alchemy abusing which basically turns everybody into god mode characters, by drinking dozens of potions while paused. Link to comment Share on other sites More sharing options...
hipolipolopigus Posted December 3, 2011 Author Share Posted December 3, 2011 More outlandish ideas: It's possible that, in continuing (again) with my distributed server model, we could abolish the notion of a “hosting player” completely - for example, one could allow every player to interact with NPCs, but only if nobody else is currently using it. Since quest stages would be synched, this could allow for, example, one player starting a quest and another player finishing the same, with quest rewards being distributed to all players (the non-accepting players would receive it inside a special “quest reward” crate to 1. force them to actually travel home/outside, 2. prevent over-encumbering them in the middle of combat). While a client is paused (inventory) or in a different cell, synch events for a given cell would be pushed onto a “synch queue”, which then gets executed once un-paused. Since synch events are all provided by the player which triggered them, this basically allows players to be completely unaffected by the “hosting” player pausing his game, and similarly, if one player pauses his game, he needs to be careful or he could still die in the meantime. This has the handy side-effect of removing the alchemy abusing which basically turns everybody into god mode characters, by drinking dozens of potions while paused.We're a tad ahead of you ^-^ We discussed this just this afternoon (My time)! The NPC "locking" is most likely being implemented if it's possible. The only reason why we need a single player as a host is because we need Skyrim's internal processes (At this stage, at least. It wouldn't be impossible to have a GUI running outside of Skyrim). Again, discussed already ^-^ You sure you aren't a mind reader? xD Seeing as you're thinking the way we are, perhaps you'd like a role in the Think-tank/Brainstorming team? (No final name... I think "Think-tank" sounds neater, though :P) Link to comment Share on other sites More sharing options...
nandchan Posted December 3, 2011 Share Posted December 3, 2011 (edited) I see. I'm not reading the original discussions/posts here or elsewhere, just throwing ideas out there for you to use. As I've said, I won't be actively participating more than I want to, just giving you what comes to mind. Make of my ideas what you will. The only reason why we need a single player as a host is because we need Skyrim's internal processes If each client uses his own client's internal processing, I don't see where the problem would be. There's still no need for a single “host”. Note: If using UDP broadcast or multicast packets to synch, it may be possible to remove one client's “knowledge” of other clients completely. Edited December 3, 2011 by nandchan Link to comment Share on other sites More sharing options...
hipolipolopigus Posted December 3, 2011 Author Share Posted December 3, 2011 I see. I'm not reading the original discussions/posts here or elsewhere, just throwing ideas out there for you to use. As I've said, I won't be actively participating more than I want to, just giving you what comes to mind. Make of my ideas what you will. The only reason why we need a single player as a host is because we need Skyrim's internal processes If each client uses his own client's internal processing, I don't see where the problem would be. There's still no need for a single “host”. Note: If using UDP broadcast or multicast packets to synch, it may be possible to remove one client's “knowledge” of other clients completely.Well I'm glad to have you assisting, actively or not :happy: I'm failing to comprehend this distributed model you're suggesting :confused: It's likely due to the way I've operated in the past (WoW/Aion private servers, I'd mention Minecraft but that doesn't really count :P). Link to comment Share on other sites More sharing options...
Recommended Posts