MCP HubMCP Hub
Retour aux compétences

jahro-watcher

jahro-console
Mis à jour 2 days ago
5 vues
12
12
Voir sur GitHub
Métageneral

À propos

Cette Compétence Claude ajoute automatiquement des attributs `[JahroWatch]` aux champs et propriétés C# pour une surveillance en temps réel lors de l'exécution dans Unity. Elle identifie les variables clés de l'état du jeu et génère des modèles optimisés pour les performances, remplaçant ainsi la journalisation manuelle. Utilisez-la lorsque vous avez besoin de suivre des variables, d'inspecter l'état du jeu ou d'intégrer le système JahroWatch.

Installation rapide

Claude Code

Recommandé
Principal
npx skills add jahro-console/unity-agent-skills -a claude-code
Commande PluginAlternatif
/plugin add https://github.com/jahro-console/unity-agent-skills
Git CloneAlternatif
git clone https://github.com/jahro-console/unity-agent-skills.git ~/.claude/skills/jahro-watcher

Copiez et collez cette commande dans Claude Code pour installer cette compétence

Documentation

Jahro Watcher

Help users monitor game variables in real-time using Jahro's [JahroWatch] attribute system.

Workflow

  1. Analyze the user's code — identify fields/properties worth monitoring
  2. Generate correct [JahroWatch] attributes
  3. Add registration if needed (instance members require RegisterObject)
  4. VERIFY — "Enter Play Mode, open the Watcher tab, confirm values update"

Analyzing Code for Watcher Candidates

When the user shares a class, identify members worth monitoring:

Good candidates:

  • Game state fields: health, score, level, currency, inventory counts
  • Physics values: velocity, position, rotation (especially via properties wrapping Rigidbody)
  • Performance metrics: FPS, memory, draw calls
  • Enum state fields: game state, player state, AI state
  • Key counters: enemy count, player count, item count

Skip these:

  • Constants and readonly compile-time values
  • Private implementation details that change every frame with no debugging value
  • References to other objects (Transform, GameObject) — watch their properties instead
  • Collections and dictionaries (arrays are supported, but dictionaries are not)

Suggest replacing Debug.Log polling: If the user has Debug.Log($"Health: {health}") in Update(), recommend [JahroWatch] instead — it eliminates log spam and provides a clean real-time dashboard.

Attribute Syntax

[JahroWatch("Display Name", "GroupName", "Description for detail modal")]

Constructor: [JahroWatch(string name, string group, string description)]

All parameters are optional. Defaults: name = member name (leading _ stripped), group = "Default", description = "".

Complete example

using JahroConsole;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [JahroWatch("Health", "Player", "Current hit points")]
    public float health = 100f;

    [JahroWatch("Stamina", "Player", "Current stamina")]
    public float stamina = 50f;

    [JahroWatch("Position", "Player", "World position")]
    public Vector3 Position => transform.position;

    [JahroWatch("Velocity", "Player", "Movement velocity")]
    public Vector3 Velocity => GetComponent<Rigidbody>().velocity;

    [JahroWatch("Is Grounded", "Player", "Touching ground")]
    public bool isGrounded;

    void OnEnable()  => Jahro.RegisterObject(this);
    void OnDisable() => Jahro.UnregisterObject(this);
}

Registration

Instance members — require RegisterObject

void OnEnable()  => Jahro.RegisterObject(this);
void OnDisable() => Jahro.UnregisterObject(this);

This same call also registers [JahroCommand] attributes on the class. If the class already has RegisterObject for commands, do not add a second call — one call handles both.

Read references/common-patterns.md for the canonical lifecycle pattern.

Static members — no registration needed

Static fields and properties with [JahroWatch] are discovered via assembly scanning:

public static class GameStats
{
    [JahroWatch("Total Score", "Game")]
    public static int Score;

    [JahroWatch("Session Time", "Game")]
    public static float SessionTime => Time.realtimeSinceStartup;
}

Adding watchers to a class that already has commands

If the class already has [JahroCommand] attributes and RegisterObject, just add [JahroWatch] attributes — no registration changes:

public class GameManager : MonoBehaviour
{
    // Existing command
    [JahroCommand("reset-game", "Game", "Reset game")]
    public void ResetGame() { /* ... */ }

    // New watchers — just add attributes
    [JahroWatch("Player Count", "Game")]
    public int playerCount;

    [JahroWatch("Game Time", "Game")]
    public float gameTime;

    // Already present — no changes needed
    void OnEnable()  => Jahro.RegisterObject(this);
    void OnDisable() => Jahro.UnregisterObject(this);
}

Supported Types

TypeList View DisplayDetail Modal
int, float, double, boolValue as-isSame
stringTruncatedFull text
Vector2Compact coordsCoords + magnitude
Vector3Compact coordsCoords + magnitude
QuaternionRaw valuesRaw + Euler angles
TransformPositionPosition, rotation, scale, child count
RigidbodySummaryMass, kinematic, gravity, velocity, angular velocity
ColliderSummaryTrigger status, material, bounds
AudioSourceSummaryClip, volume, loop, pitch, mute
CameraSummaryFOV, clip planes, aspect ratio
Arrays (any T[])TypeName[length]Full contents

