Jobs & elections
Government
Employment, departments, salaries, exams, elections, public offices, and the rules that shape civic life.
01
What it handles
Employment categories
Configurable white-collar, blue-collar, restricted, and exempt roles with enforced category limits.
Offers & management
Expiring job offers, hiring, promotion, demotion, dismissal, rank scope, and complete management history.
Duty status
Players can enter or leave active duty for employed government tracks without losing their underlying job.
Salaries
Rank and individual salary policies with metadata ready for scheduled Economy payroll integration.
Job exams
Sign-bound multiple-choice exams with pass scores, cooldowns, job awards, and configurable completion commands.
Election methods
FPTP, approval, two-round, IRV, STV, and referendum voting with recountable round records.
Office lifecycle
Declarations, terms, vacancies, succession, recalls, quorum rules, and automated LuckPerms certification.
Ballot privacy
Secret UUID-unique ballots, anonymous staff review, and separately restricted formal audit correlation.
02
Detailed guide
Government is a Paper 1.21.11 plugin for Java 21 that provides LuckPerms-backed jobs, supervised government departments, configurable entrance exams, salary policy, terms of office, and secret-ballot elections. LuckPerms is the authority for every current job and rank. SQLite stores workflow and historical data without duplicating current membership.
Highlights
- One ordinary job in each configured category (
white_collar,blue_collar, and the combined government/criminalrestrictedcategory) - Configured exempt appointments, such as city council, which do not consume a category slot
- Employment offers with expiration; acceptance rechecks and atomically replaces the prior non-exempt job in that category
- Track-scoped management requiring both
government.manage.track.<track>and a configured rank scope - Promotion, demotion, dismissal, employee lists, individual and rank salary policy, and complete audit history
- Sign-bound multiple-choice exams with configurable answers, pass scores, cooldowns, job awards, and pass commands
/quitjob <job>and/about; players may select the job used for their display prefix- Lectern polling stations and player-head ballot GUIs
- FPTP, approval, two-round, IRV, fractional-transfer STV using the Droop quota, and referendum voting
- Declaration stages with permission and active-playtime requirements
- Secret, UUID-unique, optionally revisable ballots; election staff see anonymous ballots and administrators can perform restricted correlations
- Quorum, referendum approval thresholds, deterministic tie resolution, recountable round records, terms, vacancies, succession, recall petitions, recall referenda, and automatic LuckPerms certification
- SQLite WAL, prepared statements, foreign keys, startup integrity checks, backups, and serialized database work
- PlaceholderAPI and a Bukkit services API for chat/economy integrations
Install
- Run Paper 1.21.11 on Java 21.
- Install LuckPerms. It is required.
- Optionally install PlaceholderAPI if Carbon or another chat plugin should display the player-selected job.
- Copy the current
build/libs/MCSkylines-Government-*.jarto the server'spluginsfolder. - Start and stop the server once, then configure
plugins/Government/. - Create every group named in
jobs.ymlandelections.ymlin LuckPerms. - Grant only the dynamic track, salary, election, and station permissions that each role needs.
Configuration
config.yml— storage, offers, job limits, prefix behavior, salary schedule metadata, election scheduling, recall timing, and security limitsjobs.yml— categories, tracks, rank order, management scopes, LuckPerms groups, salaries, prefixes, exemptions, and examselections.yml— offices, groups, seat counts, methods, terms, candidacy requirements, voting permissions, succession, and referendum defaultsguis.yml— reserved GUI presentation settingsmessages.yml— MiniMessage user-facing textdata.db— offers, salary overrides, display selections, exams, stations, elections, candidates, ballots, terms, recalls, vacancies, and audits
Configuration reload is all-or-nothing. A database path change requires a restart. Keys must be lowercase-safe identifiers; durations support s, m, h, d, w, mo, and y, including compounds such as 1d12h.
Job rules
Each job maps to one LuckPerms group. A player may hold one non-exempt job per configured category. Assigning a new non-exempt job removes only configured, non-exempt groups in the same category. Unrelated LuckPerms groups and nodes are never touched.
limit-exempt: true makes a configured appointment not count against its category. The inherited permission government.jobs.limit-exempt provides a personal bypass when a server needs a broader exception.
Management requires:
government.manage.track.<target-track>(orgovernment.admin), and- at least one current job whose configured management scope contains the target rank.
This permits a mayor rank to manage a police commissioner while preventing the mayor from directly managing ordinary police ranks unless the configuration explicitly allows it.
Exams and stations
Define an exam under exams in jobs.yml, look at a sign, and run:
/government station exam <exam>Right-clicking that sign opens the exam. Correct-answer indexes are zero-based. Passing assigns pass-job and may execute the configured console commands after replacing <player> and <uuid>.
Look at a lectern and run:
/government station pollRight-clicking that lectern lists open elections. Ordinary voters do not receive a remote voting command.
Election workflow
/government election create <key> <office> <method> <declarations-in> <opens-in> <duration> <seats> [revisions]
/government election declare <key> [statement]
/government election candidate add <key> <player> [statement]
/government election close <key>
/government election count <key>
/government election certify <key>Two-round elections that lack a first-round majority report two finalists. Create their second round with:
/government election runoff <original> <new-key> <opens-in> <duration>Referenda use:
/government election referendum <key> <opens-in> <duration> <quorum%> <approval%> <revisions> <question>Certification grants winner groups, removes outgoing certified officeholders, creates terms, and enforces normal job-category replacement for non-exempt office groups. A failed quorum is not certifiable. A tied referendum resolves to the status-quo NO result.
Recall petitions are created with /government election recall <term-id> <required-signatures> <duration> <reason> and signed with /government election recall-sign <recall-id>. Reaching the configured threshold schedules a secret recall referendum; certification of YES vacates the term and applies succession.
Ballot privacy
The current voter ledger and ballot payloads are separate tables. Election staff may use /government election ballots <key> and /government election count <key> to inspect anonymous ballots and aggregates. Only government.election.audit may correlate a random ballot UUID with its voter through /government election audit-ballot <key> <ballot-uuid>. Replaced ballot revisions remain in the administrator audit mapping but are marked superseded and never counted.
As with any server-side voting system, a person with direct filesystem/database access is ultimately trusted.
Chat prefix selection
Players use /about display <job> or click one of their own jobs in /about. With PlaceholderAPI installed, Carbon can use:
%government_job_prefix%%player_name%: %message%Available values are job, job_key, job_prefix, job_category, job_track, and job_rank. LUCKPERMS_PERSONAL prefix mode is also available but should be used only when the existing LuckPerms meta stack is understood; the plugin removes only exact configured prefixes at its configured priority.
Economy integration
When Economy is installed and salary payments are enabled, payroll runs once per configured real-world day. Salary calculation follows: individual override, then database rank override, then the configured job salary. Each job may map to a treasury or department account. Economy enforces the prior-24-hour attendance threshold, tax/debt withholding, idempotency, and arrears. Without an economy adapter, Government continues operating but does not pay salaries. Other plugins can obtain GovernmentApi from Bukkit's services manager.
Build
..\gradlew.bat -p . clean test jarSee docs/PERMISSIONS.md and SECURITY.md before granting management or election powers.
Launch a job department
- Define the category, track, rank order, LuckPerms group, salary, prefix, and management scopes in
jobs.yml. - Create every referenced LuckPerms group before assigning players. Government treats LuckPerms as current membership authority and does not mirror membership into SQLite.
- Grant managers both the dynamic
government.manage.track.<track>node and a job whose configured scope reaches the target rank. Permission alone is not enough unlessgovernment.adminis used. - Test an offer from creation through acceptance and expiry. Acceptance rechecks the player's current groups and replaces only configured, non-exempt jobs in the same category.
- Map salary funding to the correct treasury or department account and verify the Economy attendance requirement and budget before relying on payroll.
Use exemptions for appointments that should coexist with an ordinary category job. A personal government.jobs.limit-exempt permission is broader than a configured exempt job and should be reserved for deliberate exceptions.
Build and test an entrance exam
Define the exam questions, zero-based correct answers, pass score, cooldown, awarded job, and optional completion commands in jobs.yml. Look at the sign that should become the station and run /government station exam <exam>. Players right-click that bound sign to begin; passing applies the configured job and then executes approved console commands with player placeholders.
Test every answer index, the exact pass boundary, cooldown behavior, a player whose current category job must be replaced, and a player who no longer qualifies at completion time.
Run an election from declaration to certification
- Define the office in
elections.yml, including its LuckPerms group, seats, voting permission, method, term, candidacy requirements, succession, and referendum defaults. - Register at least one lectern poll station with
/government station poll. Ordinary voters vote through a station, not a remote command. - Create the election with its declaration, opening, duration, seat, and ballot-revision settings.
- Let candidates declare or have staff add them. Eligibility and configured active-play requirements are checked.
- Open a poll station as multiple eligible test voters. Confirm one UUID-unique ballot per voter and, when enabled, that a revision supersedes rather than double-counts the prior ballot.
- Close and count the election. Inspect anonymous ballot output and recorded rounds before certification.
- Certify only after quorum and result checks. Certification changes office groups, creates terms, removes outgoing certified holders, and applies normal category replacement rules.
For two-round voting, create the runoff from the reported finalists. For IRV and STV, retain the round records so recounts are explainable. A referendum tied exactly at the threshold resolves to the status quo NO. A failed-quorum election cannot be certified.
Recalls, vacancies, and succession
Create a recall against an active term, collect the configured number of unique signatures before expiry, and allow Government to schedule the secret recall referendum. Certifying YES vacates the term and applies the office's configured succession. Test ordinary term expiry and manual vacancy handling on staging as well; election groups should never be managed by ad-hoc LuckPerms commands during an active certification workflow.
Privacy and audit boundaries
Election staff can inspect anonymous ballots and aggregates. Only government.election.audit can correlate a random ballot UUID with a voter, including superseded revisions. Limit that permission to the smallest trusted group. Direct database/filesystem administrators remain part of the system's trust boundary.
Government testing checklist
- Offer, accept, replace, promote, demote, dismiss, and voluntarily quit representative jobs in every category.
- Verify exempt appointments and manager rank scopes.
- Pass and fail each configured entrance exam.
- Test FPTP, approval, runoff, IRV, STV, and referendum counts with ties and failed quorum.
- Test ballot revision, anonymous inspection, restricted audit correlation, certification, term expiry, succession, and recall.
- Verify display-job selection and PlaceholderAPI output for players with multiple jobs.
- Fund and underfund payroll accounts and confirm eligible, ineligible, and arrears outcomes.
03
Commands
| Command | Usage | Description | Permission |
|---|---|---|---|
/government | /government <help|reload|status|hire|offers|employees|salary|election|station> | Government, job, and election management. | Subcommand-based |
/quitjob | /quitjob <job> | Leave one of your jobs. | Subcommand-based |
/about | /about [player|display <job>] | View a player's jobs or select your displayed job. | Subcommand-based |
/duty | /duty [track] | Enter or leave duty for an employed government track. | Subcommand-based |
04
Permissions
| Node | Default | Description / children |
|---|---|---|
government.admin | Full Government access. Operators receive this parent automatically.Includes government.reload, government.status, government.manage.*, government.salary.set.rank, government.salary.set.player, government.electioneer, government.election.audit, government.station.manage, government.job.direct, government.jobs.limit-exempt, government.about.others, government.job.quit, government.vote, government.declare | |
government.reload | No additional description. | |
government.status | No additional description. | |
government.manage.* | Manage all configured tracks. Individual nodes are government.manage.track.<track>. | |
government.salary.set.rank | No additional description. | |
government.salary.set.player | No additional description. | |
government.electioneer | No additional description. | |
government.election.audit | Correlate voters with ballots for formal audits. | |
government.station.manage | No additional description. | |
government.job.direct | No additional description. | |
government.jobs.limit-exempt | Personal bypass for job category limits; configured exempt jobs do not need this. | |
government.about.others | No additional description. | |
government.job.quit | No additional description. | |
government.vote | No additional description. | |
government.declare | No additional description. |
Command and permission references reflect the current plugin.yml manifests in this workspace.