From cb9c0d1d00c1fd7ea53bc4a745e20d1160dde5ce Mon Sep 17 00:00:00 2001 From: Big Bad Waffle Date: Sun, 19 Feb 2017 22:07:23 +0200 Subject: [PATCH] Initial Commit for Mod Support --- .gitignore | 4 +- src/client/images/characters.png | Bin 914 -> 3779 bytes src/client/images/items.pyxel | Bin 26335 -> 26330 bytes src/client/js/main.js | 16 ++++- src/client/js/renderer.js | 8 ++- src/client/js/resources.js | 10 +-- src/client/js/system/client.js | 9 ++- .../ui/templates/characters/characters.js | 4 +- .../createCharacter/createCharacter.js | 15 ++--- .../ui/templates/equipment/equipment.js | 8 ++- .../ui/templates/inventory/inventory.js | 2 +- src/client/ui/templates/smithing/smithing.js | 2 +- src/client/ui/templates/spells/spells.js | 3 +- src/client/ui/templates/trade/trade.js | 2 +- src/server/components/auth.js | 22 +++---- src/server/components/inventory.js | 1 - src/server/components/player.js | 3 +- src/server/components/spellbook.js | 16 +++-- src/server/config/classes.js | 13 +++- src/server/config/clientConfig.js | 17 +++++ src/server/config/skins.js | 33 +++++++++- src/server/config/spells.js | 9 ++- src/server/config/spellsConfig.js | 9 ++- src/server/globals.js | 9 ++- src/server/items/config/types.js | 9 ++- src/server/items/generators/types.js | 2 + src/server/misc/events.js | 62 ++++++++++++++++++ src/server/misc/mods.js | 14 ++++ src/server/mods/modList.js | 9 +++ src/server/server.js | 5 +- src/server/startup.js | 7 +- src/server/world/worker.js | 6 +- 32 files changed, 263 insertions(+), 66 deletions(-) create mode 100644 src/server/config/clientConfig.js create mode 100644 src/server/misc/events.js create mode 100644 src/server/misc/mods.js create mode 100644 src/server/mods/modList.js diff --git a/.gitignore b/.gitignore index dd41ccd3..3f7ed0db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules -storage.db \ No newline at end of file +storage.db +*.sublime-project +*.sublime-workspace \ No newline at end of file diff --git a/src/client/images/characters.png b/src/client/images/characters.png index 33524599ee2f9ff9903a76e64f3008314c87cf5c..a099f0be95f8adfb98d84f7687614c6b22a5ec87 100644 GIT binary patch literal 3779 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Ξ5*nTyg`^Ng^!ORVz+v|-IzLtN! zKD}O!LEE22;ohQzS4s}Y7cg)%kcr-y{$?$Yo+xViewQ{duQ7PK`njxgN@xNAk~WVZ diff --git a/src/client/images/items.pyxel b/src/client/images/items.pyxel index 1f478522754a1eb0c2af451d30db8bdc45420f3a..3ddfb66fe33eb1d29e6b2e686f4071eab5dabbf5 100644 GIT binary patch delta 4615 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 diff --git a/src/client/js/main.js b/src/client/js/main.js index 54091360..f2aa49b1 100644 --- a/src/client/js/main.js +++ b/src/client/js/main.js @@ -35,8 +35,23 @@ define([ hasFocus: true, init: function() { + client.init(this.onClientReady.bind(this)); + }, + + onClientReady: function() { + client.request({ + module: 'clientConfig', + method: 'getResourcesList', + callback: this.onGetResourceList.bind(this) + }); + }, + + onGetResourceList: function(list) { + resources.init(list); + events.on('onResourcesLoaded', this.start.bind(this)); }, + start: function() { window.onfocus = this.onFocus.bind(this, true); window.onblur = this.onFocus.bind(this, false); @@ -46,7 +61,6 @@ define([ }); objects.init(); - client.init(); renderer.init(); input.init(); diff --git a/src/client/js/renderer.js b/src/client/js/renderer.js index 025e3f0b..198b7ac3 100644 --- a/src/client/js/renderer.js +++ b/src/client/js/renderer.js @@ -97,7 +97,13 @@ define([ this.stage.addChild(layers[l]) }, this); - ['sprites', 'tiles', 'mobs', 'bosses', 'bigObjects', 'objects', 'characters', 'attacks', 'auras', 'walls', 'ui', 'animChar', 'animMob', 'animBoss'].forEach(function(t) { + var spriteNames = ['sprites', 'tiles', 'mobs', 'bosses', 'bigObjects', 'objects', 'characters', 'attacks', 'auras', 'walls', 'ui', 'animChar', 'animMob', 'animBoss']; + resources.spriteNames.forEach(function(s) { + if (s.indexOf('.png') > -1) + spriteNames.push(s); + }); + + spriteNames.forEach(function(t) { this.textures[t] = new pixi.BaseTexture(resources.sprites[t].image); this.textures[t].scaleMode = pixi.SCALE_MODES.NEAREST; }, this); diff --git a/src/client/js/resources.js b/src/client/js/resources.js index 168a310c..405c2c6f 100644 --- a/src/client/js/resources.js +++ b/src/client/js/resources.js @@ -28,13 +28,17 @@ define([ ], sprites: {}, ready: false, - init: function() { + init: function(list) { + list.forEach(function(l) { + this.spriteNames.push(l); + }, this); + this.spriteNames.forEach(function(s) { var sprite = { image: (new Image()), ready: false }; - sprite.image.src = 'images/' + s + '.png'; + sprite.image.src = s.indexOf('png') > -1 ? s : 'images/' + s + '.png'; sprite.image.onload = this.onSprite.bind(this, sprite); this.sprites[s] = sprite; @@ -59,7 +63,5 @@ define([ } }; - resources.init(); - return resources; }); \ No newline at end of file diff --git a/src/client/js/system/client.js b/src/client/js/system/client.js index 72df6ff6..bc08fc1f 100644 --- a/src/client/js/system/client.js +++ b/src/client/js/system/client.js @@ -8,7 +8,7 @@ define([ var client = { doneConnect: false, - init: function() { + init: function(onReady) { var tType = 'websocket'; if (window.location.href.indexOf('polling') > -1) tType = 'polling'; @@ -17,17 +17,20 @@ define([ transports: [ tType ] }); - this.socket.on('connect', this.onConnected.bind(this)); + this.socket.on('connect', this.onConnected.bind(this, onReady)); this.socket.on('handshake', this.onHandshake.bind(this)); this.socket.on('event', this.onEvent.bind(this)); this.socket.on('events', this.onEvents.bind(this)); this.socket.on('dc', this.onDisconnect.bind(this)); }, - onConnected: function() { + onConnected: function(onReady) { if (this.doneConnect) this.onDisconnect(); else this.doneConnect = true; + + if (onReady) + onReady(); }, onDisconnect: function() { window.location = window.location; diff --git a/src/client/ui/templates/characters/characters.js b/src/client/ui/templates/characters/characters.js index 99fa970b..28ddeae3 100644 --- a/src/client/ui/templates/characters/characters.js +++ b/src/client/ui/templates/characters/characters.js @@ -135,8 +135,10 @@ define([ spirteX = -(spirteX * 32); spriteY = -(spriteY * 32); + var spritesheet = result.previewSpritesheet || '../../../images/charas.png'; + this.find('.sprite') - .css('background', 'url("../../../images/charas.png") ' + spirteX + 'px ' + spriteY + 'px') + .css('background', 'url("' + spritesheet + '") ' + spirteX + 'px ' + spriteY + 'px') .show(); this.find('.name').html(name); diff --git a/src/client/ui/templates/createCharacter/createCharacter.js b/src/client/ui/templates/createCharacter/createCharacter.js index 3328bf69..556d9714 100644 --- a/src/client/ui/templates/createCharacter/createCharacter.js +++ b/src/client/ui/templates/createCharacter/createCharacter.js @@ -15,12 +15,7 @@ define([ tpl: template, centered: true, - classSprites: { - warrior: [1, 1], - wizard: [2, 0], - thief: [6, 0], - cleric: [4, 0] - }, + classSprites: null, class: 'wizard', costume: 0, @@ -172,13 +167,15 @@ define([ }, setSprite: function() { - var classSprite = this.classSprites[this.class]; - var costume = classSprite[this.costume].split(','); + var classSprite = this.classSprites[this.class][this.costume]; + var costume = classSprite.sprite.split(','); var spirteX = -costume[0] * 32; var spriteY = -costume[1] * 32; + var spritesheet = classSprite.spritesheet || '../../../images/charas.png'; + this.find('.sprite') - .css('background', 'url("../../../images/charas.png") ' + spirteX + 'px ' + spriteY + 'px'); + .css('background', 'url("' + spritesheet + '") ' + spirteX + 'px ' + spriteY + 'px'); } }; }); \ No newline at end of file diff --git a/src/client/ui/templates/equipment/equipment.js b/src/client/ui/templates/equipment/equipment.js index 40b38322..2cb18346 100644 --- a/src/client/ui/templates/equipment/equipment.js +++ b/src/client/ui/templates/equipment/equipment.js @@ -113,12 +113,14 @@ define([ slot = 'rune-' + spellId; } + var spritesheet = item.spritesheet || '../../../images/items.png'; + var elSlot = this.find('[slot="' + slot + '"]'); elSlot .data('item', item) .removeClass('empty') .find('.icon') - .css('background', 'url(../../../images/items.png) ' + imgX + 'px ' + imgY + 'px') + .css('background', 'url("' + spritesheet + '") ' + imgX + 'px ' + imgY + 'px') .off() .on('mousemove', this.onHoverItem.bind(this, elSlot, item, null)) .on('mouseleave', this.onHoverItem.bind(this, null, null)) @@ -159,7 +161,7 @@ define([ .forEach(function(item) { var sprite = item.sprite || [7, 0]; - var spriteSheet = item.empty ? 'uiIcons' : 'items'; + var spriteSheet = item.empty ? '../../../images/uiIcons.png' : item.spritesheet || '../../../images/items.png'; var imgX = -sprite[0] * 64; var imgY = -sprite[1] * 64; @@ -168,7 +170,7 @@ define([ el .find('.icon') - .css('background', 'url(../../../images/' + spriteSheet + '.png) ' + imgX + 'px ' + imgY + 'px') + .css('background', 'url("' + spriteSheet + '") ' + imgX + 'px ' + imgY + 'px') .on('mousemove', this.onHoverItem.bind(this, el, item, null)) .on('mouseleave', this.onHoverItem.bind(this, null, null)) .on('click', this.equipItem.bind(this, item)); diff --git a/src/client/ui/templates/inventory/inventory.js b/src/client/ui/templates/inventory/inventory.js index b16cc343..66ed9e8a 100644 --- a/src/client/ui/templates/inventory/inventory.js +++ b/src/client/ui/templates/inventory/inventory.js @@ -119,7 +119,7 @@ define([ var itemEl = $(tplItem) .appendTo(container); - var spritesheet = 'items'; + var spritesheet = item.spritesheet || 'items'; if (item.material) spritesheet = 'materials'; else if (item.quest) diff --git a/src/client/ui/templates/smithing/smithing.js b/src/client/ui/templates/smithing/smithing.js index 1b135b36..e2994310 100644 --- a/src/client/ui/templates/smithing/smithing.js +++ b/src/client/ui/templates/smithing/smithing.js @@ -220,7 +220,7 @@ define([ var imgX = -item.sprite[0] * 64; var imgY = -item.sprite[1] * 64; - var spritesheet = 'items'; + var spritesheet = item.spritesheet || 'items'; if (item.material) spritesheet = 'materials'; else if (item.quest) diff --git a/src/client/ui/templates/spells/spells.js b/src/client/ui/templates/spells/spells.js index 5abd6fb7..5bff7b83 100644 --- a/src/client/ui/templates/spells/spells.js +++ b/src/client/ui/templates/spells/spells.js @@ -43,9 +43,10 @@ define([ .on('mouseover', this.onShowTooltip.bind(this, el, spells[i])) .on('mouseleave', this.onHideTooltip.bind(this, el)); + var spritesheet = spells[i].spritesheet || '../../../images/abilityIcons.png'; el .find('.icon').css({ - 'background': 'url("../../../images/abilityIcons.png") ' + x + 'px ' + y + 'px' + 'background': 'url("' + spritesheet + '") ' + x + 'px ' + y + 'px' }) .next().html(i + 1); diff --git a/src/client/ui/templates/trade/trade.js b/src/client/ui/templates/trade/trade.js index cb786760..3aebcea8 100644 --- a/src/client/ui/templates/trade/trade.js +++ b/src/client/ui/templates/trade/trade.js @@ -62,7 +62,7 @@ define([ var size = 64; var offset = 0; - var spritesheet = 'items'; + var spritesheet = item.spritesheet || 'items'; if (item.material) spritesheet = 'materials'; else if (item.quest) diff --git a/src/server/components/auth.js b/src/server/components/auth.js index 7df5c54e..83a20e90 100644 --- a/src/server/components/auth.js +++ b/src/server/components/auth.js @@ -115,8 +115,8 @@ define([ var result = characters .map(c => ({ - name: c, - level: leaderboard.getLevel(c) + name: c.name ? c.name : c, + level: leaderboard.getLevel(c.name ? c.name : c) })); data.callback(result); @@ -300,14 +300,8 @@ define([ this.obj.class = data.class; this.obj.costume = data.costume; - var tiles = { - wizard: [2, 3], - cleric: [4, 5], - thief: [6, 7], - warrior: [9, 10] - }; - - this.obj.cell = tiles[data.class][data.costume]; + this.obj.cell = skins.getCell(this.obj.class, this.obj.costume); + this.obj.previewSpritesheet = skins.getSpritesheet(this.obj.class); var simple = this.obj.getSimple(true); simple.components.push({ @@ -360,10 +354,16 @@ define([ }, onDeleteCharacter: function(msg, result) { this.characterList.spliceWhere(c => c == msg.data.name); + var characterList = this.characterList + .map(c => ({ + name: c.name ? c.name : c, + level: leaderboard.getLevel(c.name ? c.name : c) + })); + io.set({ ent: this.username, field: 'characterList', - value: JSON.stringify(this.characterList), + value: JSON.stringify(characterList), callback: this.onRemoveFromList.bind(this, msg) }); diff --git a/src/server/components/inventory.js b/src/server/components/inventory.js index 02217d1e..418c7794 100644 --- a/src/server/components/inventory.js +++ b/src/server/components/inventory.js @@ -11,7 +11,6 @@ define([ objects, classes ) { - return { type: 'inventory', diff --git a/src/server/components/player.js b/src/server/components/player.js index efe75a97..490265c2 100644 --- a/src/server/components/player.js +++ b/src/server/components/player.js @@ -26,9 +26,10 @@ define([ spawn: function(character) { var obj = this.obj; extend(true, obj, { - sheetName: 'characters', + sheetName: classes.getSpritesheet(character.class), layerName: 'mobs', cell: character.cell, + previewSpritesheet: character.previewSpritesheet, name: character.name, class: character.class, zoneName: character.zoneName || 'tutorial-cove', diff --git a/src/server/components/spellbook.js b/src/server/components/spellbook.js index 73095a31..e7e45892 100644 --- a/src/server/components/spellbook.js +++ b/src/server/components/spellbook.js @@ -2,12 +2,14 @@ define([ './../config/spells/spellTemplate', './../config/animations', './../config/spells', - './../config/spellsConfig' + './../config/spellsConfig', + 'misc/events' ], function( spellTemplate, animations, playerSpells, - playerSpellsConfig + playerSpellsConfig, + events ) { return { type: 'spellbook', @@ -82,9 +84,15 @@ define([ var type = options.type[0].toUpperCase() + options.type.substr(1); - var typeTemplate = require('./config/spells/spell' + type); + var typeTemplate = { + type: type, + template: null + }; + events.emit('onBeforeGetSpellTemplate', typeTemplate); + if (!typeTemplate.template) + typeTemplate.template = require('./config/spells/spell' + type); - var builtSpell = extend(true, {}, spellTemplate, typeTemplate, options); + var builtSpell = extend(true, {}, spellTemplate, typeTemplate.template, options); builtSpell.obj = this.obj; builtSpell.baseDamage = builtSpell.damage; builtSpell.damage += (options.damageAdd || 0); diff --git a/src/server/config/classes.js b/src/server/config/classes.js index ac68917b..c46080aa 100644 --- a/src/server/config/classes.js +++ b/src/server/config/classes.js @@ -1,9 +1,9 @@ define([ - + 'misc/events' ], function( - + events ) { - return { + var classes = { spells: { wizard: ['ice spear'], cleric: ['healing circle'], @@ -41,6 +41,13 @@ define([ cleric: 'Mace', thief: 'Dagger', warrior: 'Axe' + }, + + getSpritesheet: function(className) { + return this.stats[className].spritesheet || 'characters'; } }; + + events.emit('onBeforeGetClasses', classes); + return classes; }); \ No newline at end of file diff --git a/src/server/config/clientConfig.js b/src/server/config/clientConfig.js new file mode 100644 index 00000000..5625e440 --- /dev/null +++ b/src/server/config/clientConfig.js @@ -0,0 +1,17 @@ +define([ + 'misc/events' +], function( + events +) { + return { + resourceList: [], + + init: function() { + events.emit('onBeforeGetResourceList', this.resourceList); + }, + + getResourcesList: function(msg) { + msg.callback(this.resourceList); + } + }; +}); \ No newline at end of file diff --git a/src/server/config/skins.js b/src/server/config/skins.js index 888f6a16..9b218218 100644 --- a/src/server/config/skins.js +++ b/src/server/config/skins.js @@ -1,7 +1,7 @@ define([ - + 'misc/events' ], function( - + events ) { var config = { 'wizard 1': { @@ -60,6 +60,8 @@ define([ } }; + events.emit('onBeforeGetSkins', config); + return { getBlueprint: function(skinId) { return config[skinId]; @@ -79,10 +81,35 @@ define([ if (!result[l.class]) result[l.class] = []; - result[l.class].push(l.sprite[0] + ',' + l.sprite[1]); + result[l.class].push({ + sprite: l.sprite[0] + ',' + l.sprite[1], + spritesheet: l.spritesheet + }); }); return result; + }, + + getCell: function(className, costume) { + var res = Object.keys(config) + .filter(function(s) { + return (config[s].class == className); + }) + .map(function(s) { + return config[s]; + })[costume]; + + return (res.sprite[1] * 8) + res.sprite[0]; + }, + + getSpritesheet: function(className) { + return Object.keys(config) + .filter(function(s) { + return (config[s].class == className); + }) + .map(function(s) { + return config[s]; + })[0].spritesheet; } }; }); \ No newline at end of file diff --git a/src/server/config/spells.js b/src/server/config/spells.js index 762add35..01baa07c 100644 --- a/src/server/config/spells.js +++ b/src/server/config/spells.js @@ -1,9 +1,9 @@ define([ - + 'misc/events' ], function( - + events ) { - return [{ + var spells = [{ name: 'Magic Missile', description: 'Launches an orb of unfocussed energy at your target.', type: 'projectile', @@ -382,4 +382,7 @@ define([ chance: 0.02 } }]; + + events.emit('onBeforeGetSpellsInfo', spells); + return spells; }); \ No newline at end of file diff --git a/src/server/config/spellsConfig.js b/src/server/config/spellsConfig.js index cb09914f..69092cc5 100644 --- a/src/server/config/spellsConfig.js +++ b/src/server/config/spellsConfig.js @@ -1,9 +1,9 @@ define([ - + 'misc/events' ], function( - + events ) { - return { + var spells = { 'magic missile': { statType: 'int', statMult: 0.216, @@ -172,4 +172,7 @@ define([ } } }; + + events.emit('onBeforeGetSpellsConfig', spells); + return spells; }); \ No newline at end of file diff --git a/src/server/globals.js b/src/server/globals.js index 93ec4a85..3713eed8 100644 --- a/src/server/globals.js +++ b/src/server/globals.js @@ -4,14 +4,16 @@ define([ 'misc/helpers', 'items/lootRoller', 'world/atlas', - 'leaderboard/leaderboard' + 'leaderboard/leaderboard', + 'config/clientConfig' ], function( extend, cons, helpers, lootRoller, atlas, - leaderboard + leaderboard, + clientConfig ) { return { init: function() { @@ -21,6 +23,9 @@ define([ global.lootRoller = lootRoller; global.atlas = atlas; global.leaderboard = leaderboard; + global.clientConfig = clientConfig; + + clientConfig.init(); } }; }); \ No newline at end of file diff --git a/src/server/items/config/types.js b/src/server/items/config/types.js index 450fca0c..4b5715f6 100644 --- a/src/server/items/config/types.js +++ b/src/server/items/config/types.js @@ -1,9 +1,9 @@ define([ - + 'misc/events' ], function( - + events ) { - return { + var types = { head: { 'Helmet': { sprite: [0, 0], @@ -191,4 +191,7 @@ define([ } } } + + events.emit('onBeforeGetItemTypes', types); + return types; }); \ No newline at end of file diff --git a/src/server/items/generators/types.js b/src/server/items/generators/types.js index ba49e4c5..b251c4a8 100644 --- a/src/server/items/generators/types.js +++ b/src/server/items/generators/types.js @@ -15,6 +15,8 @@ define([ item.type = type; item.sprite = typeBlueprint.sprite; + if (typeBlueprint.spritesheet) + item.spritesheet = typeBlueprint.spritesheet; if (typeBlueprint.spellName) blueprint.spellName = typeBlueprint.spellName; diff --git a/src/server/misc/events.js b/src/server/misc/events.js new file mode 100644 index 00000000..edda6923 --- /dev/null +++ b/src/server/misc/events.js @@ -0,0 +1,62 @@ +define([ + +], function( + +) { + return { + events: {}, + queue: [], + on: function(event, callback) { + var list = this.events[event] || (this.events[event] = []); + list.push(callback); + + for (var i = 0; i < this.queue.length; i++) { + var q = this.queue[i]; + if (q.event != event) + continue; + + this.queue.splice(i, 1); + i--; + + q.args.splice(0, 0, event); + + this.emit.apply(this, q.args); + } + + return callback; + }, + off: function(event, callback) { + var list = this.events[event] || []; + var lLen = list.length; + for (var i = 0; i < lLen; i++) { + if (list[i] == callback) { + list.splice(i, 1); + i--; + lLen--; + } + } + + if (lLen == 0) + delete this.events[event]; + }, + emit: function(event) { + var args = [].slice.call(arguments, 1); + + var list = this.events[event]; + if (!list) { + this.queue.push({ + event: event, + args: args + }); + + return; + } + + var len = list.length + for (var i = 0; i < len; i++) { + var l = list[i]; + l.apply(null, args); + } + } + }; +}); \ No newline at end of file diff --git a/src/server/misc/mods.js b/src/server/misc/mods.js new file mode 100644 index 00000000..7ca54fbb --- /dev/null +++ b/src/server/misc/mods.js @@ -0,0 +1,14 @@ +define([ + 'mods/modList' +], function( + modList +) { + return { + init: function() { + modList.forEach(function(m) { + var mod = require('mods/' + m + '/index'); + mod.init(); + }, this); + } + }; +}); \ No newline at end of file diff --git a/src/server/mods/modList.js b/src/server/mods/modList.js new file mode 100644 index 00000000..47cce6b9 --- /dev/null +++ b/src/server/mods/modList.js @@ -0,0 +1,9 @@ +define([ + +], function( + +) { + return [ + + ]; +}); \ No newline at end of file diff --git a/src/server/server.js b/src/server/server.js index ed2f7037..12b0e561 100644 --- a/src/server/server.js +++ b/src/server/server.js @@ -10,7 +10,10 @@ define([ global.io = require('socket.io')(server); app.use(function(req, res, next) { - req.url = '/client/' + req.url; + if (req.url.indexOf('/server') != 0) + req.url = '/client/' + req.url; + else + req.url.substr(7); next(); }); diff --git a/src/server/startup.js b/src/server/startup.js index 0f937ee0..35308852 100644 --- a/src/server/startup.js +++ b/src/server/startup.js @@ -4,14 +4,16 @@ define([ 'world/atlas', 'components/components', 'leaderboard/leaderboard', - 'security/io' + 'security/io', + 'misc/mods' ], function( globals, server, atlas, components, leaderboard, - io + io, + mods ) { return { init: function() { @@ -30,6 +32,7 @@ define([ server.init(this.onServerReady.bind(this)); }, onServerReady: function() { + mods.init(); atlas.init(); leaderboard.init(); } diff --git a/src/server/world/worker.js b/src/server/world/worker.js index 1616887e..acf56164 100644 --- a/src/server/world/worker.js +++ b/src/server/world/worker.js @@ -9,9 +9,9 @@ global.io = true; var instancer = null; requirejs([ - 'extend', 'misc/helpers', 'components/components', 'world/instancer', 'security/io' + 'extend', 'misc/helpers', 'components/components', 'world/instancer', 'security/io', 'misc/mods' ], function( - extend, helpers, components, _instancer, io + extend, helpers, components, _instancer, io, mods ) { var onDbReady = function() { global.extend = extend; @@ -26,6 +26,8 @@ requirejs([ }); }); + mods.init(); + setInterval(function() { global.gc(); }, 60000);