Басқа модтармен жұмыс
Модтар бір-бірінің үстіне құрыла алады, тіпті әр түрлі тілдер арасында. Үш құрал, бәрі API 0.2-ден:
| Құрал | Не үшін | Мысал |
|---|---|---|
| Сервистер | басқа модтың функцияларын шақырып, жауап алу | landclaim economy модынан монета алады |
| Өз оқиғалар | бірдеңе болғанын жариялау; басқалар жауап беруі немесе бас тартуы мүмкін | economy:balance-changed |
| Арналар | модтар арасында шикі хабар жіберу (кейін клиенттерге де) | тікелей жаңартулар |
Мәндер қарапайым Lua мәндері ретінде өтеді (ішінде CBOR); ойыншылар ойыншы күйінде қалады. Шақырулар синхронды және негізгі ағында жұмыс істейді.
Сервистер
Провайдер сервисті mod.toml ішінде жариялап, функцияларын тіркейді:
# economy/mod.toml
[provides]
services = [{ name = "economy", version = "1.0.0", wit = "wit/economy.wit" }]bh.services.provide("economy", "1.0.0", {
balance = function(p) return balances[p:id()] or 100 end,
withdraw = function(p, n) ... end,
})Тұтынушы провайдерге тәуелді болып, оны шақырады:
# landclaim/mod.toml
[dependencies]
economy = "^1"local eco = bh.services.get("economy", "^1")
if not eco.withdraw(p, 50) then
return "A plot costs 50 coins."
end- Тек тәуелді болатын немесе жұмсақ тәуелді болатын (
[soft-dependencies], бар болса қолданылады) модтарды ғана шақыра аласыз. - Сәйкес келетін ең жоғары нұсқа жеңеді.
- Провайдердің
error("msg", 0)шақырушығаpcallарқылы ұстауға болатын қате болып жетеді. - Қазір жұмыс істеп тұрған модқа кері шақыру (A → B → A)
reentrantқатесімен аяқталады. wit/файлы сервистің функцияларын басқа авторларға құжаттайды.
Желі арқылы (клиент және сервер)
API 0.3.1. Клиент моды сервер модының сервисін, ал сервер моды ойыншының клиент модының сервисін қалыпты ойын байланысы арқылы шақыра алады. Желілік шақырулар асинхронды: сіз кері шақыру (callback) бересіз, ол кейін орындалады, шақырудың ішінде ешқашан емес.
# shop/mod.toml (the provider: a server mod)
api = "^0.3.1"
[provides]
services = [{ name = "shop", version = "1.0.0", wit = "wit/shop.wit", remote = true, remote-methods = ["price"] }]-- provider (server)
bh.services.provide("shop", "1.0.0", {
price = function(item)
local who = bh.services.caller() -- { mod = "shop-ui", player = <player> }
return prices[item]
end,
})
-- caller (client mod, permission `channels`)
local id = bh.services.call_remote("server", "shop", "^1", "price", { "apple" }, function(ok, v)
if ok then bh.ui.toast("apple: " .. tostring(v)) else print(v.kind .. ": " .. v.message) end
end, 3000)
bh.services.cancel_remote(id) -- the callback never runs- Провайдер нені шақыруға болатынын шешеді:
[provides]ішіндеremote = true(онсыз сервисті тек сол жақтағы модтар шақыра алады) және қаласаңыз, тек кейбір әдістерге рұқсат беретінremote-methods. - Шақырушы
api = "^0.3.1"деп жазады және оғанchannelsрұқсаты керек. - Жауап дәл бір рет
(true, мән)немесе(false, { kind, message })болады.kindмысалы:not-found,not-permitted,busy(жиілік шегі),provider-error,timeout,unavailable(модталған сервер жоқ немесе ойыншыда мод жүктегіші жоқ) немесеdisconnected. - Провайдердің ішінде
bh.services.caller()қай мод шақырғанын, ал клиент шақырса қай ойыншы екенін айтады. - Шектеулер: күту уақыты әдепкіде 5 с, ең көбі 30 с; мод үшін 16 ашық шақыру; аргументтер мен нәтиже үшін 32 КиБ; ойыншыға секундына 10 шақыру (20-ға дейін жылдам). Провайдер өз уақыт бюджетімен жұмыс істейді, ал құлауы провайдердің қатесі саналады: аргументтерді тексеріңіз, шақырушыға ешқашан сенбеңіз.
- Rust модтары
services::call_remote, Java модтарыapi.callRemote(...)қолданады; барлық тілдерде жауап<mod-id>:service-resultөз оқиғасы ретінде келеді. Luau API және мысал модтарprices-lua,prices-rust.
Өз оқиғалар
-- economy жібереді:
bh.events.fire_custom("economy:balance-changed", { player = p, balance = n })
-- кез келген мод әдеттегі басымдық және бас тарту ережелерімен тыңдайды:
bh.events.on_custom("economy:balance-changed", function(ev)
ev.payload.player:send_chat("You now have " .. ev.payload.balance .. " coins.")
end)Мод тек өз id-імен аталған оқиғаларды (<id>:<name>) жібере алады. fire_custom оқиғаның бас тартылғанын қайтарады.
Арналар
local ch = bh.channels.open("my-mod:updates", function(origin, data) ... end)
bh.channels.send(ch, "local", "hello")channels рұқсаты керек. "local" дәл сол атауды ашқан әрбір басқа модқа келесі тикте жетеді. Ойыншыларға, "all-players" немесе "server" жіберу үшін мод жүктегіші бар клиент моды керек.
Мысалдар
Бәрі SDK-да, бірге іске қосуға дайын:
economy: монеталар,/balance,/pay;economyсервисін ұсынады жәнеeconomy:balance-changedжібереді.landclaim: монеталарға/claimтелімдері; басқалардың жеріндеblock-place/block-breakбас тартады;permsмодына жұмсақ тәуелді.perms:permissionsсервисі ретінде рұқсат түйіндері.shop-rust: Lua economy арқылы төлейтін Rust моды (WASM модтары сервердің әзірлеу құрастырмаларында жұмыс істейді).
Анықтама: services, events, channels. Мән ережелері: Luau API сәйкестігі.