本文へ移動
cccskills
無料GitHub で公開

scenario-godot-gameplay

Use when building gameplay systems in Godot 4.7: enemy AI that patrols, chases and attacks, state machines, behavior trees (LimboAI), NavigationAgent3D pathfinding and avoidance for 100 to 1000 enemies, 'agents stack up' or 'path is empty', hitbox and hurtbox combat, fast bullets going through walls, save and load, inventory, quests, dialogue (Dialogue Manager), input remapping, procedural dungeons, or measuring agent counts and frame time headless.

インストール方法を見る

含まれるファイル(33)

  • SKILL.md19.1 KB
  • references/critique.md3.9 KB
  • references/expert-notes.md9.5 KB
  • references/gui-paths.md4.1 KB
  • references/procedures.md22.5 KB
  • references/sources.md11.5 KB
  • scripts/agentkit/gameplay/arena.gd4.1 KB
  • scripts/agentkit/gameplay/brain.gd1.8 KB
  • scripts/agentkit/gameplay/bullet_pool.gd3.1 KB
  • scripts/agentkit/gameplay/combat_layers.gd1.2 KB
  • scripts/agentkit/gameplay/crowd_bench.gd12.4 KB
  • scripts/agentkit/gameplay/dungeon_gen.gd6.0 KB
  • scripts/agentkit/gameplay/enemy_body.gd3.1 KB
  • scripts/agentkit/gameplay/enemy_manager.gd3.4 KB
  • scripts/agentkit/gameplay/hero_enemy.gd3.2 KB
  • scripts/agentkit/gameplay/hit_log.gd486 B
  • scripts/agentkit/gameplay/hitbox_3d.gd1.7 KB
  • scripts/agentkit/gameplay/hurtbox_3d.gd1007 B
  • scripts/agentkit/gameplay/inventory/inventory.gd1.8 KB
  • scripts/agentkit/gameplay/inventory/item_stack.gd206 B
  • scripts/agentkit/gameplay/inventory/item.gd337 B
  • scripts/agentkit/gameplay/nav_tools.gd5.7 KB
  • scripts/agentkit/gameplay/perception.gd2.2 KB
  • scripts/agentkit/gameplay/quest_rules.gd973 B
  • scripts/agentkit/gameplay/save_io.gd3.6 KB
  • scripts/agentkit/gameplay/state_machine.gd2.5 KB
  • scripts/agentkit/gameplay/state.gd1.3 KB
  • scripts/agentkit/gameplay/states/attack.gd697 B
  • scripts/agentkit/gameplay/states/chase.gd605 B
  • scripts/agentkit/gameplay/states/patrol.gd553 B
  • scripts/agentkit/gameplay/states/search.gd577 B
  • scripts/agentkit/gameplay/voice_pool.gd1.8 KB
  • scripts/gd_gameplay.py8.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Godot gameplay systems (gameplay systems programmer)

Target: Godot 4.7.2.stable, Jolt, macOS Apple Silicon.

At expert level, gameplay systems are small contracts that can be tested without a scene: pure decision functions, Resources for data, groups for discovery. Their cost is measured at the agent count the game needs before anyone argues about it. The core stance: build the rule as data, run it headless at --fixed-fps 60, then look at one capture. If a sibling skill named here is missing from your available skills, ask the user to install it (npx skills add scenario-labs/skills --skill <name>); unattended, proceed from tool schemas and flag the gap.

REQUIRED BACKGROUND: scenario-godot-expert (channels, gd_run, the review loop, 4.7 traps).

Status (2026-10-02): 16 live tests, the round-2 checks (P15) and the offline suite pass in Godot 4.7.2 (references/procedures.md, tests/code/godot-gameplay/). Dialogue Manager 4.1.0, LimboAI 1.8.1 and GUT 9.7.1 were run in their own project copies.

