-
Notifications
You must be signed in to change notification settings - Fork 3
Writing Maps
In solarus, map scripts define how the environment reacts to player actions given the environment state. These reactions consist most of the time in state change. This state change is then displayed visually to the player.
Given this matter of fact, solarus-online main way to 'synchronise' maps is to provide a network synchronised state and ways to capture changes in this state, react to it and decide further state alterations.
--Template for online map scripts
local map = ...
function map:on_restore_from_state(state)
--Init you local map copy from state here
--Setup callback as you usually do for an offline map
--make sure code only affect state
--given state table is just a shorthand for
--map.state
end
map:watch_state_val(
'key',
function(value,old_value)
--React to change of map.state[key] here
end)
map:watch_state_vals(
'key1', 'key2',
function(val1,val2)
-- React to change of key1 or key2 here
end)
Since online maps inherit the stateful trait, they are blessed with a state
field. This state
is a smart table that will report to the server any modification. This is your main way of communicating and expressing map changes. As every client automatically sees and capture the changes in this table, expressing map events and actions through state guarantee that everyone has the same map under their eyes, by construction.
-- Sample online map script
-- Applying simple rules presented in solarus-online wiki
-- https://github.com/stdgregwar/solarus-online/wiki/Writing-Maps
-- Simple map with two switch 'switch_1' and 'switch_2 and a door 'door'
-- Pressing both switches at the same time open the door
local map = ...
local game = map:get_game()
-- Map actual state just arrived from the server - init local map object from
-- remote state :
function map:on_restore_from_state(state)
map:switch_to_state(switch_1)
map:switch_to_state(switch_2)
-- open doors with prefix 'door' when state key
-- door_open is truthy
map:state_to_door('door_open','door')
end
-- Set state changes watches
-- Watch the two state key we filled with switch states
map:watch_state_vals(
'switch_1','switch_2',
function(sw1,sw2)
if sw1 and sw2 then
map.state.door_open = true
end
end)
------------------------------------------------------------
-- DUPLICATES of metas/map.lua added methods
-- Added here for reference
------------------------------------------------------------
-- Open or close door with prefix prefix
-- given b truthyness
function map_meta:open_close_doors(prefix,b)
if b then
self:open_doors(prefix)
else
self:close_doors(prefix)
end
end
-- Sync a shared state variable with a local switch
-- switch => state[key]
function map_meta:switch_to_state(sw,key)
local map = self
local key = key or sw:get_name()
function sw:on_activated()
map.state[key] = true
end
function sw:on_inactivated()
map.state[key] = nil
end
end
-- Sync a local door with a shared state variable
-- state[key] => door
function map_meta:state_to_door(key,door_prefix)
self:watch_state_val(
key,
function(val)
self:open_close_doors(door_prefix,val)
end
)
end
-----------------------------------------------------------
-- END DUPLICATES
-----------------------------------------------------------