asobi_lua_world (asobi v0.84.0)

View Source

An asobi_world implementation that delegates all callbacks to Lua scripts via Luerl.

The Lua script must define these functions:

function init(config)                        -- return initial game state
function join(player_id, state, ctx)         -- ctx is the client join context
function leave(player_id, state)             -- return updated state
function spawn_position(player_id, state)    -- return {x, y}
function zone_tick(entities, zone_state)     -- return entities, zone_state
function handle_input(player_id, input, entities) -- return entities
function post_tick(tick, state)              -- return state (or state + vote/finished)
-- Optional:
function generate_world(seed, config)        -- return zone_states table
function get_state(player_id, state)         -- return state visible to player
function phases(config)                      -- return list of phase definitions
function on_phase_started(phase_name, state) -- return updated state
function on_phase_ended(phase_name, state)   -- return updated state
function spawn_templates(config)             -- return template registry table
function on_world_recovered(snapshots, state) -- return updated state
function terrain_provider(config)            -- return {module, args} or nil
function on_zone_loaded(cx, cy, state)       -- return zone_state, state
function on_zone_unloaded(cx, cy, state)     -- return state

vote_resolved is deliberately absent. asobi_world_server reaches it through erlang:function_exported/3 and this module does not export it, so a Lua world script defining vote_resolved is never called. Match scripts are unaffected; see guides/voting.md.

After a hot reload (ASOBI_LUA_RELOAD/reload_mode), spawn_templates_hint/1 tells the running zone to re-fetch spawn_templates(config) so an edited script's new templates become spawnable without restarting the zone. The game.zone.spawn guard reads that live set from a per-zone ETS table rather than a value snapshotted once into Ctx, so this stays correct across any number of hot reloads.

Summary

Functions

dump_zone_state/1

-spec dump_zone_state(map()) -> map().

generate_world/2

-spec generate_world(integer(), map()) -> {ok, map()}.

get_state/2

-spec get_state(binary(), map()) -> map().

handle_input(PlayerId, Input, Entities)

-spec handle_input(binary(), map(), map()) -> {ok, map()} | {error, term()}.

init(Config)

-spec init(map()) -> {ok, map()}.

init_zone_state(Config, ZoneState00)

-spec init_zone_state(map(), term()) -> map().

join(PlayerId, State)

-spec join(binary(), map()) -> {ok, map()} | {error, term()}.

join/3

-spec join(binary(), map(), map()) -> {ok, map()} | {error, term()}.

Join carrying the client-supplied join context (asobi's optional join/3).

Passed to the Lua join as a third argument: function join(player_id, state) keeps working (Lua discards extra arguments) and function join(player_id, state, ctx) receives it.

leave/2

-spec leave(binary(), map()) -> {ok, map()}.

on_phase_ended/2

-spec on_phase_ended(binary(), map()) -> {ok, map()}.

on_phase_started/2

-spec on_phase_started(binary(), map()) -> {ok, map()}.

on_world_recovered/2

-spec on_world_recovered(map(), map()) -> {ok, map()}.

on_zone_loaded/2

-spec on_zone_loaded({integer(), integer()}, map()) -> {ok, map(), map()}.

on_zone_unloaded/2

-spec on_zone_unloaded({integer(), integer()}, map()) -> {ok, map()}.

phases/1

-spec phases(map()) -> [map()].

post_tick(TickN, State0)

-spec post_tick(non_neg_integer(), map()) ->
                   {ok, map()} | {vote, map(), map()} | {finished, map(), map()}.

spawn_position/2

-spec spawn_position(binary(), map()) -> {ok, {number(), number()}}.

spawn_templates/1

-spec spawn_templates(map()) -> #{binary() => asobi_zone_spawner:spawn_template()}.

spawn_templates_hint/1

-spec spawn_templates_hint(map()) ->
                              unchanged | {changed, #{binary() => asobi_zone_spawner:spawn_template()}}.

terrain_provider/1

-spec terrain_provider(map()) -> {module(), map()} | none.

zone_tick/2

-spec zone_tick(map(), term()) -> {map(), term()}.