Stance (the expert delta)

  1. Benchmark with --fixed-fps 60, never plain headless. A headless frame sleeps 6.9 ms (low_processor_usage_mode_sleep_usec) and runs fewer physics ticks than frames. Performance.TIME_* monitors refresh about once per second and read 0 under fixed fps. Measure wall milliseconds per frame, median of 3, and compare A/B pairs from the same run (observed, P0).
  2. The crowd is not the bottleneck the baseline thinks. 200 CharacterBody3D enemies with NavigationAgent3D avoidance cost about 2 ms per frame on an M5 Max. Cost is linear to 800 agents (7.3 ms), and avoidance itself is within noise at 200. Tuning max_neighbors or the repath interval gave no measurable gain. What avoidance buys is correctness: 0 overlapping pairs against 3108 without it (P2). Go to server agents plus one MultiMesh (0.26 ms for 200) only when the agents need no nodes.
  3. Wait for the mesh you assigned, not for "the map". The docs say wait one physics frame. Live, the first sync took 3. After a rebake the map id moved while the region still served the old polygons. Read region_get_iteration_id before assigning, wait for it to move, then one more map sync (nav_tools.wait_applied, P1).
  4. Bake from a group of static colliders. A new NavigationMesh parses Both (meshes and colliders) from the region's children, so an NPC under the region carves a 3 m hole (Bramwell 2W4JP48oZ8U 00:12:37; measured P1).
  5. Pick the AI tier by the deciding condition. Use an enum brain for crowds (Shaggy Dev oqFbZoA2lnU 00:00:32) and a node FSM for a hero or player character. Use a behavior tree when designers author behavior (Chap.C E_FIy2dTkNc), and GOAP only when many generic actions recombine (Wahaha Yes cm5Jxo31plw). Budget thinking: 5 Hz with 40 enemies per tick cost 0.07 ms over no AI; every enemy every tick cost 0.45 ms (P3).
  6. Hitboxes mask, hurtboxes layer, one HitLog per swing (Queble cX-vzfmzjnE 00:06:36, 00:12:55). New areas start on layer 1 and mask 1 and hit their own owner (P4).
  7. Fast bullets are data, or bodies with CCD. Without continuous_cd, 6 of 8 balls went through a 0.1 m wall even at 30 m/s. Jolt clamps at 500 m/s. Ray-swept data bullets drawn by one MultiMesh cost 0.35 ms per 1000, against 1.05 ms for pooled RigidBody3D with CCD (P5).
  8. A .tres save is code. A GDScript sub_resource runs on load (Godotneers 43BZsLZheA4 01:03:14; reproduced P6). Scan before loading, load with CACHE_MODE_IGNORE, version and migrate, validate values instead of encrypting (01:01:37).

The NavigationAgent3D contract (P15, measured)

Docs warnings (NavigationAgents page) and Bramwell (2W4JP48oZ8U 00:14:14), measured in 4.7.2 unless marked:

  • Avoidance needs a target_position. With avoidance on and no target, safe_velocity stayed 0 for 30 ticks; with a target it returned the full 3 m/s.
  • Avoidance never feeds pathfinding. Agents are circles with no navmesh or physics knowledge, so walls still come from the path (docs).
  • One get_next_path_position() per physics frame, and none after the end. Once is_navigation_finished() is true it still returns the last point (0.93 m away here): stop steering there, or the agent creeps.
  • path_desired_distance must exceed one tick of travel and the navmesh's float above the floor (about 0.3 m). At 25 m/s (0.42 m per tick) with 0.1, the agent reversed on 1782 of 1800 ticks and never arrived; at 1.0 it arrived in 182. With 0.1 and the feet measured at floor height, it never left the first path point.
  • Defaults: time_horizon_agents 1.0, time_horizon_obstacles 0.0. Lower the horizon if agents slow down too early. Too few max_neighbors and avoidance is ignored (docs; not measured here).

Establish first

InputWhy it changes the planDefault
Agent count on screennodes vs server agents, think budget200
Frame budget for gameplaythe gate for every benchmarka quarter of 16.67 ms (4.2 ms) at 60 fps [added]
2D or 3DNavigationAgent2D vs 3D, Area2D vs 3D3D
Who authors behaviorcode (FSM, enum) vs designers (LimboAI)code
Save trustown files only vs shared or modded savesshared: scan or JSON
Platforminput devices, CPU budgetdesktop, keyboard and mouse plus pad

