diff --git a/config.lua b/config.lua
index 3a48d7a2..698c27dc 100644
--- a/config.lua
+++ b/config.lua
@@ -167,7 +167,7 @@ global.config = {
         -- prints messages when the player joins
         join_messages = {
             'Welcome to this map created by the RedMew team. You can join our discord at: redmew.com/discord',
-            'Click the question mark in the top left corner for server information and map details.'
+            'Click the infomation icon in the top left corner for server information and map details.'
         },
         cutscene = false,
         -- format is a table: {{message, weight}, {message, weight}}, where a higher weight has more chance to be shown
diff --git a/locale/en/redmew_maps.cfg b/locale/en/redmew_maps.cfg
index 692f05b0..9decba2b 100644
--- a/locale/en/redmew_maps.cfg
+++ b/locale/en/redmew_maps.cfg
@@ -126,3 +126,18 @@ switch_msg=Go ahead and pick a quadrant you'd like to help out!
 force_sync_research=New research complete:
 
 train_notice1=## - Your items have been returned to __1__ at:
+
+# locale linked to concrete jungle
+[concrete_jungle]
+welcome_popup_title=Welcome to Concrete jungle
+welcome_popup_player_name=Hello __1__
+welcome_popup_line_1=Most items can't be placed on the ground!
+welcome_popup_line_2=Place stone brick, concrete or reinforced concrete on the ground,\nbefore placing items and machines!
+welcome_popup_line_3=More information can be found in the __1__ tab\nin __3__ __2__
+
+blueprint=blueprint
+blueprint_not_enough_ground_support=Some parts of this __1__ cannot be placed here, they need better ground support!
+entity_not_enough_ground_support=__1__ requires at least: __2__
+
+anti_grief_kick_reason=Spilling too many items on the ground
+anti_grief_jail_reason=You have spilled too many items on the ground, contact an admin
diff --git a/map_gen/maps/concrete_jungle.lua b/map_gen/maps/concrete_jungle.lua
index 77becc33..4cd82634 100644
--- a/map_gen/maps/concrete_jungle.lua
+++ b/map_gen/maps/concrete_jungle.lua
@@ -7,6 +7,8 @@ local Color = require 'resources.color_presets'
 local Retailer = require 'features.retailer'
 local Task = require 'utils.task'
 local Popup = require 'features.gui.popup'
+local Global = require 'utils.global'
+local Report = require 'features.report'
 
 local redmew_config = global.config
 
@@ -43,6 +45,16 @@ if concrete_unlocker then
     )
 end
 
+local times_spilled = {}
+Global.register(
+    {
+        times_spilled = times_spilled
+    },
+    function(tbl)
+        times_spilled = tbl.times_spilled
+    end
+)
+
 local ScenarioInfo = require 'features.gui.info'
 
 ScenarioInfo.set_map_name('Concrete Jungle')
@@ -195,6 +207,7 @@ Thanks to Sangria_Louie for the map suggestion!
 )
 
 RestrictEntities.set_tile_bp()
+RestrictEntities.enable_spill()
 
 --- The logic for checking that there are the correct ground support under the entity's position
 RestrictEntities.set_keep_alive_callback(
@@ -230,6 +243,56 @@ RestrictEntities.set_keep_alive_callback(
     )
 )
 
+local clean_cursor_delay =
+    Token.register(
+    function(params)
+        params.player.clean_cursor()
+    end
+)
+
+--- Anti griefing
+
+local anti_grief_tries = 3 -- Change this number to change how many 'shots' a player has got
+local forgiveness_time = 432000 -- Time before previous offences are forgiven, in ticks (60 ticks/sec)
+local anti_grief_kick_tries = math.ceil(anti_grief_tries / 2) -- Tries before kick warning
+
+RestrictEntities.set_anti_grief_callback(
+    Token.register(
+        function(_, player)
+            Popup.player(player, [[
+Look out!
+
+You are trying to replace entities which have items inside!
+This is causing the items to spill out on the ground.
+
+Please be careful!
+]], nil, nil, 'entity_placement_restriction_inventory_warning')
+            local player_stat = times_spilled[player.index]
+            local number_of_spilled = player_stat and player_stat.count or 0
+
+            local last_offence = player_stat and player_stat.tick or 0
+            local time_since_last_offence = game.tick - last_offence
+
+            if (last_offence > 0 and time_since_last_offence >= forgiveness_time) then
+                game.print('Forgiven!')
+                number_of_spilled = 0
+            end
+
+            if number_of_spilled >= anti_grief_tries then
+                Report.jail(player, nil)
+                player.print({'', '[color=yellow]', {'concrete_jungle.anti_grief_jail_reason'}, '[/color]'})
+                Report.report(nil, player, 'Spilling too many items on the ground')
+                times_spilled[player.index] = nil
+                return
+            elseif number_of_spilled == anti_grief_kick_tries then
+                game.kick_player(player, {'concrete_jungle.anti_grief_kick_reason'})
+            end
+            times_spilled[player.index] = {count = number_of_spilled + 1, tick = game.tick}
+            Task.set_timeout_in_ticks(1, clean_cursor_delay, {player = player})
+        end
+    )
+)
+
 local function print_floating_text(player, entity, text, color)
     color = color or Color.white
     local surface = player.surface
@@ -259,17 +322,17 @@ local function on_destroy(event)
 
     if p and p.valid then
         if not (name == 'blueprint') then
-            local tier = '[tile=stone-path] stone path'
+            local tier = {'item-name.stone-path'}
             if (entity_tiers[name] == 2) then
-                tier = '[tile=concrete] concrete'
+                tier = {'item-name.concrete'}
             elseif (entity_tiers[name] == 3) then
-                tier = '[tile=refined-concrete] refined concrete'
+                tier = {'item-name.refined-concrete'}
             end
-            local text = '[item=' .. name .. '] requires at least ' .. tier
+            local text = {'concrete_jungle.entity_not_enough_ground_support', '[item=' .. name .. ']', tier}
             --local text = '[color=yellow]This [/color][item=' .. name .. '][color=yellow] cannot be placed here, it needs ground support of at least [/color]' .. tier
             print_floating_text(p, entity, text)
         else
-            p.print('[color=yellow]Some parts of this [/color][color=red]blueprint[/color][color=yellow] cannot be placed here, they need better ground support![/color]')
+            p.print({'', '[color=yellow]', {'concrete_jungle.blueprint_not_enough_ground_support', {'', '[/color][color=red]', {'concrete_jungle.blueprint'}, '[/color][color=yellow]'}}, '[/color]'})
         end
     end
 end
@@ -361,32 +424,44 @@ local function player_built_tile(event)
     end
 end
 
-local function first_time(event)
-    local p = game.get_player(event.player_index)
-    Popup.player(p, '[color=yellow]Hello ' .. p.name .. '[/color]' ..
-[[
-
-
-Most items can't be placed on the ground!
-
-Place stone brick, concrete or reinforced concrete on the ground,
-before placing items and machines!
-
-More information can be found in the [color=red]Map Info[/color] tab
-in [virtual-signal=signal-info] [color=red]Redmew Info[/color]
-]],
-'Welcome to Concrete Jungle', nil, 'concrete_jungle_intro')
-end
+local first_time =
+    Token.register(
+    function(params)
+        local p = game.get_player(params.event.player_index)
+        Popup.player(
+            p,
+            {
+                '',
+                '[color=yellow]',
+                {'concrete_jungle.welcome_popup_player_name', p.name},
+                '[/color]\n\n',
+                {'concrete_jungle.welcome_popup_line_1'},
+                '\n\n',
+                {'concrete_jungle.welcome_popup_line_2'},
+                '\n\n',
+                {'concrete_jungle.welcome_popup_line_3', '[color=red]Map Info[/color]', '[color=red]Redmew Info[/color]', '[virtual-signal=signal-info]'}
+            },
+            {'concrete_jungle.welcome_popup_title'},
+            nil,
+            'concrete_jungle_intro'
+        )
+    end
+)
 
 Event.add(RestrictEntities.events.on_pre_restricted_entity_destroyed, on_destroy)
 Event.add(defines.events.on_player_mined_tile, player_mined_tile)
 Event.add(defines.events.on_marked_for_deconstruction, marked_for_deconstruction)
 Event.add(defines.events.on_player_built_tile, player_built_tile)
 Event.add(defines.events.on_robot_built_tile, player_built_tile)
