Custom Components
General
bridge. allows you to define new entity, block and item components to make writing long and complex and repetitive behaviors quicker. In order to get started, navigate to the "Custom Components" tab in the preset window and fill in the options, so whether you want to write the component in TypeScript or JavaScript and the file name, as well as whether you want to create an item, entity or block component. If you are creating the component outside of bridge., or in an extension, you need to create a js or ts file in the BP/components/<COMPONENT TYPE> or <EXTENSION NAME>/components/<COMPONENT TYPE> folder.
Execution Scope
defineComponent
Custom components have access to the defineComponent function, which looks like this:
defineComponent({ name: (name: string) => void, schema: (schema: any) => void, template: (templateFunction: (componentArgs: T, opts: TemplateContext) => void) => void }): void
Arguments:
name(name: string): voidThe name of the custom component that will show up in auto-completions.schema(schema: any): voidThe schema of the component. This is used to create auto-completions for custom component arguments and should be written in standard JSON schema. You can also access bridge.'s built-in auto-completions with the$refproperty. They can be found here and should be referenced from thedatafolder root, for example$ref: '/data/packages/minecraftBedrock/schema/general/slotType.json'would access slot type auto-completions.template(templateFunction: (componentArgs: any, opts: TemplateContext) => void): voidThetemplateFunctionreceivescomponentArgswhich is the component arguments defined by the user, and theoptsprovides functions to allow you to merge data with the file that the component is created on and allows you to create animations and animation controllers.
TemplateContext
Common
compilerMode: 'build' | 'dev'Gives you access to read the current compiler mode.create(template: any, location?: string, operation?: (deepMerge: (oldData: any, newData: any) => any, oldData: any, newData: any) => any): voidAllows you to create data inside of the entity/block/item that the component is in.templateshould be a JavaScript object of the data to merge with the file at the givenlocation.locationshould be a path separated by'/'to where you want thetemplateto be created. For example:minecraft:entity/description. The default merge behaviour can optionally be overridden withoperationwhich should be a function that takes default merge functiondeepMerge, the data atlocation(oldData) and the new data being merged in (newData). It should return the result of the custom merge. For example:(deepMerge, oldData, newData) => newDatawill overwrite the data atlocation.location: stringGives you access to the location of the component in the entity/block/item file.identifier: stringGives you access to the identifier of the entity/block/item that the component is in.
Entity
interface TemplateContext {
compilerMode: 'build' | 'dev'
create: (
template: any,
location?: string,
operation?: (
deepMerge: (oldData: any, newData: any) => any,
oldData: any,
newData: any
) => any
) => void
sourceEntity: () => any
animation: (animation: any, condition?: string | false) => void
animationController: (
animationController: any,
condition?: string | false
) => void
location: string
identifier: string
projectNamespace: string
client: {
create: (clientEntity: any, formatVersion = "1.10.0") => void
}
dialogueScene: (sceneDefinition: any, openDialogue = true) => void
onActivated: (eventResponse: any) => void
onDeactivated: (eventResponse: any) => void
lootTable: (lootTable: any) => string
tradeTable: (tradeTable: any) => string
spawnRule: (spawnRule: any) => void
}
sourceEntity(): anyAccess the source entity that your component currently gets applied to.animation(animation: any, condition?: string | false): voidAllows you to create a BP animation that is automatically linked to the entity.animationshould be a JavaScript object containing the animation data that should be added to the animation name.conditionis an optional parameter that allows you to set a molang condition for the animation to be run.animationController(animationController: any, condition?: string | false): voidAllows you to create a BP animation controller that is automatically linked to the entity.animationControllershould be a JavaScript object containing the animation controller data that should be added to the animation controller name.conditionis an optional parameter that allows you to set a molang condition for the animation controller to be run.client.create(clientEntity: any, formatVersion?: string): voidCreate a new client entity file for entities that use the custom component.onActivated(eventResponse: any): voidTrigger an event reponse whenever your component gets applied to this entityonDeactivated(eventResponse: any): voidTrigger an event reponse whenever your component gets removed from this entitydialogueScene(sceneDefinition: any, openDialogue?: boolean): voidCreates a new dialogue scene to be used within your add-on. This function is only available if your project target version is at least "1.17.40"lootTable(lootTable: any): stringCreates a loot table for the entity and returns a string that points to this loot tabletradeTable(tradeTable: any): stringCreates a trade table for the entity and returns a string that points to this trade tablespawnRule(spawnRule: any): voidCreates a new spawn rule file for entities that uses the custom component
Item
interface TemplateContext {
compilerMode: 'build' | 'dev'
create: (
template: any,
location?: string,
operation?: (
deepMerge: (oldData: any, newData: any) => any,
oldData: any,
newData: any
) => any
) => void
location: string
identifier: string
projectNamespace: string
sourceItem: () => any
lootTable: (lootTable: any) => string
recipe: (recipe: any) => void
player: {
create: (
template: any,
location?: string,
operation?: (
deepMerge: (oldData: any, newData: any) => any,
oldData: any,
newData: any
) => any
) => void
animation: (animation: any, condition?: string | false) => void
animationController: (
animationController: any,
condition?: string | false
) => void
}
}
sourceItem(): anyAccess the source item that your component currently gets applied to.lootTable(lootTable: any): stringCreates a loot table for the item and returns a string that points to this loot tablerecipe(recipe: any): voidCreates a new recipe for items that uses the custom component
The player object gives access to these functions:
animation(animation: any, condition?: string | false): voidAllows you to create a BP animation that is automatically linked to the player.animationshould be a JavaScript object containing the animation data that should be added to the animation name.conditionis an optional parameter that allows you to set a molang condition for the animation to be run.animationController(animationController: any, condition?: string | false): voidAllows you to create a BP animation controller that is automatically linked to the player.animationControllershould be a JavaScript object containing the animation controller data that should be added to the animation controller name.conditionis an optional parameter that allows you to set a molang condition for the animation controller to be run.create(template: any, location?: string): voidAllows you to create data inside of the player.templateshould be a JavaScript object of the data to merge into the player behavior file at the givenlocation.locationshould be a path separated by'/'to where you want thetemplateto be created. For example:minecraft:entity/description. The default merge behaviour can optionally be overridden withoperationwhich should be a function that takes default merge functiondeepMerge, the data atlocation(oldData) and the new data being merged in (newData). It should return the result of the custom merge. For example:(deepMerge, oldData, newData) => newDatawill overwrite the data atlocation.
Block
interface TemplateContext {
compilerMode: 'build' | 'dev'
create: (
template: any,
location?: string,
operation?: (
deepMerge: (oldData: any, newData: any) => any,
oldData: any,
newData: any
) => any
) => void
sourceBlock: () => any
location: string
identifier: string
projectNamespace: string
onActivated: (eventResponse: any) => void
onDeactivated: (eventResponse: any) => void
lootTable: (lootTable: any) => string
recipe: (recipe: any) => void
}
sourceBlock(): anyAccess the source block that your component currently gets applied to.onActivated(eventResponse: any): voidTrigger an event reponse whenever your component gets applied to this blockonDeactivated(eventResponse: any): voidTrigger an event reponse whenever your component gets removed from this blocklootTable(lootTable: any): stringCreates a loot table for the block and returns a string that points to this loot tablerecipe(recipe: any): voidCreates a new recipe for blocks that uses the custom component
Creating Files
Files can also be automatically created with custom components. Functions that can be called to create files are:
animation(animation: any, condition: string | false): stringwhich returns the name of the animationanimationController(animationController: any, condition: string | false): stringwhich returns the name of the animation controllerclient.create(clientEntity: any, formatVersion?: string): voiddialogueScene(sceneDefinition: any, openDialogue?: boolean): void
Extension Manifest
When you are creating a custom component in an extension you need to specify where it should be installed in the extension manifest using the contributeFiles field.
Example
Examples can be found here: