games/factorio: make more configurable

This makes the server fully configurable, and adds the contents of
example JSON configs as the defaults for all servers.

Change-Id: I8ff3e66a586a9db3acb9721810c8c5aa13072b4b
This commit is contained in:
q3k 2021-06-21 14:05:56 +00:00 committed by q3k
parent f7efc40ea4
commit 0808034e6a
4 changed files with 341 additions and 0 deletions

View file

@ -0,0 +1,81 @@
{
// The following options are defaults taken verbatim from Factorio 1.1.35
// headless' map-gen-settings.example.json, with the following changes:
// - field names unquoted where possible
// - pseudo-comments converted to jsonnet comments
// - comments reflowed to fit 80 columns
// The inverse of 'water scale' in the map generator GUI.
terrain_segmentation: 1,
// The equivalent to 'water coverage' in the map generator GUI. Higher
// coverage means more water in larger oceans.
// Water level = 10 * log2(this value)
water: 1,
// Width and height of map, in tiles; 0 means infinite
width: 0,
height: 0,
// Multiplier for 'biter free zone radius'
starting_area: 1,
peaceful_mode: false,
autoplace_controls: {
"coal": {"frequency": 1, "size": 1, "richness": 1},
"stone": {"frequency": 1, "size": 1, "richness": 1},
"copper-ore": {"frequency": 1, "size": 1,"richness": 1},
"iron-ore": {"frequency": 1, "size": 1, "richness": 1},
"uranium-ore": {"frequency": 1, "size": 1, "richness": 1},
"crude-oil": {"frequency": 1, "size": 1, "richness": 1},
"trees": {"frequency": 1, "size": 1, "richness": 1},
"enemy-base": {"frequency": 1, "size": 1, "richness": 1}
},
cliff_settings:
{
// Name of the cliff prototype
name: "cliff",
// Elevation of first row of cliffs
cliff_elevation_0: 10,
// Elevation difference between successive rows of cliffs.
// This is inversely proportional to 'frequency' in the map generation
// GUI. Specifically, when set from the GUI the value is 40 / frequency.
cliff_elevation_interval: 40,
// Called 'cliff continuity' in the map generator GUI. 0 will result in
// no cliffs, 10 will make all cliff rows completely solid
richness: 1
},
// Overrides for property value generators (map type)
// Leave 'elevation' blank to get 'normal' terrain.
// Use 'elevation': '0_16-elevation' to reproduce terrain from 0.16.
// Use 'elevation': '0_17-island' to get an island.
// Moisture and terrain type are also controlled via this.
property_expression_names:
{
// 'control-setting:moisture:frequency:multiplier' is the inverse of the
// 'moisture scale' in the map generator GUI.
"control-setting:moisture:frequency:multiplier": "1",
// 'control-setting:moisture:bias' is the 'moisture bias' in the map
// generator GUI.
"control-setting:moisture:bias": "0",
// 'control-setting:aux:frequency:multiplier' is the inverse of the
// 'terrain type scale' in the map generator GUI.
"control-setting:aux:frequency:multiplier": "1",
// 'control-setting:aux:bias' is the 'terrain type bias' in the map
// generator GUI
"control-setting:aux:bias": "0"
},
starting_points:
[
{ x: 0, y: 0}
],
// Use null for a random seed, number for a specific seed.
seed: null
}

View file

@ -0,0 +1,126 @@
{
// The following options are defaults taken verbatim from Factorio 1.1.35
// headless' map-settings.example.json, with the following changes:
// - field names unquoted where possible
// - pseudo-comments converted to jsonnet comments
// - comments reflowed to fit 80 columns
difficulty_settings:
{
recipe_difficulty: 0,
technology_difficulty: 0,
technology_price_multiplier: 1,
research_queue_setting: "after-victory"
},
pollution:
{
enabled: true,
// these are values for 60 ticks (1 simulated second)
// amount that is diffused to neighboring chunk
diffusion_ratio: 0.02,
min_to_diffuse: 15,
ageing: 1,
expected_max_per_chunk: 150,
min_to_show_per_chunk: 50,
min_pollution_to_damage_trees: 60,
pollution_with_max_forest_damage: 150,
pollution_per_tree_damage: 50,
pollution_restored_per_tree_damage: 10,
max_pollution_to_restore_trees: 20,
enemy_attack_pollution_consumption_modifier: 1
},
enemy_evolution:
{
enabled: true,
time_factor: 0.000004,
destroy_factor: 0.002,
pollution_factor: 0.0000009
},
enemy_expansion:
{
enabled: true,
min_base_spacing: 3,
max_expansion_distance: 7,
friendly_base_influence_radius: 2,
enemy_building_influence_radius: 2,
building_coefficient: 0.1,
other_base_coefficient: 2.0,
neighbouring_chunk_coefficient: 0.5,
neighbouring_base_chunk_coefficient: 0.4,
max_colliding_tiles_coefficient: 0.9,
settler_group_min_size: 5,
settler_group_max_size: 20,
min_expansion_cooldown: 14400,
max_expansion_cooldown: 216000
},
unit_group:
{
min_group_gathering_time: 3600,
max_group_gathering_time: 36000,
max_wait_time_for_late_members: 7200,
max_group_radius: 30.0,
min_group_radius: 5.0,
max_member_speedup_when_behind: 1.4,
max_member_slowdown_when_ahead: 0.6,
max_group_slowdown_factor: 0.3,
max_group_member_fallback_factor: 3,
member_disown_distance: 10,
tick_tolerance_when_member_arrives: 60,
max_gathering_unit_groups: 30,
max_unit_group_size: 200
},
steering:
{
default:
{
radius: 1.2,
separation_force: 0.005,
separation_factor: 1.2,
force_unit_fuzzy_goto_behavior: false
},
moving:
{
radius: 3,
separation_force: 0.01,
separation_factor: 3,
force_unit_fuzzy_goto_behavior: false
}
},
path_finder:
{
fwd2bwd_ratio: 5,
goal_pressure_ratio: 2,
max_steps_worked_per_tick: 100,
max_work_done_per_tick: 8000,
use_path_cache: true,
short_cache_size: 5,
long_cache_size: 25,
short_cache_min_cacheable_distance: 10,
short_cache_min_algo_steps_to_cache: 50,
long_cache_min_cacheable_distance: 30,
cache_max_connect_to_cache_steps_multiplier: 100,
cache_accept_path_start_distance_ratio: 0.2,
cache_accept_path_end_distance_ratio: 0.15,
negative_cache_accept_path_start_distance_ratio: 0.3,
negative_cache_accept_path_end_distance_ratio: 0.3,
cache_path_start_distance_rating_multiplier: 10,
cache_path_end_distance_rating_multiplier: 20,
stale_enemy_with_same_destination_collision_penalty: 30,
ignore_moving_enemy_collision_distance: 5,
enemy_with_different_destination_collision_penalty: 30,
general_entity_collision_penalty: 10,
general_entity_subsequent_collision_penalty: 3,
extended_collision_penalty: 3,
max_clients_to_accept_any_new_request: 10,
max_clients_to_accept_short_new_request: 100,
direct_distance_to_consider_short_request: 100,
short_request_max_steps: 1000,
short_request_ratio: 0.5,
min_steps_to_check_path_find_termination: 2000,
start_to_goal_cost_multiplier_to_terminate_path_find: 500.0,
overload_levels: [0, 100, 500],
overload_multipliers: [2, 3, 4],
negative_path_cache_delay_interval: 20
},
max_failed_behavior_count: 3
}

View file

@ -0,0 +1,91 @@
{
// The following options are defaults taken verbatim from Factorio 1.1.35
// headless' server-settings.example.json, with the following changes:
// - field names unquoted where possible
// - pseudo-comments converted to jsonnet comments
// - comments reflowed to fit 80 columns
name: "Name of the game as it will appear in the game listing",
description: "Description of the game that will appear in the listing",
tags: ["game", "tags"],
// Maximum number of players allowed, admins can join even a full server. 0
// means unlimited.
max_players: 0,
visibility:
{
// Game will be published on the official Factorio matching server
public: true,
// Game will be broadcast on LAN
lan: true,
},
// Your factorio.com login credentials. Required for games with visibility
// public
username: "",
password: "",
// Authentication token. May be used instead of 'password' above.
token: "",
game_password: "",
// When set to true, the server will only allow clients that have a valid
// Factorio.com account
require_user_verification: true,
// optional, default value is 0. 0 means unlimited.
max_upload_in_kilobytes_per_second: 0,
// optional, default value is 5. 0 means unlimited.
max_upload_slots: 5,
// optional one tick is 16ms in default speed, default value is 0.
// 0 means no minimum.
minimum_latency_in_ticks: 0,
// Players that played on this map already can join even when the max
// player limit was reached.
ignore_player_limit_for_returning_players: false,
// possible values are, true, false and admins-only
allow_commands: "admins-only",
// Autosave interval in minutes
autosave_interval: 10,
// server autosave slots, it is cycled through when the server autosaves.
autosave_slots: 5,
// How many minutes until someone is kicked when doing nothing, 0 for
// never.
afk_autokick_interval: 0,
// Whether should the server be paused when no players are present.
auto_pause: true,
only_admins_can_pause_the_game: true,
// Whether autosaves should be saved only on server or also on all
// connected clients. Default is true.
autosave_only_on_server: true,
// Highly experimental feature, enable only at your own risk of losing your
// saves. On UNIX systems, server will fork itself to create an autosave.
// Autosaving on connected Windows clients will be disabled regardless of
// autosave_only_on_server option.
non_blocking_saving: false,
// Long network messages are split into segments that are sent over
// multiple ticks. Their size depends on the number of peers currently
// connected. Increasing the segment size will increase upload bandwidth
// requirement for the server and download bandwidth requirement for
// clients. This setting only affects server outbound messages. Changing
// these settings can have a negative impact on connection stability for
// some clients.
minimum_segment_size: 25,
minimum_segment_size_peer_count: 20,
maximum_segment_size: 100,
maximum_segment_size_peer_count: 10,
}

View file

@ -17,6 +17,42 @@ local proxy = import "proxy.libsonnet";
rconPort: 2137,
rconPassword: "farts",
// Configuration options that will get serialized into
// --config config.ini
factorioConfig: {
// There is no documentation for this file, but you can check
// config.ini in any installed Factorio data directory for a
// sample.
//
// This uses std.manifestIni, so to create a file containing:
// version=9
// [other]
// verbose-logging=true
// You would set the following:
// main: {
// version: "9",
// },
// other: {
// "verbose-logging": "true",
// },
},
// Configuration options that will get serialized into
// --server-settings server-settings.json.
serverSettings: (import "config/server-settings.libsonnet") {
visibility+: {
public: false,
lan: false,
},
},
// Configuration options that will get serialized into
// --map-settings map-settings.json.
mapSettings: (import "config/map-settings.libsonnet") {
},
// Configuration options that will get serialized into
// --map-gen-settings map-gen-settings.json.
mapGenSettings: (import "config/map-gen-settings.libsonnet") {
},
tag: "latest",
image: "registry.k0.hswaw.net/q3k/factorio:" + cfg.tag,
resources: {
@ -78,6 +114,9 @@ local proxy = import "proxy.libsonnet";
"mod { name: \"%s\" version: \"%s\" }" % [m.name, m.version],
for m in cfg.mods
]),
"server-settings.json": std.manifestJson(cfg.serverSettings),
"map-settings.json": std.manifestJson(cfg.mapSettings),
"map-gen-settings.json": std.manifestJson(cfg.mapGenSettings),
},
},
@ -115,6 +154,9 @@ local proxy = import "proxy.libsonnet";
"/entrypoint.sh",
"--rcon-port", std.toString(cfg.rconPort),
"--rcon-password", cfg.rconPassword,
"--server-settings", "/factorio/config/server-settings.json",
"--map-settings", "/factorio/config/map-settings.json",
"--map-gen-settings", "/factorio/config/map-gen-settings.json",
],
ports_: {
client: { containerPort: 34197 },
@ -123,6 +165,7 @@ local proxy = import "proxy.libsonnet";
volumeMounts_: {
data: { mountPath: "/data" },
mods: { mountPath: "/factorio/mods" },
config: { mountPath: "/factorio/config" },
},
resources: cfg.resources,
},