Difference between revisions of "Modding:Main Page"
(add link to new mapmaking page) |
(add custom mob drops code) |
||
Line 234: | Line 234: | ||
</pre> | </pre> | ||
Call this helper function with the object to send to, the event to send, and the data of the event, and it will work on the main thread or the map threads. | Call this helper function with the object to send to, the event to send, and the data of the event, and it will work on the main thread or the map threads. | ||
+ | |||
+ | === Adding custom drops to a mob === | ||
+ | <pre> | ||
+ | mob.inventory.blueprint = extend(mob.inventory.blueprint || {}, { | ||
+ | noRandom: true, | ||
+ | alsoRandom: true, | ||
+ | blueprints: [{ | ||
+ | chance: 100, | ||
+ | name: 'Family Heirloom', | ||
+ | quality: 1, | ||
+ | slot: 'neck', | ||
+ | type: 'Choker', | ||
+ | stats: ['vit', 'regenMana'] | ||
+ | }] | ||
+ | }); | ||
+ | </pre> | ||
+ | This snippet will add the chance to drop a family heirloom from the mob, as well as normal random gear items. This change can also be applied in the zone file (<code>zone.mobs.mob_name.regular.drops</code>) with <code>extend</code>. | ||
<!-- i'm going to finish this later --> | <!-- i'm going to finish this later --> | ||
<!-- === Give a player an item === | <!-- === Give a player an item === | ||
<pre></pre> --> | <pre></pre> --> |
Revision as of 17:30, 16 February 2019
Modding
Modding may refer to multiple things in Isleward. See Modding (disambiguation) for more information.
WIP: This article is a work in progress, meaning that it is being worked on but is unfinished. You can help by editing it.
Stub: This article is a stub. You may complete the article by expanding it.
THIS ARTICLE IS VERY OUTDATED AND INCOMPLETE SINCE NOT MANY MODS HAVE BEEN MADE. ALWAYS CHECK THE CURRENT CODEBASE FIRST TO MAKE SURE THE INFORMATION IS CORRECT.
Isleward allows for server-side mods by dropping mod folders into another folder in the server source. A few tools are available to assist users with modding, such as the Modding:Sprite Editor, Modding:Map Editor, Modding:Tree Editor, and Modding:Item Tooltip Generator.
See also: Mod (outside of the modding namespace since it's more player-facing), Modding:Mapmaking
Running the Server
You can run an Isleward server on your own computer if you would like to make/play with mods, test the game, or run a private server.
First, you'll need to install Node.JS and NPM. NPM should be included in the download linked above.
There are two ways to get the source code. The first way uses Git, a Source Control Management program. The second way is to download the source files from the repository yourself, which doesn't require you to install another program but it is more difficult to update your server version later on.
Method 1: This way works best because you can run a single command to download the latest version without having to manually set up the files again.
Once you install Git, navigate to the parent directory of where you want to install the server.
Run git clone https://gitlab.com/Isleward/Isleward.git FOLDER
, replacing FOLDER
with whatever you want to call the folder you are installing Isleward into.
After that, cd
into FOLDER/src/server
.
The server is now downloaded.
Method 2: This way doesn't require a download but is harder to maintain.
Open this page in your browser.
Click on the download button and download the source in a format of your choice.
Extract the downloaded files into a directory you want to install Isleward into.
Navigate to FOLDER/src/server
Both methods will get you to the same place.
Make sure you are in FOLDER/src/server
and run npm install
.
If you installed Node.JS and NPM correctly, it should start installing.
Wait for it to install.
It should install everything it needs on its own without needing you to install other dependencies.
If you encounter other errors, try running it again with administrative permissions and try other basic troubleshooting problems.
The Isleward Discord might also be able to help you with your problem.
Now that you have all the dependencies installed, you should be ready to go!
Run node --expose-gc index.js
(in FOLDER/src/server
) and you should see something like
Server: ready (M estuary): Ready (M sewer): Ready (M cave): Ready (M tutorial): Ready
If you see something like that (zone names may be different), your server is running. Head over to http://localhost:4000/ and you should see the game running!
You can change the message shown in the console (the Server: ready
part) and the port that it runs on in FOLDER/src/server/config/serverConfig.js
, the file should be pretty self-explanatory.
Using Mods
You can use a modpack by dropping it into the "mods" folder of the server source code.
Events
A list of events available.
onAfterGetLayerObjects
onBeforeBuildLayerTile
onBeforeGetAnimations
onBeforeGetClasses
onBeforeGetDialogue
onBeforeGetEffect
First, look at this code snippet from the effect component (src/server/components/effects.js
):
var type = options.type[0].toUpperCase() + options.type.substr(1); var result = { type: type, url: 'config/effects/effect' + type + '.js' }; this.obj.instance.eventEmitter.emit('onBeforeGetEffect', result); typeTemplate = require(result.url);
It fires an event, in case a mod wants to modify the path which the effect is loaded from. Because the code allows us to mod this easily, we use (in our mod's index.js
, bound to the event, of course):
onBeforeGetEffect: function(data) { if(data.type == "newType") { data.url = 'mods/newTypeMod/newType.js' } }
Then, in our mod's newType.js
:
module.exports = { type: 'newType', events: { beforeTakeDamage: function(damage, source) { damage.failed = true; // have not tested whether we need this, probably do this.obj.instance.syncer.queue('onGetDamage', { id: this.obj.id, event: true, text: 'newType cancel' }); } } }
This creates an example effect that cancels all damage and shows a message (mostly copied paraphrased from the ReflectDamage effect in the core codebase). Be warned, this hasn't been tested yet, but in theory it should work.
onBeforeGetEventList
onBeforeGetFactions
onBeforeGetHerbConfig
onBeforeGetItemTypes
onBeforeGetMtxList
onBeforeGetQuests
onBeforeGetResourceList
onBeforeGetSkins
Called with an Object of all the skins. Each skin is its own Object that looks like this:
'skin key': { name: 'Full Skin Name', sprite: [ 0, 0 ], class: 'wizard', spritesheet: 'optional path to spritesheet', default: true }
This will likely change in future updates, with the addition of Spirits and the removal of class-restricted skins.
onBeforeGetSpellsConfig
onBeforeGetSpellsInfo
onBeforeGetSpellTemplate
onBeforeGetZone
Other Tips
cpn
refers to a component.
obj
refers to an object.
ttl
is an object's "time to live." When it runs out, the object is destroyed.
In-Game Event System Findings
A player is considered close to an event if:
- The events needed distance is -1 (marks the player as participating as well)
- The event doesn't have a needed distance
- The player is within the needed distance from any object that is part of the event (usually mobs spawned by the even)
- The player has already been marked as participating in the event (if you participate and leave, the event will still show up)
A 'mark' in time is in ticks (each are 350 milliseconds). To turn marks into minutes, multiply by 0.00583333333. To turn marks into seconds, multiply by 0.35.
Code Samples
Below are some code samples for common things to do in mods.
Only run on the main thread
let isMapThread = !!process.send;
If the variable is true, then it is a map thread, of course.
Add a new skin
In the mod's init:
this.events.on('onBeforeGetSkins', this.onBeforeGetSkins.bind(this))
The onBeforeGetSkins
part:
onBeforeGetSkins: function(skins) { skins['renamed thief'] = { name: 'Renamed Thief 1 Skin', sprite: [ 6, 0 ], class: 'thief', default: true } }
A component that saves
In yourNewComponent.js
:
module.exports = { type: 'killStats', kills: {}, init: function (blueprint) { this.kills = blueprint.kills || {}; }, simplify: function (self) { if (!self) return null; return { type: 'killStats', kills: this.kills }; }, events: { afterKillMob: function (mob) { this.kills[mob.name] = (this.kills[mob.name] || 0) + 1; } } };
In your mod's index file:
module.exports = { name: 'Your New Mod', init: function () { this.events.on('onBeforeGetComponents', this.onBeforeGetComponents.bind(this)); }, onBeforeGetComponents: function (components) { components.yourNewComponent = require('./yourNewComponent'); } // Need to add the kill counter component to the player somehow }
Fire an event on the client
fireClientEvent = function (obj, event, data = {}) { if (obj.socket) obj.socket.emit('events', { [event]: [data] }); else obj.instance.syncer.queue(event, data, [obj.serverId]); }
Call this helper function with the object to send to, the event to send, and the data of the event, and it will work on the main thread or the map threads.
Adding custom drops to a mob
mob.inventory.blueprint = extend(mob.inventory.blueprint || {}, { noRandom: true, alsoRandom: true, blueprints: [{ chance: 100, name: 'Family Heirloom', quality: 1, slot: 'neck', type: 'Choker', stats: ['vit', 'regenMana'] }] });
This snippet will add the chance to drop a family heirloom from the mob, as well as normal random gear items. This change can also be applied in the zone file (zone.mobs.mob_name.regular.drops
) with extend
.