[{"data":1,"prerenderedAt":1408},["ShallowReactive",2],{"navigation":3,"reference-navigation":62,"\u002Fdocs\u002Fcustom-registries":365,"\u002Fdocs\u002Fcustom-registries-surround":1403},[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":23,"body":367,"description":1398,"extension":1399,"meta":1400,"navigation":1107,"path":24,"seo":1401,"stem":25,"__hash__":1402},"docs\u002F1.docs\u002Fcustom-registries.md",{"type":368,"value":369,"toc":1382},"minimark",[370,374,383,388,391,412,418,422,432,437,444,561,564,585,591,595,598,612,615,632,635,647,664,668,671,681,692,700,712,715,719,725,730,733,737,900,903,915,919,922,933,937,1003,1007,1072,1074,1085,1089,1094,1124,1130,1134,1139,1186,1189,1213,1222,1226,1229,1250,1253,1257,1260,1291,1295,1306,1339,1348,1352,1378],[371,372,23],"h1",{"id":373},"custom-registry-developer-guide",[375,376,377,378,382],"p",{},"Custom registries let you ship your own structured data sets in bundles without adding a new built-in Kotlin registry type. The engine loads a registry definition from the built-in ",[379,380,381],"code",{},"registries"," registry, then loads that registry's entries from bundle JSON files.",[384,385,387],"h2",{"id":386},"when-to-use-a-custom-registry","When to use a custom registry",[375,389,390],{},"Use a custom registry when:",[392,393,394,401,404,409],"ul",{},[395,396,397,398],"li",{},"You want bundle data to be addressable by identifier, like ",[379,399,400],{},"mygame:quests\u002Fmain_story",[395,402,403],{},"You want hot-reload support for registry files during development",[395,405,406,407],{},"You want to query entries from Lua through ",[379,408,102],{},[395,410,411],{},"You do not need a dedicated typed Kotlin serializer for each entry",[375,413,414,415,417],{},"Custom registries store each entry as raw JSON and expose it as a ",[379,416,267],{}," in Lua.",[384,419,421],{"id":420},"how-custom-registries-are-declared","How custom registries are declared",[375,423,424,425,427,428,431],{},"Custom registry definitions live in the built-in ",[379,426,381],{}," registry on the ",[379,429,430],{},"common"," platform. In practice, that means your bundle declares them in:",[375,433,434],{},[379,435,436],{},"common\u002Fdata\u002F\u003Cnamespace>\u002Fregistries.json",[375,438,439,440,443],{},"The merged file format uses an ",[379,441,442],{},"entries"," object:",[445,446,451],"pre",{"className":447,"code":448,"language":449,"meta":450,"style":450},"language-json shiki shiki-themes github-light github-dark","{\n  \"entries\": {\n    \"mygame:quests\": {\n      \"name\": \"quests\",\n      \"platform\": \"server\"\n    },\n    \"mygame:music_presets\": {\n      \"name\": \"music_presets\",\n      \"platform\": \"client\"\n    }\n  }\n}\n","json","",[379,452,453,462,472,480,496,507,513,521,533,543,549,555],{"__ignoreMap":450},[454,455,458],"span",{"class":456,"line":457},"line",1,[454,459,461],{"class":460},"sVt8B","{\n",[454,463,465,469],{"class":456,"line":464},2,[454,466,468],{"class":467},"sj4cs","  \"entries\"",[454,470,471],{"class":460},": {\n",[454,473,475,478],{"class":456,"line":474},3,[454,476,477],{"class":467},"    \"mygame:quests\"",[454,479,471],{"class":460},[454,481,483,486,489,493],{"class":456,"line":482},4,[454,484,485],{"class":467},"      \"name\"",[454,487,488],{"class":460},": ",[454,490,492],{"class":491},"sZZnC","\"quests\"",[454,494,495],{"class":460},",\n",[454,497,499,502,504],{"class":456,"line":498},5,[454,500,501],{"class":467},"      \"platform\"",[454,503,488],{"class":460},[454,505,506],{"class":491},"\"server\"\n",[454,508,510],{"class":456,"line":509},6,[454,511,512],{"class":460},"    },\n",[454,514,516,519],{"class":456,"line":515},7,[454,517,518],{"class":467},"    \"mygame:music_presets\"",[454,520,471],{"class":460},[454,522,524,526,528,531],{"class":456,"line":523},8,[454,525,485],{"class":467},[454,527,488],{"class":460},[454,529,530],{"class":491},"\"music_presets\"",[454,532,495],{"class":460},[454,534,536,538,540],{"class":456,"line":535},9,[454,537,501],{"class":467},[454,539,488],{"class":460},[454,541,542],{"class":491},"\"client\"\n",[454,544,546],{"class":456,"line":545},10,[454,547,548],{"class":460},"    }\n",[454,550,552],{"class":456,"line":551},11,[454,553,554],{"class":460},"  }\n",[454,556,558],{"class":456,"line":557},12,[454,559,560],{"class":460},"}\n",[375,562,563],{},"Each definition has:",[392,565,566,572],{},[395,567,568,571],{},[379,569,570],{},"name",": the directory or merged-file name used on disk for this registry",[395,573,574,577,578,581,582],{},[379,575,576],{},"platform",": where the registry entries are loaded from, currently ",[379,579,580],{},"client"," or ",[379,583,584],{},"server",[375,586,587,588,590],{},"The key inside ",[379,589,442],{}," is the registry identifier. That identifier is what Lua uses to look the registry up.",[384,592,594],{"id":593},"identifier-vs-storage-name","Identifier vs storage name",[375,596,597],{},"There are two names involved, and they serve different purposes:",[392,599,600,606],{},[395,601,602,603],{},"Registry identifier: ",[379,604,605],{},"mygame:quests",[395,607,608,609],{},"Storage name: ",[379,610,611],{},"quests",[375,613,614],{},"The identifier is used when you query the registry from Lua:",[445,616,620],{"className":617,"code":618,"language":619,"meta":450,"style":450},"language-lua shiki shiki-themes github-light github-dark","local Registries = require(\"selene.registries\")\nlocal quest = Registries.findByName(\"mygame:quests\", \"mygame:introduction\")\n","lua",[379,621,622,627],{"__ignoreMap":450},[454,623,624],{"class":456,"line":457},[454,625,626],{},"local Registries = require(\"selene.registries\")\n",[454,628,629],{"class":456,"line":464},[454,630,631],{},"local quest = Registries.findByName(\"mygame:quests\", \"mygame:introduction\")\n",[375,633,634],{},"The storage name is used for the JSON path on disk:",[392,636,637,642],{},[395,638,639],{},[379,640,641],{},"server\u002Fdata\u002Fmygame\u002Fquests.json",[395,643,644],{},[379,645,646],{},"server\u002Fdata\u002Fmygame\u002Fquests\u002Fintroduction.json",[375,648,649,650,652,653,655,656,659,660,663],{},"If you only pass ",[379,651,492],{}," to ",[379,654,102],{},", the engine will parse it as ",[379,657,658],{},"selene:quests",", which is not your custom registry. Use the full identifier such as ",[379,661,662],{},"\"mygame:quests\"",".",[384,665,667],{"id":666},"where-registry-entries-go","Where registry entries go",[375,669,670],{},"Once a custom registry is declared, its entries are loaded from the platform named in the definition.",[375,672,673,674,676,677,680],{},"For a server registry named ",[379,675,611],{}," in namespace ",[379,678,679],{},"mygame",", the engine looks in:",[392,682,683,687],{},[395,684,685],{},[379,686,641],{},[395,688,689],{},[379,690,691],{},"server\u002Fdata\u002Fmygame\u002Fquests\u002F**\u002F*.json",[375,693,694,695,676,698,680],{},"For a client registry named ",[379,696,697],{},"music_presets",[379,699,679],{},[392,701,702,707],{},[395,703,704],{},[379,705,706],{},"client\u002Fdata\u002Fmygame\u002Fmusic_presets.json",[395,708,709],{},[379,710,711],{},"client\u002Fdata\u002Fmygame\u002Fmusic_presets\u002F**\u002F*.json",[375,713,714],{},"The same rule applies to any namespace and registry name.",[384,716,718],{"id":717},"two-supported-file-layouts","Two supported file layouts",[375,720,721,724],{},[379,722,723],{},"FileBasedRegistry"," supports both a merged JSON file and a directory tree of per-entry JSON files.",[726,727,729],"h3",{"id":728},"option-1-merged-file","Option 1: merged file",[375,731,732],{},"Use a single file when the registry is small or you want everything together:",[375,734,735],{},[379,736,641],{},[445,738,740],{"className":447,"code":739,"language":449,"meta":450,"style":450},"{\n  \"entries\": {\n    \"introduction\": {\n      \"title\": \"Introduction\",\n      \"recommendedLevel\": 1,\n      \"metadata\": {\n        \"category\": \"main\",\n        \"repeatable\": false\n      }\n    },\n    \"blacksmith_help\": {\n      \"title\": \"A Favor for the Blacksmith\",\n      \"recommendedLevel\": 3,\n      \"metadata\": {\n        \"category\": \"side\",\n        \"repeatable\": true\n      }\n    }\n  }\n}\n",[379,741,742,746,752,759,771,783,790,802,812,817,821,828,839,851,858,870,880,885,890,895],{"__ignoreMap":450},[454,743,744],{"class":456,"line":457},[454,745,461],{"class":460},[454,747,748,750],{"class":456,"line":464},[454,749,468],{"class":467},[454,751,471],{"class":460},[454,753,754,757],{"class":456,"line":474},[454,755,756],{"class":467},"    \"introduction\"",[454,758,471],{"class":460},[454,760,761,764,766,769],{"class":456,"line":482},[454,762,763],{"class":467},"      \"title\"",[454,765,488],{"class":460},[454,767,768],{"class":491},"\"Introduction\"",[454,770,495],{"class":460},[454,772,773,776,778,781],{"class":456,"line":498},[454,774,775],{"class":467},"      \"recommendedLevel\"",[454,777,488],{"class":460},[454,779,780],{"class":467},"1",[454,782,495],{"class":460},[454,784,785,788],{"class":456,"line":509},[454,786,787],{"class":467},"      \"metadata\"",[454,789,471],{"class":460},[454,791,792,795,797,800],{"class":456,"line":515},[454,793,794],{"class":467},"        \"category\"",[454,796,488],{"class":460},[454,798,799],{"class":491},"\"main\"",[454,801,495],{"class":460},[454,803,804,807,809],{"class":456,"line":523},[454,805,806],{"class":467},"        \"repeatable\"",[454,808,488],{"class":460},[454,810,811],{"class":467},"false\n",[454,813,814],{"class":456,"line":535},[454,815,816],{"class":460},"      }\n",[454,818,819],{"class":456,"line":545},[454,820,512],{"class":460},[454,822,823,826],{"class":456,"line":551},[454,824,825],{"class":467},"    \"blacksmith_help\"",[454,827,471],{"class":460},[454,829,830,832,834,837],{"class":456,"line":557},[454,831,763],{"class":467},[454,833,488],{"class":460},[454,835,836],{"class":491},"\"A Favor for the Blacksmith\"",[454,838,495],{"class":460},[454,840,842,844,846,849],{"class":456,"line":841},13,[454,843,775],{"class":467},[454,845,488],{"class":460},[454,847,848],{"class":467},"3",[454,850,495],{"class":460},[454,852,854,856],{"class":456,"line":853},14,[454,855,787],{"class":467},[454,857,471],{"class":460},[454,859,861,863,865,868],{"class":456,"line":860},15,[454,862,794],{"class":467},[454,864,488],{"class":460},[454,866,867],{"class":491},"\"side\"",[454,869,495],{"class":460},[454,871,873,875,877],{"class":456,"line":872},16,[454,874,806],{"class":467},[454,876,488],{"class":460},[454,878,879],{"class":467},"true\n",[454,881,883],{"class":456,"line":882},17,[454,884,816],{"class":460},[454,886,888],{"class":456,"line":887},18,[454,889,548],{"class":460},[454,891,893],{"class":456,"line":892},19,[454,894,554],{"class":460},[454,896,898],{"class":456,"line":897},20,[454,899,560],{"class":460},[375,901,902],{},"This produces the identifiers:",[392,904,905,910],{},[395,906,907],{},[379,908,909],{},"mygame:introduction",[395,911,912],{},[379,913,914],{},"mygame:blacksmith_help",[726,916,918],{"id":917},"option-2-directory-tree","Option 2: directory tree",[375,920,921],{},"Use per-entry files when the registry is large or you want nested paths:",[392,923,924,928],{},[395,925,926],{},[379,927,646],{},[395,929,930],{},[379,931,932],{},"server\u002Fdata\u002Fmygame\u002Fquests\u002Fchapters\u002Fchapter1.json",[375,934,935],{},[379,936,646],{},[445,938,940],{"className":447,"code":939,"language":449,"meta":450,"style":450},"{\n  \"title\": \"Introduction\",\n  \"recommendedLevel\": 1,\n  \"metadata\": {\n    \"category\": \"main\",\n    \"repeatable\": false\n  }\n}\n",[379,941,942,946,957,968,975,986,995,999],{"__ignoreMap":450},[454,943,944],{"class":456,"line":457},[454,945,461],{"class":460},[454,947,948,951,953,955],{"class":456,"line":464},[454,949,950],{"class":467},"  \"title\"",[454,952,488],{"class":460},[454,954,768],{"class":491},[454,956,495],{"class":460},[454,958,959,962,964,966],{"class":456,"line":474},[454,960,961],{"class":467},"  \"recommendedLevel\"",[454,963,488],{"class":460},[454,965,780],{"class":467},[454,967,495],{"class":460},[454,969,970,973],{"class":456,"line":482},[454,971,972],{"class":467},"  \"metadata\"",[454,974,471],{"class":460},[454,976,977,980,982,984],{"class":456,"line":498},[454,978,979],{"class":467},"    \"category\"",[454,981,488],{"class":460},[454,983,799],{"class":491},[454,985,495],{"class":460},[454,987,988,991,993],{"class":456,"line":509},[454,989,990],{"class":467},"    \"repeatable\"",[454,992,488],{"class":460},[454,994,811],{"class":467},[454,996,997],{"class":456,"line":515},[454,998,554],{"class":460},[454,1000,1001],{"class":456,"line":523},[454,1002,560],{"class":460},[375,1004,1005],{},[379,1006,932],{},[445,1008,1010],{"className":447,"code":1009,"language":449,"meta":450,"style":450},"{\n  \"title\": \"Chapter 1\",\n  \"recommendedLevel\": 5,\n  \"metadata\": {\n    \"category\": \"main\",\n    \"chapter\": 1\n  }\n}\n",[379,1011,1012,1016,1027,1038,1044,1054,1064,1068],{"__ignoreMap":450},[454,1013,1014],{"class":456,"line":457},[454,1015,461],{"class":460},[454,1017,1018,1020,1022,1025],{"class":456,"line":464},[454,1019,950],{"class":467},[454,1021,488],{"class":460},[454,1023,1024],{"class":491},"\"Chapter 1\"",[454,1026,495],{"class":460},[454,1028,1029,1031,1033,1036],{"class":456,"line":474},[454,1030,961],{"class":467},[454,1032,488],{"class":460},[454,1034,1035],{"class":467},"5",[454,1037,495],{"class":460},[454,1039,1040,1042],{"class":456,"line":482},[454,1041,972],{"class":467},[454,1043,471],{"class":460},[454,1045,1046,1048,1050,1052],{"class":456,"line":498},[454,1047,979],{"class":467},[454,1049,488],{"class":460},[454,1051,799],{"class":491},[454,1053,495],{"class":460},[454,1055,1056,1059,1061],{"class":456,"line":509},[454,1057,1058],{"class":467},"    \"chapter\"",[454,1060,488],{"class":460},[454,1062,1063],{"class":467},"1\n",[454,1065,1066],{"class":456,"line":515},[454,1067,554],{"class":460},[454,1069,1070],{"class":456,"line":523},[454,1071,560],{"class":460},[375,1073,902],{},[392,1075,1076,1080],{},[395,1077,1078],{},[379,1079,909],{},[395,1081,1082],{},[379,1083,1084],{},"mygame:chapters\u002Fchapter1",[384,1086,1088],{"id":1087},"lua-access","Lua access",[375,1090,1091,1092,663],{},"Custom registries are queried through ",[379,1093,102],{},[445,1095,1097],{"className":617,"code":1096,"language":619,"meta":450,"style":450},"local Registries = require(\"selene.registries\")\n\nlocal allQuests = Registries.findAll(\"mygame:quests\")\nlocal introQuest = Registries.findByName(\"mygame:quests\", \"mygame:introduction\")\nlocal firstMainQuest = Registries.findByMetadata(\"mygame:quests\", \"category\", \"main\")\n",[379,1098,1099,1103,1109,1114,1119],{"__ignoreMap":450},[454,1100,1101],{"class":456,"line":457},[454,1102,626],{},[454,1104,1105],{"class":456,"line":464},[454,1106,1108],{"emptyLinePlaceholder":1107},true,"\n",[454,1110,1111],{"class":456,"line":474},[454,1112,1113],{},"local allQuests = Registries.findAll(\"mygame:quests\")\n",[454,1115,1116],{"class":456,"line":482},[454,1117,1118],{},"local introQuest = Registries.findByName(\"mygame:quests\", \"mygame:introduction\")\n",[454,1120,1121],{"class":456,"line":498},[454,1122,1123],{},"local firstMainQuest = Registries.findByMetadata(\"mygame:quests\", \"category\", \"main\")\n",[375,1125,1126,1127,1129],{},"For custom registries, these functions return ",[379,1128,267],{}," instances.",[384,1131,1133],{"id":1132},"reading-fields-and-metadata-in-lua","Reading fields and metadata in Lua",[375,1135,1136,1138],{},[379,1137,267],{}," exposes the identifier plus helper methods for raw JSON access.",[445,1140,1142],{"className":617,"code":1141,"language":619,"meta":450,"style":450},"local Registries = require(\"selene.registries\")\n\nlocal quest = Registries.findByName(\"mygame:quests\", \"mygame:introduction\")\nif quest then\n  print(quest.Name)\n  print(quest:GetField(\"title\"))\n  print(quest:GetField(\"recommendedLevel\"))\n  print(quest:GetMetadata(\"category\"))\nend\n",[379,1143,1144,1148,1152,1156,1161,1166,1171,1176,1181],{"__ignoreMap":450},[454,1145,1146],{"class":456,"line":457},[454,1147,626],{},[454,1149,1150],{"class":456,"line":464},[454,1151,1108],{"emptyLinePlaceholder":1107},[454,1153,1154],{"class":456,"line":474},[454,1155,631],{},[454,1157,1158],{"class":456,"line":482},[454,1159,1160],{},"if quest then\n",[454,1162,1163],{"class":456,"line":498},[454,1164,1165],{},"  print(quest.Name)\n",[454,1167,1168],{"class":456,"line":509},[454,1169,1170],{},"  print(quest:GetField(\"title\"))\n",[454,1172,1173],{"class":456,"line":515},[454,1174,1175],{},"  print(quest:GetField(\"recommendedLevel\"))\n",[454,1177,1178],{"class":456,"line":523},[454,1179,1180],{},"  print(quest:GetMetadata(\"category\"))\n",[454,1182,1183],{"class":456,"line":535},[454,1184,1185],{},"end\n",[375,1187,1188],{},"Use:",[392,1190,1191,1197,1203],{},[395,1192,1193,1196],{},[379,1194,1195],{},"Name"," for the object's full identifier string",[395,1198,1199,1202],{},[379,1200,1201],{},"GetField(\"key\")"," for top-level JSON fields",[395,1204,1205,1208,1209,1212],{},[379,1206,1207],{},"GetMetadata(\"key\")"," for values inside the ",[379,1210,1211],{},"metadata"," object",[375,1214,1215,1218,1219,1221],{},[379,1216,1217],{},"findByMetadata"," only searches values stored inside the entry's ",[379,1220,1211],{}," object.",[384,1223,1225],{"id":1224},"hot-reload-behavior","Hot reload behavior",[375,1227,1228],{},"Custom registries participate in the same file watching flow as other bundle-backed registries.",[392,1230,1231,1237,1243],{},[395,1232,1233,1234,1236],{},"Updating ",[379,1235,436],{}," reloads the registry definitions",[395,1238,1239,1240,1242],{},"Updating a merged registry file like ",[379,1241,641],{}," reloads the whole custom registry",[395,1244,1245,1246,1249],{},"Updating a single file under ",[379,1247,1248],{},"server\u002Fdata\u002Fmygame\u002Fquests\u002F"," reloads just that entry",[375,1251,1252],{},"If both a merged file and a directory exist for the same registry in the same namespace, the merged file is authoritative.",[384,1254,1256],{"id":1255},"recommended-layout","Recommended layout",[375,1258,1259],{},"For most bundles:",[1261,1262,1263,1268,1277,1280,1283],"ol",{},[395,1264,1265,1266],{},"Declare the registry once in ",[379,1267,436],{},[395,1269,1270,1271,581,1274],{},"Put the actual entries under ",[379,1272,1273],{},"client\u002Fdata\u002F...",[379,1275,1276],{},"server\u002Fdata\u002F...",[395,1278,1279],{},"Use merged files for small registries",[395,1281,1282],{},"Use directory trees for large registries or when nested identifiers are useful",[395,1284,1285,1286,1288,1289],{},"Put searchable tags in ",[379,1287,1211],{}," if you plan to use ",[379,1290,1217],{},[384,1292,1294],{"id":1293},"migration-note","Migration note",[375,1296,1297,1298,1301,1302,1305],{},"Older bundle examples may use a different schema with fields like ",[379,1299,1300],{},"suffix",". The current engine code in ",[379,1303,1304],{},"\u002Fhome\u002Fblay\u002FDevelopment\u002FSelene"," expects:",[445,1307,1309],{"className":447,"code":1308,"language":449,"meta":450,"style":450},"{\n  \"name\": \"quests\",\n  \"platform\": \"server\"\n}\n",[379,1310,1311,1315,1326,1335],{"__ignoreMap":450},[454,1312,1313],{"class":456,"line":457},[454,1314,461],{"class":460},[454,1316,1317,1320,1322,1324],{"class":456,"line":464},[454,1318,1319],{"class":467},"  \"name\"",[454,1321,488],{"class":460},[454,1323,492],{"class":491},[454,1325,495],{"class":460},[454,1327,1328,1331,1333],{"class":456,"line":474},[454,1329,1330],{"class":467},"  \"platform\"",[454,1332,488],{"class":460},[454,1334,506],{"class":491},[454,1336,1337],{"class":456,"line":482},[454,1338,560],{"class":460},[375,1340,1341,1342,1344,1345,1347],{},"If you are writing new bundles, follow the ",[379,1343,570],{}," and ",[379,1346,576],{}," format shown in this guide.",[384,1349,1351],{"id":1350},"troubleshooting","Troubleshooting",[392,1353,1354,1362,1367,1375],{},[395,1355,1356,1357,1359,1360],{},"Registry lookup fails in Lua: use the full registry identifier, for example ",[379,1358,605],{},", not just ",[379,1361,611],{},[395,1363,1364,1365],{},"Entry lookup fails: use the full entry identifier such as ",[379,1366,909],{},[395,1368,1369,1371,1372,1374],{},[379,1370,1217],{}," returns nothing: make sure the value is under ",[379,1373,1211],{},", not only at the top level",[395,1376,1377],{},"File changes do not behave as expected: do not mix a merged file and per-entry files for the same registry unless you intend the merged file to override the directory",[1379,1380,1381],"style",{},"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);}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}",{"title":450,"searchDepth":464,"depth":464,"links":1383},[1384,1385,1386,1387,1388,1392,1393,1394,1395,1396,1397],{"id":386,"depth":464,"text":387},{"id":420,"depth":464,"text":421},{"id":593,"depth":464,"text":594},{"id":666,"depth":464,"text":667},{"id":717,"depth":464,"text":718,"children":1389},[1390,1391],{"id":728,"depth":474,"text":729},{"id":917,"depth":474,"text":918},{"id":1087,"depth":464,"text":1088},{"id":1132,"depth":464,"text":1133},{"id":1224,"depth":464,"text":1225},{"id":1255,"depth":464,"text":1256},{"id":1293,"depth":464,"text":1294},{"id":1350,"depth":464,"text":1351},"Define custom bundle-backed registries, populate them from JSON, and query them from Lua.","md",{},{"title":23,"description":1398},"VSyRpBV8eEd-uovhbsvd0DQsaTtpgmhFyljDIuDHrgs",[1404,1406],{"title":19,"path":20,"stem":21,"description":1405,"children":-1},"Structure bundle directories and manifest fields the way Selene expects them.",{"title":27,"path":28,"stem":29,"description":1407,"children":-1},"Define entity registry entries in Selene bundles, attach visuals and scripts, and create entities from Lua.",1792747966450]