Not really what you are asking for, but something that your comment inspired: https://redmine.freeciv.org/issues/1073Molo_Parko wrote: ↑Fri Nov 08, 2024 7:48 pm A flag for nation geographical type (island, coastal, inland or land-locked) in the ruleset files might be helpful.
New features via Lua script
Re: New features via Lua script
-
- Hardened
- Posts: 200
- Joined: Fri Jul 02, 2021 4:00 pm
Re: New features via Lua script
This is the script section from the scenario "MiniMap Terrain Defense Trainer", shared at this link: https://forum.freeciv.org/f/viewtopic.php?p=110011
The first part provides 4 Fortresses, randomly placed on 4 of the map's land tiles. The second part places tile labels showing the tile terrain defense bonus. This script should work as-is when added to another scenario, though if the scenario is for Freeciv v3 and later then turn_started should be changed to turn_begin to avoid deprecation warnings. Ahh, and the # of tiles would change from 255, presumably.
^ version 1.1 with either City Walls x3 modifier or city only 1.5 modifier not both.
The first part provides 4 Fortresses, randomly placed on 4 of the map's land tiles. The second part places tile labels showing the tile terrain defense bonus. This script should work as-is when added to another scenario, though if the scenario is for Freeciv v3 and later then turn_started should be changed to turn_begin to avoid deprecation warnings. Ahh, and the # of tiles would change from 255, presumably.
Code: Select all
function setup()
if find.tile( 255 ):has_extra( "River" ) then
local count = 0
for tries = 1, 10, 1 do
tile = find.tile( random( 0, 255 ) )
if tile.terrain:class_name() == "Land"
and not tile:city()
and tile.terrain:rule_name() ~= "Inaccessible"
and not tile:has_extra ( "Fortress" ) then
edit.create_extra( tile, "Fortress" )
count = count + 1
if count >= 4 then
edit.remove_extra( find.tile( 255 ), "River" )
goto all_done
end
end
end
end
::all_done::
end
setup()
function s_map_labels( turn, year )
for tile in whole_map_iterate() do
local defense_bonus = 0
local defense_multiplier = ""
local defense_special = ""
if tile.terrain == find.terrain( "Grassland" ) then defense_bonus = 1 end
if tile.terrain == find.terrain( "Plains" ) then defense_bonus = 1 end
if tile.terrain == find.terrain( "Tundra" ) then defense_bonus = 1 end
if tile.terrain == find.terrain( "Desert" ) then defense_bonus = 1 end
if tile.terrain == find.terrain( "Glacier" ) then defense_bonus = 1 end
if tile.terrain == find.terrain( "Mountains" ) then defense_bonus = 3 end
if tile.terrain == find.terrain( "Hills" ) then defense_bonus = 2 end
if tile.terrain == find.terrain( "Jungle" ) then defense_bonus = 1.5 end
if tile.terrain == find.terrain( "Swamp" ) then defense_bonus = 1.5 end
if tile.terrain == find.terrain( "Forest" ) then defense_bonus = 1.5 end
if tile:has_extra( "River" ) then defense_multiplier = " x 1.5" end
if tile:has_extra( "Fortress" ) then
defense_multiplier = defense_multiplier .. " x 2"
defense_special = "No Stack Kill"
-- plus Diplomat vs Diplomat +25% defense
end
local cityWalls = false
if tile:city() then
city = tile:city()
defense_special = "No Stack Kill"
local id, building, buildingName
for id = 0, 67, 1 do
building = find.building_type( id )
buildingName = ( building ):rule_name()
if buildingName == "City Walls" then
if city:has_building( building ) then
cityWalls = true
defense_multiplier = defense_multiplier .. " x 3"
break
end
end
if buildingName == "Coinage" then break end
end
if cityWalls == false then
defense_multiplier = defense_multiplier .. " x 1.5"
end
end
if defense_bonus ~= 0 then
edit.tile_set_label( tile, " + " .. defense_bonus .. "\n" .. defense_multiplier )
else
edit.tile_set_label( tile, "" )
end
end
end
signal.connect( "turn_started", "s_map_labels" )
-
- Hardened
- Posts: 200
- Joined: Fri Jul 02, 2021 4:00 pm
Re: New features via Lua script
These are the Lua scripts included in the scenario "The Gridiron", shared at this link: https://forum.freeciv.org/f/viewtopic.p ... 33#p110033
The top portion is "loose code" not within a function, such code runs once on gamestart and after reload of saved games.
Then the functions are:
"s_unit_moved" is the routine which handles the movement of the football (a single segment of the River extra), touchdowns, kicks and field goals.
The top portion is "loose code" not within a function, such code runs once on gamestart and after reload of saved games.
Then the functions are:
- function s_select_unit_type( player )
- function s_add_new_tech( player )
- function s_unit_moved( unit, src_tile, dst_tile )
- function s_name( player )
- function s_unit_lost( unit, loser, reason )
- function s_endzone_and_bench_labels()
- function s_main()
- function s_position_units()
"s_unit_moved" is the routine which handles the movement of the football (a single segment of the River extra), touchdowns, kicks and field goals.
Code: Select all
if find.tile( 2, 0 ):has_extra( "River" ) then
edit.remove_extra( find.tile( 2, 0 ), "River" )
notify.event( nil, nil, E.REPORT, _(
"[c fg=\"#0000ff\"][b]\n\n\
Welcome to The Gridiron scenario for Freeciv 2.6.4 and later[/b]\n\
Created and tested with Freeciv 2.6.4 and GTK2 client.\n\
A basic football game between two teams, to the death for one or the other!\n\n\
Victory is acheived by eliminating all eleven enemy units in a single turn.\n\
Unit losses are replaced at the beginning of each turn.\n\n\
Touchdowns earn six points, field goals two.\n\
Touchdowns and field goals also make new unit types available to both teams.\n\
Types of units are random among those of known technologies.\n\n\
The next turn after a touchdown or field goal begins with units returned to the starting formation.\n\n\
The football is blue. To carry it, move a unit onto the tile, and the unit will carry the ball.\n\
To kick, have one unit hold the football, and move a second unit onto the tile.\n\
The goalposts are the ends of the white tiles on either side of the field.\n\n\
In the final score report, the football score is the column labeled Culture\n\n[/c]" ) )
_G.ReloadDetected = false
log.error( "%s", "The game is about to begin" )
else
log.error( "%s", "Reload detected" )
_G.ReloadDetected = true
_G.endzone = {}
_G.bench = {}
if find.tile( 0, 18 ):has_extra( "Irrigation" ) then
_G.endzone[ find.player( 0 ) ] = 0
_G.bench[ find.player( 0 ) ] = 1
_G.endzone[ find.player( 1 ) ] = 32
_G.bench[ find.player( 1 ) ] = 17
else
_G.endzone[ find.player( 0 ) ] = 32
_G.bench[ find.player( 0 ) ] = 17
_G.endzone[ find.player( 1 ) ] = 0
_G.bench[ find.player( 1 ) ] = 1
end
if _G.unit_type_names == nil then
_G.unit_type_names = "Warriors|Horsemen|Phalanx|Archers"
end
end
-- Emulate Fc 3.0 game.current_turn()
if game.current_turn == nil then
function _G.game.current_turn()
return math.floor( game.turn() )
end
end
function s_select_unit_type( player )
local unit_type_names_table = {}
for field in string.gmatch( _G.unit_type_names, "[^|]+" ) do
unit_type_names_table[ #unit_type_names_table + 1 ] = field
end
local unit_type_name = unit_type_names_table[ random( 1, #unit_type_names_table ) ]
return find.unit_type( unit_type_name )
end
function s_add_new_tech( player )
local military_land_unit_types_tech = {
"Horseback Riding", "Bronze Working", "Warrior Code",
"The Wheel", "Iron Working", "Mathematics", "Feudalism",
"Chivalry", "Gunpowder", "Metallurgy", "Leadership",
"Conscription", "Tactics", "Tactics", "Guerilla Warfare",
"Machine Tools", "Amphibious Warfare", "Mobile Warfare",
"Labor Union", "Robotics" }
local military_land_unit_types_names = {
"Horsemen", "Phalanx", "Archers", "Chariot",
"Legion", "Catapult", "Pikemen", "Knights",
"Musketeers", "Cannon", "Dragoons", "Riflemen",
"Alpine Troops", "Cavalry", "Partisan",
"Artillery", "Marines", "Armor", "Mech. Inf.",
"Howitzer" }
for i = 1, #military_land_unit_types_tech, 1 do
local tech = find.tech_type( military_land_unit_types_tech[ i ] )
if not player:knows_tech( tech ) then
for player in players_iterate() do
if player == find.player( 2 ) then goto skip_it end
edit.give_tech( player, tech, -1, nil, "hut" )
::skip_it::
end
_G.unit_type_names = _G.unit_type_names .. "|" .. military_land_unit_types_names[ i ]
local output = military_land_unit_types_names[ i ] .. " units are now available for both teams."
notify.event( nil, nil, E.REPORT, output )
notify.event( nil, nil, E.CHAT_MSG, output )
break
end
end
end
function s_unit_moved( unit, src_tile, dst_tile )
edit.tile_set_label( dst_tile, math.floor( unit.id - 100 ) )
edit.tile_set_label( src_tile, "" )
if _G.position_units_in_progress == true then return end
local ball_src_tile = _G.ball
-- Remove Lures from endzone if unit enters endzone
if ( unit.tile.x < 3 or unit.tile.x > 30 )
and unit.utype ~= find.unit_type( "Spy" )
and unit.utype ~= find.unit_type( "Workers" ) then
if _G.lure_unit_1 ~= nil and _G.lure_unit_1:exists() then
edit.unit_kill( _G.lure_unit_1, "disbanded", Barbarians )
end
end
-- Touchdown and Own Goal
if _G.ball == src_tile then
edit.remove_extra( src_tile, "River" )
edit.create_extra( dst_tile, "River" )
_G.ball = dst_tile
if _G.ball.x < 2 and _G.ball.y > 0 and _G.ball.y < 18 then
if _G.endzone[ unit.owner ] ~= 0 then
edit.add_player_history( unit.owner, 6 )
_G.reset_positions_next_turn = true
local output = "TOUCHDOWN! \tBy #" .. math.floor( tostring( unit.id ) ) ..
" of " .. s_name( unit.owner ) .. "\t"
notify.event( nil, nil, E.SCRIPT, output )
notify.event( nil, nil, E.CHAT_MSG, output )
s_add_new_tech( unit.owner )
s_add_new_tech( unit.owner ) -- twice for touchdowns
edit.remove_extra( dst_tile, "River" )
_G.ball = find.tile( 16, 9 )
elseif _G.endzone[ unit.owner ] == 0 then
_G.reset_positions_next_turn = true
if unit.owner.id == 0 then
edit.add_player_history( find.player( 1 ), 6 )
else
edit.add_player_history( find.player( 0 ), 6 )
end
local output = "OWN GOAL! " .. tostring( unit.owner ) ..
" scored for the other team!"
notify.event( nil, nil, E.SCRIPT, output )
notify.event( nil, nil, E.CHAT_MSG, output )
edit.remove_extra( dst_tile, "River" )
_G.ball = find.tile( 16, 9 )
end
end
if _G.ball.x > 30 and _G.ball.y > 0 and _G.ball.y < 18 then
if _G.endzone[ unit.owner ] ~= 32 then
edit.add_player_history( unit.owner, 6 )
_G.reset_positions_next_turn = true
local output = "TOUCHDOWN! By #" .. math.floor( tostring( unit.id ) ) ..
" of " .. s_name( unit.owner )
notify.event( nil, nil, E.SCRIPT, output )
notify.event( nil, nil, E.CHAT_MSG, output )
s_add_new_tech( unit.owner )
s_add_new_tech( unit.owner ) -- twice for touchdowns
edit.remove_extra( dst_tile, "River" )
_G.ball = find.tile( 16, 9 )
elseif _G.endzone[ unit.owner ] == 32 then
_G.reset_positions_next_turn = true
if unit.owner.id == 0 then
edit.add_player_history( find.player( 1 ), 6 )
else
edit.add_player_history( find.player( 0 ), 6 )
end
local output = "OWN GOAL! " .. tostring( unit.owner ) ..
" scored for the other team!"
notify.event( nil, nil, E.SCRIPT, output )
notify.event( nil, nil, E.CHAT_MSG, output )
edit.remove_extra( dst_tile, "River" )
_G.ball = find.tile( 16, 9 )
end
end
end
-- Kick
if src_tile ~= ball_src_tile and _G.ball == dst_tile and dst_tile:num_units() > 1 then
local x_direction, y_direction, count = 0, 0, 0
if dst_tile:num_units() > 1 and dst_tile == _G.ball then
if src_tile.x < dst_tile.x then x_direction = 1 end
if src_tile.x > dst_tile.x then x_direction = -1 end
if src_tile.y < dst_tile.y then y_direction = 1 end
if src_tile.y > dst_tile.y then y_direction = -1 end
for i = 1, random( 2, 13 ), 1 do
if ball.x + x_direction >= 14 and ball.x + x_direction <= 18 then
if ball.y + y_direction == 0 or ball.y + y_direction == 18 then
goto off_the_map
end
end
if ball.x + x_direction < 0
or ball.x + x_direction > 32 then
goto off_the_map
end
if ball.y + y_direction < 0
or ball.y + y_direction > 18 then
goto off_the_map
end
edit.remove_extra( _G.ball, "River" )
_G.ball = find.tile( ball.x + x_direction, ball.y + y_direction )
edit.create_extra( _G.ball, "River" )
end
::off_the_map::
-- Field goal
if ( _G.ball.x < 2 or _G.ball.x > 30 )
and ( _G.ball.y >= 7 and _G.ball.y <= 11 ) then
edit.add_player_history( unit.owner, 2 )
local output = "FIELD GOAL! " .. tostring( unit.owner )
notify.event( nil, nil, E.SCRIPT, output )
notify.event( nil, nil, E.CHAT_MSG, output )
s_add_new_tech( unit.owner )
_G.reset_positions_next_turn = true
else
local output = "#" .. math.floor( tostring( unit.id ) - 100 ) ..
" of " .. s_name( unit.owner ) .. " kicked the ball to " ..
math.floor( _G.ball.x ) .. ", " .. math.floor( _G.ball.y )
notify.event( unit.owner, dst_tile, E.SCRIPT, output )
notify.event( nil, dst_tile, E.CHAT_MSG, output )
end
end
-- Remove lure after a kick
if _G.lure_unit_1 ~= nil and _G.lure_unit_1:exists() then
edit.unit_kill( _G.lure_unit_1, "disbanded", Barbarians )
end
end
-- Fumble
if ball == dst_tile and random( 1, 400 ) > 395 then
edit.remove_extra( src_tile, "River" )
edit.remove_extra( dst_tile, "River" )
local x = dst_tile.x + random( -2, 2 )
local y = dst_tile.y + random( -2, 2 )
local tile = find.tile( x, y )
if tile then
edit.create_extra( tile, "River" )
_G.ball = tile
end
if ball ~= dst_tile then
local output = " FUMBLE by #" .. math.floor( unit.id - 100 ) ..
" of " .. s_name( unit.owner ) .. "!"
notify.event( unit.owner, dst_tile, E.SCRIPT, output )
notify.event( nil, dst_tile, E.CHAT_MSG, output )
end
end
end
signal.connect( "unit_moved", "s_unit_moved" )
function s_name( player )
local playerName
if player and player ~= "" then
playerName = string.sub( tostring( player.nation ), 14, -2 )
playerName = playerName:gsub( "^.-%s", "", 1 )
playerName = ( "#" .. math.floor( player.id ) .. " " ..
playerName .. " ( " .. player.name .. " )"
)
return playerName
end
return false
end
function s_unit_lost( unit, loser, reason )
edit.tile_set_label( unit.tile, "" )
local output
if reason == "killed" then
if unit.owner == find.player( 0 ) then
output = "[c fg=\"#660000\"][b]"
else
output = "[c fg=\"#006600\"][b]"
end
output = output .. "Unit lost: #" .. math.floor( unit.id - 100 ) .. " " .. unit.utype:rule_name() .. " of " .. s_name( unit.owner ) .. "! \tRemaining:" .. math.floor( unit.owner:num_units() - 1 ) .. "[/b][/c]"
notify.event( nil, dst_tile, E.CHAT_MSG, output )
if loser.id == 0 then
player_0_losses = player_0_losses + 1
player_1_kills = player_1_kills + 1
else
player_1_losses = player_1_losses + 1
player_0_kills = player_0_kills + 1
end
end
end
signal.connect( "unit_lost", "s_unit_lost" )
function s_endzone_and_bench_labels()
local tile
for player in players_iterate() do
if player == find.player( 2 ) then goto fuggedaboutit end
if _G.endzone[ player ] == 0 then
tile = find.tile( 2, 8 )
edit.tile_set_label( tile, player.nation:rule_name() )
tile = find.tile( 16, 1 )
edit.tile_set_label( tile, player.nation:rule_name() .. " bench" )
elseif _G.endzone[ player ] == 32 then
tile = find.tile( 30, 8 )
edit.tile_set_label( tile, player.nation:rule_name() )
tile = find.tile( 16, 17 )
edit.tile_set_label( tile, player.nation:rule_name() .. " bench" )
end
::fuggedaboutit::
end
end
function s_main()
if ( not _G.ReloadDetected ) and ( game.current_turn() == 0 ) then
local tech_types = { "Bronze Working", "Horseback Riding", "Warrior Code" }
for tech_type = 1, 3, 1 do
local tech = find.tech_type( tech_types[ tech_type ] )
edit.give_tech( find.player( 0 ), tech, -1, nil, "hut" )
edit.give_tech( find.player( 1 ), tech, -1, nil, "hut" )
end
_G.unit_type_names = "Warriors|Horsemen|Phalanx|Archers"
Barbarians = edit.create_player( "Dedbreth", find.nation_type( "Barbarian" ), Land )
_G.endzone = {}
_G.bench = {}
_G.ball = find.tile( 16, 9 )
player_0_losses = 0
player_1_losses = 0
player_0_kills = 0
player_1_kills = 0
for player in players_iterate() do
if player == find.player( 2 ) then goto no_thanks end
for unit in player:units_iterate() do
tile = unit.tile
if tile.x <= 16 then
_G.endzone[ player ] = 0
_G.bench[ player ] = 1
else
_G.endzone[ player ] = 32
_G.bench[ player ] = 17
end
break
end
::no_thanks::
end
-- for reloads
if _G.endzone[ find.player( 0 ) ] == 0 then
edit.create_extra( find.tile( 0, 18 ), "Irrigation" )
end
s_endzone_and_bench_labels()
s_position_units()
end
if game.current_turn() > 0 and _G.ReloadDetected == false then
local output = "[c fg=\"#000066\"][b]Turn: " .. game.current_turn() ..
" \t\tScore: " .. math.floor( find.player( 0 ):culture() ) .. " - " .. math.floor( find.player( 1 ):culture() ) ..
" \t\tKills: " .. player_0_kills .. " - " .. player_1_kills ..
" \tUnits: Player 0: " .. math.floor( find.player( 0 ):num_units() ) .. " \tPlayer 1: " .. math.floor( find.player( 1 ):num_units() ) ..
" \t\tBall at: " .. math.floor( _G.ball.x ) .. ", " .. math.floor( _G.ball.y ) .. "[/b][/c]"
notify.event( nil, dst_tile, E.REPORT, output )
notify.event( nil, dst_tile, E.CHAT_MSG, "" )
notify.event( nil, dst_tile, E.CHAT_MSG, output )
end
for player in players_iterate() do
if player == find.player( 2 ) then goto not_now end
local count = 0
for unit in player:units_iterate() do
count = count + 1
if count > 11 then edit.unit_kill( unit, "disbanded", player ) end
end
::not_now::
end
s_endzone_and_bench_labels()
for player in players_iterate() do
if player == find.player( 2 ) then goto no_way end
if player:num_units() < 11 then
repeat
local tile = find.tile( random( 13, 19 ), _G.bench[ player ] )
local unit_type = s_select_unit_type( player )
pcall( edit.create_unit_full( player, tile, unit_type, 0, nil, -1, -1, nil ) )
until player:num_units() >= 11
end
::no_way::
end
if _G.reset_positions_next_turn == true then
_G.reset_positions_next_turn = false
s_position_units()
end
-- Skip creating lures if units in the endzones
local columns = { 0, 1, 31, 32 }
for row = 1, 18, 1 do
for x = 1, #columns, 1 do
tile = find.tile( columns[ x ], row )
for unit in tile:units_iterate() do
if unit.owner ~= Barbarians then
goto nevermind
end
end
end
end
-- Lure whenever a computer-controlled team unit has the ball
if game.current_turn() > 5 and find.player( 1 ):is_human() == false then
local unit_type
local lure_tileIDs_west = { 231, 264, 297, 330, 363 }
local lure_tileIDs_east = { 263, 296, 329, 362, 395 }
local lure_tile_west = find.tile( lure_tileIDs_west[ random( 1, #lure_tileIDs_west ) ] )
local lure_tile_east = find.tile( lure_tileIDs_east[ random( 1, #lure_tileIDs_east ) ] )
local lure_tile
if random( 1, 2 ) == 1 then
unit_type = find.unit_type( "Workers" )
else
unit_type = find.unit_type( "Spy" )
end
for unit in _G.ball:units_iterate() do
if _G.endzone[ unit.owner ] == 0 then
lure_tile = lure_tile_east
else
lure_tile = lure_tile_west
end
if _G.lure_unit_1 ~= nil and _G.lure_unit_1:exists() then
edit.unit_move( _G.lure_unit_1, lure_tile, 99 )
edit.tile_set_label( lure_tile, "" )
else
_G.lure_unit_1 = edit.create_unit_full( Barbarians, lure_tile, unit_type, 0, nil, -1, -1, nil )
local output = "Cheerleaders are dancing in the endzones!"
notify.event( nil, nil, E.CHAT_MSG, output )
end
break
end
end
::nevermind::
end
signal.connect( "turn_started", "s_main" )
function s_position_units()
if _G.lure_unit_1 ~= nil and _G.lure_unit_1:exists() then
edit.unit_kill( _G.lure_unit_1, "disbanded", Barbarians )
end
_G.position_units_in_progress = true
if ball then edit.remove_extra( ball, "River" ) end
ball = find.tile( 16, 9 )
edit.create_extra( ball, "River" )
local tileIDs_right = { 316, 184, 186, 217, 221, 318, 352, 415, 419, 448, 450 }
local tileIDs_left = { 310, 178, 176, 207, 211, 274, 308, 405, 409, 440, 442 }
local tile
for player in players_iterate() do
if player == find.player( 2 ) then goto get_outta_here end
if _G.endzone[ player ] == 0 then
tile = find.tile( tileIDs_left[ 1 ] )
elseif _G.endzone[ player ] == 32 then
tile = find.tile( tileIDs_right[ 1 ] )
end
if player:num_units() < 11 then
repeat
local unit_type = s_select_unit_type( player )
edit.create_unit_full( player, tile, unit_type, 0, nil, -1, -1, nil )
until player:num_units() == 11
end
local i = 1
if _G.endzone[ player ] == 32 then
for unit in player:units_iterate() do
edit.tile_set_label( unit.tile, "" )
local offset_x = random( -1, 1 )
local offset_y = random( -1, 1 )
if offset_y == 1 then
offset_y = -33
elseif offset_y == 2 then
offset_y = 33
end
tile = find.tile( tileIDs_right[ i ] + offset_x + offset_y )
edit.unit_move( unit, tile, 0 )
edit.tile_set_label( tile, math.floor( unit.id - 100 ) )
i = i + 1
end
elseif _G.endzone[ player ] == 0 then
for unit in player:units_iterate() do
edit.tile_set_label( unit.tile, "" )
local offset_x = random( -1, 1 )
local offset_y = random( -1, 1 )
if offset_y == 1 then
offset_y = -33
elseif offset_y == 2 then
offset_y = 33
end
tile = find.tile( tileIDs_left[ i ] + offset_x + offset_y )
edit.unit_move( unit, tile, 0 )
edit.tile_set_label( tile, math.floor( unit.id - 100 ) )
i = i + 1
end
end
::get_outta_here::
end
_G.position_units_in_progress = false
end
-
- Hardened
- Posts: 200
- Joined: Fri Jul 02, 2021 4:00 pm
Re: New features via Lua script
This routine demonstrates a variety of Lua script commands and functions.
Each entry shows the command, the live result, and the data type where applicable. The "userdata" output type = tolua.
Limited to Freeciv 2.6.4 to 2.6.11 compatible stuff, because I am using Freeciv 2.6.4 and 2.6.11.
The top part of the script is the "echo" output routine, the rest is the list of commands and their output.

^ Sample output.
EDIT: Updated to include routine showing all known server.setting.get() values (such as the [settings] section of a scenario .sav file.) Updated version also includes at the end a "dump globals" feature to list all Lua global vars and functions.
EDIT: Updated the routine to list known options and values.
This is for Lua script development and testing rather than a game feature.
Each entry shows the command, the live result, and the data type where applicable. The "userdata" output type = tolua.
Limited to Freeciv 2.6.4 to 2.6.11 compatible stuff, because I am using Freeciv 2.6.4 and 2.6.11.
The top part of the script is the "echo" output routine, the rest is the list of commands and their output.

^ Sample output.
Code: Select all
function echo( return_type, command, output, note )
if command == nil and output == nil then notify.event( nil, nil, E.CHAT_MSG, "" ) return end
if output == nil then output = "" end
if command == nil then command = "" end
-- This output is to the Chat pane only
notify.event( nil, nil, E.CHAT_MSG, return_type .. "\t" .. command .. " = " .. tostring( output ) )
if note ~= "" then
notify.event( nil, nil, E.CHAT_MSG, "\t\t" .. note )
end
-- A blank line after the output
notify.event( nil, nil, E.CHAT_MSG, "")
end
function s_command_examples( turn, year )
if game.turn() > 1 then return end
echo()
local output, note
local return_type = ""
local command = ""
local Player = find.player( 0 )
local Nation_type = find.nation_type( Player.nation.id )
local Government = find.government( 0 )
local Tech_type = find.tech_type( "Bridge Building" )
local Terrain = find.terrain( "Hills" )
local Unit_type = find.unit_type( "Phalanx" )
local Building_type = find.building_type( "City Walls" )
local Unit
for unit in Player:units_iterate() do
Unit = unit
break
end
note = "[b]Examples of Freeciv 2.6.4 Lua commands and functions[/b]"
notify.event( nil, nil, E.CHAT_MSG, "\t\t" .. note )
notify.event( nil, nil, E.CHAT_MSG, "" )
note = "Info source: https://freeciv.fandom.com/wiki/Lua_reference_manual#Tech_Type"
notify.event( nil, nil, E.CHAT_MSG, "\t\t" .. note )
notify.event( nil, nil, E.CHAT_MSG, "" )
note = "Variable names are in [ c fg \"#000099\"]blue[/c]"
notify.event( nil, nil, E.CHAT_MSG, "\t\t" .. note )
notify.event( nil, nil, E.CHAT_MSG, "" )
notify.event( nil, nil, E.CHAT_MSG, "" )
note = "[b]Output Command Result[/b]"
notify.event( nil, nil, E.CHAT_MSG, note )
notify.event( nil, nil, E.CHAT_MSG, "" )
output = fc_version() command = "fc_version()" return_type = type( output )
note = ""
echo( return_type, command, output, note )
output = _VERSION command = '[ c fg \"#000099\"]_VERSION[/c] is a variable which holds the Lua version' return_type = type( output )
note = ""
echo( return_type, command, output, note )
output = turn command = "[ c fg \"#000099\"]turn[/c]" return_type = type( output )
note = ""
echo( return_type, command, output, note )
output = year command = "[ c fg \"#000099\"]year[/c]" return_type = type( output )
note = ""
echo( return_type, command, output, note )
output = game.turn() command = "game.turn()" return_type = type( output )
note = "Deprecated as of Freeciv 3.0. Use game.current_turn() instead."
echo( return_type, command, output, note )
output = math.floor( game.turn() ) command = "math.floor( game.turn() )" return_type = type( output )
note = ""
echo( return_type, command, output, note )
output = find.player( 0 ) command = "find.player( 0 )" return_type = type( output )
note = "Like \"player #0 AI*1\" before gamestart, after it is like \"Player #0 Klef\""
echo( return_type, command, output, note )
output = Player.id command = "[ c fg \"#000099\"](Player)[/c].id" return_type = type( output )
note = ""
echo( return_type, command, output, note )
output = Player.name command = "[ c fg \"#000099\"](Player)[/c].name" return_type = type ( output )
note = "Like \"AI*1\" before gamestart, after it is like \"Klef\""
echo( return_type, command, output, note )
output = Player.ai_controlled command = "[ c fg \"#000099\"](Player)[/c].ai_controlled" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player.is_alive command = "[ c fg \"#000099\"](Player)[/c].is_alive" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:is_human() command = "[ c fg \"#000099\"](Player)[/c]:is_human()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:num_cities() command = "[ c fg \"#000099\"](Player)[/c]:num_cities()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:num_units() command = "[ c fg \"#000099\"](Player)[/c]:num_units()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:gold() command = "[ c fg \"#000099\"](Player)[/c]:gold()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:exists() command = "[ c fg \"#000099\"](Player)[/c]:exists()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.tech_type( "Bridge Building" ) command = "find.tech_type( \"Bridge Building\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.tech_type( 8 ) command = "find.tech_type( 7 )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Tech_type.id command = "[ c fg \"#000099\"](Tech_type)[/c].id" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Tech_type:rule_name() command = "[ c fg \"#000099\"](Tech_type)[/c]:rule_name()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Tech_type:name_translation() command = "[ c fg \"#000099\"](Tech_type)[/c]:name_translation()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:knows_tech( Tech_type ) command = "[ c fg \"#000099\"](Player)[/c]:knows_tech( [ c fg \"#000099\"](Tech_type)[/c] )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:units_iterate() command = "[ c fg \"#000099\"](Player)[/c]:units_iterate()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:cities_iterate() command = "[ c fg \"#000099\"](Player)[/c]:cities_iterate()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player:shares_research( (Player) ) command = "[ c fg \"#000099\"](Player)[/c]:shares_research( [ c fg \"#000099\"](Player)[/c] )" return_type = type ( output )
note = "I like that I share with myself. It gives me a warm feeling."
echo( return_type, command, output, note )
output = Player:culture() command = "[ c fg \"#000099\"](Player)[/c]:culture()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player.nation command = "[ c fg \"#000099\"](Player)[/c].nation" return_type = type ( output )
note = "nil before gamestart, after like \"<Nation_Type #269 Langobardic>\""
echo( return_type, command, output, note )
output = Player.nation.id command = "[ c fg \"#000099\"](Player)[/c].nation.id" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.nation_type( Player.nation.id ) command = "find.nation_type( [ c fg \"#000099\"](Player)[/c].nation.id )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.nation_type( 555 ) command = "find.nation_type( 555 )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.nation_type( "Barbarian" ) command = "find.nation_type( \"Barbarian\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.nation_type( "Pirate" ) command = "find.nation_type( \"Pirate\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player.nation:rule_name() command = "[ c fg \"#000099\"](Player)[/c].nation:rule_name()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player.nation:name_translation() command = "[ c fg \"#000099\"](Player)[/c].nation:name_translation()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Player.nation:plural_translation() command = "[ c fg \"#000099\"](Player)[/c].nation:plural_translation()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_min( "expansionist" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_min( \"expansionist\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_max( "expansionist" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_max( \"expansionist\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_default( "expansionist" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_default( \"expansionist\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_min( "trader" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_min( \"trader\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_max( "trader" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_max( \"trader\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_default( "trader" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_default( \"trader\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_min( "aggressive" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_min( \"aggressive\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_max( "aggressive" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_max( \"aggressive\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Nation_type:trait_default( "aggressive" ) command = "[ c fg \"#000099\"](Player)[/c].nation:trait_default( \"aggressive\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.government( "Monarchy" ) command = "find.government( \"Monarchy\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.government( 3 ) command = "find.government( 3 )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Government:rule_name() command = "[ c fg \"#000099\"](Government)[/c]:rule_name()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Government:name_translation() command = "[ c fg \"#000099\"](Government)[/c]:name_translation()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = server.started() command = "server.started()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = server.civilization_score( Player ) command = "server.civilization_score( [ c fg \"#000099\"](Player)[/c] )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = server.setting.get( "startunits" ) command = "server.setting.get( \"startunits\" )" return_type = type ( output )
note = "Works for settings listed in a scenario .sav file, and any omitted there and thus from current settings on server."
echo( return_type, command, output, note )
Direction = direction.str2dir( "west" )
output = direction.str2dir( "north" ) command = "direction.str2dir( \"north\" )" return_type = type ( output )
note = "Malfunctional in Freeciv 2.6.4 -- returns a string rather than a tolua object. Direction stuff won't work at all, including 'Unit:facing()'."
echo( return_type, command, output, note )
output = direction.next_ccw( Direction ) command = "direction.next_ccw( [ c fg \"#000099\"](Direction)[/c] )" return_type = type ( output )
note = "Works in 2.6.11"
echo( return_type, command, output, note )
output = direction.next_cw( Direction ) command = "direction.next_cw( [ c fg \"#000099\"](Direction)[/c] )" return_type = type ( output )
note = "Works in 2.6.11"
echo( return_type, command, output, note )
output = direction.opposite( Direction ) command = "direction.opposite( [ c fg \"#000099\"](Direction)[/c] )" return_type = type ( output )
note = "Works in 2.6.11"
echo( return_type, command, output, note )
output = Unit:facing() command = "[ c fg \"#000099\"](Unit)[/c]:facing()" return_type = type ( output )
note = "Works in 2.6.11"
echo( return_type, command, output, note )
-- testing Directions
for unit in Player:units_iterate() do
Unit = unit
Direction = direction.str2dir( "east" )
output = edit.unit_turn( Unit, Direction ) command = "[ c fg \"#000099\"](Unit)[/c], [ c fg \"#000099\"](Direction)[/c] )" return_type = type ( output )
note = "Works in 2.6.11?"
echo( return_type, command, output, note )
end
output = find.building_type( 7 ) command = "find.building_type( 7 )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.building_type( "City Walls" ) command = "find.building_type( \"City Walls\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type.build_cost command = "[ c fg \"#000099\"](Building_type)[/c].build_cost" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type:build_shield_cost() command = "[ c fg \"#000099\"](Building_type)[/c]:build_shield_cost()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type.id command = "[ c fg \"#000099\"](Building_type)[/c].id" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type:is_wonder() command = "[ c fg \"#000099\"](Building_type)[/c]:is_wonder()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type:is_great_wonder() command = "[ c fg \"#000099\"](Building_type)[/c]:is_great_wonder()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type:is_small_wonder() command = "[ c fg \"#000099\"](Building_type)[/c]:is_small_wonder()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type:is_improvement() command = "[ c fg \"#000099\"](Building_type)[/c]:is_improvement()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type:rule_name() command = "[ c fg \"#000099\"](Building_type)[/c]:rule_name()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Building_type:name_translation() command = "[ c fg \"#000099\"](Building_type)[/c]:name_translation()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.unit_type( 4 ) command = "find.unit_type( 4 )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.unit_type( "Phalanx" ) command = "find.unit_type( \"Phalanx\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Unit_type.build_cost command = "[ c fg \"#000099\"](Unit_type)[/c].build_cost" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Unit_type:build_shield_cost() command = "[ c fg \"#000099\"](Unit_type)[/c]:build_shield_cost()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Unit_type:has_flag( "Paratroopers" ) command = "[ c fg \"#000099\"](Unit_type)[/c]:has_flag( \"Paratroopers\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Unit_type:has_role( "AttackFastStartUnit" ) command = "[ c fg \"#000099\"](Unit_type)[/c].has_role( \"AttackFastStartUnit\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.role_unit_type( "DefendGood", nil ) command = "find.role_unit_type( \"DefendGood\", nil )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.role_unit_type( "DefendOk", Player ) command = "find.role_unit_type( \"DefendOk\", [ c fg \"#000099\"](Player)[/c] )" return_type = type ( output )
note = "If nil is replaced with a player, then response unit type is limited to those which the player can build."
echo( return_type, command, output, note )
output = Unit_type:can_exist_at_tile( find.tile( 0, 1 ) ) command = "[ c fg \"#000099\"](Unit_type)[/c]:can_exist_at_tile( find.tile( 0, 1 )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.tile( 10, 15 ) command = "find.tile( 10, 15 )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.tile( 1810 ) command = "find.tile( 1810 )" return_type = type ( output )
note = "Tile ID is ( x = 10 ) + ( ( y = 15 ) * server.setting.get( \"xsize\" ) )"
echo( return_type, command, output, note )
Tech_type = find.tech_type( "Bronze Working" )
output = edit.give_tech( Player, Tech_type, 0, nil, "hut" ) command = "edit.give_tech( [ c fg \"#000099\"](Player)[/c], [ c fg \"#000099\"](Tech_type)[/c], 0, nil, \"hut\" )" return_type = type ( output )
note = "Fields are: player, tech_type or nil for random tech, cost, notify, reason"
echo( return_type, command, output, note )
output = find.terrain( 1 ) command = "find.terrain( 1 )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = find.terrain( "Grassland" ) command = "find.terrain( \"Grassland\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Terrain:rule_name() command = "[ c fg \"#000099\"](Terrain)[/c]:rule_name()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Terrain:name_translation() command = "[ c fg \"#000099\"](Terrain)[/c]:name_translation()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = Terrain:class_name() command = "[ c fg \"#000099\"](Terrain)[/c]:class_name()" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
output = effects.world_bonus( "Enable_Space" ) command = "effects.world_bonus( \"Enable_Space\" )" return_type = type ( output )
note = "Effects names are listed in effects.ruleset"
echo( return_type, command, output, note )
output = effects.player_bonus( Player, "Specialist_Output" ) command = "effects.player_bonus( Player, \"Specialist_Output\" )" return_type = type ( output )
note = ""
echo( return_type, command, output, note )
for index = 0, 100, 1 do
Signal = find.signal( index )
if Signal == nil then break end
output = find.signal( index ) command = "find.signal( " .. index .. " )" return_type = type ( output )
echo( return_type, command, output, note )
output = find.signal_callback( Signal, index ) command = "find.signal_callback( Signal, index )" return_type = type ( output )
if output ~= nil then echo( return_type, command, output, note ) end
end
notify.event( nil, nil, E.CHAT_MSG, "notify.event E.CHAT_MSG goes to the chat pane only, no pop-ups, no Messages pane, works on turn 0 too")
notify.all( "notify.all: ALWAYS pop-up message even on turn 0, does not show in Messages or Chat panes on turn 0, does show in Messages and Chat panes after turn 0" )
notify.event( nil, nil, E.SCRIPT, "notify.event E.SCRIPT: ALWAYS pop-up message, even on turn 0, but no message in Messages pane on turn 0, does show after turn 0" )
notify.event( nil, nil, E.REPORT, "notify.event E.REPORT: goes to chat on turn 0, to Messages thereafter, never a pop-up" )
log.error( "%s", "log.error: Appears on turn 0 and thereafter in Chat pane if msg is different each time, otherwise msg becomes only 'Last message repeated x times'', bright red text, also included in error log files." )
notify.event( nil, nil, E.CHAT_MSG, "" )
option_names={ "aifill", "airliftingstyle", "allowtake", "alltemperate", "animals", "aqueductloss", "autoattack", "autosaves", "autotoggle", "barbarians", "borders", "citymindist", "citynames", "civilwarsize", "compress", "compresstype", "conquercost", "contactturns", "demography", "diplbulbcost", "diplchance", "diplgoldcost", "diplomacy", "disasters", "dispersion", "ec_chat", "ec_info", "ec_max_size", "ec_turns", "endspaceship", "endturn", "first_timeout", "fixedlength", "flatpoles", "foggedborders", "fogofwar", "foodbox", "freecost", "fulltradesize", "gameseed", "generator", "globalwarming", "gold", "happyborders", "homecaughtunits", "huts", "kicktime", "killcitizen", "killstack", "killunhomed", "landmass", "mapseed", "mapsize", "maxconnectionsperhost", "maxplayers", "mgr_distance", "mgr_foodneeded", "mgr_nationchance", "mgr_turninterval", "mgr_worldchance", "migration", "minplayers", "nationset", "naturalcitynames", "nettimeout", "netwait", "notradesize", "nuclearwinter", "occupychance", "onsetbarbs", "persistentready", "phasemode", "pingtime", "pingtimeout", "plrcolormode", "rapturedelay", "razechance", "restrictinfra", "revealmap", "revolen", "revolentype", "savefrequency", "savename", "savepalace", "saveturns", "sciencebox", "scorefile", "scorelog", "scoreloglevel", "separatepoles", "shieldbox", "singlepole", "size", "specials", "startcity", "startpos", "startunits", "steepness", "team_pooled_research", "teamplacement", "techlevel", "techlossforgiveness", "techlossrestore", "techlost_donor", "techlost_recv", "techpenalty", "temperature", "tilesperplayer", "timeaddenemymove", "timeout", "tinyisles", "topology", "trademindist", "trading_city", "trading_gold", "trading_tech", "traitdistribution", "turnblock", "unitwaittime", "unreachableprotects", "victories", "wetness", "xsize", "ysize"}
log.error( "%s", "\nNumber of known option names = " .. #option_names .. "\n" )
for i = 1, #option_names, 1 do
-- if the server.setting.get output is a number then no quotes, else ""
local option_value = server.setting.get( option_names[ i ] )
if type( tonumber( option_value ) ) ~= "number" then option_value="\"" .. option_value .. "\"" end
log.error("%s","\"" .. option_names[ i ] .. "\"" .. "," .. option_value )
end
notify.event( nil, nil, E.CHAT_MSG, "" )
notify.event( nil, nil, E.CHAT_MSG, "Dump global vars and functions list" )
-- globals.lua
-- show all global variables
local seen={}
function dump( t, i )
seen[ t ] = true
local s={}
local n = 0
for k in pairs( t ) do
n = n + 1
s[ n ] = k
end
table.sort(s)
for k, v in ipairs( s ) do
log.error( "%s", tostring(i) .. tostring(v) )
v = t[ v ]
if type( v ) == "table" and not seen[ v ] then
dump( v, i .. "\t" )
end
end
end
dump( _G, " " )
notify.event( nil, nil, E.CHAT_MSG, "" )
end
signal.connect( "turn_started", "s_command_examples" )
EDIT: Updated the routine to list known options and values.
This is for Lua script development and testing rather than a game feature.
Last edited by Molo_Parko on Thu Dec 05, 2024 4:15 pm, edited 4 times in total.
-
- Hardened
- Posts: 200
- Joined: Fri Jul 02, 2021 4:00 pm
Re: New features via Lua script
Code: Select all
option_names={ "aifill", "airliftingstyle", "allowtake", "alltemperate", "animals", "aqueductloss", "autoattack", "autosaves", "autotoggle", "barbarians", "borders", "citymindist", "citynames", "civilwarsize", "compress", "compresstype", "conquercost", "contactturns", "demography", "diplbulbcost", "diplchance", "diplgoldcost", "diplomacy", "disasters", "dispersion", "ec_chat", "ec_info", "ec_max_size", "ec_turns", "endspaceship", "endturn", "first_timeout", "fixedlength", "flatpoles", "foggedborders", "fogofwar", "foodbox", "freecost", "fulltradesize", "gameseed", "generator", "globalwarming", "gold", "happyborders", "homecaughtunits", "huts", "kicktime", "killcitizen", "killstack", "killunhomed", "landmass", "mapseed", "mapsize", "maxconnectionsperhost", "maxplayers", "mgr_distance", "mgr_foodneeded", "mgr_nationchance", "mgr_turninterval", "mgr_worldchance", "migration", "minplayers", "nationset", "naturalcitynames", "nettimeout", "netwait", "notradesize", "nuclearwinter", "occupychance", "onsetbarbs", "persistentready", "phasemode", "pingtime", "pingtimeout", "plrcolormode", "rapturedelay", "razechance", "restrictinfra", "revealmap", "revolen", "revolentype", "savefrequency", "savename", "savepalace", "saveturns", "sciencebox", "scorefile", "scorelog", "scoreloglevel", "separatepoles", "shieldbox", "singlepole", "size", "specials", "startcity", "startpos", "startunits", "steepness", "team_pooled_research", "teamplacement", "techlevel", "techlossforgiveness", "techlossrestore", "techlost_donor", "techlost_recv", "techpenalty", "temperature", "tilesperplayer", "timeaddenemymove", "timeout", "tinyisles", "topology", "trademindist", "trading_city", "trading_gold", "trading_tech", "traitdistribution", "turnblock", "unitwaittime", "unreachableprotects", "victories", "wetness", "xsize", "ysize"}
log.error( "%s", "\nNumber of known option names = " .. #option_names .. "\n" )
for i = 1, #option_names, 1 do
-- if the server.setting.get output is a number then no quotes, else ""
local option_value = server.setting.get( option_names[ i ] )
if type( tonumber( option_value ) ) ~= "number" then option_value="\"" .. option_value .. "\"" end
log.error("%s","\"" .. option_names[ i ] .. "\"" .. "," .. option_value )
end
Code: Select all
Number of known option names = 124
"aifill",13
"airliftingstyle",""
"allowtake","HAhadOo"
"alltemperate","DISABLED"
"animals",20
"aqueductloss",0
"autoattack","DISABLED"
"autosaves","TURN|GAMEOVER|QUITIDLE|INTERRUPT"
"autotoggle","DISABLED"
"barbarians","NORMAL"
"borders","ENABLED"
"citymindist",2
"citynames","PLAYER_UNIQUE"
"civilwarsize",10
"compress",6
"compresstype","BZIP2"
"conquercost",0
"contactturns",20
"demography","NASRLPEMOqrb"
"diplbulbcost",0
"diplchance",80
"diplgoldcost",0
"diplomacy","ALL"
"disasters",10
"dispersion",0
"ec_chat","ENABLED"
"ec_info","DISABLED"
"ec_max_size",256
"ec_turns",1
"endspaceship","ENABLED"
"endturn",5000
"first_timeout",-1
"fixedlength","DISABLED"
"flatpoles",100
"foggedborders","DISABLED"
"fogofwar","ENABLED"
"foodbox",100
"freecost",0
"fulltradesize",1
"gameseed",0
"generator","SCENARIO"
"globalwarming","ENABLED"
"gold",50
"happyborders","NATIONAL"
"homecaughtunits","ENABLED"
"huts",50
"kicktime",1800
"killcitizen","ENABLED"
"killstack","ENABLED"
"killunhomed",0
"landmass",33
"mapseed",0
"mapsize","FULLSIZE"
"maxconnectionsperhost",4
"maxplayers",11
"mgr_distance",0
"mgr_foodneeded","ENABLED"
"mgr_nationchance",50
"mgr_turninterval",5
"mgr_worldchance",10
"migration","DISABLED"
"minplayers",1
"nationset",""
"naturalcitynames","ENABLED"
"nettimeout",10
"netwait",4
"notradesize",0
"nuclearwinter","ENABLED"
"occupychance",0
"onsetbarbs",60
"persistentready","DISABLED"
"phasemode","ALL"
"pingtime",20
"pingtimeout",60
"plrcolormode","PLR_ORDER"
"rapturedelay",1
"razechance",20
"restrictinfra","DISABLED"
"revealmap",""
"revolen",5
"revolentype","RANDOM"
"savefrequency",15
"savename","freeciv"
"savepalace","ENABLED"
"saveturns",10
"sciencebox",150
"scorefile","freeciv-score.log"
"scorelog","DISABLED"
"scoreloglevel","ALL"
"separatepoles","ENABLED"
"shieldbox",100
"singlepole","DISABLED"
"size",4
"specials",250
"startcity","DISABLED"
"startpos","DEFAULT"
"startunits","ccxx"
"steepness",30
"team_pooled_research","ENABLED"
"teamplacement","CLOSEST"
"techlevel",3
"techlossforgiveness",-1
"techlossrestore",50
"techlost_donor",0
"techlost_recv",0
"techpenalty",100
"temperature",50
"tilesperplayer",100
"timeaddenemymove",0
"timeout",0
"tinyisles","DISABLED"
"topology","WRAPX"
"trademindist",9
"trading_city","ENABLED"
"trading_gold","ENABLED"
"trading_tech","ENABLED"
"traitdistribution","FIXED"
"turnblock","ENABLED"
"unitwaittime",0
"unreachableprotects","ENABLED"
"victories","ALLIED"
"wetness",50
"xsize",144
"ysize",96
When the contents of the 'code' section are added to a scenario file's [script]code=$$ section, the above displays the values of all known scenario [settings] (Freeciv 2.6.4 to 2.6.11 at least) whether or not they are listed in the scenario file itself.
EDIT: Updated to show count of known options ( 124 ) and to output as "option name",30 or "option name","text_string" so that it matches the format used in sav files in v2.6.x.
This is for Lua script development and testing rather than a game feature.