Workflow

  1. Set up the project.
    • Clone Base3D with gd_env.base_project("3d", P) and give it its own application/config/name, because clones otherwise share user://. Run gg.install(P).
    • GATE: project.godot has 3d/physics_engine="Jolt Physics" and a stated renderer; gd_run.check_all(P) reports 0 parse errors.
  2. Level navigation.
    • Static geometry goes in group nav_source. Build the mesh with make_navmesh(parsed colliders, source group), then bake, then wait_applied.
    • GATE: map_get_path between sample points is non-empty with 0 obstacle crossings; the polygon count is above 0; no hole at NPC spawns (P1).
  3. Movement and the crowd.
    • Enable avoidance; velocity_computed drives move_and_slide; repath is throttled; steering is XZ only.
    • Run gg.crowd_bench(P, n) at 50, 200 and 800, then gg.scaling_verdict. In your own benchmark scene, log Performance.add_custom_monitor(&"ai/thinks", callable) and OBJECT_ORPHAN_NODE_COUNT beside wall time (it read 5 after 5 stray Node.new(), P15).
    • GATE: 0 overlapping pairs; exponent under 1.3; the median at the target count fits the gameplay budget (gg.budget_share); the orphan count is flat. Then a windowed capture of the crowd, opened.
  4. AI.
    • Write the brain as decide(state, percept) with hysteresis. Perception is cheap first (distance, cone, one ray, stale-hit check). The manager thinks at about 5 Hz with a per-tick cap. Far enemies think less: key the tiers on squared distance, because VisibleOnScreenNotifier3D.is_on_screen() stays false headless and a benchmark would put everyone in the far tier (P15). The node FSM is for the hero; LimboAI if designers author.
    • GATE: the GUT transition table is green; the hero scenario history matches the expected sequence (patrol, chase, attack, chase, search, patrol); the think-cost A/B is measured (P3, P9, P13).
  5. Combat.
    • Name the layers (World 1, Player 2, Enemy 3, PlayerHurtbox 5, EnemyHurtbox 6, Projectile 7). Hitbox and hurtbox come from the kit. Bullets go through bullet_pool; bouncing objects are RigidBody3D with CCD.
    • GATE: a shared-log swing scores 1 hit; same faction 0; the tunnelling test reads 0 of 8 at the top speed; bullets on their own layer (P4, P5).
  6. Persistence.
    • Typed save Resource with VERSION and migrate(), save_io.save_resource_atomic, load_resource_checked; inventories duplicated per holder.
    • GATE: round trip equal; every old fixture loads; the evil fixture is refused; the cache test passes (P6, P7).
  7. Dialogue and quests.
    • Dialogue Manager 4.x .dialogue files; quest order is turn in, then continue, then offer.
    • GATE: the import compiles every file with 0 errors; gg.check_dialogue_text finds no missing cue; a headless walk reaches each branch and mutates state (P8).
  8. Input.
    • Physical-key actions; gameplay in _unhandled_input; remaps go to a ConfigFile.
    • GATE: synthetic press and just-pressed tests pass; the STOP panel consumes a pushed click; the remap survives a reload (P10).
  9. Procedural content.
    • Seeded data first (dungeon_gen), validators, then geometry, bake and path.
    • GATE: 1000 seeds with 0 validator failures; the same seed gives the same hash; a path from start to boss exists; the top capture is opened (P11).
  10. Wrap up.

Numbers

