Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

discord

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

discord - npm Package Compare versions

Comparing version 0.7.1 to 0.8.0

178

classes/AdvancedParser.js

@@ -14,20 +14,14 @@ /**

AdvancedParser = new Class({
command: {},
actor: null, //The actor object calling the command.
Implements: CommandParser,
//Format: command: { [syntaxes], method }
commands: {},
//Format: pattern: method
syntaxes: {},
//Until we're set for multiple syntaxes, this will hold us over.
syntax: null,
living: null, //The living object calling the command.
holder: null, //The object this command is defined on.
failure_message: null,
initialize: function(actor, holder) {
this.actor = actor;
this.holder = holder;
},
/**

@@ -39,3 +33,3 @@ * This method is intended to let the developer create different handlers

* eventually be more complex.
*/
*
add_syntax: function(pattern, handler) {

@@ -49,3 +43,3 @@ this.set_syntax(pattern, handler);

},
/**

@@ -59,2 +53,6 @@ * Get syntax patterns for a particular command.

},
add_failure_message: function(message) {
this.failure_message = '';
},

@@ -74,64 +72,44 @@ /**

*/
parseLine: function(line, living, holder) {
this.failure_message = false;
parse: function(line, syntax) {
var args = this.extractArguments(line,syntax);
holder = holder || this;
this.living = living;
this.holder = holder;
var words = line.split(' ');
var command = words.shift();
line = words.join(' ');
var patterns = this.getPatterns(command, holder.commands);
var handler = this.getHandler(command, holder.commands);
if (!patterns || !handler) { return false; }
var result = false;
var success = false;
patterns.each(function(syntax) {
if (success) { return; }
var args = this.extractArguments(syntax, line);
if (args===false) { return false; }
var valid = true;
if (args.each) {
args.each(function(obj, i) {
if (!valid) { return; }
args[i] = this.findObject(obj.tag, obj.str);
if (!args[i]) {
valid = false;
var any = this.findAnyObject(obj.str);
if (!any) {
this.add_failure_message("Cannot find '"+obj.str+"'.");
} else {
this.add_failure_message(
"You can't do that with "+any.get('definite')+"."
);
}
}
}, this);
if (args===false) { return false; }
var valid = true, lastFail = '';
args.each(function(obj, i) {
if (!valid) { return; }
if (!obj.tag) {
args[i] = obj.str;
return;
}
//If we have arguments and the syntax hasn't been discounted.
if (valid && args!==false) {
var bind = (this.command) ? this.living : this.holder;
result = handler.bind(bind).pass(args)();
if (result!==false) {
if (!result) { result = true; }
success = true;
args[i] = this.findObject(obj.tag, obj.str);
//If we didn't find anything, it means this set of arguments are
//invalid for this particular command execution. Let's see if the
//player is calling invalid items, or if they items are entirely
//nonexistent.
if (!args[i]) {
valid = false;
var any = this.findAnyObject(obj.str);
if (!any) {
//If no matching object is found.
lastFail = "Cannot find '"+obj.str+"'.";
} else {
//If a matching object is found which doesn't fit the
//syntax pattern.
lastFail = "You can't do that with "+any.get('definite')+".";
}
if (this.holder.failure_message) {
this.failure_mesage = this.holder.failure_message;
result = this.failure_message;
} else { success = true; }
} else if (!valid && this.failure_message) {
result = this.failure_message;
}
}, this);
//If we have arguments and the syntax hasn't been discounted.
if (valid) {
return args;
} else return lastFail;
return result;
},

@@ -142,6 +120,6 @@

*/
extractArguments: function(syntax, line) {
extractArguments: function(line,syntax) {
//If there is no syntax, just return the string unaltered.
if (syntax=="*") { return line; }
if (syntax=="*") { return [{str:line, tag:false}]; }

@@ -186,4 +164,2 @@ //The ' is a delimiter within a tag for user-friendly syntax

if (!valid) { return false; }
sections = sections.flatten();

@@ -194,7 +170,9 @@

});
if (!tags) { return false; }
//If there aren't any tags, there aren't any arguments.
if (!tags.length) { return []; }
valid = true;
var args = [];
sections.each(function(sec, i) {

@@ -210,2 +188,4 @@ if (!tags[i]) {

});
if (args.length!=tags.length) valid = false;

@@ -217,10 +197,14 @@ return (valid) ? args : false;

findObject: function(tag, words) {
if (words.trim().length==0) return false;
if (!tag) return words;
var obj = this.holder,
living = this.living,
actor = this.actor,
list = [],
room = (living.get('room')) ? living.get('room').getItems() : [],
container = (living.getItems()),
everyone = (living.get('room')) ? living.get('room').getLiving() : [],
players = (living.get('room')) ? living.get('room').getPlayers() : [];
room = (actor.get('room')) ? actor.get('room').getItems() : [],
container = (actor.getItems()),
everyone = (actor.get('room')) ? actor.get('room').getLiving() : [],
players = (actor.get('room')) ? actor.get('room').getPlayers() : [];

@@ -234,12 +218,14 @@ // A lot of reproduction of code here! This will make it easier for people

list.combine(room);
} else if (tag == "living") {
list.combine(everyone);
} else if (tag == "direct:living") {
list.push(living);
list.push(actor);
} else if (tag == "direct:object") {
list.push(obj);
} else if (tag == "direct:player") {
if (living.player) { list.push(living); }
if (actor.player) { list.push(actor); }
} else if (tag=="indirect") {
list.combine(container);
list.combine(everyone);
list.erase(living);
list.erase(actor);
list.erase(obj);

@@ -263,3 +249,3 @@ } else if (tag == "indirect:object") {

} else if (tag == "indirect:living") {
list.combine(everyone).erase(living);
list.combine(everyone).erase(actor);
} else if (tag == "indirect:player") {

@@ -269,3 +255,3 @@ } else if (tag == "string") {

} else if (tag == "number") {
if (words.toInt()) { return words; }
if (words.toInt()) { return words.toInt(); }
} else if (tag == "fraction") {

@@ -284,3 +270,3 @@

} else {
log_error("Unsupported command tag: "+tag);
throw new Error("Unsupported command tag: "+tag);
return false;

@@ -305,5 +291,5 @@ }

}
if (this.living.room) {
list.combine(this.living.room.getLiving());
list.combine(this.living.room.getItems());
if (this.actor.room) {
list.combine(this.actor.room.getLiving());
list.combine(this.actor.room.getItems());
}

@@ -310,0 +296,0 @@ return this.checkList(list, words);

@@ -6,3 +6,3 @@ /**

Implements: AdvancedParser,
Implements: CommandParser,

@@ -16,5 +16,4 @@ //Command is filled in by the object that instantiates this object, since it

this.init();
if (!this.syntax) { this.syntax = "*"; }
if (!this.getPatterns(this.command)) {
this.add_command(this.command, this.syntax, this.execute);
this.add_command(this.command, this.syntax || '*', this.execute);
}

@@ -24,3 +23,5 @@ },

//Should be defined by the child class.
init: function() { },
init: function() {
this.add_command(this.command, '*', this.execute);
},

@@ -27,0 +28,0 @@ execute: function() {

@@ -9,40 +9,127 @@ /**

realParser: false,
commands: [],
caller: false,
failure_message: false,
add_failure_message: function(message) {
this.failure_message = message;
},
/**
* This method should be used on item/room creation.
*/
add_command: function(command, patterns, method) {
method = method || this['do_'+command];
if (!method) { return false; }
add_command: function(verbs, patterns, method) {
//Force verbs to be an array.
if (!verbs.each) verbs = [verbs];
//Force pattern to be an array.
if (!patterns.each) { patterns = [patterns]; }
method = method || this['do_'+verbs[0]];
if (!method) { return false; }
//Force method to be a function and not a string.
if (method.length) { method = this[method]; }
this.commands[command] = {
'syntax': patterns,
'method': method
};
this.commands.push ({
'verbs' : verbs,
'syntax' : patterns,
'handler': method
});
},
/**
* This method is intended to let the developer create different handlers
* for different argument lists.
*
* Right now it just does one pattern and one handler, but it should
* eventually be more complex.
*/
add_syntax: function(pattern, handler) {
this.set_syntax(pattern, handler);
},
/**
* Get syntax patterns for a particular command.
*/
getPatterns: function(command) {
return this.commands;
},
parseLine: function(line, living) {
this.user = living;
this.failure_message = false;
var realParser = new AdvancedParser();
var output = realParser.parseLine(line, this.user, this);
if (realParser.failure_message) {
this.failure_message = realParser.failure_message;
} return output;
/**
* Overwrites all exisiting syntaxes to create one canonical syntax.
*/
set_syntax: function(pattern, handler) {
handler = handler || this.execute;
this.add_command(this.command, pattern, handler);
},
parseLine: function(line, actor) {
var holder = this;
line = line.trim().split(/\s/);
//If the line is empty, we don't need to go through all the available
//verbs.
if (!line) return;
var verb = line.shift(), success = false, out = '',
binding = (this.command) ? actor : holder;
line = line.join(' ');
//There's really no scenario where the actor should be nonexistent.
if (!actor) throw new Error("No actor for command "+line);
this.commands.each(function(c) {
//If we've already succeeded, skip this.
if (success) { return; }
//If the verb provided isn't in the command verb list, skip.
if (!c.verbs.contains(verb)) return;
//Otherwise, we have a match, so let's parse this line using
//this command syntax to pull out its arguments.
//Instantiate a new instance of the parser.
var parser = new AdvancedParser(actor, holder);
//Next, we take the syntax patterns and pass them to the
//parser to parse the arguments string and convert it into
//matching game objects.
c.syntax.each(function(syntax) {
if (success) return;
var args = parser.parse(line, syntax);
//We got a failure message.
if (typeOf(args)=='string') {
//It's a failure message, so we'll store it in case no
//better match can later be made.
out = args;
//We have arguments from this syntax, which means it's been a
//match.
} else if (args && typeOf(args)=='array') {
//Find the handler method for this syntax and pass the
//arguments to it.
if (binding!=actor) { //This'll be removed in a bit.
//binding = actor means we're dealing with a Command.
args = ([actor]).combine(args);
}
var result = c.handler.bind(binding).pass(args)();
if (result!==false) {
success = true;
out = result || true;
}
}
return { output: out, success: success }
});
});
/**
* We return both success and output because we could have a failure
* message where output should be sent but success is false.
*
* This message can be overruled upon further command chain execution
* assuming some other command can take the same syntax pattern and
* convert it to a successful request.
*/
return {success: success, output: out};
}
});
});

@@ -13,2 +13,15 @@ String.implement({

},
/**
* Ensures that a given string is a "sentence" by enforcing a capital
* beginning letter and a punctuation mark at the end. Will default to a
* period as ending punctuation for now, until I can get the irony mark
* to render correctly.
*/
makeSentence: function() {
var str = this.trim();
str = this.charAt(0).toUpperCase() + this.slice(1);
if (!str.match(/[?!.]$/)) str = str+'.';
return str;
},

@@ -15,0 +28,0 @@ /**

@@ -55,2 +55,6 @@ Item = new Class({

},
getContainer: function() {
return this.container;
},

@@ -57,0 +61,0 @@ getNoun: function() {

@@ -5,3 +5,4 @@ Living = new Class({

Implements: [Events, Options, Container, CombatStandard, Visible, CommandParser],
Implements: [Events, Options, Container, CombatStandard, Visible,
CommandParser],

@@ -202,3 +203,2 @@ player: false,

this.rest();
this.guiSend(this.dumpStats(), 'status');
},

@@ -263,3 +263,4 @@

if (assert && assert.equal && expected) {
assert.equal(result, expected, "\nExpected: "+expected+"\nGot: "+result);
assert.equal(result, expected, "\nExpected: "+expected+
"\nGot: "+result);
}

@@ -347,4 +348,2 @@ if (!expected) { return result; }

var com = this.world.getCommand(command);
//Check to see if it's a room exit.

@@ -355,24 +354,25 @@ if (this.get('room') && this.get('room').hasExit(string)){

return this.do('move '+command);
} else if (com){
params = params.join(' ');
if (com.can_execute.bind(this)()) {
var params = string.split(' ');
params.shift();
//out = com.execute.bind(this)(params.join(' '));
out = com.parseLine(string,this,com);
}
}
var success = (out) ? true : false;
var caller = this;
this.getItems().each(function(item) {
var caller = this;
var callables = [];
callables.combine(this.getItems());
callables.combine(this.getRoom().getLiving());
callables.push(this.getRoom());
callables.push(this.world.getCommand(command));
//Now we keep calling until we've received a successful execution of
//the command.
callables.each(function(item) {
if (!success && item.parseLine) {
result = item.parseLine(string, caller);
if (result) { out = result; }
if (item.failure_message) {
out = item.failure_message;
} else if (result) { success = true; }
}
if (result) {
success = result.success;
if (result.output) out = result.output;
}
}
}, this);
//The commands either have to return before this point or have

@@ -383,9 +383,9 @@ //output that is equal to true or a string.

if (!out) { out = 'What?'; }
if (!out&&!success) { out = 'What?'; }
if (out.charAt) {
out.charAt(0).toUpperCase() + out.slice(1);
} else if (out.each) {
if (typeOf(out)=="string") {
out = out.makeSentence();
} else if (out && out.each) {
out.each(function(ln, i) {
ln[i] = ln.charAt(0).toUpperCase + ln.slice(1);
out[i] = ln.makeSentence();
});

@@ -392,0 +392,0 @@ }

@@ -77,3 +77,5 @@ Room = new Class({

});
objs.combine(this.get('players'));
Object.each(this.get('players'), function(v,k) {
objs.push(v);
});
return objs;

@@ -97,2 +99,3 @@ }

Object.each(this.exits, function(data, direction) {
if (!data.to) return;
var room = this.world.getRoom(data.to);

@@ -144,4 +147,5 @@ if (room) { exits[direction] = room; }

if (exits.length==0) observer.send('There are no obvious exits.', 'exits');
else observer.send('Exits: '+exits.join(', '), 'exits', 'exits');
if (exits.length==0) observer.send('There are no obvious exits.',
'exits');
else observer.send('Exits: '+exits.join(', '), 'exits');

@@ -179,3 +183,4 @@ var living = this.listLiving(observer);

living[living.length-1] = 'and '+last;
living[living.length-2] = living[living.length-2].replace(/, $/, ' ');
living[living.length-2] = living[living.length-2]
.replace(/, $/, ' ');
} return living;

@@ -199,2 +204,11 @@ }

},
/**
* Sends a given message to everyone in the room.
*/
emit: function(message) {
Object.each(this.get('living'), function(l) {
l.send(message);
});
},

@@ -227,2 +241,6 @@ set_short: function(short) {

},
remove_exit: function(dir) {
delete(this.exits[dir]);
},

@@ -238,3 +256,5 @@ add_living: function(path) {

var that = this;
Object.each(aliases, function(alias) { that.desc_items[alias] = keyword; });
Object.each(aliases, function(alias) {
that.desc_items[alias] = keyword;
});
},

@@ -251,3 +271,5 @@

getAdjacentRooms: function(range, zRange) {
return this.zone.getAdjacentRooms(this.getCoordinates(), range, zRange);
return this.zone.getAdjacentRooms(
this.getCoordinates(), range, zRange
);
},

@@ -254,0 +276,0 @@

@@ -1,5 +0,3 @@

require('string-color');
//Color styles for outputting classed text to the terminal.
var styles = {
Styles = {

@@ -19,12 +17,11 @@ 'tell' : ['bold','yellow'],

style: function(style) {
var str = this;
if (styles[style]) {
var classes = (styles[style]), my=this;
if (Styles[style]) {
var classes = (Styles[style]),my=this;
if (!classes.each) classes = [classes];
classes.each(function(color) {
str = my.color(color);
my = my.color(color);
});
} return str;
} return this;
},
});

@@ -65,3 +65,4 @@ var fs = require('fs'),

var path = require('path').normalize(this.joinPath(this.worldPath+'/'+this.roomPath));
var path = require('path').normalize(this.joinPath(this.worldPath+
'/'+this.roomPath));

@@ -142,12 +143,19 @@ //Recursive glob of all .js files in rooms/.

getRoom: function(path) {
if (typeOf(path)=='object') {
path = path.to;
}
if (path===undefined) console.trace();
if (!this.rooms[path]) {
var room = this.loadModule(this.roomPath+path);
if (!room) { console.warn("Room not found for "+path); }
if (!room) { log_error("Room not found for "+path); }
if (room) {
this.rooms[path] = new room(this, path);
this.rooms[path].create();
this.rooms[path].zone = this.getZone(this.rooms[path].zoneName);
this.rooms[path].game_path = path;
this.rooms[path].file_path = room.file_path;
var zn = this.rooms[path].zoneName;
this.rooms[path].zone = this.getZone(zn);
}

@@ -229,2 +237,4 @@ } return this.rooms[path];

mob.world = this;
mob.game_path = path;
mob.file_path = file;
return mob;

@@ -254,3 +264,4 @@

//Synchronous is OK in this case because we'll be loading these files on initialization.
//Synchronous is OK in this case because we'll be loading these files
//on initialization.
var files = [], stats;

@@ -291,2 +302,3 @@ stats = fs.statSync(filename);

mod.file_path = file;
mod.game_path = path;
return mod;

@@ -300,2 +312,3 @@ } else {

}
log_error(e);
return false;

@@ -306,5 +319,6 @@ }

reloadModule: function(file, opts) {
delete(require.cache[file+'.js']);
this.loadModule(file, opts);
reloadModule: function(file_path, opts) {
var game_path = file_path.replace(this.worldPath, '');
delete(require.cache[file_path+'.js']);
return this.loadModule(game_path, opts);
},

@@ -315,3 +329,27 @@

this.reloadModule(object.file_path);
return this.loadItem(object.game_path);
},
reloadRoom: function(object) {
var dislodgedPlayers = object.getPlayers();
delete(this.rooms[object.game_path]);
var success = this.reloadModule(object.file_path),
newRoom = this.getRoom(object.game_path);
if (!success) {
//Let the caller know to send a message to the players about why
//they don't exist in physical space anymore.
return false;
} else {
dislodgedPlayers.each(function(l) {
l.moveTo(newRoom.game_path);
});
return newRoom;
}
},
reloadNPC: function(object) {
delete(this.npcs[object.game_path]);
this.reloadModule(object.file_path);
return this.loadNPC(object.game_path);
},

@@ -318,0 +356,0 @@ /**

@@ -38,4 +38,4 @@ /**

}
//This is our first room, so we'll just arbitrarily pick 0,0 as its
//coordinates.
//This is our first room, so we'll just arbitrarily pick 0,0 as
//its coordinates.
coords = [0,0,0];

@@ -77,3 +77,4 @@ }

//If set to true, we'll have to walk rooms every time we want surroundings.
//If set to true, we'll have to walk rooms every time we want
//surroundings.
coordinateConflict: false,

@@ -88,3 +89,4 @@

if (other) {
log_error("Room coordinate conflict! (["+[x,y,z]+"]: "+room.path+", "+other.path+")");
log_error("Room coordinate conflict! (["+[x,y,z]+"]: "+
room.path+", "+other.path+")");
this.coordinateConflict = true;

@@ -91,0 +93,0 @@ return;

@@ -6,15 +6,61 @@ module.exports = new Class({

init: function() {
this.set_syntax('<object>');
//Epic multiple syntaxes with different handlers action!
this.add_syntax('<object>', 'reload_item');
this.add_syntax('<living>', 'reload_living');
this.add_syntax('', 'reload_room');
},
execute: function(object) {
this.world.reloadItem(object);
this.removeItem(object);
var item = this.world.loadItem('strawberry');
if (!item) return "Invalid path: "+object.file_path;
this.send("You reload "+item.get('definite')+".");
this.addItem(item);
return true;
reload_item: function(object) {
//We need to know if this object is in the room or in an inventory.
var holder = object.getContainer(),
//Attempt to get a new item to replace it.
replacement = this.world.reloadItem(object),
//We'll store some text here to append to the destruction message.
andThen;
//Take the item away.
object.getContainer().removeItem(object);
if (replacement) {
andThen = "A new "+replacement.get('short')+
" erupts within a flash of fire to take its place.";
holder.addItem(replacement);
} else {
andThen = "A spark ignites in its place for a moment before "+
"fading away with a disappointing fizz.";
if (holder.send) holder.send("The object couldn't be reloaded. "+
"Please check for errors.");
}
if (holder instanceof Living) {
holder.emit("%Your "+ object.get('definite') +" disappears in a "+
"cloud of smoke. "+andThen);
} else {
holder.emit(object.get('definite')+" disappears in a cloud of "+
"smoke. "+andThen);
}
},
reload_room: function() {
var success = this.world.reloadRoom(this.get('room')),
andThen;
if (success) {
andThen = "The world shimmers around you and seems to take on a "+
"new life.";
} else {
andThen = "Nothing seems to happen.";
}
this.emit("%You snap%s %your fingers. "+andThen);
},
reload_living: function(l) {
this.send("ZOMG");
}
});

@@ -9,3 +9,3 @@ module.exports = new Class({

if (!item) return "You don't see that.";
this.emit("%You take%s "+item.get('definite'));
this.emit("%You take%s "+item.get('definite')+".");
this.get('room').removeItem(item);

@@ -12,0 +12,0 @@ this.addItem(item);

@@ -27,7 +27,1 @@ ENGINE_PATH = __dirname+'/';

require('./classes/Conversation');
log_error = function(err) {
sys.puts('ERROR: '.color('red')+err);
if (err.stack) { sys.puts("====>"+err.stack); }
}

@@ -23,7 +23,7 @@ module.exports = new Class({

*/
do_feed: function(item, target) {
this.user.removeItem(item);
this.user.emit("%You feed%s "+this.get('definite')+" to %Name.", target);
do_feed: function(actor, item, target) {
actor.removeItem(item);
actor.emit("%You feed%s "+item.get('definite')+" to %Name.", target);
}
});

@@ -9,3 +9,3 @@ module.exports = new Class({

"This is a large, empty room, which smells of fresh " +
"paint and sawdust. You can't help but feel a sense " +
"paint and sawdust. You can't help but feel a sense " +
"of endless possibility as you stand here."

@@ -15,4 +15,9 @@ );

this.load_item('strawberry');
this.add_command('pull', 'lever');
},
do_pull: function(actor) {
actor.emit("%You pull%s the lever.");
}
});
{
"name":"discord",
"description":"A LP/Discworld inspired MUD server running on Node.JS and MooTools.",
"version":"0.7.1",
"version":"0.8.0",
"repository": {

@@ -6,0 +6,0 @@ "type": "git",

@@ -21,2 +21,6 @@ /**

log_error = function (e) {
console.log("ERROR:".color('red'), e.stack);
}
exports.start = function(config) {

@@ -23,0 +27,0 @@

@@ -19,8 +19,8 @@ var brush = new Class({

do_polish: function(item, me) {
this.user.emit("You polish "+item.get('definite')+" with "+me.get('definite')+".");
do_polish: function(actor, item, me) {
actor.emit("You polish "+item.get('definite')+" with "+me.get('definite')+".");
},
do_rebristle: function(me) {
this.user.emit("%You rebristle%s "+me.get('definite'));
do_rebristle: function(actor, me) {
actor.emit("%You rebristle%s "+me.get('definite'));
}

@@ -40,3 +40,3 @@

whoah: function(me) {
whoah: function(actor, me) {
return "There are narwhals inside!";

@@ -56,4 +56,4 @@ }

do_polish: function(obj, me) {
this.user.emit("You polish "+obj.get('definite')+" with "+me.get('definite')+".");
do_polish: function(actor, obj, me) {
actor.emit("You polish "+obj.get('definite')+" with "+me.get('definite')+".");
}

@@ -95,4 +95,4 @@

var args = new AdvancedParser().extractArguments(
"<indirect:object> with <direct:object>",
"locket with brush"
"locket with brush",
"<indirect:object> with <direct:object>"
);

@@ -113,3 +113,3 @@ var expected = '[{"str":"locket","tag":"indirect:object"},{"str":"brush","tag":"direct:object"}]';

living.testCommand(
"polish locket using brush",
"polish locket with brush",
"You polish the brass locket with the scrubbing brush."

@@ -141,3 +141,2 @@ );

'polish brush with toothbrush: pass through failures': function() {
var result = living.do("polish brush with toothbrush");
living.testCommand(

@@ -148,4 +147,4 @@ "polish brush with toothbrush",

},
'feed strawberry to rat: <indirect:living> within room': function() {
'take object from environment': function(){
var player = new Player();

@@ -155,9 +154,25 @@ player.name = 'trogdor';

player.moveTo('lobby');
player.do('take strawberry');
player.testCommand(
'take strawberry',
"You take the strawberry."
);
},
'feed strawberry to rat: <indirect:living> within room': function() {
var player = new Player();
player.name = 'trogdorr';
player.enterWorld(world);
player.moveTo('lobby');
player.do('look');
player.do('materialize strawberry');
player.testCommand(
'feed strawberry to rat',
"You feed the strawberry to the lab rat."
);
},
'room command (pull lever)': function() {
living.testCommand('pull lever', 'You pull the lever.');
}
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc