merged changes, using standardized lazy table length function instead of for loop in interactions module
This commit is contained in:
37
README.md
37
README.md
@@ -1,26 +1,12 @@
|
|||||||
# Modpol for Minetest
|
# Modpol for Minetest
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
Modpol, short for "modular politics," enables diverse governance processes on multi-user platforms. It offers a library with which users can choose, modify, and create modules that add specific governance functionalities.
|
Modpol, short for "modular politics," enables diverse governance processes on multi-user platforms. It offers a library with which users can choose, modify, and create modules that add specific governance functionalities.
|
||||||
|
|
||||||
This implementation is a mod for [Minetest](https://minetest.net), a free/open-source voxel game. It is designed to be adapted to other multi-user platforms that also employ Lua as an extension language.
|
This implementation is a mod for [Minetest](https://minetest.net), a free/open-source voxel game. It is designed to be adapted to other multi-user platforms that also employ Lua as an extension language.
|
||||||
|
|
||||||
## How to use it
|
**Learn more at [modpol.net](https://modpol.net).**
|
||||||
|
|
||||||
Modpol is built around groups called *orgs*. At the base is an org with all users in it, called `Root` by default. *Modules* enable people to do things within orgs, such as decide on membership, grant powers to the org, and much more. To get started in Minetest:
|
|
||||||
|
|
||||||
* Type the command `/mp`
|
|
||||||
* Select the org `Root`
|
|
||||||
* Choose one of its modules to make new orgs and craft their behavior
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Modules can be nested in each other, so one module can rely on another module to accomplish a process. Users might use a module to unilaterally carry out actions in the game, or the module might require a group decision to do so. Users can also change the modules available to users of a given org. There are currently two ways of doing this:
|
|
||||||
|
|
||||||
* Admins can remove modules from the list of modules loaded in `modpol_core/api.lua` and `modpol_minetest/api.lua`. This will make those modules no longer available to any user.
|
|
||||||
* Players can change the modules available in a given org from within the program using the `Change modules` module. Removed modules can be re-added in any org by using `Change modules` again.
|
|
||||||
|
|
||||||
Modpol should give you the ability to do whatever kind of politics you want with your modules. If there is something you would like to do that is not available, [develop a module for it](https://gitlab.com/medlabboulder/modpol/-/wikis/Module-Writing-Guide) (or ask us for help!).
|
|
||||||
|
|
||||||
|
|
||||||
## Installation in Minetest
|
## Installation in Minetest
|
||||||
|
|
||||||
@@ -55,23 +41,6 @@ In the interpreter, for a list of global functions and tables, use `modpol.menu(
|
|||||||
The persistent storage method may be chosen in `modpol.lua`. If available, Modpol uses Minetest's built-in StorageRef system for Minetest 5.*. If that is not available, or in CLI mode, data will be stored in a data directory at `modpol_core/data/`. This will contain a log file and serialized program data files.
|
The persistent storage method may be chosen in `modpol.lua`. If available, Modpol uses Minetest's built-in StorageRef system for Minetest 5.*. If that is not available, or in CLI mode, data will be stored in a data directory at `modpol_core/data/`. This will contain a log file and serialized program data files.
|
||||||
|
|
||||||
|
|
||||||
## Design philosophy
|
|
||||||
|
|
||||||
Modpol seeks to implement a theoretical framework called "[modular politics](https://metagov.org/modpol)," which proposes these design goals:
|
|
||||||
|
|
||||||
* *Modularity*: Platform operators and community members should have the ability to construct systems by creating, importing, and arranging composable parts together as a coherent whole.
|
|
||||||
* *Expressiveness*: The governance layer should be able to implement as wide a range of processes as possible.
|
|
||||||
* *Portability*: Governance tools developed for one platform should be portable to another platform for reuse and adaptation.
|
|
||||||
* *Interoperability*: Governance systems operating on different platforms and protocols should have the ability to interact with each other, sharing data and influencing each other's processes.
|
|
||||||
|
|
||||||
Additionally, Modpol seeks to counteract the tendency for "[implicit feudalism](https://ntnsndr.in/ImplicitFeudalism)," according to which rigid, top-down power structures are the norm in online spaces. To this end, some design patterns include:
|
|
||||||
|
|
||||||
* *Groups, not roles*: While most platforms assign powers through particular permissions given to individuals, in Modpol, power lies in groups (which Modpol calls "orgs").
|
|
||||||
* *Consent, not oligarchy*: Rather than assuming that decisions will be made by a few power-holders, the software assumes that consent by all affected users is the norm.
|
|
||||||
* *Inheritance, not blank slates*: When a new group is formed, it inherits the patterns of what preceded it, rather than imagining that it is starting from scratch.
|
|
||||||
|
|
||||||
It is certainly possible to use Modpol to replicate practices of implicit feudalism, such as all-powerful admins, but doing so requires extra work to overcome these defaults.
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Various guides are available at the [GitLab wiki](https://gitlab.com/medlabboulder/modpol/-/wikis/home).
|
Various guides are available at the [GitLab wiki](https://gitlab.com/medlabboulder/modpol/-/wikis/home).
|
||||||
|
BIN
lib/empire-modpol.png
Normal file
BIN
lib/empire-modpol.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 588 KiB |
@@ -224,19 +224,16 @@ function modpol.interactions.org_dashboard(user, org_string)
|
|||||||
modpol.interactions.org_dashboard(user, org.id)
|
modpol.interactions.org_dashboard(user, org.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif sel == 'p' or sel == 'P' then
|
elseif sel == 'p' or sel == 'P' then -- Pending processes
|
||||||
local processes = {}
|
|
||||||
print("All processes: (* indicates pending)")
|
print("All processes: (* indicates pending)")
|
||||||
for i,v in ipairs(org.processes) do
|
for i,v in ipairs(processes) do
|
||||||
if v ~= "deleted" then
|
local active = ''
|
||||||
local active = ''
|
if org.pending[user] then
|
||||||
if org.pending[user] then
|
if org.pending[user][v.id] then
|
||||||
if org.pending[user][v.id] then
|
active = '*'
|
||||||
active = '*'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
print("["..v.id.."] "..v.slug..active)
|
|
||||||
end
|
end
|
||||||
|
print("["..v.id.."] "..v.slug..active)
|
||||||
end
|
end
|
||||||
print()
|
print()
|
||||||
print("Interact with which one (use [id] number)?")
|
print("Interact with which one (use [id] number)?")
|
||||||
|
@@ -32,7 +32,8 @@ function defer:initiate(result)
|
|||||||
self.org:delete_process(self.id)
|
self.org:delete_process(self.id)
|
||||||
else
|
else
|
||||||
defer_org:call_module(
|
defer_org:call_module(
|
||||||
self.config.approval_module, self.initiator,
|
self.config.approval_module,
|
||||||
|
self.initiator,
|
||||||
{
|
{
|
||||||
prompt = self.config.prompt
|
prompt = self.config.prompt
|
||||||
},
|
},
|
||||||
@@ -40,6 +41,8 @@ function defer:initiate(result)
|
|||||||
if result then result() end
|
if result then result() end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
modpol.interactions.org_dashboard(
|
||||||
|
self.initiator, self.org.id)
|
||||||
if result then result() end
|
if result then result() end
|
||||||
self.org:delete_process(self.id)
|
self.org:delete_process(self.id)
|
||||||
end
|
end
|
||||||
|
@@ -19,7 +19,7 @@ display_processes.config = {
|
|||||||
-- @param result Callback if this module is embedded in other modules
|
-- @param result Callback if this module is embedded in other modules
|
||||||
function display_processes:initiate(result)
|
function display_processes:initiate(result)
|
||||||
local display_table = {}
|
local display_table = {}
|
||||||
for k,v in pairs(self.org.processes) do
|
for k,v in ipairs(self.org.processes) do
|
||||||
if v ~= "deleted" then
|
if v ~= "deleted" then
|
||||||
local input = v.id..": "..v.slug
|
local input = v.id..": "..v.slug
|
||||||
table.insert(display_table, input)
|
table.insert(display_table, input)
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
local remove_process = {
|
local remove_process = {
|
||||||
name = "Remove process",
|
name = "Remove process",
|
||||||
slug = "remove_process",
|
slug = "remove_process",
|
||||||
desc = "User can remove own processes, consent required for those of others",
|
desc = "User can remove own processes, approval required for those of others",
|
||||||
hide = false;
|
hide = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@ remove_process.data = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remove_process.config = {
|
remove_process.config = {
|
||||||
|
approval_module = "consent"
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Initiate function
|
--- Initiate function
|
||||||
@@ -71,11 +72,12 @@ function remove_process:initiate(result)
|
|||||||
self.org:delete_process(self.id)
|
self.org:delete_process(self.id)
|
||||||
else
|
else
|
||||||
self:call_module(
|
self:call_module(
|
||||||
"consent",
|
self.config.approval_module,
|
||||||
self.initiator,
|
self.initiator,
|
||||||
{
|
{
|
||||||
prompt = "Approve removal of process "..process_choice.."?",
|
prompt =
|
||||||
votes_required = #self.org.members
|
"Approve removal of process "
|
||||||
|
..process_choice.."?"
|
||||||
},
|
},
|
||||||
function(input)
|
function(input)
|
||||||
modpol.interactions.message_org(
|
modpol.interactions.message_org(
|
||||||
|
Reference in New Issue
Block a user