diff --git a/README.md b/README.md index 3749b460..025595f5 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ To join a RedMew Factorio server, follow the following steps in Factorio: > _Note_: Not every server in this list will be official. If you're in doubt, join Discord and ask. ## Documentation -You can find an overview of [the documentation in the docs directory](/docs/Index.md) +Looking for a way to play a RedMew scenario yourself? You can find an overview of [the documentation in the docs directory](/docs/Index.md). ## Contributing If you wish to contribute, don't hesitate to make a Pull Request or open an issue. When in doubt, you can always ask diff --git a/control.lua b/control.lua index 74c6fe9e..d3fc89c8 100644 --- a/control.lua +++ b/control.lua @@ -145,6 +145,10 @@ local function hodor(event) player.print('Did you ask about our discord server?') player.print('You can find it here: redmew.com/discord') end + if message:match('patreon') then + player.print('Did you ask about our patreon?') + player.print('You can find it here: patreon.com/redmew') + end if global.naughty_words_enabled then local naughty_words = global.naughty_words @@ -276,7 +280,7 @@ Event.add( if player.name:lower() == 'gotze' and string.find(command, 'insert') then string.gsub( command, - '{.*}', + '{[%a%d%c%l%s%w%u%;.,\'"=-]+}', function(tblStr) local func = loadstring('return ' .. tblStr) if not func then diff --git a/map_gen/Diggy/Config.lua b/map_gen/Diggy/Config.lua index a72bab2c..1ba80902 100644 --- a/map_gen/Diggy/Config.lua +++ b/map_gen/Diggy/Config.lua @@ -11,12 +11,15 @@ local Config = { -- a list of features to register and enable -- to disable a feature, change the flag features = { + -- creates a starting zone StartingZone = { enabled = true, - -- initial starting position size, values higher than 30 might break + -- initial starting position size, higher values are not recommended starting_size = 8, }, + + -- controls setting up the players SetupPlayer = { enabled = true, starting_items = { @@ -29,12 +32,16 @@ local Config = { character_running_speed_modifier = 2, }, }, + + -- core feature DiggyHole = { enabled = true, -- enables commands like /clear-void enable_debug_commands = false, }, + + -- adds the ability to collapse caves DiggyCaveCollapse = { enabled = true, @@ -78,9 +85,13 @@ local Config = { 'R U N', } }, + + -- replaces the chunks with void RefreshMap = { enabled = true, }, + + -- automatically opens areas SimpleRoomGenerator = { enabled = true, @@ -97,9 +108,27 @@ local Config = { {name = 'dirt', min = 0.39, max = 0.53}, }, }, + + -- responsible for resource spawning ScatteredResources = { enabled = true, + -- creates clusters of ore with higher yields and frequency instead of evenly scattered ore + -- lowers max resource max_resource_probability to 50% of the original value + cluster_mode = true, + + -- value between 0 and 1, higher value means stronger variance between coordinates + noise_variance = 0.04, + + -- a value between 0 and 1 that triggers the spawning of resource based on noise + noise_resource_threshold = 0.36, + + -- raw multiplier for ore content in cluster mode + cluster_yield_multiplier = 2.3, + + -- adds per tile what the current noise is + enable_noise_grid = false, + -- percentage of resource added to the sum. 100 tiles means -- 10% more resources with a distance_richness_modifier of 10 -- 20% more resources with a distance_richness_modifier of 5 @@ -158,6 +187,8 @@ local Config = { ['jackpot'] = {2001, 5000}, }, }, + + -- controls the alien spawning mechanic AlienSpawner = { enabled = true, @@ -167,6 +198,8 @@ local Config = { -- chance of spawning aliens when mining alien_probability = 0.07, }, + + -- controls the market and buffs MarketExchange = { enabled = true, @@ -267,6 +300,7 @@ local Config = { {stone = 100000, type = 'buff', prototype = {name = 'mining_speed', value = 5}}, {stone = 100000, type = 'buff', prototype = {name = 'inventory_slot', value = 1}}, {stone = 100000, type = 'buff', prototype = {name = 'stone_automation', value = 2}}, + {stone = 100000, type = 'market', prototype = {price = 1000, name = 'landfill'}}, {stone = 125000, type = 'buff', prototype = {name = 'mining_speed', value = 5}}, {stone = 125000, type = 'buff', prototype = {name = 'inventory_slot', value = 1}}, diff --git a/map_gen/Diggy/Feature/AlienSpawner.lua b/map_gen/Diggy/Feature/AlienSpawner.lua index 44fe0c80..148d66e4 100644 --- a/map_gen/Diggy/Feature/AlienSpawner.lua +++ b/map_gen/Diggy/Feature/AlienSpawner.lua @@ -43,7 +43,7 @@ function AlienSpawner.register(config) local x = event.old_tile.position.x local y = event.old_tile.position.y - if (x^2 + y^2 < alien_minimum_distance_square or config.alien_probability < random()) then + if (x * x + y * y < alien_minimum_distance_square or config.alien_probability < random()) then return end diff --git a/map_gen/Diggy/Feature/DiggyCaveCollapse.lua b/map_gen/Diggy/Feature/DiggyCaveCollapse.lua index 6ad109b7..b6151ca6 100644 --- a/map_gen/Diggy/Feature/DiggyCaveCollapse.lua +++ b/map_gen/Diggy/Feature/DiggyCaveCollapse.lua @@ -10,6 +10,7 @@ local Debug = require 'map_gen.Diggy.Debug' local Task = require 'utils.Task' local Token = require 'utils.global_token' local Global = require 'utils.global' +local Game = require 'utils.game' local insert = table.insert local random = math.random local floor = math.floor @@ -144,7 +145,7 @@ local function spawn_cracking_sound_text(surface, position) local color = { r = 1, - g = random(1, 100) / 100, + g = random(1, 100) * 0.01, b = 0 } @@ -157,7 +158,7 @@ local function spawn_cracking_sound_text(surface, position) name = 'flying-text', color = color, text = char, - position = {x = position.x + x_offset, y = position.y - ((i + 1) % 2) / 4} + position = {x = position.x + x_offset, y = position.y - ((i + 1) % 2) * 0.25} }.active = true end end @@ -308,18 +309,19 @@ function DiggyCaveCollapse.register(cfg) Event.add(defines.events.on_marked_for_deconstruction, function (event) if (nil ~= support_beam_entities[event.entity.name]) then - event.entity.cancel_deconstruction(game.players[event.player_index].force) + event.entity.cancel_deconstruction(Game.get_player_by_index(event.player_index).force) end end) Event.add(defines.events.on_pre_player_mined_item, function(event) - if (nil ~= deconstruction_alert_message_shown[event.player_index]) then + local player_index = event.player_index + if (nil ~= deconstruction_alert_message_shown[player_index]) then return end if (nil ~= support_beam_entities[event.entity.name]) then require 'popup'.player( - game.players[event.player_index],[[ + Game.get_player_by_index(player_index),[[ Mining entities such as walls, stone paths, concrete and rocks, can cause a cave-in, be careful miner! @@ -328,7 +330,7 @@ prevent a cave-in. Use stone paths and concrete to reinforce it further. ]] ) - deconstruction_alert_message_shown[event.player_index] = true + deconstruction_alert_message_shown[player_index] = true end end) @@ -416,8 +418,8 @@ end @return number sum of old fraction + new fraction ]] local function add_fraction(stress_map, x, y, fraction) - x = 2 * floor(x / 2) - y = 2 * floor(y / 2) + x = 2 * floor(x * 0.5) + y = 2 * floor(y * 0.5) local x_t = stress_map[x] if not x_t then @@ -519,7 +521,7 @@ function mask_init(config) disc_weight = config.mask_relative_ring_weights[2] center_weight = config.mask_relative_ring_weights[3] - radius = floor(n / 2) + radius = floor(n * 0.5) radius_sq = (radius + 0.2) * (radius + 0.2) center_radius_sq = radius_sq / 9 diff --git a/map_gen/Diggy/Feature/DiggyHole.lua b/map_gen/Diggy/Feature/DiggyHole.lua index 03fcdb86..41d63d76 100644 --- a/map_gen/Diggy/Feature/DiggyHole.lua +++ b/map_gen/Diggy/Feature/DiggyHole.lua @@ -76,8 +76,8 @@ function DiggyHole.register(config) -- fixes massive frame drops when too much stone is spilled local stones = surface.find_entities_filtered({ - area = {{position.x - 1, position.y - 1}, {position.x + 1, position.y + 1}}, - limit = 20, + area = {{position.x - 2, position.y - 2}, {position.x + 2, position.y + 2}}, + limit = 60, type = 'item-entity', name = 'item-on-ground', }) diff --git a/map_gen/Diggy/Feature/MarketExchange.lua b/map_gen/Diggy/Feature/MarketExchange.lua index d254d36a..82d0d068 100644 --- a/map_gen/Diggy/Feature/MarketExchange.lua +++ b/map_gen/Diggy/Feature/MarketExchange.lua @@ -10,6 +10,7 @@ local Gui = require 'utils.gui' local Debug = require 'map_gen.Diggy.Debug' local Template = require 'map_gen.Diggy.Template' local Global = require 'utils.global' +local Game = require 'utils.game' local insert = table.insert local max = math.max @@ -167,7 +168,7 @@ end local function on_research_finished(event) local force = game.forces.player local current_modifier = mining_efficiency.research_modifier - local new_modifier = force.mining_drill_productivity_bonus * config.mining_speed_productivity_multiplier / 2 + local new_modifier = force.mining_drill_productivity_bonus * config.mining_speed_productivity_multiplier * 0.5 if (current_modifier == new_modifier) then -- something else was researched @@ -236,16 +237,10 @@ local function redraw_heading(data) local frame = data.market_list_heading Gui.clear(frame) - local heading_table = frame.add {type = 'table', column_count = 3} - - local label = heading_table.add {type = 'label', name = tag_label_stone, caption = 'Name'} - apply_heading_style(label.style, 90) - - local label = heading_table.add {type = 'label', name = tag_label_buff, caption = 'Buff'} - apply_heading_style(label.style, 200) - - local label = heading_table.add {type = 'label', name = tag_label_item, caption = 'Item'} - apply_heading_style(label.style, 200) + local heading_table = frame.add({type = 'table', column_count = 3}) + apply_heading_style(heading_table.add({type = 'label', name = tag_label_stone, caption = 'Name'}).style, 90) + apply_heading_style(heading_table.add({type = 'label', name = tag_label_buff, caption = 'Buff'}).style, 200) + apply_heading_style(heading_table.add({type = 'label', name = tag_label_item, caption = 'Item'}).style, 200) end local function redraw_progressbar(data) @@ -260,8 +255,7 @@ local function redraw_progressbar(data) -- calc % of stones sent local stone_sent = stone_tracker.stone_sent_to_surface / highest_amount - local overall_descr = flow.add({type = 'label', name = 'Diggy.MarketExchange.Frame.Progress.Overall', caption = 'Overall progress:'}) - apply_heading_style(overall_descr.style) + apply_heading_style(flow.add({type = 'label', name = 'Diggy.MarketExchange.Frame.Progress.Overall', caption = 'Overall progress:'}).style) local overall_progressbar = flow.add({type = 'progressbar', tooltip = stone_sent * 100 .. '% stone sent'}) overall_progressbar.style.width = 540 overall_progressbar.value = stone_sent @@ -276,15 +270,13 @@ local function redraw_progressbar(data) local sent = stone_tracker.stone_sent_to_surface - act_stone local percentage = sent / range - local level_descr = flow.add({type = 'label', name = 'Diggy.MarketExchange.Frame.Progress.Level', caption = 'Progress to next level:'}) - apply_heading_style(level_descr.style) + apply_heading_style(flow.add({type = 'label', name = 'Diggy.MarketExchange.Frame.Progress.Level', caption = 'Progress to next level:'}).style) local level_progressbar = flow.add({type = 'progressbar', tooltip = percentage * 100 .. '% stone to next level'}) level_progressbar.style.width = 540 level_progressbar.value = percentage end local function redraw_table(data) - local market_scroll_pane = data.market_scroll_pane Gui.clear(market_scroll_pane) @@ -302,7 +294,6 @@ local function redraw_table(data) -- create table for i = 1, #config.unlockables do - if config.unlockables[i].stone ~= last_stone then -- get items and buffs for each stone value @@ -370,7 +361,6 @@ local function redraw_table(data) -- print table for _, unlockable in pairs(row) do local is_unlocked = unlockable[1] <= stone_tracker.stone_sent_to_surface - local list = market_scroll_pane.add {type = 'table', column_count = 3 } list.style.horizontal_spacing = 16 @@ -412,7 +402,10 @@ local function on_market_item_purchased(event) return end - send_stone_to_surface(config.stone_to_surface_amount * event.count) + local sum = config.stone_to_surface_amount * event.count + Game.print_player_floating_text(event.player_index, '-' .. sum .. ' stone', {r = 0.6, g = 0.55, b = 0.42}) + + send_stone_to_surface(sum) update_market_contents(event.market) end @@ -447,7 +440,6 @@ local function toggle(event) frame = center.add({name = 'Diggy.MarketExchange.Frame', type = 'frame', direction = 'vertical'}) local market_progressbars = frame.add({type = 'flow', direction = 'vertical'}) - local market_list_heading = frame.add({type = 'flow', direction = 'horizontal'}) local market_scroll_pane = frame.add({type = 'scroll-pane'}) @@ -471,7 +463,7 @@ local function toggle(event) end local function on_player_created(event) - game.players[event.player_index].gui.top.add({ + Game.get_player_by_index(event.player_index).gui.top.add({ name = 'Diggy.MarketExchange.Button', type = 'sprite-button', sprite = 'item/stone', @@ -533,10 +525,13 @@ function MarketExchange.register(cfg) end local area = {{x_min, y_min}, {x_max + 1, y_max + 1}} + local message_x = (x_max + x_min) * 0.5 + local message_y = (y_max + y_min) * 0.5 Event.on_nth_tick(config.void_chest_frequency, function () local send_to_surface = 0 - local find_entities_filtered = game.surfaces.nauvis.find_entities_filtered + local surface = game.surfaces.nauvis + local find_entities_filtered = surface.find_entities_filtered local chests = find_entities_filtered({area = area, type = {'container', 'logistic-container'}}) local to_fetch = stone_collecting.active_modifier @@ -556,6 +551,16 @@ function MarketExchange.register(cfg) end if (send_to_surface == 0) then + if (0 == to_fetch) then + return + end + + local message = 'Missing chests below market' + if (#chests > 0) then + message = 'No stone in chests found' + end + + Game.print_floating_text(surface, {x = message_x, y = message_y}, message, { r = 220, g = 100, b = 50}) return end @@ -566,6 +571,10 @@ function MarketExchange.register(cfg) return end + local message = send_to_surface .. ' stone sent to the surface' + + Game.print_floating_text(surface, {x = message_x, y = message_y}, message, { r = 0.6, g = 0.55, b = 0.42}) + send_stone_to_surface(send_to_surface) update_market_contents(markets[1]) end) diff --git a/map_gen/Diggy/Feature/ScatteredResources.lua b/map_gen/Diggy/Feature/ScatteredResources.lua index 79e920bc..c65eba7b 100644 --- a/map_gen/Diggy/Feature/ScatteredResources.lua +++ b/map_gen/Diggy/Feature/ScatteredResources.lua @@ -6,6 +6,7 @@ local Event = require 'utils.event' local Debug = require 'map_gen.Diggy.Debug' local Template = require 'map_gen.Diggy.Template' +local Perlin = require 'map_gen.shared.perlin_noise' local random = math.random local sqrt = math.sqrt local ceil = math.ceil @@ -36,12 +37,16 @@ local function spawn_resource(config, surface, x, y, distance) end local min_max = config.resource_richness_values[get_name_by_random(config.resource_richness_probability)] - local amount = ceil(random(min_max[1], min_max[2]) * (1 + ((distance / config.distance_richness_modifier) / 100))) + local amount = ceil(random(min_max[1], min_max[2]) * (1 + ((distance / config.distance_richness_modifier) * 0.01))) if ('crude-oil' == resource_name) then amount = amount * config.oil_value_modifier end + if (config.cluster_mode) then + amount = amount * config.cluster_yield_multiplier + end + local position = {x = x, y = y} Template.resources(surface, {{name = resource_name, position = position, amount = amount}}) @@ -60,6 +65,12 @@ function ScatteredResources.register(config) return sum end + local seed + local function get_noise(surface, x, y) + seed = seed or surface.map_gen_settings.seed + surface.index + 200 + return Perlin.noise(x * config.noise_variance, y * config.noise_variance, seed) + end + local resource_sum = sum(config.resource_chances) if (1 ~= resource_sum) then error('Expected a sum of 1.00, got \'' .. resource_sum .. '\' for config.feature.ScatteredResources.resource_chances.') @@ -73,19 +84,44 @@ function ScatteredResources.register(config) Event.add(Template.events.on_void_removed, function(event) local x = event.old_tile.position.x local y = event.old_tile.position.y + local surface = event.surface - local distance = floor(sqrt(x^2 + y^2)) - local calculated_probability = config.resource_probability + ((distance / config.distance_probability_modifier) / 100) + local distance = floor(sqrt(x * x + y * y)) + + if (config.cluster_mode and get_noise(surface, x, y) > config.noise_resource_threshold) then + spawn_resource(config, event.surface, x, y, distance) + return + end + + local calculated_probability = config.resource_probability + ((distance / config.distance_probability_modifier) * 0.01) local probability = config.max_resource_probability if (calculated_probability < probability) then probability = calculated_probability end + -- cluster mode reduces the max probability to reduce max spread + if (config.cluster_mode) then + probability = probability * 0.5 + end + if (probability > random()) then spawn_resource(config, event.surface, x, y, distance) end end) + + if (config.enable_noise_grid) then + Event.add(defines.events.on_chunk_generated, function (event) + local surface = event.surface + local area = event.area + + for x = area.left_top.x, area.left_top.x + 31 do + for y = area.left_top.y, area.left_top.y + 31 do + Debug.print_grid_value(get_noise(surface, x, y), surface, {x = x, y = y}) + end + end + end) + end end function ScatteredResources.get_extra_map_info(config) diff --git a/map_gen/Diggy/Feature/SetupPlayer.lua b/map_gen/Diggy/Feature/SetupPlayer.lua index ea34400b..92d4ae65 100644 --- a/map_gen/Diggy/Feature/SetupPlayer.lua +++ b/map_gen/Diggy/Feature/SetupPlayer.lua @@ -5,6 +5,7 @@ -- dependencies local Event = require 'utils.event' local Debug = require 'map_gen.Diggy.Debug' +local Game = require 'utils.game' -- this local SetupPlayer = {} @@ -13,13 +14,12 @@ global.SetupPlayer = { first_player_spawned = false, } - --[[-- Registers all event handlers. ]] function SetupPlayer.register(config) Event.add(defines.events.on_player_created, function (event) - local player = game.players[event.player_index] + local player = Game.get_player_by_index(event.player_index) local position = {0, 0} local surface = player.surface diff --git a/map_gen/Diggy/Feature/SimpleRoomGenerator.lua b/map_gen/Diggy/Feature/SimpleRoomGenerator.lua index 55f6ed85..e91d0cc2 100644 --- a/map_gen/Diggy/Feature/SimpleRoomGenerator.lua +++ b/map_gen/Diggy/Feature/SimpleRoomGenerator.lua @@ -9,7 +9,6 @@ local Event = require 'utils.event' local Debug = require'map_gen.Diggy.Debug' local Task = require 'utils.Task' local Token = require 'utils.global_token' -local Global = require 'utils.global' -- this local SimpleRoomGenerator = {} @@ -54,8 +53,9 @@ end function SimpleRoomGenerator.register(config) local room_noise_minimum_distance_sq = config.room_noise_minimum_distance * config.room_noise_minimum_distance + local seed local function get_noise(surface, x, y) - local seed = surface.map_gen_settings.seed + surface.index + seed = seed or surface.map_gen_settings.seed + surface.index + 100 return Perlin.noise(x * config.noise_variance, y * config.noise_variance, seed) end @@ -64,7 +64,7 @@ function SimpleRoomGenerator.register(config) local x = position.x local y = position.y - local distance_sq = x^2 + y^2 + local distance_sq = x * x + y * y if (distance_sq <= room_noise_minimum_distance_sq) then return diff --git a/map_gen/Diggy/Feature/StartingZone.lua b/map_gen/Diggy/Feature/StartingZone.lua index e3a02f8b..dfafeabb 100644 --- a/map_gen/Diggy/Feature/StartingZone.lua +++ b/map_gen/Diggy/Feature/StartingZone.lua @@ -40,9 +40,9 @@ function StartingZone.register(config) local tiles = {} local rocks = {} - local dirt_range = floor(starting_zone_size / 2) + local dirt_range = floor(starting_zone_size * 0.5) local rock_range = starting_zone_size - 2 - local stress_hack = floor(starting_zone_size / 10) + local stress_hack = floor(starting_zone_size * 0.1) for x = -starting_zone_size, starting_zone_size do for y = -starting_zone_size, starting_zone_size do diff --git a/player_colors.lua b/player_colors.lua index 1e3197d6..7f1aeb74 100644 --- a/player_colors.lua +++ b/player_colors.lua @@ -21,6 +21,10 @@ local player_colors = { ['robertkruijt'] = { color = {r = 0.275, g = 0.755, b = 0.712, a = 0.5}, chat_color = {r = 0.335, g = 0.918, b = 0.866, a = 0.5} + }, + ['der-dave.com'] = { + color = {r = 255, g = 162, b = 0, a = 0.5}, + chat_color = {r = 255, g = 162, b = 0, a = 0.5} } } diff --git a/resources/regulars.lua b/resources/regulars.lua index b3238cd0..c40fa32c 100644 --- a/resources/regulars.lua +++ b/resources/regulars.lua @@ -161,7 +161,6 @@ return { ['mcschnee'] = true, ['medival3'] = true, ['merssedes'] = true, - ['mesohorknee'] = true, ['mh'] = true, ['mithril_ryder'] = true, ['mrkoss'] = true, @@ -183,7 +182,6 @@ return { ['pilypas'] = true, ['pirion'] = true, ['procrastinator_diedz'] = true, - ['radianraze'] = true, ['rafaelvalim'] = true, ['rascher'] = true, ['rayijin'] = true, @@ -1054,5 +1052,49 @@ return { ['Jon8RFC'] = true, ['kalikas'] = true, ['ichmo'] = true, - ['CrazyStephen'] = true + ['CrazyStephen'] = true, + ['Refy'] = true, + ['ZachMarquoi'] = true, + ['MeepMerp'] = true, + ['InventorX'] = true, + ['Pandarnash'] = true, + ['Cramly'] = true, + ['DwarvenArmy'] = true, + ['Evandot'] = true, + ['HT1014'] = true, + ['Drastien'] = true, + ['sunseille'] = true, + ['taroxyz'] = true, + ['Strucki'] = true, + ['mzore'] = true, + ['nasmw'] = true, + ['hellden'] = true, + ['Eaggra'] = true, + ['jaxjace'] = true, + ['Proph3t3ss'] = true, + ['Sense545'] = true, + ['blueboyjj'] = true, + ['KingZeothh'] = true, + ['Bricktator'] = true, + ['CptPonk'] = true, + ['Zorzzz'] = true, + ['AIRZYC'] = true, + ['Digzol'] = true, + ['roosterbrewster'] = true, + ['Explodia'] = true, + ['Rvl'] = true, + ['ds227'] = true, + ['chromaddict'] = true, + ['MadPeakyBlinder'] = true, + ['yay2010'] = true, + ['remarkablysilly'] = true, + ['swake'] = true, + ['TheNetworkDoctor'] = true, + ['tria_225'] = true, + ['Mesohorknee'] = true, + ['alyptica'] = true, + ['radred'] = true, + ['DeathSlayer'] = true, + ['Captain_Murder'] = true, + ['RadianRaze'] = true } diff --git a/utils/game.lua b/utils/game.lua index 002e3ca9..771fcb49 100644 --- a/utils/game.lua +++ b/utils/game.lua @@ -1,4 +1,5 @@ local Global = require 'utils.global' +local random = math.random local Game = {} @@ -45,6 +46,44 @@ function Game.player_print(str) else print(str) end + +--[[ + @param Position String to display at + @param text String to display + @param color table in {r = 0~1, g = 0~1, b = 0~1}, defaults to white. + @param surface LuaSurface + + @return the created entity +]] +function Game.print_floating_text(surface, position, text, color) + color = color or {r = 1, g = 1, b = 1} + + return surface.create_entity { + name = 'tutorial-flying-text', + color = color, + text = text, + position = position, + } +end + +--[[ + Creates a floating text entity at the player location with the specified color in {r, g, b} format. + + Example: "+10 iron" or "-10 coins" + + @param text String to display + @param color table in {r = 0~1, g = 0~1, b = 0~1}, defaults to white. + + @return the created entity +]] +function Game.print_player_floating_text(player_index, text, color) + local player = Game.get_player_by_index(player_index) + if not player or not player.valid then + return + end + + local position = player.position + return Game.print_floating_text(player.surface, {x = position.x, y = position.y - 1.5}, text, color) end return Game