For custom types not in this table, the watcher calls .ToString(). If you need rich display, consider watching individual primitive properties instead.

Read references/api-reference.md for the full type display details.

Performance

Watchers are designed to be safe for development and testing:

  • Values are only read when the Watcher UI tab is visible. No continuous polling when the console is closed or on another tab.
  • No overhead when disabled. If Jahro is disabled via JAHRO_DISABLE or auto-disable, watchers are never evaluated.
  • Be mindful of expensive property getters. A property like public int Count => expensiveList.Where(...).Count() runs its getter every frame the Watcher is open. Cache expensive computations.

Performance-safe property pattern

private float _cachedFps;
private float _lastFpsUpdate;

void Update()
{
    if (Time.time - _lastFpsUpdate > 0.25f)
    {
        _cachedFps = 1f / Time.unscaledDeltaTime;
        _lastFpsUpdate = Time.time;
    }
}

[JahroWatch("FPS", "Performance")]
public float FPS => _cachedFps;

Group Organization

By system (recommended default)

"Player"      — Health, Stamina, Position, Velocity
"Physics"     — Is Grounded, Angular Velocity, Collision Count
"Performance" — FPS, Memory, Draw Calls
"Game"        — Game State, Level Progress, Player Count
"AI"          — AI State, Target, Path Length

By priority

"Critical"    — Health, Frame Time (always need these)
"Gameplay"    — Enemy Count, Spawn Timer
"Diagnostics" — GC Allocs, Memory

Watcher UI behavior

  • Favorites group always appears at top (user stars individual watchers)
  • Custom groups are alphabetically sorted
  • Groups are collapsible to reduce clutter
  • Tapping a watcher opens a detail modal with description and full type info

Contextual Awareness

Pattern in codeSuggestion
Debug.Log in Update() logging variable valuesReplace with [JahroWatch] — cleaner, no log spam
[JahroWatch] already presentSuggest additional watchers, better groups, performance tips
[JahroCommand] but no watchersSuggest adding watchers for key state the commands modify
Rigidbody or physics-heavy codeSuggest velocity, angular velocity, isGrounded watchers
Game manager with state fieldsSuggest watching game state enum, counts, timers

Verification

After generating watchers, always include:

Verify: Enter Play Mode → press ~ → switch to the Watcher tab. Confirm your watched values appear in the correct groups and update in real-time as the game runs. Tap a watcher to see its detail modal.

If watchers appear but don't update, or don't appear at all, suggest the jahro-troubleshooting skill — common causes: missing RegisterObject, Watcher tab not open, object destroyed without unregistering.

Dépôt GitHub

jahro-console/unity-agent-skills
Chemin: skills/jahro-watcher
0
agent-skillsai-assistantai-codingclaude-codecursordebugging

Compétences associées

content-collections

Méta

Cette compétence propose une configuration éprouvée en production pour Content Collections, un outil axé sur TypeScript qui transforme des fichiers Markdown/MDX en collections de données typées de manière sûre avec une validation Zod. Utilisez-la lors de la création de blogs, de sites de documentation ou d'applications Vite + React riches en contenu pour garantir la sécurité de typage et la validation automatique du contenu. Elle couvre tout, de la configuration du plugin Vite et de la compilation MDX à l'optimisation des déploiements et la validation des schémas.

Voir la compétence

polymarket

Méta

Cette compétence permet aux développeurs de créer des applications avec la plateforme de marchés prédictifs Polymarket, incluant l'intégration d'API pour le trading et les données de marché. Elle fournit également une diffusion de données en temps réel via WebSocket pour surveiller les transactions en direct et l'activité du marché. Utilisez-la pour mettre en œuvre des stratégies de trading ou pour créer des outils traitant les mises à jour de marché en direct.

Voir la compétence

creating-opencode-plugins

Méta

Cette compétence aide les développeurs à créer des plugins OpenCode qui s'interconnectent avec plus de 25 types d'événements tels que les commandes, les fichiers et les opérations LSP. Elle fournit la structure du plugin, les spécifications de l'API événementielle et les modèles d'implémentation pour les modules JavaScript/TypeScript. Utilisez-la lorsque vous avez besoin d'intercepter, de surveiller ou d'étendre le cycle de vie de l'assistant IA OpenCode avec une logique personnalisée pilotée par les événements.

Voir la compétence

sglang

Méta

SGLang est un framework de service LLM haute performance spécialisé dans la génération rapide et structurée pour les workflows JSON, regex et agentiques grâce à son cache de préfixe RadixAttention. Il offre une inférence nettement plus rapide, particulièrement pour les tâches avec des préfixes répétés, ce qui le rend idéal pour les sorties complexes et structurées ainsi que les conversations multi-tours. Choisissez SGLang plutôt que des alternatives comme vLLM lorsque vous avez besoin d'un décodage contraint ou que vous construisez des applications avec un partage étendu de préfixes.

Voir la compétence