1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-26 20:54:12 +02:00

Code clean, refactored modules, prepping for more custom ai work

This commit is contained in:
Aaron Veden 2017-06-15 18:30:26 -07:00
parent 1fbd91908c
commit 337951c548
16 changed files with 71 additions and 70 deletions

View File

@ -57,7 +57,12 @@ Configure Options not in game menu:
# Version History
0.15.16 -
- Optimization: Greatly reduced reindexing time
- Tweak: Increased chunks processed at a time from 200 to 3000
- Tweak: Increased failed unit behaviors from 6 to 10
- Optimization: Preallocated a position for use in squad movement
- Optimization: Greatly reduced reindexing time and chunk scoring
- Framework: Split chunk scoring and custom ai chunk purging
- Framework: Refactored code into more appropriate modules
0.15.15 -
- Fixed: Desync when reindexing chunks (https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=180#p287941)

View File

@ -94,8 +94,6 @@ function upgrade.attempt(natives)
game.map_settings.path_finder.short_cache_size = constants.PATH_FINDER_SHORT_CACHE_SIZE
game.map_settings.path_finder.long_cache_size = constants.PATH_FINDER_LONG_REQUEST_RATIO
game.map_settings.max_failed_behavior_count = constants.MAX_FAILED_BEHAVIORS
game.map_settings.unit_group.max_group_radius = constants.UNIT_GROUP_MAX_RADIUS
game.map_settings.unit_group.max_member_speedup_when_behind = constants.UNIT_GROUP_MAX_SPEED_UP
game.map_settings.unit_group.max_member_slowdown_when_ahead = constants.UNIT_GROUP_MAX_SLOWDOWN
@ -149,6 +147,8 @@ function upgrade.attempt(natives)
end
if (global.version < constants.VERSION_26) then
game.map_settings.max_failed_behavior_count = constants.MAX_FAILED_BEHAVIORS
game.surfaces[1].print("Rampant - Version 0.15.16")
global.version = constants.VERSION_26
end

View File

@ -98,9 +98,12 @@ local function rebuildRegionMap()
regionMap.processQueue = {}
regionMap.processPointer = 1
regionMap.scanPointer = 1
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
regionMap.neighbors = { nil, nil, nil, nil, nil, nil, nil, nil }
regionMap.cardinalNeighbors = { nil, nil, nil, nil }
regionMap.chunkTiles = {}
regionMap.position = {x=0,
y=0}
for i=1,1024 do
regionMap.chunkTiles[i] = nil
end

View File

@ -106,10 +106,11 @@ function aiAttackWave.formSquads(regionMap, surface, natives, chunk, cost)
validUnitGroupLocation,
scoreUnitGroupLocation)
if squadPath then
local squadPosition = positionFromDirectionAndChunk(squadDirection, chunk, {x=0,y=0}, 0.98)
squadPosition = surface.find_non_colliding_position("biter-spawner-hive",
squadPosition,
local squadPosition = surface.find_non_colliding_position("biter-spawner-hive",
positionFromDirectionAndChunk(squadDirection,
chunk,
regionMap.position,
0.98),
32,
4)
if squadPosition then

View File

@ -40,6 +40,8 @@ local canAttack = aiPredicates.canAttack
local randomTickEvent = mathUtils.randomTickEvent
local mFloor = math.floor
local mMax = math.max
-- module code
@ -74,7 +76,7 @@ function aiPlanning.planning(natives, evolution_factor, tick, surface)
natives.attackWaveThreshold = (threshold - (threshold * evolution_factor)) + natives.attackThresholdMin
if (natives.points < maxPoints) then
natives.points = natives.points + math.floor((AI_POINT_GENERATOR_AMOUNT * math.random()) +
natives.points = natives.points + mFloor((AI_POINT_GENERATOR_AMOUNT * math.random()) +
((AI_POINT_GENERATOR_AMOUNT * 0.7) * (evolution_factor ^ 2.5)) * natives.aiPointsScaler)
end

View File

@ -2,7 +2,7 @@ local baseUtils = {}
-- imports
local mapUtils = require("MapUtils")
local mathUtils = require("MathUtils")
local constants = require("Constants")
local tendrilUtils = require("TendrilUtils")
@ -20,7 +20,7 @@ local MAGIC_MAXIMUM_BASE_NUMBER = constants.MAGIC_MAXIMUM_BASE_NUMBER
-- imported functions
local euclideanDistancePoints = mapUtils.euclideanDistancePoints
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
local buildHive = buildUtils.buildHive

View File

@ -16,9 +16,6 @@ local CHUNK_SIZE = constants.CHUNK_SIZE
local createChunk = chunkUtils.createChunk
local checkChunkPassability = chunkUtils.checkChunkPassability
local scoreChunk = chunkUtils.scoreChunk
local remakeChunk = chunkUtils.remakeChunk
local registerChunkEnemies = chunkUtils.registerChunkEnemies
-- module code
@ -33,7 +30,7 @@ function chunkProcessor.processPendingChunks(natives, regionMap, surface, pendin
local count = 0
local useCustomAI = natives.useCustomAI
local vanillaAI = not natives.useCustomAI
local chunkTiles = regionMap.chunkTiles
@ -59,7 +56,7 @@ function chunkProcessor.processPendingChunks(natives, regionMap, surface, pendin
regionMap[chunkX][chunk.cY] = chunk
checkChunkPassability(chunkTiles, chunk, surface)
if not useCustomAI then
if vanillaAI then
registerChunkEnemies(chunk, surface, query)
end
scoreChunk(chunk, surface, natives, query)

View File

@ -53,16 +53,10 @@ local function fullScan(chunkTiles, x, y, get_tile)
local passableNorthSouth = false
local passableEastWest = false
-- local skip = true
for xi=x, x + 31 do
local northSouth = true
-- skip = not skip
for yi=y, endY do
i = i + 1
-- if skip then
-- skip = false
-- else
-- skip = true
local tile = get_tile(xi, yi)
if not tile.collides_with("player-layer") then
validTiles = validTiles + 1
@ -71,26 +65,18 @@ local function fullScan(chunkTiles, x, y, get_tile)
northSouth = false
chunkTiles[i] = nil
end
-- end
end
if northSouth then
passableNorthSouth = true
end
end
-- skip = true
for yi=1, 32 do
local westEast = true
-- skip = not skip
for xi=0, 992, 32 do
-- if skip then
-- skip = false
-- else
-- skip = true
if not chunkTiles[yi + xi] then
westEast = false
break
end
-- end
end
if westEast then
passableEastWest = true
@ -122,16 +108,16 @@ function chunkUtils.checkChunkPassability(chunkTiles, chunk, surface)
local get_tile = surface.get_tile
--[[
0 represents water chunk
1-48 chunk requires full scan
49 assume chunk is passable in all directions
0-4 represents water chunk
5-46 chunk requires full scan
47-49 assume chunk is passable in all directions
--]]
local cleanSpotCheck = spotCheck(x, y, get_tile)
local pass = CHUNK_ALL_DIRECTIONS
if (cleanSpotCheck > 0) and (cleanSpotCheck < 49) then
if (cleanSpotCheck > 5) and (cleanSpotCheck < 47) then
pass = CHUNK_IMPASSABLE
local rating, passableNorthSouth, passableEastWest = fullScan(chunkTiles, x, y, get_tile, surface)
local rating, passableNorthSouth, passableEastWest = fullScan(chunkTiles, x, y, get_tile)
if passableEastWest and passableNorthSouth then
pass = CHUNK_ALL_DIRECTIONS
@ -145,8 +131,10 @@ function chunkUtils.checkChunkPassability(chunkTiles, chunk, surface)
if (rating < 0.6) then
pass = CHUNK_IMPASSABLE
end
elseif (cleanSpotCheck == 0) then
elseif (cleanSpotCheck <= 4) then
pass = CHUNK_IMPASSABLE
else
chunk[PATH_RATING] = 1
end
chunk[PASSABLE] = pass
end

View File

@ -20,7 +20,7 @@ constants.MAGIC_MAXIMUM_NUMBER = 1e99 -- used in loops trying to find the lowest
constants.MAGIC_MAXIMUM_BASE_NUMBER = 100000000
constants.RETREAT_MOVEMENT_PHEROMONE_LEVEL = 10000
constants.CHUNK_QUEUE_SIZE = 1500
constants.CHUNK_QUEUE_SIZE = 3000
constants.PROCESS_QUEUE_SIZE = 450
constants.SCAN_QUEUE_SIZE = 6
constants.BASE_QUEUE_SIZE = 1
@ -191,7 +191,7 @@ constants.PATH_FINDER_SHORT_CACHE_SIZE = 25
constants.PATH_FINDER_LONG_REQUEST_RATIO = 5
constants.PATH_FINDER_MIN_STEPS_TO_CHECK_PATH = 100
constants.MAX_FAILED_BEHAVIORS = 6
constants.MAX_FAILED_BEHAVIORS = 10
constants.UNIT_GROUP_DISOWN_DISTANCE = 10
constants.UNIT_GROUP_TICK_TOLERANCE = 360

View File

@ -11,6 +11,8 @@ local constants = require("Constants")
local mapUtils = require("MapUtils")
local playerUtils = require("PlayerUtils")
local mathUtils = require("MathUtils")
-- constants
local PROCESS_QUEUE_SIZE = constants.PROCESS_QUEUE_SIZE
@ -51,7 +53,7 @@ local playerScent = pheromoneUtils.playerScent
local canAttack = aiPredicates.canAttack
local euclideanDistanceNamed = mapUtils.euclideanDistanceNamed
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
local mMin = math.min

View File

@ -26,7 +26,7 @@ local distortPosition = mathUtils.distortPosition
function movementUtils.findMovementPosition(surface, position, distort)
local pos = position
if not surface.can_place_entity({name="behemoth-biter", position=position}) then
pos = surface.find_non_colliding_position("behemoth-biter", position, 5, 2) or position
pos = surface.find_non_colliding_position("behemoth-biter", position, 5, 2)
end
return (distort and distortPosition(pos)) or pos
end

View File

@ -2,11 +2,11 @@ local playerUtils = {}
-- imports
local mapUtils = require("MapUtils")
local mathUtils = require("MathUtils")
-- imported functions
local euclideanDistanceNamed = mapUtils.euclideanDistanceNamed
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
-- module code

View File

@ -8,6 +8,7 @@ local unitGroupUtils = require("UnitGroupUtils")
local playerUtils = require("PlayerUtils")
local neighborUtils = require("NeighborUtils")
local movementUtils = require("MovementUtils")
local mathUtils = require("MathUtils")
-- constants
@ -33,16 +34,16 @@ local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
-- imported functions
local findMovementPoint = movementUtils.findMovementPoint
local findMovementPosition = movementUtils.findMovementPosition
local getNeighborChunks = mapUtils.getNeighborChunks
local getChunkByPosition = mapUtils.getChunkByPosition
local addMovementPenalty = unitGroupUtils.addMovementPenalty
local lookupSquadMovementPenalty = unitGroupUtils.lookupSquadMovementPenalty
local addMovementPenalty = movementUtils.addMovementPenalty
local lookupMovementPenalty = movementUtils.lookupMovementPenalty
local calculateKamikazeThreshold = unitGroupUtils.calculateKamikazeThreshold
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
local euclideanDistanceNamed = mapUtils.euclideanDistanceNamed
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
local playersWithinProximityToPosition = playerUtils.playersWithinProximityToPosition
@ -52,7 +53,7 @@ local scoreNeighborsForAttack = neighborUtils.scoreNeighborsForAttack
local function scoreAttackLocation(squad, neighborChunk)
local damage = neighborChunk[MOVEMENT_PHEROMONE] + neighborChunk[BASE_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
return damage - lookupSquadMovementPenalty(squad, neighborChunk.cX, neighborChunk.cY)
return damage - lookupMovementPenalty(squad, neighborChunk.cX, neighborChunk.cY)
end
function squadAttack.squadsAttack(regionMap, surface, natives)
@ -61,7 +62,7 @@ function squadAttack.squadsAttack(regionMap, surface, natives)
local attackCmd
if (#squads > 0) then
attackPosition = {x=0, y=0}
attackPosition = regionMap.position
attackCmd = { type = DEFINES_COMMAND_ATTACK_AREA,
destination = attackPosition,
radius = 32,
@ -99,7 +100,7 @@ function squadAttack.squadsAttack(regionMap, surface, natives)
attackCmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
end
local position = findMovementPoint(surface,
local position = findMovementPosition(surface,
positionFromDirectionAndChunk(attackDirection,
groupPosition,
attackPosition,

View File

@ -6,11 +6,13 @@ local constants = require("Constants")
local mapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils")
local neighborUtils = require("NeighborUtils")
local movementUtils = require("MovementUtils")
-- constants
local RETREAT_GRAB_RADIUS = constants.RETREAT_GRAB_RADIUS
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
local BASE_PHEROMONE = constants.BASE_PHEROMONE
@ -33,16 +35,16 @@ local WORM_COUNT = constants.WORM_COUNT
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
local getNeighborChunks = mapUtils.getNeighborChunks
local findNearBySquad = unitGroupUtils.findNearBySquad
local addSquadMovementPenalty = unitGroupUtils.addSquadMovementPenalty
local addMovementPenalty = movementUtils.addMovementPenalty
local createSquad = unitGroupUtils.createSquad
local membersToSquad = unitGroupUtils.membersToSquad
local scoreNeighborsForRetreat = neighborUtils.scoreNeighborsForRetreat
local findMovementPosition = movementUtils.findMovementPosition
-- module code
local function scoreRetreatLocation(neighborChunk)
local danger = neighborChunk[BASE_PHEROMONE] + -neighborChunk[MOVEMENT_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * 100)
return -danger
return -(neighborChunk[BASE_PHEROMONE] + -neighborChunk[MOVEMENT_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * 100) + (neighborChunk[PLAYER_BASE_GENERATOR] * 20))
end
function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, natives, tick)
@ -65,18 +67,17 @@ function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, nati
chunk.cY),
scoreRetreatLocation)
if exitPath then
local retreatPosition = positionFromDirectionAndChunk(exitDirection, position, {x=0,y=0}, 0.98)
local retreatPosition = findMovementPosition(surface,
positionFromDirectionAndChunk(exitDirection,
position,
regionMap.position,
0.98),
false)
if not surface.can_place_entity({name="behemoth-biter", position=retreatPosition}) then
local newRetreatPosition = surface.find_non_colliding_position("behemoth-biter", retreatPosition, 5, 2)
if newRetreatPosition then
retreatPosition.x = newRetreatPosition.x
retreatPosition.y = newRetreatPosition.y
else
if not retreatPosition then
return
end
end
-- in order for units in a group attacking to retreat, we have to create a new group and give the command to join
-- to each unit, this is the only way I have found to have snappy mid battle retreats even after 0.14.4
@ -98,7 +99,7 @@ function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, nati
newSquad.rabid = true
end
end
addSquadMovementPenalty(natives, newSquad, chunk.cX, chunk.cY)
addMovementPenalty(natives, newSquad, chunk.cX, chunk.cY)
end
end
end

View File

@ -9,6 +9,7 @@ local neighborsUtils = require("NeighborUtils")
local mathUtils = require("MathUtils")
local buildUtils = require("BuildUtils")
local mathUtils = require("MathUtils")
-- constants
@ -30,7 +31,7 @@ local registerEnemyBaseStructure = baseRegisterUtils.registerEnemyBaseStructure
local buildOutpost = buildUtils.buildOutpost
local euclideanDistanceNamed = mapUtils.euclideanDistanceNamed
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
-- module code

View File

@ -2,7 +2,7 @@ local unitGroupUtils = {}
-- imports
local mapUtils = require("MapUtils")
local mathUtils = require("MathUtils")
local constants = require("Constants")
-- constants
@ -32,7 +32,7 @@ local mLog = math.log10
local mMin = math.min
local euclideanDistanceNamed = mapUtils.euclideanDistanceNamed
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
-- module code