"Works nicely": Uher...there's no programmatic definition of "nice", so i'll skip checking that.
"Registered on first tick": I'll have to look into the timing of remote interface. Should work.
"Should not change during game": Trivial. Just write lock.
"Disable normal gen in data": Trivial. Just provide a function.
"Modification to existing": Easy. Provide a method to give a mod an existing table and get back a new one.
If you have any actual interest in this i'm sure we can figure something out (and i can benefit from it in the future ;).
If you've already given up on it internally...please tell so i don't have to waste effort :p.
So...i wrote a very small sample verifier. The main question is: What do you think about the "specification" part? Is it easy enough for you to fill in the missing values (for now all number ranges are 0 to 10000)? Do you feel comfortable writing a complete specification if i write the verification function?
Code: Select all
local specification = {
  type = {
    type = 'string',
    optional = false,
    allowed_values = {['resource-liquid']=true,['resource-ore']=true},
    },
  --
  allotment = {
    type = 'integer',
    optional = false,
    min_value = 0,
    max_value = 10000,
    },
  --
  spawns_per_region = {
    type = 'table',
    optional = false,
    values = {
      min = {
        type = 'integer',
        min_value = 0,
        max_value = 10000,
        optional = false,
        },
      max = {
        type = 'integer',
        min_value = 0,
        max_value = 10000,
        compare = {min = 'greater_or_equal'},
        },
      }
    },
  --
  richness = {
    type = 'integer',
    optional = false,
    min_value = 0,
    max_value = 10000,
    },
  --
  size = {
    type = 'table',
    optional = false,
    values = {
      min = {
        type = 'integer',
        optional = false,
        min_value = 0,
        max_value = 10000,
        },
      max = {
        type = 'integer',
        optional = false,
        min_value = 0,
        max_value = 10000,
        compare = {min = 'greater_or_equal'},
        },
      }
    },
  --
  min_amount = {
    type = 'integer',
    optional = false,
    min_value = 0,
    max_value = 10000,
    },
  --
  size = {
    type = 'table',
    values = {
      min = {
        type = 'integer',
        optional = false,
        min_value = 0,
        max_value = 10000,
        },
      max = {
        type = 'integer',
        optional = false,
        min_value = 0,
        max_value = 10000,
        compare = {min = 'greater_or_equal'},
        },
      }
    },
  --
  starting = {
    type = 'table',
    values = {
      richness = {
        type = 'integer',
        optional = false,
        min_value = 0,
        max_value = 10000,
        },
      size = {
        type = 'integer',
        optional = false,
        min_value = 0,
        max_value = 10000,
        },
      probability = {
        type = 'decimal',
        optional = false,
        min_value = 0,
        max_value = 1,
        },
      }
    },
  }
  
--[[
local spec_spec = { --change with great care! this specifies the specification format.
  string = {
    allowed_values = {'table','string'},
    optional = 'boolean',
    },
  integer = {
    min_value = 'number',
    max_value = 'number',
    },
  }
  ]]
local err(name,key,message)
  error(
    'Error occured during RSO config import:\n'..
    'Problematic node: '..name..
    'Problematic key: '..key..
    'Problem: '..message)    
  end
  
local function validate_config(config)
  for name,node in pairs(config) do
    for key,spec in pairs(specification) do
      --config entry is not a table (completely broken)
      if type(node) ~= 'table' then
        error('This is not a table: '..serpent.line(node))
        end
      local value = node[key]
      --optional key is missing
      if not (spec.optional or value) then
        err(name,key,'Mandatory key is missing')
        end
      --checking strings
      if spec.type == 'string' then
        if type(value) ~= 'string' then
          err('Value must be a string')
          end
        if not spec.allowed_values[value] then
          err(name,key,'Value must be one of :'..serpent.line(spec.allowed_values))
          end
        end
      --checking integer
      if spec.type == 'integer' then
        if not (
          (type(value) == 'number')) and
          (tonumber(value) == math.floor(tonumber(value)))
          ) then
          err(name,key,'Value must be an integer')
          end
        if (value < spec.min_value) or (value > spec.max_value) then
          err(name,key,'Value is out of range: '..spec.min_value..' to '..spec.max_value)
          end
       --check table
       --TODO
          
      end
    end





