Skip to content
This repository was archived by the owner on Aug 16, 2018. It is now read-only.

Writing Maps

std::gregwar edited this page Feb 3, 2018 · 3 revisions

Abstract

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.

Online map script 101

--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)

map.state

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.

Example

-- 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
-----------------------------------------------------------
Clone this wiki locally