[{"data":1,"prerenderedAt":1977},["ShallowReactive",2],{"navigation":3,"reference-navigation":62,"\u002Fdocs\u002Fdefining-bundle-entities":365,"\u002Fdocs\u002Fdefining-bundle-entities-surround":1972},[4,22,26,30,34,38,42,46,50,54,58],{"title":5,"path":6,"stem":7,"children":8},"Bundle Developer","\u002Fdocs\u002Fbundle-developer","1.docs\u002F1.bundle-developer\u002Findex",[9,10,14,18],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"Terminology","\u002Fdocs\u002Fbundle-developer\u002Fterminology","1.docs\u002F1.bundle-developer\u002F1.terminology",{"title":15,"path":16,"stem":17},"Prerequisites","\u002Fdocs\u002Fbundle-developer\u002Fprerequisites","1.docs\u002F1.bundle-developer\u002F2.prerequisites",{"title":19,"path":20,"stem":21},"Bundle Layout","\u002Fdocs\u002Fbundle-developer\u002Flayout","1.docs\u002F1.bundle-developer\u002F3.layout",{"title":23,"path":24,"stem":25},"Custom Registry Developer Guide","\u002Fdocs\u002Fcustom-registries","1.docs\u002Fcustom-registries",{"title":27,"path":28,"stem":29},"Defining Bundle Entities","\u002Fdocs\u002Fdefining-bundle-entities","1.docs\u002Fdefining-bundle-entities",{"title":31,"path":32,"stem":33},"Defining Bundle Sounds","\u002Fdocs\u002Fdefining-bundle-sounds","1.docs\u002Fdefining-bundle-sounds",{"title":35,"path":36,"stem":37},"Defining Bundle Tile Transitions","\u002Fdocs\u002Fdefining-bundle-tile-transitions","1.docs\u002Fdefining-bundle-tile-transitions",{"title":39,"path":40,"stem":41},"Defining Bundle Tiles","\u002Fdocs\u002Fdefining-bundle-tiles","1.docs\u002Fdefining-bundle-tiles",{"title":43,"path":44,"stem":45},"Defining Bundle Visuals","\u002Fdocs\u002Fdefining-bundle-visuals","1.docs\u002Fdefining-bundle-visuals",{"title":47,"path":48,"stem":49},"Bundle Event System Developer Guide","\u002Fdocs\u002Fevent-system","1.docs\u002Fevent-system",{"title":51,"path":52,"stem":53},"Getting Started with Selene Bundles","\u002Fdocs\u002Fgetting-started-bundles","1.docs\u002Fgetting-started-bundles",{"title":55,"path":56,"stem":57},"Making Resource Packs","\u002Fdocs\u002Fmaking-resource-packs","1.docs\u002Fmaking-resource-packs",{"title":59,"path":60,"stem":61},"Bundle Network API Developer Guide","\u002Fdocs\u002Fnetwork-apis","1.docs\u002Fnetwork-apis",[63,212,253],{"title":64,"path":65,"stem":66,"children":67,"page":121},"Modules","\u002Freference\u002Fmodules","2.reference\u002F1.modules",[68,122,167],{"title":69,"path":70,"stem":71,"children":72,"page":121},"Common","\u002Freference\u002Fmodules\u002Fcommon","2.reference\u002F1.modules\u002F1.common",[73,77,81,85,89,93,97,101,105,109,113,117],{"title":74,"path":75,"stem":76},"debug","\u002Freference\u002Fmodules\u002Fcommon\u002Fdebug","2.reference\u002F1.modules\u002F1.common\u002Fdebug",{"title":78,"path":79,"stem":80},"mathx","\u002Freference\u002Fmodules\u002Fcommon\u002Fmathx","2.reference\u002F1.modules\u002F1.common\u002Fmathx",{"title":82,"path":83,"stem":84},"os","\u002Freference\u002Fmodules\u002Fcommon\u002Fos","2.reference\u002F1.modules\u002F1.common\u002Fos",{"title":86,"path":87,"stem":88},"package","\u002Freference\u002Fmodules\u002Fcommon\u002Fpackage","2.reference\u002F1.modules\u002F1.common\u002Fpackage",{"title":90,"path":91,"stem":92},"selene.grid","\u002Freference\u002Fmodules\u002Fcommon\u002Fselene.grid","2.reference\u002F1.modules\u002F1.common\u002Fselene.grid",{"title":94,"path":95,"stem":96},"selene.http","\u002Freference\u002Fmodules\u002Fcommon\u002Fselene.http","2.reference\u002F1.modules\u002F1.common\u002Fselene.http",{"title":98,"path":99,"stem":100},"selene.i18n","\u002Freference\u002Fmodules\u002Fcommon\u002Fselene.i18n","2.reference\u002F1.modules\u002F1.common\u002Fselene.i18n",{"title":102,"path":103,"stem":104},"selene.registries","\u002Freference\u002Fmodules\u002Fcommon\u002Fselene.registries","2.reference\u002F1.modules\u002F1.common\u002Fselene.registries",{"title":106,"path":107,"stem":108},"selene.resources","\u002Freference\u002Fmodules\u002Fcommon\u002Fselene.resources","2.reference\u002F1.modules\u002F1.common\u002Fselene.resources",{"title":110,"path":111,"stem":112},"selene.schedules","\u002Freference\u002Fmodules\u002Fcommon\u002Fselene.schedules","2.reference\u002F1.modules\u002F1.common\u002Fselene.schedules",{"title":114,"path":115,"stem":116},"stringx","\u002Freference\u002Fmodules\u002Fcommon\u002Fstringx","2.reference\u002F1.modules\u002F1.common\u002Fstringx",{"title":118,"path":119,"stem":120},"tablex","\u002Freference\u002Fmodules\u002Fcommon\u002Ftablex","2.reference\u002F1.modules\u002F1.common\u002Ftablex",false,{"title":123,"path":124,"stem":125,"children":126,"page":121},"Server","\u002Freference\u002Fmodules\u002Fserver","2.reference\u002F1.modules\u002F2.server",[127,131,135,139,143,147,151,155,159,163],{"title":128,"path":129,"stem":130},"selene.attributes","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.attributes","2.reference\u002F1.modules\u002F2.server\u002Fselene.attributes",{"title":132,"path":133,"stem":134},"selene.config","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.config","2.reference\u002F1.modules\u002F2.server\u002Fselene.config",{"title":136,"path":137,"stem":138},"selene.dimensions","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.dimensions","2.reference\u002F1.modules\u002F2.server\u002Fselene.dimensions",{"title":140,"path":141,"stem":142},"selene.entities","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.entities","2.reference\u002F1.modules\u002F2.server\u002Fselene.entities",{"title":144,"path":145,"stem":146},"selene.map","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.map","2.reference\u002F1.modules\u002F2.server\u002Fselene.map",{"title":148,"path":149,"stem":150},"selene.network","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.network","2.reference\u002F1.modules\u002F2.server\u002Fselene.network",{"title":152,"path":153,"stem":154},"selene.players","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.players","2.reference\u002F1.modules\u002F2.server\u002Fselene.players",{"title":156,"path":157,"stem":158},"selene.saves","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.saves","2.reference\u002F1.modules\u002F2.server\u002Fselene.saves",{"title":160,"path":161,"stem":162},"selene.server","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.server","2.reference\u002F1.modules\u002F2.server\u002Fselene.server",{"title":164,"path":165,"stem":166},"selene.sounds","\u002Freference\u002Fmodules\u002Fserver\u002Fselene.sounds","2.reference\u002F1.modules\u002F2.server\u002Fselene.sounds",{"title":168,"path":169,"stem":170,"children":171,"page":121},"Client","\u002Freference\u002Fmodules\u002Fclient","2.reference\u002F1.modules\u002F3.client",[172,176,179,183,187,190,194,197,200,204,208],{"title":173,"path":174,"stem":175},"selene.camera","\u002Freference\u002Fmodules\u002Fclient\u002Fselene.camera","2.reference\u002F1.modules\u002F3.client\u002Fselene.camera",{"title":140,"path":177,"stem":178},"\u002Freference\u002Fmodules\u002Fclient\u002Fselene.entities","2.reference\u002F1.modules\u002F3.client\u002Fselene.entities",{"title":180,"path":181,"stem":182},"selene.game","\u002Freference\u002Fmodules\u002Fclient\u002Fselene.game","2.reference\u002F1.modules\u002F3.client\u002Fselene.game",{"title":184,"path":185,"stem":186},"selene.input","\u002Freference\u002Fmodules\u002Fclient\u002Fselene.input","2.reference\u002F1.modules\u002F3.client\u002Fselene.input",{"title":144,"path":188,"stem":189},"\u002Freference\u002Fmodules\u002Fclient\u002Fselene.map","2.reference\u002F1.modules\u002F3.client\u002Fselene.map",{"title":191,"path":192,"stem":193},"selene.movement.grid","\u002Freference\u002Fmodules\u002Fclient\u002Fselene.movement.grid","2.reference\u002F1.modules\u002F3.client\u002Fselene.movement.grid",{"title":148,"path":195,"stem":196},"\u002Freference\u002Fmodules\u002Fclient\u002Fselene.network","2.reference\u002F1.modules\u002F3.client\u002Fselene.network",{"title":164,"path":198,"stem":199},"\u002Freference\u002Fmodules\u002Fclient\u002Fselene.sounds","2.reference\u002F1.modules\u002F3.client\u002Fselene.sounds",{"title":201,"path":202,"stem":203},"selene.textures","\u002Freference\u002Fmodules\u002Fclient\u002Fselene.textures","2.reference\u002F1.modules\u002F3.client\u002Fselene.textures",{"title":205,"path":206,"stem":207},"selene.ui.lml","\u002Freference\u002Fmodules\u002Fclient\u002Fselene.ui.lml","2.reference\u002F1.modules\u002F3.client\u002Fselene.ui.lml",{"title":209,"path":210,"stem":211},"selene.visuals","\u002Freference\u002Fmodules\u002Fclient\u002Fselene.visuals","2.reference\u002F1.modules\u002F3.client\u002Fselene.visuals",{"title":213,"path":214,"stem":215,"children":216,"page":121},"Data","\u002Freference\u002Fdata","2.reference\u002F2.data",[217,241],{"title":69,"path":218,"stem":219,"children":220,"page":121},"\u002Freference\u002Fdata\u002Fcommon","2.reference\u002F2.data\u002F1.common",[221,225,229,233,237],{"title":222,"path":223,"stem":224},"Component Definition","\u002Freference\u002Fdata\u002Fcommon\u002Fcomponentdefinition","2.reference\u002F2.data\u002F1.common\u002FComponentDefinition",{"title":226,"path":227,"stem":228},"Entity Definition","\u002Freference\u002Fdata\u002Fcommon\u002Fentitydefinition","2.reference\u002F2.data\u002F1.common\u002FEntityDefinition",{"title":230,"path":231,"stem":232},"Sound Definition","\u002Freference\u002Fdata\u002Fcommon\u002Fsounddefinition","2.reference\u002F2.data\u002F1.common\u002FSoundDefinition",{"title":234,"path":235,"stem":236},"Tile Definition","\u002Freference\u002Fdata\u002Fcommon\u002Ftiledefinition","2.reference\u002F2.data\u002F1.common\u002FTileDefinition",{"title":238,"path":239,"stem":240},"Transition Definition","\u002Freference\u002Fdata\u002Fcommon\u002Ftransitiondefinition","2.reference\u002F2.data\u002F1.common\u002FTransitionDefinition",{"title":168,"path":242,"stem":243,"children":244,"page":121},"\u002Freference\u002Fdata\u002Fclient","2.reference\u002F2.data\u002F3.client",[245,249],{"title":246,"path":247,"stem":248},"Audio Definition","\u002Freference\u002Fdata\u002Fclient\u002Faudiodefinition","2.reference\u002F2.data\u002F3.client\u002FAudioDefinition",{"title":250,"path":251,"stem":252},"Visual Definition","\u002Freference\u002Fdata\u002Fclient\u002Fvisualdefinition","2.reference\u002F2.data\u002F3.client\u002FVisualDefinition",{"title":254,"path":255,"stem":256,"children":257,"page":121},"Classes","\u002Freference\u002Fclasses","2.reference\u002F3.classes",[258,286,318],{"title":69,"path":259,"stem":260,"children":261,"page":121},"\u002Freference\u002Fclasses\u002Fcommon","2.reference\u002F3.classes\u002F1.common",[262,266,270,274,278,282],{"title":263,"path":264,"stem":265},"Coordinate","\u002Freference\u002Fclasses\u002Fcommon\u002Fcoordinate","2.reference\u002F3.classes\u002F1.common\u002FCoordinate",{"title":267,"path":268,"stem":269},"CustomRegistryObject","\u002Freference\u002Fclasses\u002Fcommon\u002Fcustomregistryobject","2.reference\u002F3.classes\u002F1.common\u002FCustomRegistryObject",{"title":271,"path":272,"stem":273},"LuaReference","\u002Freference\u002Fclasses\u002Fcommon\u002Fluareference","2.reference\u002F3.classes\u002F1.common\u002FLuaReference",{"title":275,"path":276,"stem":277},"Observable","\u002Freference\u002Fclasses\u002Fcommon\u002Fobservable","2.reference\u002F3.classes\u002F1.common\u002FObservable",{"title":279,"path":280,"stem":281},"RegistryObject","\u002Freference\u002Fclasses\u002Fcommon\u002Fregistryobject","2.reference\u002F3.classes\u002F1.common\u002FRegistryObject",{"title":283,"path":284,"stem":285},"Signal","\u002Freference\u002Fclasses\u002Fcommon\u002Fsignal","2.reference\u002F3.classes\u002F1.common\u002FSignal",{"title":123,"path":287,"stem":288,"children":289,"page":121},"\u002Freference\u002Fclasses\u002Fserver","2.reference\u002F3.classes\u002F2.server",[290,294,298,302,306,310,314],{"title":291,"path":292,"stem":293},"Dimension","\u002Freference\u002Fclasses\u002Fserver\u002Fdimension","2.reference\u002F3.classes\u002F2.server\u002FDimension",{"title":295,"path":296,"stem":297},"Entity","\u002Freference\u002Fclasses\u002Fserver\u002Fentity","2.reference\u002F3.classes\u002F2.server\u002FEntity",{"title":299,"path":300,"stem":301},"LoginQueueEntry","\u002Freference\u002Fclasses\u002Fserver\u002Floginqueueentry","2.reference\u002F3.classes\u002F2.server\u002FLoginQueueEntry",{"title":303,"path":304,"stem":305},"MapTree","\u002Freference\u002Fclasses\u002Fserver\u002Fmaptree","2.reference\u002F3.classes\u002F2.server\u002FMapTree",{"title":307,"path":308,"stem":309},"Player","\u002Freference\u002Fclasses\u002Fserver\u002Fplayer","2.reference\u002F3.classes\u002F2.server\u002FPlayer",{"title":311,"path":312,"stem":313},"ScopedChunkView","\u002Freference\u002Fclasses\u002Fserver\u002Fscopedchunkview","2.reference\u002F3.classes\u002F2.server\u002FScopedChunkView",{"title":315,"path":316,"stem":317},"TransientTile","\u002Freference\u002Fclasses\u002Fserver\u002Ftransienttile","2.reference\u002F3.classes\u002F2.server\u002FTransientTile",{"title":168,"path":319,"stem":320,"children":321,"page":121},"\u002Freference\u002Fclasses\u002Fclient","2.reference\u002F3.classes\u002F3.client",[322,326,330,334,337,341,345,349,353,357,361],{"title":323,"path":324,"stem":325},"Actor","\u002Freference\u002Fclasses\u002Fclient\u002Factor","2.reference\u002F3.classes\u002F3.client\u002FActor",{"title":327,"path":328,"stem":329},"Drawable","\u002Freference\u002Fclasses\u002Fclient\u002Fdrawable","2.reference\u002F3.classes\u002F3.client\u002FDrawable",{"title":331,"path":332,"stem":333},"DrawableVisual2D","\u002Freference\u002Fclasses\u002Fclient\u002Fdrawablevisual2d","2.reference\u002F3.classes\u002F3.client\u002FDrawableVisual2D",{"title":295,"path":335,"stem":336},"\u002Freference\u002Fclasses\u002Fclient\u002Fentity","2.reference\u002F3.classes\u002F3.client\u002FEntity",{"title":338,"path":339,"stem":340},"IsoVisualComponent","\u002Freference\u002Fclasses\u002Fclient\u002Fisovisualcomponent","2.reference\u002F3.classes\u002F3.client\u002FIsoVisualComponent",{"title":342,"path":343,"stem":344},"LuaTexture","\u002Freference\u002Fclasses\u002Fclient\u002Fluatexture","2.reference\u002F3.classes\u002F3.client\u002FLuaTexture",{"title":346,"path":347,"stem":348},"Skin","\u002Freference\u002Fclasses\u002Fclient\u002Fskin","2.reference\u002F3.classes\u002F3.client\u002FSkin",{"title":350,"path":351,"stem":352},"TextFieldTextFieldClickListener","\u002Freference\u002Fclasses\u002Fclient\u002Ftextfield.textfieldclicklistener","2.reference\u002F3.classes\u002F3.client\u002FTextField.TextFieldClickListener",{"title":354,"path":355,"stem":356},"Tile","\u002Freference\u002Fclasses\u002Fclient\u002Ftile","2.reference\u002F3.classes\u002F3.client\u002FTile",{"title":358,"path":359,"stem":360},"Visual2D","\u002Freference\u002Fclasses\u002Fclient\u002Fvisual2d","2.reference\u002F3.classes\u002F3.client\u002FVisual2D",{"title":362,"path":363,"stem":364},"Visual2DComponent","\u002Freference\u002Fclasses\u002Fclient\u002Fvisual2dcomponent","2.reference\u002F3.classes\u002F3.client\u002FVisual2DComponent",{"id":366,"title":27,"body":367,"description":1967,"extension":1968,"meta":1969,"navigation":1089,"path":28,"seo":1970,"stem":29,"__hash__":1971},"docs\u002F1.docs\u002Fdefining-bundle-entities.md",{"type":368,"value":369,"toc":1951},"minimark",[370,374,378,386,391,402,405,415,418,424,435,542,552,556,563,569,582,585,589,592,629,632,656,659,662,667,789,796,800,811,844,850,857,936,939,953,959,963,969,1024,1027,1031,1037,1070,1073,1133,1143,1147,1153,1185,1188,1239,1250,1254,1259,1296,1299,1328,1333,1378,1381,1400,1412,1416,1421,1697,1714,1718,1726,1729,1770,1777,1797,1800,1837,1840,1844,1847,1875,1878,1882,1885,1891,1902,1906,1947],[371,372,27],"h1",{"id":373},"defining-bundle-entities",[375,376,377],"p",{},"Entity definitions describe reusable things that can exist on the map: characters, cursors, temporary effects, NPCs, projectiles, pickups, and anything else that should be spawned as an entity.",[375,379,380,381,385],{},"Entity definitions live in the common ",[382,383,384],"code",{},"entities"," registry. Both the server and client can read the same definition, but each side only creates the components it understands.",[387,388,390],"h2",{"id":389},"where-entities-live","Where entities live",[375,392,393,394,397,398,401],{},"Put entity definitions under ",[382,395,396],{},"common\u002Fdata\u002F\u003Cnamespace>\u002F",", where ",[382,399,400],{},"\u003Cnamespace>"," becomes the namespace part of each entity identifier.",[375,403,404],{},"You can define multiple entities in one registry file:",[406,407,413],"pre",{"className":408,"code":410,"language":411,"meta":412},[409],"language-text","my-bundle\u002F\n  bundle.json\n  common\u002F\n    data\u002F\n      myworld\u002F\n        entities.json\n","text","",[382,414,410],{"__ignoreMap":412},[375,416,417],{},"Or split each entity into its own JSON file:",[406,419,422],{"className":420,"code":421,"language":411,"meta":412},[409],"my-bundle\u002F\n  common\u002F\n    data\u002F\n      myworld\u002F\n        entities\u002F\n          characters\u002F\n            guard.json\n",[382,423,421],{"__ignoreMap":412},[375,425,426,427,430,431,434],{},"The merged ",[382,428,429],{},"entities.json"," form stores entries by local name. This defines ",[382,432,433],{},"myworld:characters\u002Fguard",":",[406,436,440],{"className":437,"code":438,"language":439,"meta":412,"style":412},"language-json shiki shiki-themes github-light github-dark","{\n  \"entries\": {\n    \"characters\u002Fguard\": {\n      \"components\": {\n        \"myworld:visual\": {\n          \"type\": \"visual\",\n          \"visual\": \"myworld:characters\u002Fguard\"\n        }\n      }\n    }\n  }\n}\n","json",[382,441,442,451,461,469,477,485,501,512,518,524,530,536],{"__ignoreMap":412},[443,444,447],"span",{"class":445,"line":446},"line",1,[443,448,450],{"class":449},"sVt8B","{\n",[443,452,454,458],{"class":445,"line":453},2,[443,455,457],{"class":456},"sj4cs","  \"entries\"",[443,459,460],{"class":449},": {\n",[443,462,464,467],{"class":445,"line":463},3,[443,465,466],{"class":456},"    \"characters\u002Fguard\"",[443,468,460],{"class":449},[443,470,472,475],{"class":445,"line":471},4,[443,473,474],{"class":456},"      \"components\"",[443,476,460],{"class":449},[443,478,480,483],{"class":445,"line":479},5,[443,481,482],{"class":456},"        \"myworld:visual\"",[443,484,460],{"class":449},[443,486,488,491,494,498],{"class":445,"line":487},6,[443,489,490],{"class":456},"          \"type\"",[443,492,493],{"class":449},": ",[443,495,497],{"class":496},"sZZnC","\"visual\"",[443,499,500],{"class":449},",\n",[443,502,504,507,509],{"class":445,"line":503},7,[443,505,506],{"class":456},"          \"visual\"",[443,508,493],{"class":449},[443,510,511],{"class":496},"\"myworld:characters\u002Fguard\"\n",[443,513,515],{"class":445,"line":514},8,[443,516,517],{"class":449},"        }\n",[443,519,521],{"class":445,"line":520},9,[443,522,523],{"class":449},"      }\n",[443,525,527],{"class":445,"line":526},10,[443,528,529],{"class":449},"    }\n",[443,531,533],{"class":445,"line":532},11,[443,534,535],{"class":449},"  }\n",[443,537,539],{"class":445,"line":538},12,[443,540,541],{"class":449},"}\n",[375,543,544,545,548,549,551],{},"The split-file form uses the file path as the local name. For example, ",[382,546,547],{},"common\u002Fdata\u002Fmyworld\u002Fentities\u002Fcharacters\u002Fguard.json"," also defines ",[382,550,433],{},".",[387,553,555],{"id":554},"entity-identifiers","Entity identifiers",[375,557,558,559,562],{},"Entity identifiers use the same ",[382,560,561],{},"namespace:name"," format as other Selene registries:",[406,564,567],{"className":565,"code":566,"language":411,"meta":412},[409],"myworld:characters\u002Fguard\nmyworld:effects\u002Fsparkle\nillarion:race\u002Fhuman_male\n",[382,568,566],{"__ignoreMap":412},[375,570,571,572,575,576,578,579,551],{},"The namespace comes from the directory below ",[382,573,574],{},"common\u002Fdata\u002F",". The name comes from either the key inside ",[382,577,429],{}," or the relative path of a file below ",[382,580,581],{},"entities\u002F",[375,583,584],{},"Use stable names once scripts, saves, spawn tables, or other bundle data refer to an entity. Renaming an entity definition means updating every reference.",[387,586,588],{"id":587},"entity-shape","Entity shape",[375,590,591],{},"An entity definition has three top-level fields:",[406,593,595],{"className":437,"code":594,"language":439,"meta":412,"style":412},"{\n  \"components\": {},\n  \"tags\": [],\n  \"metadata\": {}\n}\n",[382,596,597,601,609,617,625],{"__ignoreMap":412},[443,598,599],{"class":445,"line":446},[443,600,450],{"class":449},[443,602,603,606],{"class":445,"line":453},[443,604,605],{"class":456},"  \"components\"",[443,607,608],{"class":449},": {},\n",[443,610,611,614],{"class":445,"line":463},[443,612,613],{"class":456},"  \"tags\"",[443,615,616],{"class":449},": [],\n",[443,618,619,622],{"class":445,"line":471},[443,620,621],{"class":456},"  \"metadata\"",[443,623,624],{"class":449},": {}\n",[443,626,627],{"class":445,"line":479},[443,628,541],{"class":449},[375,630,631],{},"All fields are optional in the engine:",[633,634,635,642,648],"ul",{},[636,637,638,641],"li",{},[382,639,640],{},"components"," declares client and server behavior for entities created from this definition.",[636,643,644,647],{},[382,645,646],{},"tags"," are strings used for filtering and classification.",[636,649,650,653,654,551],{},[382,651,652],{},"metadata"," stores custom data and can be searched through ",[382,655,102],{},[375,657,658],{},"In practice, most useful entities have at least one component.",[387,660,661],{"id":640},"Components",[375,663,664,666],{},[382,665,640],{}," is an object keyed by component identifier. The key is the component instance name, not a registered component type. Use stable, namespaced keys so scripts can refer to components without colliding with other bundles.",[406,668,670],{"className":437,"code":669,"language":439,"meta":412,"style":412},"{\n  \"components\": {\n    \"myworld:visual\": {\n      \"type\": \"visual\",\n      \"visual\": \"myworld:characters\u002Fguard\"\n    },\n    \"myworld:client_script\": {\n      \"type\": \"client_script\",\n      \"script\": \"my-bundle.client.lua.entities.guard\"\n    },\n    \"myworld:server_script\": {\n      \"type\": \"server_script\",\n      \"script\": \"my-bundle.server.lua.entities.guard\"\n    }\n  }\n}\n",[382,671,672,676,682,689,700,709,714,721,732,742,746,753,764,774,779,784],{"__ignoreMap":412},[443,673,674],{"class":445,"line":446},[443,675,450],{"class":449},[443,677,678,680],{"class":445,"line":453},[443,679,605],{"class":456},[443,681,460],{"class":449},[443,683,684,687],{"class":445,"line":463},[443,685,686],{"class":456},"    \"myworld:visual\"",[443,688,460],{"class":449},[443,690,691,694,696,698],{"class":445,"line":471},[443,692,693],{"class":456},"      \"type\"",[443,695,493],{"class":449},[443,697,497],{"class":496},[443,699,500],{"class":449},[443,701,702,705,707],{"class":445,"line":479},[443,703,704],{"class":456},"      \"visual\"",[443,706,493],{"class":449},[443,708,511],{"class":496},[443,710,711],{"class":445,"line":487},[443,712,713],{"class":449},"    },\n",[443,715,716,719],{"class":445,"line":503},[443,717,718],{"class":456},"    \"myworld:client_script\"",[443,720,460],{"class":449},[443,722,723,725,727,730],{"class":445,"line":514},[443,724,693],{"class":456},[443,726,493],{"class":449},[443,728,729],{"class":496},"\"client_script\"",[443,731,500],{"class":449},[443,733,734,737,739],{"class":445,"line":520},[443,735,736],{"class":456},"      \"script\"",[443,738,493],{"class":449},[443,740,741],{"class":496},"\"my-bundle.client.lua.entities.guard\"\n",[443,743,744],{"class":445,"line":526},[443,745,713],{"class":449},[443,747,748,751],{"class":445,"line":532},[443,749,750],{"class":456},"    \"myworld:server_script\"",[443,752,460],{"class":449},[443,754,755,757,759,762],{"class":445,"line":538},[443,756,693],{"class":456},[443,758,493],{"class":449},[443,760,761],{"class":496},"\"server_script\"",[443,763,500],{"class":449},[443,765,767,769,771],{"class":445,"line":766},13,[443,768,736],{"class":456},[443,770,493],{"class":449},[443,772,773],{"class":496},"\"my-bundle.server.lua.entities.guard\"\n",[443,775,777],{"class":445,"line":776},14,[443,778,529],{"class":449},[443,780,782],{"class":445,"line":781},15,[443,783,535],{"class":449},[443,785,787],{"class":445,"line":786},16,[443,788,541],{"class":449},[375,790,791,792,795],{},"The component ",[382,793,794],{},"type"," controls which configuration is decoded.",[387,797,799],{"id":798},"visual-components","Visual components",[375,801,802,803,806,807,810],{},"Use ",[382,804,805],{},"visual"," to attach a client visual from the ",[382,808,809],{},"visuals"," registry:",[406,812,814],{"className":437,"code":813,"language":439,"meta":412,"style":412},"{\n  \"type\": \"visual\",\n  \"visual\": \"myworld:characters\u002Fguard\"\n}\n",[382,815,816,820,831,840],{"__ignoreMap":412},[443,817,818],{"class":445,"line":446},[443,819,450],{"class":449},[443,821,822,825,827,829],{"class":445,"line":453},[443,823,824],{"class":456},"  \"type\"",[443,826,493],{"class":449},[443,828,497],{"class":496},[443,830,500],{"class":449},[443,832,833,836,838],{"class":445,"line":463},[443,834,835],{"class":456},"  \"visual\"",[443,837,493],{"class":449},[443,839,511],{"class":496},[443,841,842],{"class":445,"line":471},[443,843,541],{"class":449},[375,845,846,847,849],{},"The client resolves the ",[382,848,805],{}," identifier, creates a reloadable visual instance, and renders it with the entity. The server ignores visual components.",[375,851,852,853,856],{},"Visual components can also include a ",[382,854,855],{},"position"," object:",[406,858,860],{"className":437,"code":859,"language":439,"meta":412,"style":412},"{\n  \"type\": \"visual\",\n  \"visual\": \"myworld:characters\u002Fnameplate\",\n  \"position\": {\n    \"origin\": \"top\",\n    \"offsetX\": 0,\n    \"offsetY\": 4\n  }\n}\n",[382,861,862,866,876,887,894,906,918,928,932],{"__ignoreMap":412},[443,863,864],{"class":445,"line":446},[443,865,450],{"class":449},[443,867,868,870,872,874],{"class":445,"line":453},[443,869,824],{"class":456},[443,871,493],{"class":449},[443,873,497],{"class":496},[443,875,500],{"class":449},[443,877,878,880,882,885],{"class":445,"line":463},[443,879,835],{"class":456},[443,881,493],{"class":449},[443,883,884],{"class":496},"\"myworld:characters\u002Fnameplate\"",[443,886,500],{"class":449},[443,888,889,892],{"class":445,"line":471},[443,890,891],{"class":456},"  \"position\"",[443,893,460],{"class":449},[443,895,896,899,901,904],{"class":445,"line":479},[443,897,898],{"class":456},"    \"origin\"",[443,900,493],{"class":449},[443,902,903],{"class":496},"\"top\"",[443,905,500],{"class":449},[443,907,908,911,913,916],{"class":445,"line":487},[443,909,910],{"class":456},"    \"offsetX\"",[443,912,493],{"class":449},[443,914,915],{"class":456},"0",[443,917,500],{"class":449},[443,919,920,923,925],{"class":445,"line":503},[443,921,922],{"class":456},"    \"offsetY\"",[443,924,493],{"class":449},[443,926,927],{"class":456},"4\n",[443,929,930],{"class":445,"line":514},[443,931,535],{"class":449},[443,933,934],{"class":445,"line":520},[443,935,541],{"class":449},[375,937,938],{},"Supported origins are:",[633,940,941,947],{},[636,942,943,946],{},[382,944,945],{},"none",": render at the entity's normal screen position plus offsets.",[636,948,949,952],{},[382,950,951],{},"top",": render above the bounds of visuals that were rendered earlier for the same entity.",[375,954,955,956,551],{},"Component order follows the JSON object order used by the loaded definition. Put base visuals before overlays that use ",[382,957,958],{},"origin: \"top\"",[387,960,962],{"id":961},"visual-overrides","Visual overrides",[375,964,965,966,434],{},"Visual components may pass per-entity data through ",[382,967,968],{},"overrides",[406,970,972],{"className":437,"code":971,"language":439,"meta":412,"style":412},"{\n  \"type\": \"visual\",\n  \"visual\": \"myworld:labels\u002Fname\",\n  \"overrides\": {\n    \"text\": \"Guard\"\n  }\n}\n",[382,973,974,978,988,999,1006,1016,1020],{"__ignoreMap":412},[443,975,976],{"class":445,"line":446},[443,977,450],{"class":449},[443,979,980,982,984,986],{"class":445,"line":453},[443,981,824],{"class":456},[443,983,493],{"class":449},[443,985,497],{"class":496},[443,987,500],{"class":449},[443,989,990,992,994,997],{"class":445,"line":463},[443,991,835],{"class":456},[443,993,493],{"class":449},[443,995,996],{"class":496},"\"myworld:labels\u002Fname\"",[443,998,500],{"class":449},[443,1000,1001,1004],{"class":445,"line":471},[443,1002,1003],{"class":456},"  \"overrides\"",[443,1005,460],{"class":449},[443,1007,1008,1011,1013],{"class":445,"line":479},[443,1009,1010],{"class":456},"    \"text\"",[443,1012,493],{"class":449},[443,1014,1015],{"class":496},"\"Guard\"\n",[443,1017,1018],{"class":445,"line":487},[443,1019,535],{"class":449},[443,1021,1022],{"class":445,"line":503},[443,1023,541],{"class":449},[375,1025,1026],{},"The overrides are available to the visual creation context. Use them for data that changes how a visual instance is created, such as text content or variant-specific values.",[387,1028,1030],{"id":1029},"client-script-components","Client script components",[375,1032,802,1033,1036],{},[382,1034,1035],{},"client_script"," for client-only entity behavior:",[406,1038,1040],{"className":437,"code":1039,"language":439,"meta":412,"style":412},"{\n  \"type\": \"client_script\",\n  \"script\": \"my-bundle.client.lua.entities.sparkle\"\n}\n",[382,1041,1042,1046,1056,1066],{"__ignoreMap":412},[443,1043,1044],{"class":445,"line":446},[443,1045,450],{"class":449},[443,1047,1048,1050,1052,1054],{"class":445,"line":453},[443,1049,824],{"class":456},[443,1051,493],{"class":449},[443,1053,729],{"class":496},[443,1055,500],{"class":449},[443,1057,1058,1061,1063],{"class":445,"line":463},[443,1059,1060],{"class":456},"  \"script\"",[443,1062,493],{"class":449},[443,1064,1065],{"class":496},"\"my-bundle.client.lua.entities.sparkle\"\n",[443,1067,1068],{"class":445,"line":471},[443,1069,541],{"class":449},[375,1071,1072],{},"The client loads the Lua module and calls functions if they exist:",[406,1074,1078],{"className":1075,"code":1076,"language":1077,"meta":412,"style":412},"language-lua shiki shiki-themes github-light github-dark","local M = {}\n\nfunction M.Initialize(entity, data)\n  data.started = true\nend\n\nfunction M.TickEntity(entity, data, delta)\n  -- Return normally to keep the component enabled.\nend\n\nreturn M\n","lua",[382,1079,1080,1085,1091,1096,1101,1106,1110,1115,1120,1124,1128],{"__ignoreMap":412},[443,1081,1082],{"class":445,"line":446},[443,1083,1084],{},"local M = {}\n",[443,1086,1087],{"class":445,"line":453},[443,1088,1090],{"emptyLinePlaceholder":1089},true,"\n",[443,1092,1093],{"class":445,"line":463},[443,1094,1095],{},"function M.Initialize(entity, data)\n",[443,1097,1098],{"class":445,"line":471},[443,1099,1100],{},"  data.started = true\n",[443,1102,1103],{"class":445,"line":479},[443,1104,1105],{},"end\n",[443,1107,1108],{"class":445,"line":487},[443,1109,1090],{"emptyLinePlaceholder":1089},[443,1111,1112],{"class":445,"line":503},[443,1113,1114],{},"function M.TickEntity(entity, data, delta)\n",[443,1116,1117],{"class":445,"line":514},[443,1118,1119],{},"  -- Return normally to keep the component enabled.\n",[443,1121,1122],{"class":445,"line":520},[443,1123,1105],{},[443,1125,1126],{"class":445,"line":526},[443,1127,1090],{"emptyLinePlaceholder":1089},[443,1129,1130],{"class":445,"line":532},[443,1131,1132],{},"return M\n",[375,1134,1135,1138,1139,1142],{},[382,1136,1137],{},"Initialize(entity, data)"," runs before the first tick. ",[382,1140,1141],{},"TickEntity(entity, data, delta)"," runs each client update. If either function errors, Selene disables that script component for the entity.",[387,1144,1146],{"id":1145},"server-script-components","Server script components",[375,1148,802,1149,1152],{},[382,1150,1151],{},"server_script"," for server-side entity behavior:",[406,1154,1156],{"className":437,"code":1155,"language":439,"meta":412,"style":412},"{\n  \"type\": \"server_script\",\n  \"script\": \"my-bundle.server.lua.entities.wanderer\"\n}\n",[382,1157,1158,1162,1172,1181],{"__ignoreMap":412},[443,1159,1160],{"class":445,"line":446},[443,1161,450],{"class":449},[443,1163,1164,1166,1168,1170],{"class":445,"line":453},[443,1165,824],{"class":456},[443,1167,493],{"class":449},[443,1169,761],{"class":496},[443,1171,500],{"class":449},[443,1173,1174,1176,1178],{"class":445,"line":463},[443,1175,1060],{"class":456},[443,1177,493],{"class":449},[443,1179,1180],{"class":496},"\"my-bundle.server.lua.entities.wanderer\"\n",[443,1182,1183],{"class":445,"line":471},[443,1184,541],{"class":449},[375,1186,1187],{},"Server entity scripts use the same optional functions:",[406,1189,1191],{"className":1075,"code":1190,"language":1077,"meta":412,"style":412},"local M = {}\n\nfunction M.Initialize(entity, data)\n  data.time = 0\nend\n\nfunction M.TickEntity(entity, data, delta)\n  data.time = data.time + delta\nend\n\nreturn M\n",[382,1192,1193,1197,1201,1205,1210,1214,1218,1222,1227,1231,1235],{"__ignoreMap":412},[443,1194,1195],{"class":445,"line":446},[443,1196,1084],{},[443,1198,1199],{"class":445,"line":453},[443,1200,1090],{"emptyLinePlaceholder":1089},[443,1202,1203],{"class":445,"line":463},[443,1204,1095],{},[443,1206,1207],{"class":445,"line":471},[443,1208,1209],{},"  data.time = 0\n",[443,1211,1212],{"class":445,"line":479},[443,1213,1105],{},[443,1215,1216],{"class":445,"line":487},[443,1217,1090],{"emptyLinePlaceholder":1089},[443,1219,1220],{"class":445,"line":503},[443,1221,1114],{},[443,1223,1224],{"class":445,"line":514},[443,1225,1226],{},"  data.time = data.time + delta\n",[443,1228,1229],{"class":445,"line":520},[443,1230,1105],{},[443,1232,1233],{"class":445,"line":526},[443,1234,1090],{"emptyLinePlaceholder":1089},[443,1236,1237],{"class":445,"line":532},[443,1238,1132],{},[375,1240,1241,1242,1244,1245,1247,1248,551],{},"The server creates only ",[382,1243,1151],{}," components. It ignores visual and client script components. The client creates visual and ",[382,1246,1035],{}," components, and ignores ",[382,1249,1151],{},[387,1251,1253],{"id":1252},"tags-and-metadata","Tags and metadata",[375,1255,802,1256,1258],{},[382,1257,646],{}," for broad categories:",[406,1260,1262],{"className":437,"code":1261,"language":439,"meta":412,"style":412},"{\n  \"tags\": [\n    \"myworld:character\",\n    \"myworld:npc\"\n  ]\n}\n",[382,1263,1264,1268,1275,1282,1287,1292],{"__ignoreMap":412},[443,1265,1266],{"class":445,"line":446},[443,1267,450],{"class":449},[443,1269,1270,1272],{"class":445,"line":453},[443,1271,613],{"class":456},[443,1273,1274],{"class":449},": [\n",[443,1276,1277,1280],{"class":445,"line":463},[443,1278,1279],{"class":496},"    \"myworld:character\"",[443,1281,500],{"class":449},[443,1283,1284],{"class":445,"line":471},[443,1285,1286],{"class":496},"    \"myworld:npc\"\n",[443,1288,1289],{"class":445,"line":479},[443,1290,1291],{"class":449},"  ]\n",[443,1293,1294],{"class":445,"line":487},[443,1295,541],{"class":449},[375,1297,1298],{},"Client Lua can filter entities at a coordinate by tag:",[406,1300,1302],{"className":1075,"code":1301,"language":1077,"meta":412,"style":412},"local Entities = require(\"selene.entities\")\n\nlocal npcs = Entities.findEntitiesAt(100, 100, 0, {\n  tag = \"myworld:npc\"\n})\n",[382,1303,1304,1309,1313,1318,1323],{"__ignoreMap":412},[443,1305,1306],{"class":445,"line":446},[443,1307,1308],{},"local Entities = require(\"selene.entities\")\n",[443,1310,1311],{"class":445,"line":453},[443,1312,1090],{"emptyLinePlaceholder":1089},[443,1314,1315],{"class":445,"line":463},[443,1316,1317],{},"local npcs = Entities.findEntitiesAt(100, 100, 0, {\n",[443,1319,1320],{"class":445,"line":471},[443,1321,1322],{},"  tag = \"myworld:npc\"\n",[443,1324,1325],{"class":445,"line":479},[443,1326,1327],{},"})\n",[375,1329,802,1330,1332],{},[382,1331,652],{}," for structured lookup data:",[406,1334,1336],{"className":437,"code":1335,"language":439,"meta":412,"style":412},"{\n  \"metadata\": {\n    \"spawnGroup\": \"town\",\n    \"level\": 3\n  }\n}\n",[382,1337,1338,1342,1348,1360,1370,1374],{"__ignoreMap":412},[443,1339,1340],{"class":445,"line":446},[443,1341,450],{"class":449},[443,1343,1344,1346],{"class":445,"line":453},[443,1345,621],{"class":456},[443,1347,460],{"class":449},[443,1349,1350,1353,1355,1358],{"class":445,"line":463},[443,1351,1352],{"class":456},"    \"spawnGroup\"",[443,1354,493],{"class":449},[443,1356,1357],{"class":496},"\"town\"",[443,1359,500],{"class":449},[443,1361,1362,1365,1367],{"class":445,"line":471},[443,1363,1364],{"class":456},"    \"level\"",[443,1366,493],{"class":449},[443,1368,1369],{"class":456},"3\n",[443,1371,1372],{"class":445,"line":479},[443,1373,535],{"class":449},[443,1375,1376],{"class":445,"line":487},[443,1377,541],{"class":449},[375,1379,1380],{},"Registry metadata can be queried from Lua:",[406,1382,1384],{"className":1075,"code":1383,"language":1077,"meta":412,"style":412},"local Registries = require(\"selene.registries\")\n\nlocal guard = Registries.findByMetadata(\"entities\", \"spawnGroup\", \"town\")\n",[382,1385,1386,1391,1395],{"__ignoreMap":412},[443,1387,1388],{"class":445,"line":446},[443,1389,1390],{},"local Registries = require(\"selene.registries\")\n",[443,1392,1393],{"class":445,"line":453},[443,1394,1090],{"emptyLinePlaceholder":1089},[443,1396,1397],{"class":445,"line":463},[443,1398,1399],{},"local guard = Registries.findByMetadata(\"entities\", \"spawnGroup\", \"town\")\n",[375,1401,1402,1405,1406,1409,1410,551],{},[382,1403,1404],{},"\"entities\""," resolves to the built-in ",[382,1407,1408],{},"selene:entities"," registry. Entity identifiers themselves should still use your bundle namespace, such as ",[382,1411,433],{},[387,1413,1415],{"id":1414},"complete-example","Complete example",[375,1417,1418],{},[382,1419,1420],{},"common\u002Fdata\u002Fmyworld\u002Fentities.json",[406,1422,1424],{"className":437,"code":1423,"language":439,"meta":412,"style":412},"{\n  \"entries\": {\n    \"characters\u002Fguard\": {\n      \"tags\": [\n        \"myworld:character\",\n        \"myworld:npc\"\n      ],\n      \"components\": {\n        \"myworld:body\": {\n          \"type\": \"visual\",\n          \"visual\": \"myworld:characters\u002Fguard\"\n        },\n        \"myworld:nameplate\": {\n          \"type\": \"visual\",\n          \"visual\": \"myworld:ui\u002Fnameplate\",\n          \"position\": {\n            \"origin\": \"top\",\n            \"offsetX\": 0,\n            \"offsetY\": 6\n          },\n          \"overrides\": {\n            \"text\": \"Guard\"\n          }\n        },\n        \"myworld:server_ai\": {\n          \"type\": \"server_script\",\n          \"script\": \"my-bundle.server.lua.entities.guard\"\n        }\n      },\n      \"metadata\": {\n        \"spawnGroup\": \"town\",\n        \"level\": 3\n      }\n    }\n  }\n}\n",[382,1425,1426,1430,1436,1442,1449,1456,1461,1466,1472,1479,1489,1497,1502,1509,1519,1530,1537,1549,1561,1572,1578,1586,1596,1602,1607,1615,1626,1636,1641,1647,1655,1667,1677,1682,1687,1692],{"__ignoreMap":412},[443,1427,1428],{"class":445,"line":446},[443,1429,450],{"class":449},[443,1431,1432,1434],{"class":445,"line":453},[443,1433,457],{"class":456},[443,1435,460],{"class":449},[443,1437,1438,1440],{"class":445,"line":463},[443,1439,466],{"class":456},[443,1441,460],{"class":449},[443,1443,1444,1447],{"class":445,"line":471},[443,1445,1446],{"class":456},"      \"tags\"",[443,1448,1274],{"class":449},[443,1450,1451,1454],{"class":445,"line":479},[443,1452,1453],{"class":496},"        \"myworld:character\"",[443,1455,500],{"class":449},[443,1457,1458],{"class":445,"line":487},[443,1459,1460],{"class":496},"        \"myworld:npc\"\n",[443,1462,1463],{"class":445,"line":503},[443,1464,1465],{"class":449},"      ],\n",[443,1467,1468,1470],{"class":445,"line":514},[443,1469,474],{"class":456},[443,1471,460],{"class":449},[443,1473,1474,1477],{"class":445,"line":520},[443,1475,1476],{"class":456},"        \"myworld:body\"",[443,1478,460],{"class":449},[443,1480,1481,1483,1485,1487],{"class":445,"line":526},[443,1482,490],{"class":456},[443,1484,493],{"class":449},[443,1486,497],{"class":496},[443,1488,500],{"class":449},[443,1490,1491,1493,1495],{"class":445,"line":532},[443,1492,506],{"class":456},[443,1494,493],{"class":449},[443,1496,511],{"class":496},[443,1498,1499],{"class":445,"line":538},[443,1500,1501],{"class":449},"        },\n",[443,1503,1504,1507],{"class":445,"line":766},[443,1505,1506],{"class":456},"        \"myworld:nameplate\"",[443,1508,460],{"class":449},[443,1510,1511,1513,1515,1517],{"class":445,"line":776},[443,1512,490],{"class":456},[443,1514,493],{"class":449},[443,1516,497],{"class":496},[443,1518,500],{"class":449},[443,1520,1521,1523,1525,1528],{"class":445,"line":781},[443,1522,506],{"class":456},[443,1524,493],{"class":449},[443,1526,1527],{"class":496},"\"myworld:ui\u002Fnameplate\"",[443,1529,500],{"class":449},[443,1531,1532,1535],{"class":445,"line":786},[443,1533,1534],{"class":456},"          \"position\"",[443,1536,460],{"class":449},[443,1538,1540,1543,1545,1547],{"class":445,"line":1539},17,[443,1541,1542],{"class":456},"            \"origin\"",[443,1544,493],{"class":449},[443,1546,903],{"class":496},[443,1548,500],{"class":449},[443,1550,1552,1555,1557,1559],{"class":445,"line":1551},18,[443,1553,1554],{"class":456},"            \"offsetX\"",[443,1556,493],{"class":449},[443,1558,915],{"class":456},[443,1560,500],{"class":449},[443,1562,1564,1567,1569],{"class":445,"line":1563},19,[443,1565,1566],{"class":456},"            \"offsetY\"",[443,1568,493],{"class":449},[443,1570,1571],{"class":456},"6\n",[443,1573,1575],{"class":445,"line":1574},20,[443,1576,1577],{"class":449},"          },\n",[443,1579,1581,1584],{"class":445,"line":1580},21,[443,1582,1583],{"class":456},"          \"overrides\"",[443,1585,460],{"class":449},[443,1587,1589,1592,1594],{"class":445,"line":1588},22,[443,1590,1591],{"class":456},"            \"text\"",[443,1593,493],{"class":449},[443,1595,1015],{"class":496},[443,1597,1599],{"class":445,"line":1598},23,[443,1600,1601],{"class":449},"          }\n",[443,1603,1605],{"class":445,"line":1604},24,[443,1606,1501],{"class":449},[443,1608,1610,1613],{"class":445,"line":1609},25,[443,1611,1612],{"class":456},"        \"myworld:server_ai\"",[443,1614,460],{"class":449},[443,1616,1618,1620,1622,1624],{"class":445,"line":1617},26,[443,1619,490],{"class":456},[443,1621,493],{"class":449},[443,1623,761],{"class":496},[443,1625,500],{"class":449},[443,1627,1629,1632,1634],{"class":445,"line":1628},27,[443,1630,1631],{"class":456},"          \"script\"",[443,1633,493],{"class":449},[443,1635,773],{"class":496},[443,1637,1639],{"class":445,"line":1638},28,[443,1640,517],{"class":449},[443,1642,1644],{"class":445,"line":1643},29,[443,1645,1646],{"class":449},"      },\n",[443,1648,1650,1653],{"class":445,"line":1649},30,[443,1651,1652],{"class":456},"      \"metadata\"",[443,1654,460],{"class":449},[443,1656,1658,1661,1663,1665],{"class":445,"line":1657},31,[443,1659,1660],{"class":456},"        \"spawnGroup\"",[443,1662,493],{"class":449},[443,1664,1357],{"class":496},[443,1666,500],{"class":449},[443,1668,1670,1673,1675],{"class":445,"line":1669},32,[443,1671,1672],{"class":456},"        \"level\"",[443,1674,493],{"class":449},[443,1676,1369],{"class":456},[443,1678,1680],{"class":445,"line":1679},33,[443,1681,523],{"class":449},[443,1683,1685],{"class":445,"line":1684},34,[443,1686,529],{"class":449},[443,1688,1690],{"class":445,"line":1689},35,[443,1691,535],{"class":449},[443,1693,1695],{"class":445,"line":1694},36,[443,1696,541],{"class":449},[375,1698,1699,1700,1702,1703,1706,1707,1710,1711,551],{},"This assumes matching visual definitions such as ",[382,1701,433],{}," and ",[382,1704,1705],{},"myworld:ui\u002Fnameplate"," exist in ",[382,1708,1709],{},"client\u002Fdata\u002Fmyworld\u002Fvisuals.json"," or ",[382,1712,1713],{},"client\u002Fdata\u002Fmyworld\u002Fvisuals\u002F",[387,1715,1717],{"id":1716},"creating-entities-from-lua","Creating entities from Lua",[375,1719,1720,1721,1723,1724,551],{},"Look up an entity definition through ",[382,1722,102],{},", then pass it to ",[382,1725,140],{},[375,1727,1728],{},"Server Lua:",[406,1730,1732],{"className":1075,"code":1731,"language":1077,"meta":412,"style":412},"local Registries = require(\"selene.registries\")\nlocal Entities = require(\"selene.entities\")\n\nlocal guardDef = Registries.findByName(\"entities\", \"myworld:characters\u002Fguard\")\nlocal guard = Entities.create(guardDef)\n\nguard:SetCoordinate(100, 100, 0)\nguard:Spawn(dimension)\n",[382,1733,1734,1738,1742,1746,1751,1756,1760,1765],{"__ignoreMap":412},[443,1735,1736],{"class":445,"line":446},[443,1737,1390],{},[443,1739,1740],{"class":445,"line":453},[443,1741,1308],{},[443,1743,1744],{"class":445,"line":463},[443,1745,1090],{"emptyLinePlaceholder":1089},[443,1747,1748],{"class":445,"line":471},[443,1749,1750],{},"local guardDef = Registries.findByName(\"entities\", \"myworld:characters\u002Fguard\")\n",[443,1752,1753],{"class":445,"line":479},[443,1754,1755],{},"local guard = Entities.create(guardDef)\n",[443,1757,1758],{"class":445,"line":487},[443,1759,1090],{"emptyLinePlaceholder":1089},[443,1761,1762],{"class":445,"line":503},[443,1763,1764],{},"guard:SetCoordinate(100, 100, 0)\n",[443,1766,1767],{"class":445,"line":514},[443,1768,1769],{},"guard:Spawn(dimension)\n",[375,1771,1772,1773,1776],{},"The server-created entity is saved and synchronized with clients. Use ",[382,1774,1775],{},"createTransient"," for fire-and-forget entities that are synchronized but not assigned a persistent network id:",[406,1778,1780],{"className":1075,"code":1779,"language":1077,"meta":412,"style":412},"local effect = Entities.createTransient(guardDef)\neffect:SetCoordinate(100, 100, 0)\neffect:Spawn(dimension)\n",[382,1781,1782,1787,1792],{"__ignoreMap":412},[443,1783,1784],{"class":445,"line":446},[443,1785,1786],{},"local effect = Entities.createTransient(guardDef)\n",[443,1788,1789],{"class":445,"line":453},[443,1790,1791],{},"effect:SetCoordinate(100, 100, 0)\n",[443,1793,1794],{"class":445,"line":463},[443,1795,1796],{},"effect:Spawn(dimension)\n",[375,1798,1799],{},"Client Lua can create local-only entities:",[406,1801,1803],{"className":1075,"code":1802,"language":1077,"meta":412,"style":412},"local Registries = require(\"selene.registries\")\nlocal Entities = require(\"selene.entities\")\n\nlocal cursorDef = Registries.findByName(\"entities\", \"myworld:cursor\")\nlocal cursor = Entities.create(cursorDef)\ncursor:SetCoordinate(100, 100, 0)\ncursor:Spawn()\n",[382,1804,1805,1809,1813,1817,1822,1827,1832],{"__ignoreMap":412},[443,1806,1807],{"class":445,"line":446},[443,1808,1390],{},[443,1810,1811],{"class":445,"line":453},[443,1812,1308],{},[443,1814,1815],{"class":445,"line":463},[443,1816,1090],{"emptyLinePlaceholder":1089},[443,1818,1819],{"class":445,"line":471},[443,1820,1821],{},"local cursorDef = Registries.findByName(\"entities\", \"myworld:cursor\")\n",[443,1823,1824],{"class":445,"line":479},[443,1825,1826],{},"local cursor = Entities.create(cursorDef)\n",[443,1828,1829],{"class":445,"line":487},[443,1830,1831],{},"cursor:SetCoordinate(100, 100, 0)\n",[443,1833,1834],{"class":445,"line":503},[443,1835,1836],{},"cursor:Spawn()\n",[375,1838,1839],{},"Use client-created entities for cursors, previews, local effects, and UI-adjacent map overlays. Use server-created entities for gameplay objects that other players should see.",[387,1841,1843],{"id":1842},"hot-reload-behavior","Hot reload behavior",[375,1845,1846],{},"Entity definitions are loaded through the common bundle registry system.",[633,1848,1849,1856,1863],{},[636,1850,1851,1852,1855],{},"Updating ",[382,1853,1854],{},"common\u002Fdata\u002F\u003Cnamespace>\u002Fentities.json"," reloads the merged entity file.",[636,1857,1858,1859,1862],{},"Updating a file below ",[382,1860,1861],{},"common\u002Fdata\u002F\u003Cnamespace>\u002Fentities\u002F"," reloads that single entity entry.",[636,1864,1865,1866,1868,1869,1871,1872,1874],{},"If both ",[382,1867,429],{}," and an ",[382,1870,581],{}," directory exist for the same namespace in the same bundle, ",[382,1873,429],{}," is authoritative.",[375,1876,1877],{},"Existing client entities subscribe to their definition reference. When an entity definition reloads, the client rebuilds that entity's components from the new definition.",[387,1879,1881],{"id":1880},"recommended-layout","Recommended layout",[375,1883,1884],{},"For most bundles:",[406,1886,1889],{"className":1887,"code":1888,"language":411,"meta":412},[409],"my-bundle\u002F\n  common\u002F\n    data\u002F\n      myworld\u002F\n        entities.json\n  client\u002F\n    data\u002F\n      myworld\u002F\n        visuals.json\n    lua\u002F\n      entities\u002F\n        sparkle.lua\n  server\u002F\n    lua\u002F\n      entities\u002F\n        guard.lua\n",[382,1890,1888],{"__ignoreMap":412},[375,1892,1893,1894,1897,1898,1901],{},"Keep the entity definition in ",[382,1895,1896],{},"common\u002Fdata",", client visuals in ",[382,1899,1900],{},"client\u002Fdata",", and platform-specific behavior in platform-specific Lua directories.",[387,1903,1905],{"id":1904},"checklist","Checklist",[633,1907,1908,1914,1919,1926,1936,1944],{},[636,1909,393,1910,1710,1912,551],{},[382,1911,1854],{},[382,1913,1861],{},[636,1915,1916,1917,551],{},"Reference visuals by full identifier, such as ",[382,1918,433],{},[636,1920,1921,1922,1925],{},"Use namespaced component keys, such as ",[382,1923,1924],{},"myworld:visual",", to avoid collisions.",[636,1927,802,1928,1702,1930,1932,1933,1935],{},[382,1929,805],{},[382,1931,1035],{}," for client behavior, and ",[382,1934,1151],{}," for server behavior.",[636,1937,802,1938,1940,1941,1943],{},[382,1939,646],{}," for filtering and ",[382,1942,652],{}," for registry lookup.",[636,1945,1946],{},"Create gameplay entities on the server; create cursors, previews, and local effects on the client.",[1948,1949,1950],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":412,"searchDepth":453,"depth":453,"links":1952},[1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966],{"id":389,"depth":453,"text":390},{"id":554,"depth":453,"text":555},{"id":587,"depth":453,"text":588},{"id":640,"depth":453,"text":661},{"id":798,"depth":453,"text":799},{"id":961,"depth":453,"text":962},{"id":1029,"depth":453,"text":1030},{"id":1145,"depth":453,"text":1146},{"id":1252,"depth":453,"text":1253},{"id":1414,"depth":453,"text":1415},{"id":1716,"depth":453,"text":1717},{"id":1842,"depth":453,"text":1843},{"id":1880,"depth":453,"text":1881},{"id":1904,"depth":453,"text":1905},"Define entity registry entries in Selene bundles, attach visuals and scripts, and create entities from Lua.","md",{},{"title":27,"description":1967},"NxwvoBpRWudPgxVMNR07BPuoQKWbMal9KGHooUNtuoc",[1973,1975],{"title":23,"path":24,"stem":25,"description":1974,"children":-1},"Define custom bundle-backed registries, populate them from JSON, and query them from Lua.",{"title":31,"path":32,"stem":33,"description":1976,"children":-1},"Define sound registry entries in Selene bundles, connect them to client audio files, and play them from Lua.",1792747966451]