-Event.add(defines.events.on_player_created, first_time)
+Event.add(
+    defines.events.on_player_created,
+    function(event)
+        Task.set_timeout_in_ticks(900, first_time, {event = event})
+    end
+)
 Event.on_init(on_init)
 
---Creating the starting circle
+--- Creating the starting circle (Map_gen)
 local circle = b.circle(6)
 local square = b.rectangle(3, 3)
 local concrete_square = b.change_tile(square, true, 'hazard-concrete-left')
diff --git a/map_gen/shared/entity_placement_restriction.lua b/map_gen/shared/entity_placement_restriction.lua
index ea84e558..ca14f3d1 100644
--- a/map_gen/shared/entity_placement_restriction.lua
+++ b/map_gen/shared/entity_placement_restriction.lua
@@ -44,8 +44,6 @@ local Event = require 'utils.event'
 local Global = require 'utils.global'
 local Token = require 'utils.token'
 local table = require 'utils.table'
-local Popup = require 'features.gui.popup'
-local Report = require 'features.report'
 
 -- Localized functions
 local raise_event = script.raise_event
@@ -87,30 +85,65 @@ local primitives = {
     event = nil, -- if the event is registered or not
     refund = true, -- if we issue a refund or not
     prevent_tile_bp = false, -- prevents players from placing blueprints with tiles
-    keep_alive_callback = nil -- the function to process entities through
+    spill = false, -- spills items from entities with inventories to prevent destroying items when upgrading
+    keep_alive_callback = nil, -- the token registered function to process entities through
+    anti_grief_callback = nil -- the token registered function to process anti griefing through
 }
-local times_spilled = {}
 
 Global.register(
     {
         allowed_entities = allowed_entities,
         banned_entities = banned_entities,
-        primitives = primitives,
-        times_spilled = times_spilled
+        primitives = primitives
     },
     function(tbl)
         allowed_entities = tbl.allowed_entities
         banned_entities = tbl.banned_entities
         primitives = tbl.primitives
-        times_spilled = tbl.times_spilled
     end
 )
 
 -- Local functions
 
+--- Spill items stacks
+-- @param entity <LuaEntity> the entity from which the items should be spilled
+-- @param item <ItemStackSpecification> the item stack that should be spilled
 local function spill_item_stack(entity, item)
     entity.surface.spill_item_stack(entity.position, item, true, entity.force, false)
 end
+--- Checks if entity has an inventory with items inside, and spills them on the ground
+local function entities_with_inventory(entity, player)
+    if primitives.spill and entity.has_items_inside() then
+        local type = entity.type
+        if type == 'container' or type == 'logistic-container' then
+            for item, count in pairs(entity.get_inventory(defines.inventory.chest).get_contents()) do
+                spill_item_stack(entity, {name = item, count = count})
+            end
+        elseif type == 'furnace' then
+            for item, count in pairs(entity.get_inventory(defines.inventory.fuel).get_contents()) do
+                spill_item_stack(entity, {name = item, count = count})
+            end
+            for item, count in pairs(entity.get_inventory(defines.inventory.furnace_result).get_contents()) do
+                spill_item_stack(entity, {name = item, count = count})
+            end
+            for item, count in pairs(entity.get_inventory(defines.inventory.furnace_source).get_contents()) do
+                spill_item_stack(entity, {name = item, count = count})
+            end
+        elseif type == 'assembling-machine' then
+            for item, count in pairs(entity.get_inventory(defines.inventory.assembling_machine_input).get_contents()) do
+                spill_item_stack(entity, {name = item, count = count})
+            end
+            for item, count in pairs(entity.get_inventory(defines.inventory.assembling_machine_modules).get_contents()) do
+                spill_item_stack(entity, {name = item, count = count})
+            end
+            for item, count in pairs(entity.get_inventory(defines.inventory.assembling_machine_output).get_contents()) do
+                spill_item_stack(entity, {name = item, count = count})
+            end
+        end
+
+        Token.get(primitives.anti_grief_callback)(entity, player)
+    end
+end
 
 --- Token for the on_built event callback, checks if an entity should be destroyed.
 local on_built_token =
