跳到主要内容
知仓学习社ZHICANG

godot-game-loop-time-trial

Expert patterns for racing mechanics, checkpoint tracking, and ghost recording/playback in Godot 4. Use when building racing games, speed-run platfo…

不碰外部(只输出文字)无严重或高危命中thedivergentai/GD-Agentic-Skills

它会碰到什么

扫了多少3 个文本文件,17 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Architectural Thinking: The "Validation-Chain" Pattern

A Master implementation treats Time Trials as a State-Validated Sequence. Recording a time is easy; ensuring the player didn't cheat via shortcuts requires a strictly ordered CheckpointManager.

Core Responsibilities

  • TimeTrialManager: The central clock. Validates checkpoint order and handles "Best Lap" logic.
  • GhostRecorder: Captures high-frequency transform data. Uses delta-time timestamps for frame-independent playback.
  • Checkpoint: Spatial triggers that notify the Manager.

Expert Code Patterns

1. Robust Checkpoint Validation

Prevent "Shortcut Cheating" by requiring checkpoints to be cleared in numerical order.

Wire Area body_entered (physics) → TimeTrialManager.pass_checkpoint(index). The manager owns usec timing — see script.

2. Space-Efficient Ghosting

Sample at a fixed rate (e.g. 10 Hz). Lerp position; slerp Quaternion rotation (ghost_recorder.gd / ghost_replayer.gd). Never Euler-lerp ghost heading.

Master Decision Matrix: Data Storage

| Format | Best For | Implementation |

| :--- | :--- | :--- |

| Dictionary Array | Prototyping | Simple [{t: 0.1, p: pos}, ...] |

| Typed Array | Performance | PackedVector3Array for positions. |

| JSON/Binary | Saving | FileAccess.get_var() to save ghost files. |

NEVER Do

  • NEVER use OS.get_ticks_msec() for ultra-precise race timing — Millisecond resolution is too coarse for high-end racing games. Use Time.get_ticks_usec() for microsecond precision.
  • NEVER rely exclusively on _process() for finish line triggers — Visual frames can skip during lag. Always evaluate physical overlaps in _physics_process() to guarantee detection within the fixed physics step.
  • NEVER evaluate Area3D overlaps immediately after instantiation — The physics server requires at least one physics frame to synchronize. await get_tree().physics_frame before checking for players.
  • NEVER scale a CollisionShape3D on a checkpoint non-uniformly — This breaks the underlying SAT collision math. Always scale the internal shape resource (e.g., BoxShape3D.size) instead.
  • NEVER use TCP (reliable) for syncing positions in multiplayer racing — Congestion algorithms cause huge spikes. Use ENetMultiplayerPeer with TRANSFER_MODE_UNRELIABLE for high-frequency position updates.
  • NEVER trust client-side finish line/lap crossing — Always validate triggers on the authoritative server using multiplayer.is_server() to prevent cheating.
  • NEVER use standard float equality (==) for record lap times — Use is_equal_approx() to account for precision loss in accumulated time variables.
  • NEVER hardcode input checks without flushing the buffer — For frame-perfect boost/stop responses, call Input.flush_buffered_events() to ensure the engine has processed the latest raw input.
  • NEVER allocate new Vector3 arrays inside fast path-following loops — This triggers the garbage collector. Use PackedVector3Array to maintain a contiguous memory block.
  • NEVER use dynamic string paths ($"../Checkpoint") in tight loops — Lookups are slow. Use @onready to cache node references during initialization.
  • NEVER record the whole player object for ghosts — Only record core transforms (position/rotation). Recording the whole object is memory-intensive and unnecessary for visual ghosts.
  • NEVER give the ghost collision — It should be a purely visual indicator (e.g., semi-transparent) to avoid disrupting the player's line.
  • NEVER neglect checkpoint sequencing — Don't just check if the player hit the finish line. Verify they passed every intermediate checkpoint in the correct order.
  • NEVER use Area3D without monitoring optimization — Checkpoints should only look for the Player physics layer to minimize the number of physics overlap calculations.
  • NEVER use standard lerp for ghost rotation — Use slerp() or Quaternion.slerp() to avoid gimbal lock and ensure smooth rotation interpolation.

Available Scripts

> MANDATORY: Follow the golden path order. Read each listed script before coding that stage.

Golden path (MANDATORY)

  1. time_trial_manager.gd — microsecond (Time.get_ticks_usec) or physics-frame clock; pass_checkpoint only from physics overlaps / Area signals
  2. Checkpoint Areas — ordered indices into the manager (physics frame, not _process)
  3. ghost_recorder.gd — samples {t, p, q} with Quaternion rotation
  4. ghost_replayer.gd — position lerp + Quaternion slerp (never Euler lerp)
  5. time_trial_leaderboard_bridge.gd — integer usec/msec → UI strings

Script index

[time_trial_patterns.gd](scripts/time_trial_patterns.gd)

10 Expert patterns: Microsecond timing, server-authoritative validation, rubber-banding AI, and frame-perfect input flushing.

[time_trial_manager.gd](scripts/time_trial_manager.gd)

Central clock. Accumulates Time.get_ticks_usec() (or physics-frame counts). Finish checks must come from physics overlaps.

[ghost_recorder.gd](scripts/ghost_recorder.gd)

Captures transform samples with Quaternion "q" fields for slerp-safe playback.

[ghost_replayer.gd](scripts/ghost_replayer.gd)

MANDATORY with recorder. Replays samples via position lerp + Quaternion.slerp.

[time_trial_playback_buffer.gd](scripts/time_trial_playback_buffer.gd)

Jitter-buffer for smooth ghost playback during network streaming.

[time_trial_leaderboard_bridge.gd](scripts/time_trial_leaderboard_bridge.gd)

Formatting utility for converting raw time data to human-readable strings.


Expert Time Trial Patterns

1. Delta-Compression for Ghosts

Store a keyframe only when position/rotation changes beyond a threshold. Persist with FileAccess.open_compressed() + ZSTD; prefer binary floats over JSON.

2. The Leaderboard Bridge

Store records as int usec/msec. Format with %02d:%02d.%03d for stable UI (e.g. 01:24.450).

Expert knowledge (on demand)

> LLM-ignorance rule: If a general agent would not know it before reading, load the reference — never delete expert deltas.

  • [time-trial-expert-patterns.md](references/time-trial-expert-patterns.md) — restored baseline pedagogy (architecture, WHY, implementation depth)

Reference

> Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.

Official Documentation

  • Timeget_ticks_usec() for microsecond lap clocks when OS.get_ticks_msec() is too coarse for race records.
  • Idle and Physics Processing — why finish-line and checkpoint overlap must run in _physics_process, not visual _process frames that can skip under load.
  • Area3D — monitoring, collision masks, and body_entered for ordered checkpoint gates without scanning every physics body.
  • Collision shapes (3D) — scale shape resources (BoxShape3D.size) instead of non-uniform CollisionShape3D scale so SAT stays valid on gates.
  • Using transforms — global position/basis capture for ghost samples and why Euler-only storage needs careful replay conversion.
  • Quaternionslerp() between keyframes so ghost heading avoids gimbal lock from naive Euler lerp.
  • Transform3Dinterpolate_with() for jitter-buffered network ghost playback between ordered frames.
  • Saving gamesFileAccess / store_var patterns for persisting ghost runs and best-time dictionaries without float display round-trips.
  • High-level multiplayer — server-authoritative RPC validation so clients cannot fake lap/finish crossings.
  • MultiplayerPeerTRANSFER_MODE_UNRELIABLE for high-frequency racer transforms where TCP-style reliability spikes latency.
  • Inputflush_buffered_events() when frame-perfect boost/stop must see the latest raw input before the physics step.
  • Enginephysics_ticks_per_second / get_physics_frames() for integer frame-count timing bridges into MM:SS.mmm UI.

Related Skills

Prerequisites

  • godot-project-foundations — scene tree, autoloads, and resource layout before wiring a TimeTrialManager and checkpoint Areas into a track scene.
  • godot-physics-3d — Area3D/CollisionShape3D layers, RigidBody/CharacterBody vehicles, and physics-frame overlap rules that make checkpoint sequencing trustworthy.
  • godot-signal-architecture — typed lap/split/finish signals between gates, manager, HUD, and ghost systems without brittle node-path coupling.
  • godot-gdscript-mastery — typed arrays, Packed* buffers, await physics_frame, and RPC annotations used in timing and authority patterns.

Complements

  • godot-input-handling — action maps and buffered boost/steer input that time-trial NEVER rules require to flush before physics.
  • godot-save-load-systems — compressed binary ghost files and best-time persistence beyond in-memory sample arrays.
  • godot-multiplayer-networking — ENet peers, authority, and unreliable transform sync for live races and streamed ghost frames.
  • godot-adapt-single-to-multiplayer — lag compensation, snapshots, and interest patterns when elevating a solo time trial into online racing.
  • godot-navigation-pathfinding — NavigationServer3D agent max-speed for rubber-band AI that paces against the player without cheating collision.
  • godot-monte-carlo-balancer — simulate rubber-band factors, checkpoint difficulty, and target clear times before shipping trial parameters.
  • godot-camera-systems — chase/replay cameras that must track live cars and non-colliding ghost visuals during playback.

Downstream / consumers

  • godot-genre-racing — full racing genre stack that consumes checkpoint clocks, ghosts, and leaderboard formatting as core loop primitives.
  • godot-game-loop-collection — meta inventory/collection loops that can gate unlocks on validated best times from this skill.

Master

  • godot-master — library router and mirrored module entry for cross-skill discovery.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。