rAthena roBrowser roBrowser install Config Web : https://www.robrowser.com Installation This doc will explain how to download and install roBrowser on your website or as a Chrome App and will explain how the users will be able to use it. Note: roBrowser is just an executable, so to run it you will need to have the original client files and a server to run the game. You can find all of them in forums as rAthena.org or Hercules.ws. Get the source code First of all, to run roBrowser you have to download its source code The project is packed in a zip file, you will need a ZIP unpacker to extract its content, you can google for it if your system don't have one installed. Installing a Remote Client The Remote Client is used to download game resources from a server when users don't have a FullClient on their computer. Instead of extracting your GRFs in a data directory and upload it in a server, the Remote Client have some powerfulls capacities : Client from another domain can download resources from your server (configurable). Extracting files directly from your Game Resources Files. Converting BMP files to PNG to speed up the download. Auto extracting files from your GRF to save server resources. Upload The RemoteClient is located in the client/ directory. Upload it to your web server and add : Your GRFs files and DATA.INI directly in the resources/ folder. Add your mp3 files into the BGM/ folder Add the content of your data/ folder in the client data/ folder. Configuration Once it's done you will just have to configure the configs.php and .htaccess file. The htaccess will need to know the path where is located index.php to work with URL rewriting type: myroserver.com/client/ ErrorDocument 404 /client/index.php type: myroserver.com/low/client/ ErrorDocument 404 /low/client/index.php type: client.myroserver.com/ ErrorDocument 404 /index.php Adding your customs Since some revisions, roBrowser doesn't read data files anymore (lua, xray, .txt). To avoid any problems, you'll have to convert and adding them directly to roBrowser's source code. To do it, go to tools/converter/index.html and select the type of data you need to compile and your files type.Drag drop your files into the browser and click into Convert. Save the file at the specified location. Compile roBrowser source code If not running in Development Mode, the code has to be compiled : players does not want to download ~150 javascript files to play RO... To compile roBrower, open the file tools/build/index.html in your web browser, select the application needed. The process can take some times, once done, note the location where the file have to be saved, the download the file and move it to this location. Note: every app use the Thread app, so don't forget to compile it too. Configure to run in a website If you want roBrowser to be accessible in a website, just follow the API guide.You will be able to create a page with your own settings to let your players access roBrowser from your website, directly in a div or by opening a popup Configure to use as a Chrome App What is a Chrome APP ? Chrome App is the name for Google Chrome Application. It's exactly the same as running a website directly except you have an icon of the application somewhere on Google Chrome browser. The main reason I decided to port roBrowser to Chrome App is to benefit some privileges, being able to execute native socket without relying on a plugin as JAVA. Configuration It's possible to add default configration to the Application, just open applications/settings.js and add your own parameters (same parameters used than in the API) Installation Go to the extensions management page by clicking the settings icon and choosing Tools > Extensionsor by going to this URL: chrome://extensions/ in your omnibox (more informations). Make sure the Developer mode checkbox has been selected. If you want to debug roBrowser, click the Load unpacked extension button, navigate to roBrowser main folder and click OK. If you want to create the App, click the Pack extension button, navigate to roBrowser main directory and click Package and it will create two files, a .pem and a .crx needed to publish your App (more informations). Once it's done, just click on your created App to run roBrowser. API The API is designed to run roBrowser just by passing some arguments to a function, avoiding to get rid of all roBrowser's code and just focusing in needed configuration. Audience This documentation is designed for people familiar with Javascript programming and object-oriented programming concept. This conceptual documentation is designed to let you quickly start exploring and developing applications using roBrowser API. Hello World The easiest way to start learning about roBrowser start up API is to see a simple example. The following web page run an online version of roBrowser : ROBrowser's App from https://www.robrowser.com
Initializing roBrowser...
Even in this simple example, there are a few things to note: We declare the application as HTML5 using the  declaration. We include the roBrowser API JavaScript using a script tag. We create a div element named "robrowser" to hold the result. We create a JavaScript object literal to hold a number of properties. We create a JavaScript "RO" object, passing it the properties. We use an event listener to load roBrowser after the page has loaded. Settings To initialize roBrowser, we first create a Settings object to contain the application initialization variables. This object is not constructed; instead it is created as an object literal. var ROConfig = {}; Application Because roBrowser is a set of Tools, it's better to specify which application you need to execute application: ROBrowser.APP.MAPVIEWER, The following types are supported: ONLINE Online Game MAPVIEWER Visualize RO Maps GRFVIEWER Extract Game File and show its files contents (bmp, sprites, models, ...) MODELVIEWER Show RO 3D models Integration Type roBrowser can be integrated in a webpage using two differents ways, popup or in webpage: type: ROBrowser.TYPE.FRAME, The following types are supported: FRAME Insert roBrowser in your webpage, must complete the target propertie. POPUP Will open a new window to execute roBrowser Target When using ROBrowser.TYPE.FRAME you have to specify a target element which will contain roBrowser. target: document.getElementById('robrowser'), Packet Version When using in Online Mode (ROBrowser.APP.ONLINE), the client need to know which packet version the server used. To know this, roBrowser used some in-build features and it's possible to configure how it will react: Auto (deprecated) Will extract the packetver in the executable (if given by the user) and will listen for packets received from server to detect its version: packetver: 'auto', It's not stable enough to be use in production, please use the YYYYMMD version. Executable Will extract the packetver used in the client executable: packetver: 'executable', YYYYMMDD Specify directly the packetver : packetver: 20120523, Client Hash Some server require the client hash to connect successfully on the servers. clientHash: 'FA5C3249FEDEADL33TC4FEB4B3CA9924', Packet Encryption Using the Online App (ROBrowser.APP.ONLINE), it's possible to encrypt the packets sent to server (if the server support this features). It's an official features implemented on some private server. Disable by default. Boolean If set to true, the client will use encryption keys based on the packetver. To disable set it to false. packetKeys: true, YYYYMMDD Will use the keys base on the specify date packetKeys: 20120523, Array If you are using custom keys, it's possible to define it : packetKeys: [0x7E241DE0,0x5E805580,0x3D807D80], Disable Korean Lot of servers are wrongly using the langtype 0. The langtype set to 0 mean you want korean charset in your client but it's sometimes used in servers diffed to display english characters. So if you want to use the langtype 0 with english characters, you'll have to set disableKorean to true. disableKorean: true, Window Size The initial game size is about 800x600, you can modify this value by updating the parameters: width: 800, height: 600, Note: In Popup mode the window can be resized by the user. Game Quality (deprecated) To get better performance, it's possible to reduce the game quality : For now, it's better to let the user configure itself in the Graphics Settings. quality: 100, // 100% quality: 50, // 50% Background Music Extension The default Background Music in Ragnarok Online are mp3 files. This audio format is not the most suitable for the web, .ogg are lighter and without a weird license. BGMExtension will help by defining a list of format you want to load from your remote client (for now, only .mp3 and .ogg are supported). roBrowser will select the more suitable file to load depending of your browser compatibility. If not files are supported, a flash applet will do the job. Note: You need to have the other BGM files in your remote client. BGMExtension: ['ogg', 'mp3'], Save Files If users are playing using their local fullclient, it's possible for them to let roBrowser save the content in the browser filesystem It's for now only accessible on Chrome browser. Note: the player can play while roBrowser save their fullclient, a red progressbar will be shown at the top. It can take some seconds or some minutes depending of your computer speed and it's possible roBrowser experiment some lags during the save. Once done you will not have to worrie about selecting your fullclient files again (except if you want to update them). This option will also save files downloaded from the remote client to run faster the next time the file is required saveFiles: false, Version One of the web problem is cache, it's possible you updated roBrowser's file but your users will run the older script version because of their browser cache.To avoid this problem, version parameter was created. Every time you update roBrowser script, just modify the version to let your user update the scripts. version: 1.0, Skip Server List If set to true and there is only one server in your server list (clientinfo.xml, and char-servers), then no list will be popup and you will connect directly to only server left If set to false, you will always have the server list, even if there are just one node in. skipServerList: true, Skip Intro If you ever want to skip the intro window to go directory to the connection window, you can set the parameter skipIntro to true. Note: Your players will not be able to select their own local fullclient in this case skipIntro: true, Auto Login Option designed to connect directly your players to their account, by skipping the connection window.Usefull if you embedded roBrowser in a session protected website (Control Panel, Facebook, ...). autoLogin: ['userName', 'userPass'], Socket Proxy If you are using a Websocket Proxy, specify where is located the server socketProxy: 'ws://92.124.xx.x:5999', Development / Production Mode You can define if roBrowser should run or not the development code, using the development mode will run roBrowser with the sources files instead of the compiled one. development: true, Remote Client roBrowser allow to use a remote host where to download game ressources. Files are load from this host only if they are not found in user's game files. remoteClient: 'https://myserver.com/client/', Game Archive List (deprecated) This is deprecated, please let roBrowser detect it. Specify the game files to load from player's computer. This parameters can contain three differents types of data: String Specify the file which contain Game File order: grfList: 'DATA.INI', Array Specify directly Games files to load : grfList: ['custom.grf', 'palette.grf', 'data.grf'] RegExp Specify a Regex to filter game files : grfList: /\.grf$/i By default, roBrowser will try to load "DATA.INI" file, and if not found will find all files with grf extention and will load them depending ordering by their size. Servers Specify the servers the client have to connect. It can contain two differents types of data : String Specify the file which contain servers: servers: 'data/clientinfo.xml', Array Specify directly the servers you want to connect : servers: [{ // First server declaration display: 'MyROPrivateServer', desc: 'My awesome custom server', address: '82.192.xxx.xx', port: 6905, version: 30, langtype: 20, remoteClient: 'https://grf.robrowser.com/', packetver: 20131223, packetKeys: true, adminList: [2000000, 2000005, 2013525] }, { // Second server declaration display: 'Testing server', desc: 'Server in my own computer', address: '127.0.0.1', port: 6900, version: 22, langtype: 0, disableKorean: true, socketProxy: 'ws://proxy-server.com:7012/', adminList: [2000000, 2000005, 2013525] }] Note: If there is no server declaration, players can manage their own server list in the Intro Settings.Memory Optimization Do you know about the Garbage Collector ? Javascript doesn't have an explicit memory management, you can create but not delete objects. The Garbage collector help to regular this problem by pausing the javascript execution randomly to clean up unused memory.In theory it's awesome, but in practice if you create too many objects in a rendering loop then your game can freeze each seconds to delete objects making a very bad experience for your users. Since d33283, a big change where made to avoid object creation. Since this change I'm now able to render 3 times more poring (monster) in my screen than before.Since it's actually an interesting change, I think it's a good idea to share the process. Packets reception One of the primary things I would like to improve was the packet parser. Each time you received a packet from the server, it instantiate a new packet class to parse it. It's really annoying, particularly when you have around 100 monsters in your screen moving at the same time, it will create a hell lot of objects. Fixing it was pretty easy, since the packet were not stored anywhere after its used, then we can just create one instance per packets and re-use it each time. This process is also known as singleton. As I didn't want to modify manually hundred of packets, I just applied a little hack: - var data = new packet.struct(fp, offset); + if (!packet.instance) { // no instance create it + packet.instance = new packet.struct(fp, offset); + } + else { // use the instance + packet.struct.call(packet.instance, fp, offset); + } Path Finding Another leak I found is from the PathFinder algorithm. When this class is called (each time a monster/player move), a list of cells is generated in the format array[cellcount][2], meaning 1 + cellcount * 2 objects are created each time. It's really expensive, just imagine when there are dozens of monsters following you to attack... To optimize this, I fixed the problem differently. Instead of storing on multi-dimentionals array, I stored the data on a static Int16Array. The position is then aligned each 2 indexes [x0, y0, x1, y1, x2, y2] and the array stored in Entity's class to be re-used the next time. As typedarray is not a dynamical array, you must set a limit to its size. Happily in RO there is a server limitation avoiding to move more than 32 cells a time, so the maximum defined size of the array can not exceed 32*2. The over thing to thing about, is to not depend of the array.length property anymore, you have to add a variable to stored the movement size (to not execute a movement from an old path). - this.path = []; + this.path = new Int16Array(32*2); + this.total = 0; Another problem I saw in my script, is the use of path.shift() method to move in the path array. This method (as .slice(), .shift(), .splice(), ...) are bad practices : they are creating new array. This function was replaced with a new internal variables storing the progression in the path list. // Calculate new position, base on time and walk speed. -while (path.length) { - x = path[0][0] - walk.pos[0]; - y = path[0][1] - walk.pos[1]; +while (index < total) { + x = path[index+0] - walk.pos[0]; + y = path[index+1] - walk.pos[1]; // Seems like walking on diagonal is slower ? speed = (x && y) ? walk.speed / 0.6 : walk.speed; @@ -111,13 +116,16 @@ define( function( require ) } walk.tick += speed; - walk.pos.set(path.shift()); + walk.pos[0] = path[index+0]; + walk.pos[1] = path[index+1]; + index += 2; } -delay = Math.min(speed, TICK-walk.tick); +delay = Math.min(speed, TICK-walk.tick); +walk.index = index; With this, no object creating at all while calling this function, and the average speed should be faster because optimized in a typedarray. SoundManager optimization Finally the biggest improvement, optimizing memory used by Audio objects. Sounds are one of the most important things in games, and because of the complexity of the objects, using them can lead to a lot of GC pauses. So what can we do about it ? One thing, is maybe to avoid playing a sound more than one time at a time. It will not modify user experience and avoid to create multiple sound object for nothing when only one is really needed.The idea here, is to stored sounds you play in a list, add a tick parameter. Remove them from the list when the sound just ended. And add a check while wanted to add a new sound to check if it's already playing since a depending time duration. Client.loadFile( 'data/wav/' + filename, function( url ) { - var sound = document.createElement('audio'); + var i, count = _sounds.length; + var sound, tick = Date.now(); + + // Wait a delay to replay a sound + for (i = 0; i < count; ++i) { + if (_sounds[i].src === url && _sounds[i].tick > tick - 100) { + return; + } + } An other idea, is to avoid deleting sound if they are going to be played soon. When the sound just ended, cache them in a new list. When asking to play a new sound, check in the list if the sound already exist, then use it.It's important in this case to add a timer to sound in list to automatically remove them (it's not a good idea to store indefinitely sounds in cache, it will just lead to crash your browser because it's out of memory). // Is a not used sound is ready ? var sound = getSoundFromCache(filename); if (sound) { sound.play(); _sounds.push(sound); // play list return; } // Not from cache, load it Client.loadFile( 'data/wav/' + filename, function( url ) { sound = document.createElement('audio'); sound.src = url; ... sound.addEventListener('ended', storeSoundInCache, false); }); Finally, I let you enjoy the difference: Finally! Trade Interface Finally, one of the most waiting features of roBrowser is available : The Trade Interface. A lot of works were done recently in roBrowser so I got some time playing with the Trade window. It was introduce in the version f78c6875. Available by doing a right click on another player to exchange items and/or zeny (really more enjoyable than dropping items on the ground !). As you'll see the right click menu is not completed yet, it will require some futures update to be completely full. You'll also notice than you can access the pet menu by right clicking on your own QPet. Anyway, let's enjoy your new features and have fun.Card System implemented Last week roBrowser comes with a new addition : the card system. This system is well known in Ragnarok Online because it's the main element of strategic stuff and build. Cards are rare items you can find by killing monsters with a 0.01% chance rate. They can be inserted in slotted equipment and give your characters some special effects. roBrowser implements its main logic : Double click on a card to get a list of the equipments you can insert the card on. Add slots in equipment informations (free, disabled and cards). Update item name based on card, example: +5 double lucky knife. Add card illustration, viewable in the information window. roBrowser's users now have no reason to not have an awesome stuff !Grf Viewer GRF is the file extention for Ragnarok Online Game Resource Archive. This file is a sort of .zip storing all resources files from the game in its content. Writing a loader in javascript was kind of challengeous because of some limitation: Memory limitation Binary file ZLIB compression Custom DES encryption This viewer is now used to locate errors, help searching for files, preview files (bmp, gif, jpeg, tga, models, maps, effects) and can be used to extract some type of files. As there is no API to write into the disk there is no way to modify the GRFs you are viewing, or extract a folder from it. That's why it's called GRF Viewer. Maybe in future, more access will be given to javascript and I'll be able to modify it. Note: By clicking directly into the data folder, it will use the remote client files instead of the files contained in your own GRF file.Loading local FullClient One of the most unique features of roBrowser compared to other web apps is the ability to load directly Ragnarok Online files stored in user computer.Doing this will avoid the application to download files from a remote client, loading will be far faster, and you will save your bandwidth. The remote client is still available as a fallback if a file isn't found in local files. It's mainly possible because Ragnarok Online data files are stored in a compressed file called GRF (Game Resource File) with a crazy size of 2Go. So loading just it to be able to extract all the data files is just awesome (specially in javascript). In the past, loading this kind of file just crashed the browser because of too memory allocation, there were no way to stream the file and just parse part of it. But browsers vendors thought about it and implemented File.slice, a method to read junk of a file, without having to read it entierly. At this point, it just required a zlib decompressor, and a custom DES decryption to be able to parse the file completely. I took the Mozilla PDF.js zlib decompressor with some small modifications to speed it up (the old one was using too much allocation when you can just re-use buffer) and developed a unpacker for the custom DES encryption. So, about utilisation, it differ from one browser to another. In WebKit (Chrome, Opera) you can drag and drop your full client parent folder to the box to be able to parse all the files inside. It's quick, and easy. In Firefox, IE, and other browsers, it's a litte more difficult, there are no API to read files inside a folder, so you have to manually enter the folder, select all files (ctrl+A) and drag them to the browser. If you are ever interested by the loader, you can check, there are some interesting hack to speed up things: Inflate.js (ZLIB) GameFile.js (GRF) GameFileDecrypt.js (DES) Cute Pets are now available Ragnarok Online QPet is a system which allows players to tame monsters to become pets. The pet will follow the player everywhere and give him some special stat bonuses once Cordial or Loyal, He'll need to be feed and you can even let him equip some accessories. This feature is available since #33350658 and all necessary options are supported: Select a Tame Item to capture a monster. Displaying the Slot Machine and play with it. Selecting a Pet Incubator to choose the egg you want to open. Showing Pet Information window. Feed, perform action, equip accessory, return to egg state. Rename your pet. For more official informations about the Pet System, I recommend you to take a look at IRO QPet official page.Welcome Effects Awesome graphic improvement today, I created a STR file loader and renderer. This file contain key animationsof some effects used in Ragnarok Online, so since #8cd630e0, roBrowser is now able to display some graphics effects. I also wrote a viewer you can see below: There is still some bugs as there are some part of the file I don't know how what they are used for, but it's a work in progress. Note: Not all effects are rendered, only the one using STR file (and listed in the DB). There are a lot of effects in Ragnarok Online that are hardcoded and do not rely on files to be displayed.NPC Store successfully implemented One of the most used feature in Ragnarok Online, the NPC Store, is now available in roBrowser. It was added in version #dc23ce55.This window allow to buy and sell items to a NPC, it's time to do business ! There are still some features missing, currently in our TODO list, as the support for Cash Shop, display the Discount price, Display Player Shop, ... Expect to see them in the next weeks. As always, have fun using roBrowser !Emotions and Status The latest version comes with a new feature : sprite attachment. This system help to attach sprite to characters without adding a tonnes of new code, making the code more maintainable. You can now test the result in game with two new features : emotions and status effects (freeze, stun, curse, ...) For now there is no Emotion window, it will come later using ALT+L, so you will have to know the command to enter to the chatbox. Regulars will already know the famous shortcuts /heh, /gg or /slur, others can check the complete list from IRO wiki. Let's have some fun.Party System just landed Since some days now, one of the most ask features were implemented : the Party system (and friends) is now available in roBrowser.All features from the official client are currently implemented: Chat commands: /organize, /invite, /leave. Context Menu access using right click on a character to invite people to your team, or register friends. UI windows to create party, invite people, expel people, change settings and promote leader. Lifes of your members are displayed in real time in the UI. Skills can be cast on members from the UI (helping support class to boost members). Shortcuts ALT+Z and ALT+H were added to toggle the window. As a bonus, the command /hi was implemented, to say hello to all your connected friends ! It's quiet a big update, so if you see problems or bugs it will be good to report them as fast as possible.Enjoy !