@@ -170,49 +203,8 @@ local on_built_token =
 
         -- Need to revalidate the entity since we sent it to the raised event
         if entity.valid then
-            local type = entity.type
-            if entity.has_items_inside() then
-                if type == 'container' or type == 'logistic-container' then
-                    for item, count in pairs(entity.get_inventory(defines.inventory.chest).get_contents()) do
-                        spill_item_stack(entity, {name = item, count = count})
-                    end
-                elseif type == 'furnace' then
-                    for item, count in pairs(entity.get_inventory(defines.inventory.fuel).get_contents()) do
-                        spill_item_stack(entity, {name = item, count = count})
-                    end
-                    for item, count in pairs(entity.get_inventory(defines.inventory.furnace_result).get_contents()) do
-                        spill_item_stack(entity, {name = item, count = count})
-                    end
-                    for item, count in pairs(entity.get_inventory(defines.inventory.furnace_source).get_contents()) do
-                        spill_item_stack(entity, {name = item, count = count})
-                    end
-                elseif type == 'assembling-machine' then
-                    for item, count in pairs(entity.get_inventory(defines.inventory.assembling_machine_input).get_contents()) do
-                        spill_item_stack(entity, {name = item, count = count})
-                    end
-                    for item, count in pairs(entity.get_inventory(defines.inventory.assembling_machine_modules).get_contents()) do
-                        spill_item_stack(entity, {name = item, count = count})
-                    end
-                    for item, count in pairs(entity.get_inventory(defines.inventory.assembling_machine_output).get_contents()) do
-                        spill_item_stack(entity, {name = item, count = count})
-                    end
-                end
-                Popup.player(player, [[
-Look out!
-
-You are trying to replace entities which have items inside!
-This is causing the items to spill out on the ground.
-
-Please be careful!
-]], nil, nil, 'entity_placement_restriction_inventory_warning')
-                local number_of_spilled = times_spilled[player.index] or 0
-                times_spilled[player.index] = number_of_spilled + 1
-                if number_of_spilled >= 3 then
-                    Report.jail(player, nil)
-                    player.print('[color=yellow]You have spilled too many items on the ground, contact an admin[/color]')
-                    Report.report(nil, player, 'Spilling too many items on the ground')
-                end
-            end
+            -- Checking if the entity has an inventory and spills the content on the ground to prevent destroying those too
+            entities_with_inventory(entity, player)
             entity.destroy()
         end
 
@@ -275,6 +267,21 @@ function Public.remove_keep_alive_callback()
     check_event_status()
 end
 
+--- Sets the anti_grief_callback function. This function is used to provide
+-- logic on what entities should and should not be destroyed.
+-- @param anti_grief_callback <function>
+function Public.set_anti_grief_callback(anti_grief_callback)
+    if type(anti_grief_callback) ~= 'number' then
+        error('Sending a non-token function')
+    end
+    primitives.anti_grief_callback = anti_grief_callback
+end
+
+--- Removes the anti_grief_callback function
+function Public.remove_anti_grief_callback()
+    primitives.anti_grief_callback = nil
+end
+
 --- Adds to the list of allowed entities
 -- @param ents <table> array of string entity names
 function Public.add_allowed(ents)
@@ -333,14 +340,24 @@ function Public.set_refund()
     primitives.refund = false
 end
 
---- Enables the returning of items that are destroyed by this module
+--- Enables the ability to blueprint tiles (Landfill always enabled)
 function Public.enable_tile_bp()
     primitives.prevent_tile_bp = false
 end
 
---- Disables the returning of items that are destroyed by this module
+--- Disables the ability to blueprint tiles (Landfill always enabled)
 function Public.set_tile_bp()
     primitives.prevent_tile_bp = true
 end
 
+--- Enables the spill function
+function Public.enable_spill()
+    primitives.spill = true
+end
+
+--- Disables the spill function
+function Public.set_spill()
+    primitives.spill = false
+end
+
 return Public