ValueMeasuredRelative to
200 bodies with avoidance1.98 ms per frame, 0 overlapsM5 Max, fixed fps 60, 60 m arena with 14 obstacles
Scaling with avoidance50 agents: 1.07 ms, 200: 2.00, 800: 7.31 (about 9 µs per agent)same
200 server agents plus MultiMesh0.26 mssame
Think cost, 200 enemiesbudget 0.40 ms, every tick 0.78, none 0.335 Hz, 40 per tick
First navmesh sync3 physics frames; rebake applied after 2 to 16async iterations on (default)
Bake5 ms, 180 polygons60 m arena, cell 0.25
1000 bulletsdata 0.35 ms; RigidBody3D with CCD 1.05; without CCD 1.00 (45% miss walls)60 m/s, 2 s life
Jolt speed clamp500 m/sphysics/jolt_physics_3d/limits/max_linear_velocity
Dungeon generate plus validate88 µs median, 1000 of 1000 valid14-room main path, 4 branches
NavigationAgent3D defaultsradius 0.5, max_neighbors 10, neighbor_distance 50, max_speed 10, avoidance off4.7.2 ClassDB

Quality gates

  • Measurable: crowd metrics (overlapping pairs, min pair distance, stuck, fell through the floor); scaling_verdict; budget_share; GUT (gd_run.run_tests) green after one deliberate red; check_all with 0 parse errors; validators on 1000 seeds; save fixtures; the dialogue compile.
  • Visual: windowed captures in a SubViewport (160x90 window), with gd_review.image_checks and a contact sheet of 1600 px or less, opened and looked at. Look for crowd spacing round the player, no agents inside obstacles, and the dungeon path from start to boss.

Common mistakes

MistakeWhat it looks likeFix
Benchmarking plain headlessabout 7 ms per "frame" whatever the load--fixed-fps 60
Path queried right after assigning the meshempty path, agents idle at spawnwait_applied
Default bake (Both from root) with NPCs insideholes round spawn pointsgroup plus static colliders
Avoidance off "for speed"3108 overlapping pairs, enemies mergeavoidance on: it costs little at 200
Vision as one Area3D per enemybroadphase churndistance, cone, one ray [added]
Trusting a ray hit on a teleported bodyenemy "sees" through a wallstale-hit distance check
Hit areas on layer 1 and mask 1self-hits, triple damagemask or layer only; HitLog
monitoring = false in area_entered"Function blocked during in/out signal"set_deferred
Bullet bodies on the default layer1000 bodies collide: 110 to 170 ms per frameown layer, mask world and targets
No CCD on fast bodiesbullets pass walls at 30 m/scontinuous_cd or ray-swept data
Loading a downloaded .tresits script runsload_resource_checked or JSON with from_native
Default load() after re-savingold values come backCACHE_MODE_IGNORE
save.items = [...] on Array[String]runtime error or a silent no-op through set()items.assign([...])
Preloaded inventory .tres on every chestone chest's loot shows in allduplicate(true) per holder
Always-succeeding first child in a Selectorthe attack branch never runs (Chap.C E_FIy2dTkNc 00:17:27)gate first, BTProbability or AlwaysFail
Logical keycodes in actionsWASD breaks on AZERTYphysical keycodes
Teleport with physics interpolation onthe body is drawn sliding across the jump [added, not measured]reset_physics_interpolation() after the move (method exists)
queue_free() on an autoloadno crash in 4.7.2; every later access is a "previously freed" error reading 0 (docs say crash)never free one; reset its state instead

Handoffs

  • Receives: project layout, autoload policy and save model (scenario-godot-architecture); levels with static colliders in nav_source and the controller (scenario-godot-3d-world); TileMapLayer navigation (scenario-godot-2d); art from scenario-* skills through those two.
  • Delivers: state_changed to scenario-godot-animation; play events and priorities to scenario-godot-audio (mix, buses, attenuation and the listener stay there); inventory signals, dialogue balloon and remap menu to scenario-godot-ui; hit position and normal to scenario-godot-vfx; Resources and pure decide() to scenario-godot-multiplayer; benchmark JSON to scenario-godot-performance-export.

Godot 4.7 notes

  • Navigation classes are experimental in 4.7.2. Region and map iterations are async by default, so syncs take several frames. region_bake_navigation_mesh is deprecated: use parse_source_geometry_data plus bake_from_source_geometry_data (or the async variant). region_get_iteration_id exists. query_path(params, result, callback) ran its callback before returning (P15): it does not move work off the frame.
  • A MultiMesh culls as one box: set custom_aabb (exists) and split big crowds by area.
  • The NavigationMesh default geometry_parsed_geometry_type is Both (2). Default cell size and height are 0.25.
  • Jolt is the 3D default for new projects from 4.6, but an agent-written project.godot gets GodotPhysics3D unless it sets Jolt (lead's delta).
  • duplicate(true) copies only file-internal subresources (4.5 and later). duplicate_deep(DEEP_DUPLICATE_ALL) copies external ones too.
  • JSON.from_native and to_native exist; plain JSON numbers come back as floats.
  • InputEventKey.as_text() prints "W - Physical". A new InputEventKey has device 16 (DEVICE_ID_KEYBOARD).
  • Addons: Dialogue Manager is at 4.1.0, where titles are cues; DM3 videos are a version behind. LimboAI 1.8.1 ships a "4.6" GDExtension build that runs on 4.7.2.

References

  • references/procedures.md (P0 to P15 with code and live results), expert-notes.md (judgment by expert, timestamps), critique.md (rubric), gui-paths.md (editor menus), sources.md (videos, docs, addon hashes).
  • scripts/gd_gameplay.py: install, run_job, crowd_bench, scaling_verdict, budget_share, dialogue lint, save scan.
  • scripts/agentkit/gameplay/: nav_tools, arena, crowd_bench, enemy_body, state machine and states, brain, perception, enemy_manager, hitbox, hurtbox, hit_log, combat_layers, bullet_pool, save_io, inventory, quest_rules, dungeon_gen, voice_pool.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Handle review comments received on GitHub for the current branch's PR or a given PR number or URL, by triaging each unresolved thread, fixing what is warranted, pushing, and replying in each thread, when asked to address, fix or answer PR comments. Works in any Scenario repository.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9892026年10月12日 更新

Generate one short Conventional Commits squash message describing only the net diff between the PR's base and head, set its header as the PR title, validate it with the repository's commitlint and both copy its description to the clipboard and display it, when asked for a squash message. Works in any Scenario repository, whatever its default branch.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9892026年10月12日 更新

Refresh the current pull request description from its net changes, following the repository's PR template, when asked to update or write the PR summary. Works in any Scenario repository, whatever its default branch.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9892026年10月12日 更新

scenario

無料

Use when connecting an AI agent to Scenario (scenario.com) through MCP, or when a task involves generating images, video, 3D, audio, sprites, textures, or game assets. Also when picking a Scenario model, running a LoRA, refining a generation prompt, uploading reference images, waiting on generation jobs, checking credits or quota, hitting Scenario auth, scope, or Forbidden errors, or setting up mcp.scenario.com in Claude Code, Cursor, VSCode, or another agent.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9892026年10月12日 更新

Use when generating or handling 3D assets through the Scenario MCP server, including text-to-3D or image-to-3D meshes, GPT-6 Astra 3D or Claude Opus 5.5 3D, GLB, FBX, OBJ, STL, or VOX files, PBR-textured or game-ready models, voxel models, multi-view reconstruction, retexture, remesh, UV unwrap, auto-rigging a biped or quadruped, or retargeting an animation, previewing a mesh in the inline 3D viewer, or downloading a model for import into Unity, Unreal, Godot, or Blender.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9892026年10月12日 更新

Use when generating navigable 3D worlds or Gaussian splat scenes on Scenario via MCP: text-to-world, image-to-world, a 360 panorama or skybox turned into a walkable splat, multi-view photos or a video walkthrough reconstructed as a splat, or one object photo to splat. Keywords: World Labs Marble 1.1, 1.1 Plus, 1.0 Draft, Hunyuan World, HY World, image-to-skybox, skybox-to-splat, multiview-to-splat, TripoSplat, gaussian splatting, 3DGS, spz, world generation, explorable scene, VR.

日本語の概要は準備中です。原文の説明を表示しています。

scenario-labs/skills9892026年10月12日 更新

scenario-labs のスキルをすべて見る

このスキルの問題を報告する