Skip to content

FreeCiv: support runs with different numbers of players - #14

Merged
elsehow merged 6 commits into
forecastingresearch:mainfrom
fdrocha:freeciv-nplayers
Oct 27, 2026
Merged

elsehow merged 6 commits into
forecastingresearch:mainfrom
fdrocha:freeciv-nplayers

Conversation

@fdrocha

@fdrocha fdrocha commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Adapt FreeCiv pipeline to run worlds with a different number of civilizations than the previous N=5. In particular, add support for one player runs, disabling some of the questions and contents of world report. Also support running without barbarians since one they are one they can effectively add new civilizations in some circumstances.

With default settings and arguments, the five-player paper behavior is unchanged.

Details from Claude:

Commits

  1. Barbarians setting: run_world.py --barbarians (e.g. DISABLED) sends /set barbarians at game setup. It is stored in the savegame, so forks inherit it.
  2. Draw for fewer than five civs: consolidate_v4.py --n-main. bank_v1.py and sweep_v4.py skip families that need other civs (W5_tech_lead, W1_wonder_race, civ_score_leader, P6_world_techs with one civ) and cap S3 k at the number of pairs. criteria_v1.py takes civ and pair counts from the world, and --no-barbarians drops the barbarian clauses. draw_v1.py adds --binary-only and --no-natcond.
  3. Reports: map_interval 0 and barbarian line: generate_txt_report no longer crashes at map_interval 0. The report header's barbarian line follows the savegame setting.
  4. Reports: DIPLOMACY section: rebuilds the DIPLOMACY (TURN N) table from the paper's v3 reports, whose generator was never committed. On the eight paper anchors it is byte-identical to the published section, and regen_reports.py now inserts BORDERS again. It is left out with fewer than two civs. Every generate_txt_report caller gets it, the legacy CivBench scripts included.
  5. Fleet: anchor_one.sh takes FBSIM_N_PLAYERS / FBSIM_BARBARIANS and publishes settings.txt, ruleset.json, turn states and sgtables. The old run's hard-coded pod IDs are replaced by state/archive_pods.txt. Pre-existing path bugs are fixed: sg_tables.py was not shipped to pods, and rp_list.py / make_queue.py were looked up in the wrong directory. regen_reports.py reads the player count from settings.txt. worlds/freeciv now requires Python ≥ 3.11.4, for tarfile's extraction filter.
  6. Run: FBSIM_FREECIV_N_CIVS (1–5) sets the civilization sentence in the elicitation prompts, and FBSIM_FREECIV_V3_DRAW names the draw folder.

Testing

  • Local smoke test (Docker, amd64 emulation): a 1-player and a 2-player anchor with barbarians DISABLED, each replayed 20 times T60→T210. The T60 saves carry "barbarians","DISABLED". All 40 replays published, with no truncations or gate failures.
  • consolidate_v4 --n-main → bank_v1 → draw_v1 (--binary-only and --no-natcond) → criteria_v1 → regen_reports run end to end on both smoke corpora. The later refactors (draw_v1 write helper, number words) were checked to produce identical sets and criteria.
  • regen_reports.py output is byte-identical with and without settings.txt on the smoke anchors. Elicitation prefixes are unchanged by default.
  • The fleet scripts were only checked with bash -n. They have not run on RunPod since these edits.

fdrocha and others added 6 commits October 27, 2026 10:30
run_world.py --barbarians (e.g. DISABLED) sends /set barbarians at game setup.
The setting is stored in the savegame, so forks inherit it. Empty (the default)
leaves the server default, so existing runs are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- consolidate_v4.py --n-main: number of main players (was fixed at 5)
- bank_v1.py: no W5_tech_lead, W1_wonder_race, civ_score_leader or
  P6_world_techs with one civ; S3 k capped at the number of pairs; civ count
  in the P6 text; minimum counts a tenth of the replays (100 at 1,000, as
  before); --horizons and --binary-only (skip continuous and reveals)
- sweep_v4.py: the same one-civ guard and P6 wording
- draw_v1.py: --binary-only writes bank, tails and mirrors; --no-natcond
  adds continuous but skips natcond
- criteria_v1.py: civ and pair counts from the world instead of five/ten;
  --no-barbarians drops the barbarian clauses of the capture and loss rules;
  skips set files a partial draw does not write

Defaults reproduce the five-player behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4TyWfLhxtj3vrQ8sXgs
…from the setting

regen_reports.py calls generate_txt_report with map_interval 0, which crashed
on range() with step 0; the renderer now skips the map section instead. The
report header's barbarian line now follows the savegame's barbarians setting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4TyWfLhxtj3vrQ8sXgs
The paper's turn-60 reports have a DIPLOMACY table (state, first contact turn,
embassy per pair) whose generator was never committed. Rebuilt from
diplomacy.relations in the game data: pairs in ID order, 'never' as the first
contact turn of pairs that have not met, Embassy from the lower ID's record of
the pair. On the eight paper anchors (their data json beside the reports) the
section is byte-identical to the published reports. Left out with fewer than
two civilizations. regen_reports.py inserts BORDERS after it, so BORDERS
reappears too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4TyWfLhxtj3vrQ8sXgs
- anchor_one.sh: FBSIM_N_PLAYERS and FBSIM_BARBARIANS; writes settings.txt;
  skips the diplomacy publish gate with one player; publishes ruleset.json,
  the recording's turn states (recording_states.tar.gz) and the sgtables
- make_bundle.sh ships draw/sg_tables.py, which finish_pod.sh and
  anchor_one.sh run on the pod (finish_pod.sh used to fail without it)
- the old run's hard-coded archive pod IDs replaced by
  state/archive_pods.txt; scripts that need it stop when it is missing;
  requeue_slice.sh no longer assumes 32-vCPU workers
- finalize.sh: anchors from FBSIM_ANCHORS or state/anchors/, --n-main from
  FBSIM_N_PLAYERS, ruleset from the pulled anchors
- rp.sh and switch_anchor.sh find rp_list.py and make_queue.py under draw/;
  switch_anchor.sh takes the rng range from FBSIM_RNG
- regen_reports.py: main players from the anchor's settings.txt (5 without
  one); unpacks recording_states.tar.gz when the turn states are missing;
  the ruleset falls back to the anchor's own
- worlds/freeciv requires Python 3.11.4 (tarfile's extraction filter)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4TyWfLhxtj3vrQ8sXgs
FBSIM_FREECIV_N_CIVS (1-5) replaces "Five AI civilizations are competing."
in the elicitation prompts, and stops if a prompt lacks that sentence;
FBSIM_FREECIV_V3_DRAW names the draw folder under sets/ for elicit_v2.py and
score_v2.py. Defaults reproduce the paper's prompts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4TyWfLhxtj3vrQ8sXgs
@fdrocha fdrocha changed the title FreeCiv v3: one- and two-player worlds, barbarians setting FreeCiv: support runs with different numbers of players Oct 27, 2026
@fdrocha
fdrocha marked this pull request as ready for review October 27, 2026 10:43
@elsehow
elsehow merged commit 14fc3df into forecastingresearch:main Oct 27, 2026
2 checks passed
@fdrocha
fdrocha deleted the freeciv-nplayers branch October 27, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants