AI-система автотестування та QA для ігор: розробка під ключ

AI-система тестування та QA для ігор під ключ

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1440
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    997
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1264
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    712
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1002

AI-система тестування та QA для ігор під ключ

Ручне QA тестування гри не масштабується: відкритий світ з 1000+ квестами і 100+ механіками не протестувати вручну за розумний час. Команда з 5 тестувальників за тиждень покриває близько 2000 унікальних станів, а наш RL-агент — 10 мільйонів за день. Ми розробили систему під ключ, яка автономно досліджує ігровий світ, знаходить краші, софтлоки, експлойти та проблеми балансу — працюючи 24/7 і збільшуючи покриття до 90% за години.

Чому ручне тестування не справляється?

Навіть велика QA-команда пропускає edge cases: рідкісні комбінації дій, race conditions, квести в нестандартній послідовності. Наш RL-агент з curiosity-driven exploration (ICM) цілеспрямовано шукає незвідані стани, а Go-Explore алгоритм запам'ятовує цікаві точки і повертається до них. За 10 млн кроків агент відвідує більше унікальних станів, ніж команда з 5 осіб за місяць. В результаті ми знаходимо в 3 рази більше багів на старті, а витрати на QA знижуються в 10 разів.

Як ми будуємо AI-систему тестування?

Crash/Softlock тестування

Агент випадково досліджує весь простір дій, тригерить edge cases, які крашать гру або застрягають у петлі. Код агента з ICM:

class GameTestingAgent: """Агент для coverage-based тестування""" def __init__(self, game_env): self.env = game_env self.visited_states = set() self.crashes = [] self.softlocks = [] # Curiosity-driven exploration # ICM (Intrinsic Curiosity Module): reward за нові стани self.icm = ICM(obs_dim=game_env.obs_dim, action_dim=game_env.action_dim) self.policy = PPO("MlpPolicy", game_env, ent_coef=0.05) # висока entropy для exploration def collect_coverage_data(self, n_steps=1_000_000): obs = self.env.reset() for step in range(n_steps): try: action, _ = self.policy.predict(obs) obs, _, done, _, info = self.env.step(action) # логуємо нові стани state_hash = self._hash_state(obs) self.visited_states.add(state_hash) # детектуємо softlock (агент ходить по колу) if self._detect_softlock(): self.softlocks.append(self.env.get_state_dump()) if done: obs = self.env.reset() except Exception as e: self.crashes.append({ 'error': str(e), 'state': self.env.get_state_dump(), 'action_sequence': self.recent_actions[-100:] }) obs = self.env.reset() 

Content coverage testing

Перевіряємо, чи є зони, предмети або досягнення, які ніколи не досягаються нормальним ігровим шляхом. Агент з ICM винагороджується за відвідування нових станів — приховані області виявляються автоматично. В одному з проєктів ми знайшли 23 нереалізованих квести і 5 прихованих досягнень, про які розробники забули.

Exploit detection Спеціальний агент навчений максимізувати score без обмежень:

# exploit reward: ТІЛЬКИ score, ігноруємо всі "нормальні" шляхи def exploit_reward(info): return info['score'] # + info['gold'] + info['level'] # навчаємо на мінімальній кількості кроків (швидкий експлойт) model = PPO("MlpPolicy", env, gamma=0.5, # короткий горизонт = хоче швидких нагород ent_coef=0.1) # багато exploration # якщо агент знаходить спосіб отримати 10× середній score за 1 хвилину # → це exploit для QA команди 

Що таке Intrinsic Curiosity Module (ICM)?

Детальніше про ICM

ICM — це модуль, який генерує внутрішню нагороду: чим більше модель помиляється в передбаченні наступного стану, тим цікавіше агенту. Це змушує його відкривати нові локації та механіки. Як зазначає OpenAI Spinning Up, curiosity-driven exploration — ключ до ефективного дослідження в іграх з рідкісними нагородами.

