simplify and improve docs

This commit is contained in:
Romain Beaumont 2018-06-03 16:39:59 +02:00
parent af4934baa4
commit 4543aa5d83
No known key found for this signature in database
GPG key ID: DB60E388B3BCF286
14 changed files with 1033 additions and 885 deletions

View file

1006
docs/API.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -19,14 +19,14 @@
// 각 개체는 속성, 이벤트, 메소드 또는 데이터를 개체에 주입하기 때문에 "inject"라고 합니다.
module.exports.server = function(serv) { // 여기에 서버이벤트를 작성하십시오.
serv.spawnPoint = ...;
serv.on('...', ...);
serv.spawnPoint = ...
serv.on('...', ...)
}
module.exports.entity = function(entity, serv) { // 엔티티가 생성될 때 실행됩니다. 절대 server.on이 실행될 때가 아닙니다.
entity.health = 10; // 체력 20중의 10
entity.on('...', ...);
// serv.on('...', ...); NOOOO
entity.on('...', ...)
// serv.on('...', ...) NOOOO
}
module.exports.player = function(player, serv) { // 플레이어는 엔티티 유형이며 추가된 속성 및 기능이 포함된 엔티티입니다.

View file

@ -19,19 +19,19 @@ Directory architecture :
// Each of these are called an "inject" because you're injecting properties, events, methods, or data into the objects
module.exports.server = function(serv) { // Create your server events here
serv.spawnPoint = ...;
serv.on('...', ...);
serv.spawnPoint = ...
serv.on('...', ...)
}
module.exports.entity = function(entity, serv) { // Called whenever an entity is created, do NOT do serv.on here
entity.health = 10; // Start with 10 health out of 20
entity.on('...', ...);
entity.on('...', ...)
// serv.on('...', ...); NOOOO
}
module.exports.player = function(player, serv) { // Player is a type of entity (entity inject is called first) with added properties and functions
player.setXp(100); // Example of a property player entities have but not other entities
player.on(',,,', ...);
player.on(',,,', ...)
// serv.on('...', . don't even think about it
}

View file

@ -57,7 +57,7 @@ All the basic commands that a server should have
## Documentation
For development see the [API documentation](https://PrismarineJS.github.io/flying-squid/#), [CONTRIBUTE.md](https://github.com/PrismarineJS/flying-squid/blob/master/docs/CONTRIBUTE.md) and [HISTORY.md](https://github.com/PrismarineJS/flying-squid/blob/master/docs/HISTORY.md)
For development see the [API documentation](API.md), [CONTRIBUTE.md](CONTRIBUTE.md) and [HISTORY.md](HISTORY.md)
## Using as a lib

View file

@ -1,10 +0,0 @@
# Flying-Squid
> Create Minecraft servers with a powerful, stable, and high level JavaScript API.
* Minecraft versions 1.8 and 1.12
* Supports custom plugins
[GitHub](https://github.com/PrismarineJS/flying-squid)
[Get Started](#flying-squid)

View file

@ -1,9 +1,7 @@
- Getting Started
- [Introduction](/)
- [Examples](/examples.md)
- Classes
- [Flying-Squid](/classes/flying-squid.md)
- [MCServer](/classes/MCServer.md)
- [Entity](/classes/Entity.md)
- [Player](/classes/Player.md)
- [Behaviors](/other/Behavior.md)
- [API](API.md)
- [Contribute](CONTRIBUTE.md)
- [Contribute-kr](CONTRIBUTE-kr.md)
- [Examples](examples.md)
- [History](HISTORY.md)

View file

@ -1,161 +0,0 @@
# Entity
Is a [prismarine-entity](https://github.com/PrismarineJS/prismarine-entity)
Players are a type of entity, so they will have most of the attributes and methods.
## Properties
### entity.id
ID of entity on server
### entity.position
Current position (currently in fixed position (x32 what you'd expect) so do entity.position.scaled(1/32) to get normal position)
### entity.world
World object entity is in
### entity.type
Either "player", "mob", or "object" (currently)
### entity.entityType
Numerical type of the entity.
### entity.name
Sub-category of entity. For mobs, this is which mob (Zombie/Skeleton, etc). For objects, this is which object (Arrow/Dropped item, etc)
### entity.nearbyEntities
Nearby entities to this entity
### entity.viewDistance
How far away entities are loaded/unloaded (used for players ATM)
### entity.health
How many half-hearts an entity has of health (e.g. Player has 20). Not really used for objects, only players and mobs.
### entity.pitch
Pitch of entity (rotation sideways)
### entity.headPitch
Pitch of entity's head
### entity.yaw
Yaw of entity (rotation looking up and down)
### entity.gravity
Gravity of entity (non-players) to calculate physics.
### entity.terminalvelocity
Only applies to gravity, really. You can still apply a velocity larger than terminal velocity.
### entity.friction
Decreases velocity when touching blocks
### entity.size
Used to calculate collisions for server-side entities
### entity.deathTime
How much time before an entity despawns (in ms)
### entity.pickupTime
How long before an entity can be picked up (in ms)
### entity.bornTime
When an entity was born. Used with pickupTime and deathTime (time in epoch)
### entity.itemId
If a block drop, what item id
### entity.itemDamage
If a block drop, what item damage
### entity.metadata
Metadata for the entity (not like block metadata/damage). Contains stuff like NBT.
### entity.nearbyEntities
List of entities that the entity believes is nearby.
## Events
## Behaviors
### "move"
Emitted when server calculates new position for the entity (DOES NOT APPLY TO PLAYER!)
- old (u): Where the entity came from
- onGround (u): If the entity is on the ground
Default: Send entity relative-move or teleport packets to all nearby players
Cancelled: Set entity position to old position
## Methods
### entity.getData(pluginName)
Gets object that stores data, personalized per plugin. Returns null if plugin does not exist.
Shortcut for: entity.pluginData[pluginName];
### entity.getOthers()
Get every other entity other than self
### entity.getOtherPlayers()
Gets every player other than self (all players if entity is not a player)
### entity.getNearby()
Gets all entities nearby (within entity.viewDistance)
### entity.getNearbyPlayers()
Gets all nearby players regardless of what client thinks
### entity.nearbyPlayers()
Gets all nearby players that client can see
### entity.takeDamage({sound='game.player.hurt', damage=1, velocity=new Vec3(0,0,0), maxVelocity=new Vec3(4, 4, 4), animation=true})
* sound: Sound to play (default is game.player.hurt)
* damage: Damage to deal (default is based off player's weapon, player's potions, attackEntity's potions, and attackedEntity armor)
* velocity: Which way should attackedEntity move when hit
* maxVelocity: maxVelocity from consecutive hits
* animation: Play death/hit animation
## Low level Methods
### entity._writeOthers(packetName, packetFields)
Writes to all other players on server
### entity._writeOthersNearby(packetName, packetFields)
Writes to all players within viewDistance

View file

@ -1,227 +0,0 @@
# MCServer
## Flying-squid.createMCServer(options)
Create and return an instance of the class MCServer.
Options is an object containing the following properties:
* port: default to 25565
* host: default to localhost
* kickTimeout: default to 10*1000 (10s), kick client that doesn't answer to keepalive after that time
* checkTimeoutInterval: defaults to 4*1000 (4s), send keepalive packet at that period
* online-mode: defaults to true
* beforePing: allow customisation of the answer to ping the server does. It takes a function with argument response and client, response is the default json response, and client is client who sent a ping. It can take as third argument a callback. If the callback is passed, the function should pass its result to the callback, if not it should return.
* motd: the string that players see when looking for the server. Defaults to "A Minecraft server"
* max-players: the amount of players on the server. Defaults to 20
* logging: defaults to true, enables logging
* gameMode: defaults to 0, 0 is survival 1 is creative.
* generation: is an object. contains the name and the options for the generator. example:
```json
{
"name":"diamond_square",
"options":{
"worldHeight":80
}
}
```
* modpe: defaults to false, wether or not modpe should be enabled.
* worldFolder : the world folder of the saved world (containing region, level.dat,...)
* plugins
* view-distance
* player-list-text : an object with keys header and footer, displayed on the player list
* everybody-op : true or false, makes everybody op
## Properties
### server.entityMaxId
The current maximum ID (i.e. the last entity that was spawned has that id)
### server.players
An array of players currently logged in
### server.uuidToPlayer
Object for converting UUIDs to players
### server.overworld
Contains the overworld world. This is where the default spawn point is
### server.netherworld
Contains the nether world. This **WILL** be used when a player travels through a portal if they are in the overworld!
### server.endworld
Contains the end world. **NOT YET IMPLEMENTED!**
### server.entities
All of the entities
### server.bannedPlayers
Object of players that are banned, key is their uuid. Use `server.getUUIDFromUsername()` if you only have their username.
Example player:
```
{
time: <time in epoch>,
reason: <reason given>
}
```
### server.time
Current daylight cycle time in ticks. Morning is 0, noon is 6000, evening is 12000, and night is 18000.
Resets to 0 at 24000. Use `server.setTime(time)` to set the time.
### server.tickCount
Total number of ticks that have passed since the start of the world.
Best to use with modulo (e.g. Something every 10 seconds is `server.tickCount % 20*10 === 0`)
### server.doDaylightCycle
Default `true`. If false, time will not automatically pass.
### server.plugins
List of all plugins. Use server.plugins[pluginName] to get a plugin's object and data.
## Events
### "error" (error)
Fires when there is an error.
### "clientError" (client,error)
Fires when `client` has an error.
### "listening" (port)
Fires when the server is listening.
### "newPlayer" (player)
Fires when `player` login, allow external player plugins.
### "banned" (banner,bannedUsername,reason)
`banner` banned `bannedUsername` with `reason`
### "tick" (count)
Fires when one tick has passed (default is 50ms). count is the total world ticks (same as server.tickCount)
## Methods
### server.createLog()
creates the log file
### server.log(message)
logs a `message`
### server.broadcast(message[,color])
broadcasts `message` to all the players with the optional `color`.
### server.getPlayer(username)
Returns player object with that username or, if no such player is on the server, null.
### server.getNearby(loc)
Returns array of players within loc. loc is a required paramater. The object contains:
* world: World position is in
* position: Center position
* radius: Distance from position
### server.banUsername(username,reason,callback)
Bans players given a username. Mainly used if player is not online, otherwise use `player.ban()`.
### server.ban(uuid,reason)
Ban player given a uuid. If the player is online, using `player.ban()`. Bans with reason or `You are banned!`.
### server.pardonUsername(username,callback)
Pardons a player given a username.
### server.pardon(uuid)
Pardons a player given their uuid. Returns `false` if they are not banned.
### server.getUUIDFromUsername(username,callback)
Gets UUID from username. Since it needs to fetch from mojang servers, it is not immediate.
Arguments in format: `callback(uuid)`. `uuid` is null if no such username exists.
### server.setTime(time)
Set daylight cycle time in ticks. See `server.time` for more info.
### server.setTickInterval(ticksPerSecond)
Resets tick interval to occur `ticksPerSecond` times per second.
Use `server.stopTickInterval()` if you want but this method already calls that and you can use `server.doDaylightCycle` to stop it anyway.
### server.setBlock(world, position, blockType, blockData)
Saves block in world and sends block update to all players of the same world.
### server.playSound(sound, world, position, opt)
Plays `sound` (string, google "minecraft sound list") to all players in `opt.radius`.
If position is null, will play at the location of every player (taking into account whitelist and blacklist).
Opt:
- whitelist: Array of players that can hear the sound (can be a player object)
- blacklist: Array of players who cannot hear the sound
- radius: Radius that sound can be heard (in fixed position so remember to multiply by 32, default 32*32)
- volume: float from 0-1 (default 1.0)
- pitch: float from 0.5 to 2 (default 1.0)
### server.playNoteBlock(world, position, pitch)
Plays noteblock in world at position. `pitch` is from 0-24
### server.getNote(note)
Get pitch. `note` should be between 0-24 and your output is from 0.5 to 2.0
### server.emitParticle(particle, world, position, opt)
Emits particle (see [id list](http://wiki.vg/Protocol#Particle)) at `position` in `world`.
Opt:
- whitelist: Array of players that can see the particle (can be a player object)
- blacklist: Array of players who cannot see the particle
- radius: Radius that the particle can be seen from
- longDistance: I don't know what this is. I think this is pointless with our implenetation of radius, not sure though...
- size: vec3 of the size. (0,0,0) will be at an exact position, (10,10,10) will be very spread out (particles less dense)
- count: Number of particles. 100,000,000+ will crash the client. Try not to go over 100,000 (sincerely, minecraft clients)
## Low level methods
### server._writeAll(packetName, packetFields)
Writes packet to every player on the server
### server._writeArray(packetName, packetFields, playerArray)
Writes packet to every player in playerArray
### server._writeNearby(packetName, packetFields, loc)
Writes packet to all players within distance of loc. loc has the same paramater as loc in server.getNearby()

View file

@ -1,348 +0,0 @@
# Player
See `Entity` class to see what other attributes players have (such as world, position, etc)
## Properties
### player.username
The username of the player
### player.view
The view size of the player, for example 8 for 16x16
### player.xp
Total experience the player has (int). Set this using player.setXp()
### player.displayXp
Number from 0 to 1.0 representing the progress bar at the bottom of the player's screen. Set this with player.setDisplayXp()
### player.xpLevel
Level of xp the player has. Set this with player.setXpLevel()
### player.commands
Instance of the [Command](#flying-squidcommand) class.
Here is an example to create a new command :
```js
player.commands.add({
base: 'hello',
info: 'print hello in the console',
usage: '/hello <pseudo>',
op: false,
parse(str) {
const args=str.split(' ');
if(args.length!=1)
return false;
return {pseudo:args[0]};
},
action({pseudo}) {
console.log("Hello "+pseudo);
}
});
```
## Events
### "connected"
Fires when the player is connected
### "spawned"
Fires when the player is spawned
### "disconnected"
Fires when the player disconnected
### "chat" (message)
Fires when the player says `message`.
### "kicked" (kicker,reason)
`kicker` kick the player with `reason`
### "positionChanged"
fires when the position changes in small amounts (walking, running, or flying)
## Behaviors
See entity "Behaviors" for more info
### "move"
When player tries to move
- position (u): New position player is trying to move to
- onGround (u): Whether player thinks they're on the ground or not
Default: Save position/onGround and write to all nearby players
Cancelled: Snap back to old position
### "look"
When player tries to look somewhere
- yaw (u): New yaw player is looking
- pitch (u): New pitch player is looking
- onGround (u): If player thinks they're on the ground
Default: Save look directions, send to all nearby players
Cancelled: Snap their view back to old yaw and pitch
### "chat"
Emitted when player tries to say something (unless they're message starts with /, then refer to "command")
- message (u): Message player sent
- broadcastMessage: What is put in server chat (Default: <username> message)
Default: Broadcasts to server their message
Cancelled: Nothing
### "command"
Emitted when player starts their message with a slash
- command: Their commands (excludes the slash)
Default: Handle command by command system
Cancelled: Nothing
### "punch"
When player tries to punch nothing
Default: Send punch animation to nearby players
Cancelled: Nothing
### "sendBlock"
Emitted when sending a block to a player (block changed). This is separate for every player, cancelling this for one player causes ghost blocks!
- position: Position of the block
- id: ID of the block
- data: Metadata of the block
Default: Send block change to player.
Cancelled: Nothing
### "sendChunk"
Emitted when sending a chunk to a player (loading it in)
- x: Chunk X
- z: Chunk Z
- chunk: Chunk data
Default: Continue sending chunk to client
Cancelled: Nothing
### "dig"
Emitted when any player STARTS digging (i.e. survival only)
- position: Position of block being mined
- block (u): Block being mined
Default: Allow player to start mining block, send changes in break animation to other players
Cancelled: Stop them from digging
### "dug"
Emitted when a player finishes digging something (or a player in creative breaks a block)
- position: Position of block dug
- block (u): Block dug
- dropBlock: Should it drop a block object (Default: false in creative, otherwise true)
- blockDropPosition: Where block is dropped (Default: center of block)
- blockDropWorld: World block is dropped in (Default is the world the player/block is in)
- blockDropVelocity: The velocity the block has when dropped (Default: random)
- blockDropId: ID of the block dropped
- blockDropDamage: Damage of the block dropped
- blockDropPickup: Time before user can pick up the block (Default: 0.5 seconds)
- blockDropDeath: Time before item despawns (Default: 5 minutes)
Default: Save new block as air, sends to all nearby players
Cancelled: Send to player the block that was there
### "cancelDig"
Emitted when a player cancels digging in the middle (i.e. survival only)
- position: Position of block that was being mined
- block (u): Block that was being mined
Default: Stop animation for all players, save stop digging
Cancelled: Nothing
### "forceCancelDig"
Emitted when the server cancels a dig (currently only happens if the player mines too fast)
- stop: Whether the digging should be cancelled because they mined too fast (Default: true)
- start (u): Time mining started
- time (u): How long the player has been mining
#### "breakAnimation"
Emitted when the server believes the break animation should increase (not sent by client!)
- position: Position of block being updated
- state: New state being changed to
- lastState (u): Last state of block
- start (u): When mining started
- timePassed (u): How long between start and now
Default: Send animation to everyone
Cancelled: Nothing
### "placeBlock"
Emitted when a player places a block
- position: Position they're attempting to place the block
- id: Id of block being placed
- damage: Data of block being placed
- reference (u): Reference block (position) that was placed on
- direction (u): Direction vector from reference to position
- playSound: Which sound to play (Default: true)
- sound: Sound to play (Default: default sound for that material)
Default: Place block for server and nearby players
Cancelled: Replace block with old block for player
### "attack"
Emitted when a player attacks an entity
- attackedEntity: Entity being attacked
- playSound: Play sound (Default: true)
- sound: Sound to play (default is game.player.hurt)
- damage: Damage to deal (default is based off player's weapon, player's potions, attackEntity's potions, and attackedEntity armor)
- velocity: Which way should attackedEntity move when hit
- maxVelocity: maxVelocity from consecutive hits
- animation: Play death/hit animation
Default: Damage entity, play sound, send velocity, play animation for death/hit
Cancelled: Nothing
### "requestRespawn"
Emitted when a player tries to respawn
Default: Let them respawn
Cancelled: Nothing. You monster.
## Methods
### player.login()
login
### player.ban(reason)
bans player with `reason`
### player.kick(reason)
kicks player with `reason`
### player.getOthers()
return the other players than `player`
### player.chat(message)
sends `message` to the player
### player.changeBlock(position,blockType,blockData)
change the block at position `position` to `blockType` and `blockData`
this will not change the block for the user himself. It is mainly useful when a user places a block
and only needs to send it to other players on the server
### player.sendBlock(position,blockType,blockData)
change the block at position `position` to `blockType` and `blockData`
this will not make any changes on the server's world and only sends it to the user as a "fake" or "local" block
### player.sendInitialPosition()
send its initial position to the player
### player.setGameMode(gameMode)
set player gameMode to `gameMode`
### player.handleCommand(command)
handle `command`
### player.setBlock(position,blockType,blockData)
Saves block in world and sends block update to all players of the same world.
### player.updateHealth(health)
update the player health.
### player.changeWorld(world, opt)
The world object which the player is in (use serv.overworld, serv.netherworld, serv.endworld, or a custom world). Options:
- gamemode: Gamemode of the world (Default is player gamemode)
- difficulty: Difficulty of world. Default is 0 (easiest)
- dimension: Dimension of world. 0 is Overworld, -1 is Nether, 1 is End (Default is 0)
### player.spawnAPlayer(spawnedPlayer)
Spawn `spawnedPlayer` for `player`.
### player.updateAndSpawnNearbyPlayers()
Spawn and despawn the correct players depending on distance for `player`.
### player.playSound(sound, opt)
Easy way to only play a sound for one player. Same opt as serv.playSound except no `whitelist`.
### player.setXp(xp, opt)
Sets the player's XP level. Options:
- setLevel: Calculate and set player.level (default: true)
- setDisplay: Calculate and set player.displayXp (default: true)
- send: Send xp packet (default: true)
### player.sendXp()
Updates the player's xp based on player.xp, player.displayXp, and player.xpLevel
### player.setXpLevel(level)
Sets and sends the player's new level
### player.setDisplayXp(num)
Sets and sends the player's new display amount. num should be from 0 to 1.0
## Low level properties
### player._client
The internal implementation to communicate with a client
## Low level methods
Same as entity

View file

@ -1,41 +0,0 @@
# flying_squid
## Classes
### Entity
### flying_squid.Command
### flying_squid.Behavior
## Libs
Collections of pure functions
### flying_squid.generations
### flying_squid.version
### flying_squid.experience
#### getXpLevel(xp)
Get level given XP amount
#### getXpRequired(level, toLevel=level+1)
Get's the amount of xp required to get from level to toLevel (or level to level+1)
#### getBaseXpFromLevel(level)
Gets the minimum amount of xp required to be at that level (or "base xp" for that level)
#### distanceToXpLevel(xp, toLevel=startLevel+1, startLevel=xp level)
Gets a number between 0 and 1 (used in player.displayXp as the green bar at the bottom) that is the progress of xp between startLevel and toLevel.
By default, startLevel will be the xp's lowest possible level: getXpLevel(xp)
By default, toLevel is startLevel + 1.
This means when startLevel and toLevel are at their defaults, this function returns the progress to the next level of XP (from 0.0 to 1.0)

View file

@ -34,10 +34,10 @@ When a block gets a random tick, convert the grass to stone
```js
module.exports.server = function(serv) {
serv.on('randomTickBlock', ({ world, position, blockType }) => {
if (blockType == 2) { // If grass
if (blockType === 2) { // If grass
serv.setBlock(world, position, 1, 0); // Change to stone (id 1, data 0)
}
});
})
}
```
@ -64,7 +64,7 @@ module.exports.player = function(player, serv) {
const number = Math.floor(Math.random()*(maxNumber+1)); // Generate our random number
player.chat(number); // Send it to the player
}
});
})
}
```
@ -81,28 +81,28 @@ const changeBlock = {
2: [95, 5], // Grass to green glass
3: [95, 12], // Dirt to brown glass
9: [95, 11] // Still water to blue glass
};
}
module.exports.player = function(player, serv) {
player.on('sendChunk', async (data, cancelled) => { // When sending chunks, intercept, replace blocks neccesary, then continue sending
if (cancelled) return;
var chunk = new Chunk(); // Duplicate chunk so we don't edit the actual world
const chunk = new Chunk(); // Duplicate chunk so we don't edit the actual world
chunk.load(new Buffer(data.chunk.dump()));
// Go through every block in the chunk
for (var x = 0; x < 16; x++) {
for (var z = 0; z < 16; z++) {
for (var y = 0; y < 256; y++) {
for (let x = 0; x < 16; x++) {
for (let z = 0; z < 16; z++) {
for (let y = 0; y < 256; y++) {
const vec = new Vec3(x, y, z);
const id = chunk.getBlockType(vec); // Get id of block at the current location
if (self.changeBlock[id]) { // If for this block type we have a glass color to convert it to
chunk.setBlockType(vec, self.changeBlock[id][0]); // Edit block
if (self.changeBlock[id].length > 1) chunk.setBlockData(vec, self.changeBlock[id][1]);
if (self.changeBlock[id].length > 1) chunk.setBlockData(vec, self.changeBlock[id][1])
}
}
}
}
data.chunk = chunk; // Change the chunk being sent to our new chunk
});
});
})
}
```

View file

@ -17,8 +17,8 @@
name: 'flying-squid',
repo: 'https://github.com/PrismarineJS/flying-squid',
loadSidebar: true,
subMaxLevel: 2,
coverpage: true
subMaxLevel: 3,
auto2top: true
}
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>

View file

@ -1,69 +0,0 @@
# Behaviors
Behaviors are what handle advanced events in flying-squid. They are editable and allow default actions to be cancellable so that they can take control of events and so that plugins can interact with each other. Three different events get called for a behavior in the following order:
- `EVENTNAME_cancel`
- `EVENTNAME`
- `EVENTNAME_done`
Default actions are actions an event normally takes. For example, the move event will normally set the player's position to the position they requested, and then send their position to all nearby players. Similarily, the defualt action of `placeBlock` includes putting the block in the world, removing 1 of that block from the player's hand, and playing the place block sound.
The `EVENTNAME_cancel` event passses the paramaters `data` (object of all info about the behavior; changing the data could have effects on the outcome) and `cancel`, a function. This event is run before the default action. If `cancel()` is called, it will cancel the default action.
The `EVENTNAME` event passes `data` as well as a boolean `cancelled` so that plugins can check if the default behavior has been cancelled. This is event is run before the default action.
The `EVENTNAME_done` event passes `data` and `cancelled`. This event is run after the default action.
## Example
One plugin wants to cancel a player's movement while another wants to say "HI" when they move
Plugin A:
```js
player.on('move_cancel', ({position}, cancel) => {
cancel(); // If player tries to move, shoots them back where they came from
});
```
Plugin B:
```js
player.on('move', ({position}, cancelled) => {
if (!cancelled) player.chat('You are moving!');
})
```
When a player normally moves, the server saves their position and sends it to all clients. Therefore, if a "move" behavior was truly cancelled, the player would be able to move freely while the server and other players would see the player stationary. This doesn't happen because behaviors can have "default cancel functions". In the case of a player's "move", the default cancel function sends them back where they came from. To prevent this from happening, use the "preventDefaultCancel" paramater: `cancel(false);`
Behaviors are listed in the doc with info about their default action and cancel action. If the behavior is not cancelled, their default action will take place. If any plugin cancels the behavior, their cancel action will take place. If any plugin cancels their default behavior with the "preventDefaultCancel" parameter, no further action will take place. `EVENTNAME_done` is still called regardless.
## Second Example
Plugin C
```js
player.on('move_cancel', ({position}, cancel) => {
cancel(false); // Doesn't teleport the player back. They will stand still for everyone else.
});
```
If we keep Plugin B (say "You are moving!" on player move) and use Plugin C, we'll see that the player can move freely but will not receive the "You are moving" text (since, to the server, they are not moving) and other players will be unable to see their movements.
Finally, there is hidden cancel. This is the second parameter in cancel, and allows plugins to hide the fact that they cancelled
the default action from other plugins. It's best practice to only use this when you are replacing the default action with your own action and the parameters for the event given are not enough to replicate this action.
Plugin D
```js
player.on('move_cancel', ({position}, cancel) => {
cancel(false, true); // Player doesn't teleport back and now "cancelled" will be false
})
```
Using Plugin B and D together, the player will be able to move freely and will be spammed with "You are moving!", however the server will not store their position and other players will not see the player move. Since you don't know what plugins will be added with your own, unexpected behavior may arise, so avoid this if you can.
## Format in Docs
Definition of behavior.
- var1: Variable with value, can be changed (default: defaultValue)
- var2 (u): Variable with value. You can change it however it will not have any effect on the default action (and could screw with other plugins, watch out!). U stands for unused
Default: What happens if the havior isn't cancelled.
Cancelled: What happens if the behavior is cancelled and `preventDefaultCancel` is still false.