[MOD][V2.8.1]This is a New-Star AI player mod created based on a large AI model.

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • [MOD][V2.8.1]This is a New-Star AI player mod created based on a large AI model.

    The AI players generated by this mod come with three distinct personalities and are capable of automatically upgrading buildings, advancing technologies, constructing ships, and building defenses. They also support autonomous decision-making in choosing to attack either active or inactive players. Although the mod currently functions correctly in registering AI players, there are numerous issues that I am unable to resolve on my own. Therefore, I have decided to make the mod public and kindly request everyone's assistance in addressing these problems. Thank you very much!

    The post was edited 1 time, last by Aerry ().

  • Firstly, you need to create a new field called "user_type" in the "prefix_users" table to differentiate between real human players and AI players during the operation of the mod.

    SQL-Query

    1. ALTER TABLE `uni1_users`
    2. ADD `user_type` VARCHAR(50) NOT NULL DEFAULT 'user';

    Next, you need to create a data table named "prefix_ai_players" to store the information of registered AI players.

    SQL-Query

    1. CREATE TABLE `uni1_ai_players` (
    2. `ai_id` int(11) NOT NULL,
    3. `user_id` int(11) NOT NULL,
    4. `personality` enum('aggressive','defensive','balanced') NOT NULL DEFAULT 'balanced',
    5. `activity_level` tinyint(3) NOT NULL DEFAULT '80',
    6. `last_update` int(11) NOT NULL DEFAULT '0',
    7. `state` text
    8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

    The post was edited 1 time, last by Aerry ().

  • You need to create an "AIPlayerUpdate.class.php" file in the "includes/classes/cronjob" directory to execute the system's scheduled tasks.

    PHP Source Code

    1. <?php
    2. require_once 'includes/common.php';
    3. require_once 'includes/ai_config.php';
    4. require_once 'includes/classes/cronjob/CronjobTask.interface.php';
    5. require_once 'includes/classes/Utils/Log.php';
    6. require_once 'includes/classes/Ai/AIPlayerGenerator.php';
    7. require_once 'includes/classes/Ai/AIPlayer.php';
    8. require_once 'includes/classes/Ai/AIBattleManager.php';
    9. use Utils\Log;
    10. use Ai\AIPlayerGenerator;
    11. use Ai\AIPlayer;
    12. /**
    13. * AI Player Update System
    14. * Responsible for periodically updating the status and actions of all AI players
    15. */
    16. class AIPlayerUpdate implements CronjobTask
    17. {
    18. private $aiPlayers = []; // AI player list
    19. /**
    20. * Execute scheduled task
    21. */
    22. public function run()
    23. {
    24. Log::info('Starting AI player update task');
    25. /**
    26. * Register AI players
    27. * Uncomment the following line when you need to register AI players
    28. * Comment it again after registering AI players
    29. */
    30. // $this->generateAIPlayers();
    31. $this->loadAIPlayers();
    32. $this->execute();
    33. /**
    34. * Delete all AI players
    35. * Uncomment the following line when you don't need AI players
    36. * Comment it again after deleting all AI player data
    37. */
    38. // $this->cleanupAIPlayers();
    39. Log::info('AI player update task completed');
    40. }
    41. /**
    42. * Generate AI players
    43. */
    44. private function generateAIPlayers()
    45. {
    46. $generator = new AIPlayerGenerator();
    47. // Generate 10 AI players
    48. $generator->generatePlayers(400);
    49. }
    50. /**
    51. * Execute updates
    52. * Execute decisions and update game state for each AI player
    53. */
    54. private function execute()
    55. {
    56. foreach ($this->aiPlayers as $aiPlayer) {
    57. Log::info(sprintf('Updating AI player (ID: %d)', $aiPlayer->getId()));
    58. $aiPlayer->makeDecision();
    59. $this->updateGameState($aiPlayer);
    60. }
    61. }
    62. /**
    63. * Load all AI players from the database
    64. */
    65. private function loadAIPlayers()
    66. {
    67. $sql = 'SELECT u.id as user_id, u.username, u.onlinetime, u.user_type, ap.*
    68. FROM %%USERS%% u
    69. INNER JOIN %%AI_PLAYERS%% ap ON u.id = ap.user_id
    70. WHERE u.user_type = "AI"';
    71. $result = Database::get()->select($sql);
    72. foreach ($result as $row) {
    73. $this->aiPlayers[] = new AIPlayer($row['user_id']);
    74. }
    75. Log::info(sprintf('Loaded %d AI players', count($this->aiPlayers)));
    76. }
    77. /**
    78. * Update the game state of AI players
    79. * @param AIPlayer $aiPlayer AI player instance
    80. */
    81. private function updateGameState($aiPlayer)
    82. {
    83. try {
    84. // Update resources
    85. $this->updateResources($aiPlayer);
    86. // Update buildings
    87. $this->updateBuildings($aiPlayer);
    88. // Update research
    89. $this->updateResearch($aiPlayer);
    90. // Update fleets
    91. $this->updateFleets($aiPlayer);
    92. // Save AI state
    93. $aiPlayer->saveState();
    94. } catch (Exception $e) {
    95. Log::error(sprintf(
    96. 'Failed to update AI player %d: %s',
    97. $aiPlayer->getId(),
    98. $e->getMessage()
    99. ));
    100. }
    101. }
    102. /**
    103. * Update the resource data of AI players
    104. * Update the amount of metal, crystal, and deuterium resources on all planets
    105. * @param AIPlayer $aiPlayer AI player instance
    106. */
    107. private function updateResources($aiPlayer)
    108. {
    109. $sql = 'UPDATE %%PLANETS%% SET
    110. metal = :metal,
    111. crystal = :crystal,
    112. deuterium = :deuterium
    113. WHERE id_owner = :playerId';
    114. Database::get()->update($sql, [
    115. ':metal' => $aiPlayer->getResources()['metal'],
    116. ':crystal' => $aiPlayer->getResources()['crystal'],
    117. ':deuterium' => $aiPlayer->getResources()['deuterium'],
    118. ':playerId' => $aiPlayer->getId()
    119. ]);
    120. }
    121. /**
    122. * Update the building status of AI players
    123. * Process all building upgrade requests in the building queue
    124. * @param AIPlayer $aiPlayer AI player instance
    125. */
    126. private function updateBuildings($aiPlayer)
    127. {
    128. global $resource, $LNG;
    129. foreach ($aiPlayer->getQueuedBuildings() as $planetId => $buildings) {
    130. foreach ($buildings as $k => $v) {
    131. $buildingID = $resource[$v['building_id']];
    132. Log::debug(sprintf(
    133. 'AI player %d is upgrading building %s on planet %d',
    134. $aiPlayer->getId(),
    135. $LNG['tech'][$v['building_id']],
    136. $planetId
    137. ));
    138. $sql = "UPDATE %%PLANETS%% SET
    139. $buildingID = $buildingID + 1
    140. WHERE id = :planetId";
    141. Database::get()->update($sql, [
    142. ':planetId' => $planetId
    143. ]);
    144. }
    145. }
    146. }
    147. /**
    148. * Update the research status of AI players
    149. * Process the current ongoing research projects
    150. * @param AIPlayer $aiPlayer AI player instance
    151. */
    152. private function updateResearch($aiPlayer)
    153. {
    154. global $resource, $LNG;
    155. $currentResearch = $aiPlayer->getCurrentResearch();
    156. if ($currentResearch === null) {
    157. return;
    158. }
    159. $id = $currentResearch['type'];
    160. $buildingID = $resource[$id];
    161. Log::debug(sprintf(
    162. 'AI player %d is upgrading technology %s to level %d',
    163. $aiPlayer->getId(),
    164. $LNG['tech'][$id],
    165. $currentResearch['level']
    166. ));
    167. $sql = "UPDATE %%USERS%% SET
    168. $buildingID = :level
    169. WHERE id = :playerId";
    170. Database::get()->update($sql, [
    171. ':level' => $currentResearch['level'],
    172. ':playerId' => $aiPlayer->getId()
    173. ]);
    174. }
    175. /**
    176. * Update the fleet status of AI players
    177. * Process all fleet missions in the fleet queue
    178. * @param AIPlayer $aiPlayer AI player instance
    179. */
    180. private function updateFleets($aiPlayer)
    181. {
    182. foreach ($aiPlayer->getQueuedFleets() as $fleet) {
    183. Log::debug(sprintf(
    184. 'AI player %d created a new fleet mission: %s',
    185. $aiPlayer->getId(),
    186. $fleet['mission']
    187. ));
    188. // Validate fleet mission parameters
    189. if (!$this->validateFleetMission($fleet)) {
    190. Log::error(sprintf(
    191. 'Invalid fleet mission parameters for AI player %d',
    192. $aiPlayer->getId()
    193. ));
    194. continue;
    195. }
    196. $sql = 'INSERT INTO %%FLEETS%%
    197. (fleet_owner, fleet_mission, fleet_ships,
    198. start_time, end_time, target_planet)
    199. VALUES (:owner, :mission, :ships, :start, :end, :target)';
    200. Database::get()->insert($sql, [
    201. ':owner' => $aiPlayer->getId(),
    202. ':mission' => $fleet['mission'],
    203. ':ships' => json_encode($fleet['ships']),
    204. ':start' => $fleet['start_time'],
    205. ':end' => $fleet['end_time'],
    206. ':target' => $fleet['target_planet']
    207. ]);
    208. }
    209. }
    210. /**
    211. * Validate whether the fleet mission parameters are valid
    212. * @param array $fleet Fleet mission information
    213. * @return bool Whether the parameters are valid
    214. */
    215. private function validateFleetMission($fleet)
    216. {
    217. // Check if required parameters exist
    218. $requiredParams = ['mission', 'ships', 'start_time', 'end_time', 'target_planet'];
    219. foreach ($requiredParams as $param) {
    220. if (!isset($fleet[$param])) {
    221. return false;
    222. }
    223. }
    224. // Check if time parameters are valid
    225. if ($fleet['end_time'] <= $fleet['start_time']) {
    226. return false;
    227. }
    228. // Check if the ships array is valid
    229. return ! (!is_array($fleet['ships']) || empty($fleet['ships']));
    230. }
    231. /**
    232. * Clean up all AI players
    233. */
    234. private function cleanupAIPlayers()
    235. {
    236. $generator = new AIPlayerGenerator();
    237. $sql = 'SELECT user_id FROM %%AI_PLAYERS%%';
    238. $result = Database::get()->select($sql, []);
    239. foreach ($result as $row) {
    240. $generator->deleteAIPlayer($row['user_id']);
    241. }
    242. Log::info(sprintf('Cleaned up %d AI players', count($result)));
    243. }
    244. }
    Display All
  • Then, you need to create an "ai_config.php" file in the "includes" directory.

    PHP Source Code

    1. <?php
    2. // Basic configuration
    3. define('ENABLE_DEBUG', true);
    4. // Personality-related parameter configuration
    5. $AI_PARAMS = [
    6. 'aggressive' => [
    7. 'attack_chance' => 0.8,
    8. 'fleet_ratio' => 0.7,
    9. 'resource_threshold' => 0.3,
    10. 'tech_priorities' => ['weapons', 'shield', 'armor'],
    11. 'active_target_weight' => 1.2, // Aggressive AI is more inclined to attack active players
    12. 'building_priorities' => [1 => 3, 2 => 2, 3 => 1] // Add building priorities
    13. ],
    14. 'defensive' => [
    15. 'attack_chance' => 0.2,
    16. 'fleet_ratio' => 0.3,
    17. 'resource_threshold' => 0.7,
    18. 'tech_priorities' => ['shield', 'armor', 'weapons'],
    19. 'active_target_weight' => 0.2, // Defensive AI strongly avoids attacking active players
    20. 'building_priorities' => [1 => 1, 2 => 2, 3 => 3] // Add building priorities
    21. ],
    22. 'balanced' => [
    23. 'attack_chance' => 0.5,
    24. 'fleet_ratio' => 0.5,
    25. 'resource_threshold' => 0.5,
    26. 'tech_priorities' => ['weapons', 'shield', 'energy'],
    27. 'active_target_weight' => 0.5, // Balanced AI slightly avoids attacking active players
    28. 'building_priorities' => [1 => 2, 2 => 3, 3 => 1] // Add building priorities
    29. ]
    30. ];
    31. define('AI_PARAMS', $AI_PARAMS);
    32. // Scoring weight configuration
    33. define('DISTANCE_WEIGHT', 0.3);
    34. define('RESOURCES_WEIGHT', 0.4);
    35. define('DEFENSE_WEIGHT', 0.3);
    36. // Log configuration
    37. define('AI_LOG_PATH', 'includes/logs/');
    38. define('AI_LOG_LEVEL', 'DEBUG');
    Display All

    The post was edited 1 time, last by Aerry ().

  • Next, you need to create an "Ai" folder within the "includes/classes" directory to house the classes related to AI players. Subsequently, you must create the following PHP files in the "includes/classes/Ai" directory:
    "AIPlayer.php", "AIPlayerGenerator.php", "AIDecision.php", "AIBehavior.php", and "AIBattleManager.php".
    Files
    • Ai.zip

      (14.15 kB, downloaded 38 times, last: )

    The post was edited 1 time, last by Aerry ().

  • Next, you need to create a "Utils" folder within the "includes/classes" directory to store the classes related to logging. Following that, you should create a "Log.php" file in the "includes/classes/Utils" directory.
    You can modify the "ai_config.php" file to specify the directory where the log files are printed.

    PHP Source Code

    1. <?php
    2. namespace Utils;
    3. /**
    4. * AI system log utility class
    5. * Used to record the running logs of the AI system, supporting multiple log levels
    6. */
    7. class Log
    8. {
    9. // Log storage path, obtained from AI configuration
    10. const LOG_PATH = AI_LOG_PATH;
    11. // Log date format
    12. const DATE_FORMAT = 'Y-m-d H:i:s';
    13. /**
    14. * Write log
    15. * @param string $type Log type (ERROR/INFO/DEBUG)
    16. * @param string $message Log message
    17. */
    18. public static function write($type, $message)
    19. {
    20. // Check log level
    21. if (!self::shouldLog($type)) {
    22. return;
    23. }
    24. $logFile = self::LOG_PATH . $type . '_' . date('Y-m-d') . '.log';
    25. $logEntry = sprintf(
    26. "[%s] %s\n",
    27. date(self::DATE_FORMAT),
    28. $message
    29. );
    30. // Ensure log directory exists
    31. if (!is_dir(self::LOG_PATH)) {
    32. mkdir(self::LOG_PATH, 0777, true);
    33. }
    34. // Write log
    35. file_put_contents($logFile, $logEntry, FILE_APPEND);
    36. }
    37. /**
    38. * Check if the log level should be recorded
    39. * @param string $type Log type
    40. * @return bool Whether it should be recorded
    41. */
    42. private static function shouldLog($type)
    43. {
    44. switch (AI_LOG_LEVEL) {
    45. case 'ERROR':
    46. return $type === 'ERROR';
    47. case 'INFO':
    48. return in_array($type, ['ERROR', 'INFO']);
    49. case 'DEBUG':
    50. return true;
    51. default:
    52. return false;
    53. }
    54. }
    55. /**
    56. * Record error log
    57. * @param string $message Error message
    58. */
    59. public static function error($message)
    60. {
    61. self::write('ERROR', $message);
    62. }
    63. /**
    64. * Record info log
    65. * @param string $message Log message
    66. */
    67. public static function info($message)
    68. {
    69. self::write('INFO', $message);
    70. }
    71. /**
    72. * Record debug log
    73. * @param string $message Debug message
    74. */
    75. public static function debug($message)
    76. {
    77. if (ENABLE_DEBUG) {
    78. self::write('DEBUG', $message);
    79. }
    80. }
    81. }
    Display All
  • Open the "/includes/dbtables.php" file, and before the last comma in the array, add

    PHP Source Code

    1. 'AI_PLAYERS' => DB_PREFIX . 'ai_players'
    The final step is to add a new scheduled task in the "prefix_cronjobs" table. You can execute the following SQL command to do so:

    SQL-Query

    1. INSERT INTO `uni1_cronjobs`
    2. (`cronjobID`, `name`, `isActive`, `min`, `hours`, `dom`, `month`, `dow`, `class`, `nextTime`, `lock`)
    3. VALUES
    4. (NULL, 'AIPlayer', '1', '*/10', '*', '*', '*', '*', 'AIPlayerUpdate', 1736672567, NULL);
    You can execute the scheduled task by visiting "https://domain/cronjob.php?cronjobID=scheduledTaskID".
    After execution, if further testing is required, you will also need to modify the "nextTime" field in the "prefix_cronjobs" data table to any timestamp that is not the current time.

    The post was edited 1 time, last by Aerry ().

  • So, you've essentially completed the installation of the AI virtual player mod . The current issue is that the generated AI players can only be used for registration . Although they can also upgrade technologies and buildings ️, errors are reported . I have been continuously debugging , but as soon as I fix one area, another error pops up elsewhere . As a front-end developer , I have decided to release this mod to the public , hoping to gather wisdom from the crowd and have everyone work with me to resolve these issues !

    The post was edited 1 time, last by Aerry ().