class ICM(nn.Module): """Intrinsic Curiosity: reward = prediction error for new states""" def __init__(self, obs_dim, action_dim, feature_dim=256): super().__init__() # feature encoder self.phi = nn.Sequential( nn.Linear(obs_dim, feature_dim), nn.ELU(), nn.Linear(feature_dim, feature_dim) ) # forward model: predict next state features self.forward_model = nn.Sequential( nn.Linear(feature_dim + action_dim, feature_dim), nn.ELU(), nn.Linear(feature_dim, feature_dim) ) def intrinsic_reward(self, obs, action, next_obs): phi_obs = self.phi(obs) phi_next = self.phi(next_obs) # prediction error = наскільки новий цей стан a_onehot = F.one_hot(action, self.action_dim).float() predicted_next = self.forward_model(torch.cat([phi_obs, a_onehot], dim=1)) curiosity = F.mse_loss(predicted_next, phi_next.detach(), reduction='none').mean(-1) return curiosity # високий для нових, низький для вивчених 

Як Go-Explore вирішує проблему sparse reward?

Класичний RL застрягає в іграх з рідкісними нагородами. Go-Explore (Adept AI):

  1. Зберігає архів цікавих станів (за різноманітністю).
  2. Випадково обирає стан з архіву.
  3. Повертається до нього (deterministic replay).
  4. Продовжує дослідження звідти.
class GoExploreAgent: def __init__(self, game): self.game = game self.archive = {} # cell -> (score, state_snapshot) def cell_key(self, state): """Discretize state into cell (спрощення для зберігання)""" # для 2D гри: (x//50, y//50, level_id) return (state['x'] // 50, state['y'] // 50, state['level']) def run(self, n_iterations): for _ in range(n_iterations): # обрати стан з архіву (рідко відвідуваний) cell = self._select_cell() state = self.archive[cell]['snapshot'] # відновити стан (savestate) self.game.load_state(state) # випадково дослідити N кроків for _ in range(np.random.randint(5, 100)): action = self.game.action_space.sample() new_state, _, done, _, _ = self.game.step(action) new_cell = self.cell_key(new_state) if new_cell not in self.archive: self.archive[new_cell] = { 'snapshot': self.game.save_state(), 'visits': 0 } if done: break 

Порівняння підходів: ICM vs Random vs Expert

Метод Coverage (станів/год) Exploit detection Час налаштування
Random 10 000 Низький 1 день
ICM 500 000 Середній 2 тижні
Go-Explore 1 000 000+ Високий 3 тижні

Що входить в роботу під ключ?

Компонент Опис Термін (тижнів)
Crash/Softlock агент ICM + PPO, відлов крашів і софтлоків 4
Content coverage Перевірка покриття зон, предметів, квестів 2
Exploit hunter Агент, що навчається максимізувати score 3
Go-Explore Інтеграція архіву станів для sparse reward 3
CI/CD інтеграція GitHub Actions / Jenkins, дашборд метрик 2
Документація і навчання Опис агентів, API, навчання вашої QA команди 1

Разом: 12–16 тижнів на повноцінну систему. Вартість розраховується індивідуально після аудиту вашого проєкту. Зв'яжіться з нами — оцінимо обсяг робіт і терміни. Замовте консультацію, щоб обговорити вашу гру.

Метрики ефективності

  • State space coverage: % відвіданих ігрових станів (ціль ≥90%).
  • Crash count per build: середнє 3 краші на білд до оптимізації, після — 0.
  • Softlock incidents found: 50+ на проєкт.
  • New exploits detected per patch: в середньому 8.
  • Time to 90% coverage: від 4 до 8 годин (вручну — місяць).

Regression testing

Після патча — запустити агентів, переконатися, що previously passing tests не зламалися. CI/CD пайплайн автоматично запускає тести на кожний pull request:

# GitHub Actions / Jenkins name: Game QA Tests on: [push, pull_request] jobs: ai-qa: runs-on: ubuntu-latest steps: - name: Run Coverage Agent (10 min budget) run: python run_coverage_agent.py --budget 600 --headless - name: Check Coverage Metrics run: | python check_coverage.py \ --min-level-coverage 0.85 \ --max-new-crashes 0 

Наші інженери мають 10+ років досвіду в AI геймдеві, понад 50 успішних проєктів. Ми гарантуємо: система знайде мінімум 3× більше багів, ніж ручне тестування на старті. Отримайте консультацію — оцінимо вашу гру та запропонуємо рішення.