cfsa-antigravity 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,789 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdscript
|
|
3
|
+
description: GDScript development patterns for Godot 4.x game development. Covers node hierarchy, signals, scene composition, physics, input handling, resource management, autoload singletons, animation, tilemaps, shaders, multiplayer, GDExtension, and performance optimization.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# GDScript Development Patterns (Godot 4.x)
|
|
8
|
+
|
|
9
|
+
Expert guidance for building games and interactive applications with GDScript in Godot 4.x. Covers the scene/node architecture, signals for decoupled communication, physics bodies, input handling, resource management, multiplayer networking, and performance patterns for shipping production-quality games.
|
|
10
|
+
|
|
11
|
+
## When to Use This Skill
|
|
12
|
+
|
|
13
|
+
- Building 2D or 3D games with the Godot engine
|
|
14
|
+
- Prototyping interactive experiences and simulations
|
|
15
|
+
- Creating game tools and editor plugins
|
|
16
|
+
- Implementing multiplayer game networking
|
|
17
|
+
- Optimizing game performance (draw calls, physics, memory)
|
|
18
|
+
- Writing GDExtension bindings for native code
|
|
19
|
+
|
|
20
|
+
## Core Concepts
|
|
21
|
+
|
|
22
|
+
### 1. Node Hierarchy and Scene Composition
|
|
23
|
+
|
|
24
|
+
Godot's architecture is built on a tree of Nodes organized into reusable Scenes.
|
|
25
|
+
|
|
26
|
+
```gdscript
|
|
27
|
+
# Every script extends a node type
|
|
28
|
+
extends CharacterBody2D
|
|
29
|
+
|
|
30
|
+
# Node references -- use @onready for nodes that exist at _ready()
|
|
31
|
+
@onready var sprite: Sprite2D = $Sprite2D
|
|
32
|
+
@onready var collision: CollisionShape2D = $CollisionShape2D
|
|
33
|
+
@onready var animation_player: AnimationPlayer = $AnimationPlayer
|
|
34
|
+
@onready var health_bar: ProgressBar = $UI/HealthBar
|
|
35
|
+
|
|
36
|
+
# Use unique name references (%) for deeply nested nodes
|
|
37
|
+
@onready var score_label: Label = %ScoreLabel
|
|
38
|
+
|
|
39
|
+
# _ready() is called when the node and all children are in the tree
|
|
40
|
+
func _ready() -> void:
|
|
41
|
+
health_bar.max_value = max_health
|
|
42
|
+
health_bar.value = current_health
|
|
43
|
+
|
|
44
|
+
# _process() is called every frame
|
|
45
|
+
func _process(delta: float) -> void:
|
|
46
|
+
update_ui()
|
|
47
|
+
|
|
48
|
+
# _physics_process() is called at fixed intervals (default 60fps)
|
|
49
|
+
func _physics_process(delta: float) -> void:
|
|
50
|
+
handle_movement(delta)
|
|
51
|
+
move_and_slide()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Scene composition rules:**
|
|
55
|
+
|
|
56
|
+
| Rule | Explanation |
|
|
57
|
+
|------|-------------|
|
|
58
|
+
| One script per scene root | Keep logic in the root; children are structural |
|
|
59
|
+
| Scenes are reusable components | A scene is like a prefab: self-contained, instantiatable |
|
|
60
|
+
| Prefer composition over inheritance | Combine small scenes into complex ones |
|
|
61
|
+
| Use `$NodePath` for child access | Relative paths within the same scene |
|
|
62
|
+
| Use `%UniqueName` for deep access | Set "Access as Unique Name" in the editor |
|
|
63
|
+
|
|
64
|
+
### 2. Signals
|
|
65
|
+
|
|
66
|
+
Signals are Godot's observer pattern for decoupled communication.
|
|
67
|
+
|
|
68
|
+
```gdscript
|
|
69
|
+
# Defining custom signals
|
|
70
|
+
signal health_changed(new_health: int, max_health: int)
|
|
71
|
+
signal died
|
|
72
|
+
signal damage_taken(amount: int, source: Node)
|
|
73
|
+
|
|
74
|
+
# Emitting signals
|
|
75
|
+
func take_damage(amount: int, source: Node) -> void:
|
|
76
|
+
current_health -= amount
|
|
77
|
+
health_changed.emit(current_health, max_health)
|
|
78
|
+
damage_taken.emit(amount, source)
|
|
79
|
+
|
|
80
|
+
if current_health <= 0:
|
|
81
|
+
died.emit()
|
|
82
|
+
|
|
83
|
+
# Connecting signals in code
|
|
84
|
+
func _ready() -> void:
|
|
85
|
+
# Connect to own signals
|
|
86
|
+
health_changed.connect(_on_health_changed)
|
|
87
|
+
died.connect(_on_died)
|
|
88
|
+
|
|
89
|
+
# Connect to child signals
|
|
90
|
+
$HitArea.body_entered.connect(_on_hit_area_body_entered)
|
|
91
|
+
|
|
92
|
+
# Connect with bind (extra arguments)
|
|
93
|
+
$Button.pressed.connect(_on_button_pressed.bind("special"))
|
|
94
|
+
|
|
95
|
+
# One-shot connection (auto-disconnects after first emit)
|
|
96
|
+
died.connect(_on_died_once, CONNECT_ONE_SHOT)
|
|
97
|
+
|
|
98
|
+
# Signal handlers -- naming convention: _on_<source>_<signal>
|
|
99
|
+
func _on_health_changed(new_health: int, _max_health: int) -> void:
|
|
100
|
+
health_bar.value = new_health
|
|
101
|
+
|
|
102
|
+
func _on_died() -> void:
|
|
103
|
+
queue_free()
|
|
104
|
+
|
|
105
|
+
func _on_hit_area_body_entered(body: Node2D) -> void:
|
|
106
|
+
if body.is_in_group("enemies"):
|
|
107
|
+
take_damage(10, body)
|
|
108
|
+
|
|
109
|
+
# Disconnect when needed
|
|
110
|
+
func _exit_tree() -> void:
|
|
111
|
+
if health_changed.is_connected(_on_health_changed):
|
|
112
|
+
health_changed.disconnect(_on_health_changed)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Signal guidelines:**
|
|
116
|
+
|
|
117
|
+
| Guideline | Explanation |
|
|
118
|
+
|-----------|-------------|
|
|
119
|
+
| Signals go UP the tree | Children emit, parents listen |
|
|
120
|
+
| Calls go DOWN the tree | Parents call methods on children |
|
|
121
|
+
| Never connect signals in loops without disconnecting | Memory leak / duplicate calls |
|
|
122
|
+
| Use typed signal parameters | `signal scored(points: int)` not `signal scored` |
|
|
123
|
+
|
|
124
|
+
### 3. Exported Variables
|
|
125
|
+
|
|
126
|
+
```gdscript
|
|
127
|
+
extends CharacterBody2D
|
|
128
|
+
|
|
129
|
+
# Basic exports -- editable in the Inspector
|
|
130
|
+
@export var speed: float = 200.0
|
|
131
|
+
@export var jump_force: float = -400.0
|
|
132
|
+
@export var max_health: int = 100
|
|
133
|
+
|
|
134
|
+
# Export with range
|
|
135
|
+
@export_range(0.0, 1.0, 0.01) var friction: float = 0.5
|
|
136
|
+
@export_range(1, 100) var max_enemies: int = 10
|
|
137
|
+
|
|
138
|
+
# Export enums
|
|
139
|
+
enum State { IDLE, RUNNING, JUMPING, FALLING, DEAD }
|
|
140
|
+
@export var initial_state: State = State.IDLE
|
|
141
|
+
|
|
142
|
+
# Export resources
|
|
143
|
+
@export var weapon_data: WeaponResource
|
|
144
|
+
@export var particle_effect: PackedScene
|
|
145
|
+
|
|
146
|
+
# Export groups for organization
|
|
147
|
+
@export_group("Movement")
|
|
148
|
+
@export var walk_speed: float = 150.0
|
|
149
|
+
@export var run_speed: float = 300.0
|
|
150
|
+
@export var acceleration: float = 1000.0
|
|
151
|
+
|
|
152
|
+
@export_group("Combat")
|
|
153
|
+
@export var attack_damage: int = 10
|
|
154
|
+
@export var attack_cooldown: float = 0.5
|
|
155
|
+
|
|
156
|
+
@export_subgroup("Defense")
|
|
157
|
+
@export var armor: int = 5
|
|
158
|
+
@export var dodge_chance: float = 0.1
|
|
159
|
+
|
|
160
|
+
# Export node paths (resolved at runtime)
|
|
161
|
+
@export var target_path: NodePath
|
|
162
|
+
@onready var target: Node2D = get_node(target_path) if target_path else null
|
|
163
|
+
|
|
164
|
+
# Export file paths
|
|
165
|
+
@export_file("*.tscn") var next_level: String
|
|
166
|
+
@export_dir var save_directory: String
|
|
167
|
+
|
|
168
|
+
# Export flags (bitmask)
|
|
169
|
+
@export_flags("Fire", "Water", "Earth", "Wind") var elements: int = 0
|
|
170
|
+
|
|
171
|
+
# Export color
|
|
172
|
+
@export var hit_color: Color = Color.RED
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 4. Physics Bodies
|
|
176
|
+
|
|
177
|
+
```gdscript
|
|
178
|
+
# CharacterBody2D -- for player/NPC movement (you control motion)
|
|
179
|
+
extends CharacterBody2D
|
|
180
|
+
|
|
181
|
+
@export var speed: float = 200.0
|
|
182
|
+
@export var jump_velocity: float = -400.0
|
|
183
|
+
@export var gravity_multiplier: float = 1.0
|
|
184
|
+
|
|
185
|
+
var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
|
|
186
|
+
|
|
187
|
+
func _physics_process(delta: float) -> void:
|
|
188
|
+
# Apply gravity
|
|
189
|
+
if not is_on_floor():
|
|
190
|
+
velocity.y += gravity * gravity_multiplier * delta
|
|
191
|
+
|
|
192
|
+
# Jump
|
|
193
|
+
if Input.is_action_just_pressed("jump") and is_on_floor():
|
|
194
|
+
velocity.y = jump_velocity
|
|
195
|
+
|
|
196
|
+
# Horizontal movement
|
|
197
|
+
var direction := Input.get_axis("move_left", "move_right")
|
|
198
|
+
if direction:
|
|
199
|
+
velocity.x = direction * speed
|
|
200
|
+
else:
|
|
201
|
+
velocity.x = move_toward(velocity.x, 0, speed)
|
|
202
|
+
|
|
203
|
+
move_and_slide()
|
|
204
|
+
|
|
205
|
+
# Check collisions after move_and_slide
|
|
206
|
+
for i in get_slide_collision_count():
|
|
207
|
+
var collision := get_slide_collision(i)
|
|
208
|
+
var collider := collision.get_collider()
|
|
209
|
+
if collider.is_in_group("hazards"):
|
|
210
|
+
take_damage(10, collider)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# RigidBody2D -- for physics-driven objects (engine controls motion)
|
|
214
|
+
extends RigidBody2D
|
|
215
|
+
|
|
216
|
+
@export var explosion_force: float = 500.0
|
|
217
|
+
|
|
218
|
+
func explode(origin: Vector2) -> void:
|
|
219
|
+
var direction := (global_position - origin).normalized()
|
|
220
|
+
apply_impulse(direction * explosion_force)
|
|
221
|
+
|
|
222
|
+
# Do NOT set position directly on RigidBody -- use forces/impulses
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# Area2D -- for detection zones (no physics response)
|
|
226
|
+
extends Area2D
|
|
227
|
+
|
|
228
|
+
signal item_collected(item: Node2D)
|
|
229
|
+
|
|
230
|
+
func _ready() -> void:
|
|
231
|
+
body_entered.connect(_on_body_entered)
|
|
232
|
+
|
|
233
|
+
func _on_body_entered(body: Node2D) -> void:
|
|
234
|
+
if body.is_in_group("players"):
|
|
235
|
+
item_collected.emit(self)
|
|
236
|
+
queue_free()
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# CharacterBody3D -- 3D character movement
|
|
240
|
+
extends CharacterBody3D
|
|
241
|
+
|
|
242
|
+
@export var speed: float = 5.0
|
|
243
|
+
@export var mouse_sensitivity: float = 0.002
|
|
244
|
+
|
|
245
|
+
func _physics_process(delta: float) -> void:
|
|
246
|
+
var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
|
|
247
|
+
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
|
|
248
|
+
|
|
249
|
+
if direction:
|
|
250
|
+
velocity.x = direction.x * speed
|
|
251
|
+
velocity.z = direction.z * speed
|
|
252
|
+
else:
|
|
253
|
+
velocity.x = move_toward(velocity.x, 0, speed)
|
|
254
|
+
velocity.z = move_toward(velocity.z, 0, speed)
|
|
255
|
+
|
|
256
|
+
if not is_on_floor():
|
|
257
|
+
velocity += get_gravity() * delta
|
|
258
|
+
|
|
259
|
+
move_and_slide()
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 5. Input Handling
|
|
263
|
+
|
|
264
|
+
```gdscript
|
|
265
|
+
# Use Input Map actions (Project > Project Settings > Input Map)
|
|
266
|
+
# Never hardcode keys -- always use action names
|
|
267
|
+
|
|
268
|
+
# Polling input in _process or _physics_process
|
|
269
|
+
func _physics_process(delta: float) -> void:
|
|
270
|
+
if Input.is_action_pressed("move_right"):
|
|
271
|
+
velocity.x = speed
|
|
272
|
+
if Input.is_action_just_pressed("jump"):
|
|
273
|
+
jump()
|
|
274
|
+
if Input.is_action_just_released("attack"):
|
|
275
|
+
release_attack()
|
|
276
|
+
|
|
277
|
+
# Event-based input in _unhandled_input (preferred for UI-independent input)
|
|
278
|
+
func _unhandled_input(event: InputEvent) -> void:
|
|
279
|
+
if event.is_action_pressed("pause"):
|
|
280
|
+
toggle_pause()
|
|
281
|
+
get_viewport().set_input_as_handled()
|
|
282
|
+
|
|
283
|
+
if event is InputEventMouseButton:
|
|
284
|
+
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
|
285
|
+
shoot()
|
|
286
|
+
|
|
287
|
+
if event is InputEventMouseMotion:
|
|
288
|
+
rotate_camera(event.relative)
|
|
289
|
+
|
|
290
|
+
# _input for UI-level input (processed before _unhandled_input)
|
|
291
|
+
func _input(event: InputEvent) -> void:
|
|
292
|
+
if event.is_action_pressed("ui_cancel"):
|
|
293
|
+
open_menu()
|
|
294
|
+
|
|
295
|
+
# Input strength for analog sticks
|
|
296
|
+
func _physics_process(delta: float) -> void:
|
|
297
|
+
var move_strength := Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
|
|
298
|
+
velocity.x = move_strength * speed
|
|
299
|
+
|
|
300
|
+
# Input vector for 2D movement
|
|
301
|
+
func _physics_process(delta: float) -> void:
|
|
302
|
+
var input_vector := Input.get_vector("move_left", "move_right", "move_up", "move_down")
|
|
303
|
+
velocity = input_vector * speed
|
|
304
|
+
move_and_slide()
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### 6. Resource Management
|
|
308
|
+
|
|
309
|
+
```gdscript
|
|
310
|
+
# Custom Resource -- data container saved as .tres files
|
|
311
|
+
class_name WeaponResource
|
|
312
|
+
extends Resource
|
|
313
|
+
|
|
314
|
+
@export var name: String = ""
|
|
315
|
+
@export var damage: int = 10
|
|
316
|
+
@export var attack_speed: float = 1.0
|
|
317
|
+
@export var range: float = 50.0
|
|
318
|
+
@export var icon: Texture2D
|
|
319
|
+
@export var projectile_scene: PackedScene
|
|
320
|
+
|
|
321
|
+
func get_dps() -> float:
|
|
322
|
+
return damage * attack_speed
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
# Loading resources
|
|
326
|
+
var sword: WeaponResource = preload("res://resources/weapons/sword.tres")
|
|
327
|
+
var shield: WeaponResource = load("res://resources/weapons/shield.tres")
|
|
328
|
+
|
|
329
|
+
# Preload vs load:
|
|
330
|
+
# preload() -- loads at compile time, use for always-needed resources
|
|
331
|
+
# load() -- loads at runtime, use for conditionally-needed resources
|
|
332
|
+
# ResourceLoader.load_threaded_request() -- async loading for large resources
|
|
333
|
+
|
|
334
|
+
# Async resource loading (loading screens)
|
|
335
|
+
func load_level_async(path: String) -> void:
|
|
336
|
+
ResourceLoader.load_threaded_request(path)
|
|
337
|
+
# Poll in _process
|
|
338
|
+
while true:
|
|
339
|
+
var status := ResourceLoader.load_threaded_get_status(path)
|
|
340
|
+
match status:
|
|
341
|
+
ResourceLoader.THREAD_LOAD_IN_PROGRESS:
|
|
342
|
+
var progress: Array = []
|
|
343
|
+
ResourceLoader.load_threaded_get_status(path, progress)
|
|
344
|
+
loading_bar.value = progress[0] * 100
|
|
345
|
+
await get_tree().process_frame
|
|
346
|
+
ResourceLoader.THREAD_LOAD_LOADED:
|
|
347
|
+
var scene: PackedScene = ResourceLoader.load_threaded_get(path)
|
|
348
|
+
get_tree().change_scene_to_packed(scene)
|
|
349
|
+
return
|
|
350
|
+
_:
|
|
351
|
+
push_error("Failed to load: " + path)
|
|
352
|
+
return
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
# Instantiating packed scenes
|
|
356
|
+
var enemy_scene: PackedScene = preload("res://scenes/enemies/goblin.tscn")
|
|
357
|
+
|
|
358
|
+
func spawn_enemy(pos: Vector2) -> void:
|
|
359
|
+
var enemy: CharacterBody2D = enemy_scene.instantiate()
|
|
360
|
+
enemy.global_position = pos
|
|
361
|
+
add_child(enemy)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### 7. Autoload Singletons
|
|
365
|
+
|
|
366
|
+
```gdscript
|
|
367
|
+
# Register in Project > Project Settings > Autoload
|
|
368
|
+
# Global state managers, audio, scene transitions
|
|
369
|
+
|
|
370
|
+
# game_manager.gd (autoload as "GameManager")
|
|
371
|
+
extends Node
|
|
372
|
+
|
|
373
|
+
signal score_changed(new_score: int)
|
|
374
|
+
signal game_over
|
|
375
|
+
|
|
376
|
+
var score: int = 0:
|
|
377
|
+
set(value):
|
|
378
|
+
score = value
|
|
379
|
+
score_changed.emit(score)
|
|
380
|
+
|
|
381
|
+
var high_score: int = 0
|
|
382
|
+
var is_paused: bool = false
|
|
383
|
+
|
|
384
|
+
func add_score(points: int) -> void:
|
|
385
|
+
score += points
|
|
386
|
+
if score > high_score:
|
|
387
|
+
high_score = score
|
|
388
|
+
|
|
389
|
+
func reset() -> void:
|
|
390
|
+
score = 0
|
|
391
|
+
|
|
392
|
+
func pause() -> void:
|
|
393
|
+
is_paused = true
|
|
394
|
+
get_tree().paused = true
|
|
395
|
+
|
|
396
|
+
func unpause() -> void:
|
|
397
|
+
is_paused = false
|
|
398
|
+
get_tree().paused = false
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
# audio_manager.gd (autoload as "AudioManager")
|
|
402
|
+
extends Node
|
|
403
|
+
|
|
404
|
+
var sfx_players: Array[AudioStreamPlayer] = []
|
|
405
|
+
const MAX_SFX_PLAYERS: int = 8
|
|
406
|
+
|
|
407
|
+
func _ready() -> void:
|
|
408
|
+
for i in MAX_SFX_PLAYERS:
|
|
409
|
+
var player := AudioStreamPlayer.new()
|
|
410
|
+
player.bus = "SFX"
|
|
411
|
+
add_child(player)
|
|
412
|
+
sfx_players.append(player)
|
|
413
|
+
|
|
414
|
+
func play_sfx(stream: AudioStream, volume_db: float = 0.0) -> void:
|
|
415
|
+
for player in sfx_players:
|
|
416
|
+
if not player.playing:
|
|
417
|
+
player.stream = stream
|
|
418
|
+
player.volume_db = volume_db
|
|
419
|
+
player.play()
|
|
420
|
+
return
|
|
421
|
+
# All players busy -- skip or replace oldest
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
# Accessing autoloads from any script
|
|
425
|
+
func _on_enemy_killed() -> void:
|
|
426
|
+
GameManager.add_score(100)
|
|
427
|
+
AudioManager.play_sfx(kill_sound)
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### 8. Animation
|
|
431
|
+
|
|
432
|
+
```gdscript
|
|
433
|
+
# AnimationPlayer -- keyframe animation for any property
|
|
434
|
+
@onready var anim: AnimationPlayer = $AnimationPlayer
|
|
435
|
+
|
|
436
|
+
func play_attack() -> void:
|
|
437
|
+
anim.play("attack")
|
|
438
|
+
await anim.animation_finished
|
|
439
|
+
anim.play("idle")
|
|
440
|
+
|
|
441
|
+
# AnimationTree -- state machine for blending animations
|
|
442
|
+
@onready var anim_tree: AnimationTree = $AnimationTree
|
|
443
|
+
@onready var state_machine: AnimationNodeStateMachinePlayback = anim_tree["parameters/playback"]
|
|
444
|
+
|
|
445
|
+
func _physics_process(delta: float) -> void:
|
|
446
|
+
# Blend parameter for walk/run blending
|
|
447
|
+
anim_tree["parameters/walk_run/blend_amount"] = velocity.length() / max_speed
|
|
448
|
+
|
|
449
|
+
# State machine transitions
|
|
450
|
+
if is_on_floor():
|
|
451
|
+
if velocity.length() > 0:
|
|
452
|
+
state_machine.travel("walk_run")
|
|
453
|
+
else:
|
|
454
|
+
state_machine.travel("idle")
|
|
455
|
+
else:
|
|
456
|
+
if velocity.y < 0:
|
|
457
|
+
state_machine.travel("jump")
|
|
458
|
+
else:
|
|
459
|
+
state_machine.travel("fall")
|
|
460
|
+
|
|
461
|
+
# Tween -- procedural animation (no AnimationPlayer needed)
|
|
462
|
+
func flash_damage() -> void:
|
|
463
|
+
var tween := create_tween()
|
|
464
|
+
tween.tween_property(sprite, "modulate", Color.RED, 0.1)
|
|
465
|
+
tween.tween_property(sprite, "modulate", Color.WHITE, 0.1)
|
|
466
|
+
|
|
467
|
+
func scale_bounce() -> void:
|
|
468
|
+
var tween := create_tween()
|
|
469
|
+
tween.set_trans(Tween.TRANS_ELASTIC)
|
|
470
|
+
tween.set_ease(Tween.EASE_OUT)
|
|
471
|
+
tween.tween_property(sprite, "scale", Vector2(1.2, 1.2), 0.1)
|
|
472
|
+
tween.tween_property(sprite, "scale", Vector2.ONE, 0.3)
|
|
473
|
+
|
|
474
|
+
func fade_out_and_free() -> void:
|
|
475
|
+
var tween := create_tween()
|
|
476
|
+
tween.tween_property(self, "modulate:a", 0.0, 0.5)
|
|
477
|
+
tween.tween_callback(queue_free)
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### 9. Tilemaps
|
|
481
|
+
|
|
482
|
+
```gdscript
|
|
483
|
+
# TileMapLayer (Godot 4.3+) -- replaces TileMap
|
|
484
|
+
extends Node2D
|
|
485
|
+
|
|
486
|
+
@onready var ground_layer: TileMapLayer = $GroundLayer
|
|
487
|
+
@onready var walls_layer: TileMapLayer = $WallsLayer
|
|
488
|
+
@onready var decoration_layer: TileMapLayer = $DecorationLayer
|
|
489
|
+
|
|
490
|
+
# Get tile data
|
|
491
|
+
func get_tile_at(world_pos: Vector2) -> int:
|
|
492
|
+
var tile_pos := ground_layer.local_to_map(world_pos)
|
|
493
|
+
return ground_layer.get_cell_source_id(tile_pos)
|
|
494
|
+
|
|
495
|
+
# Set tiles programmatically
|
|
496
|
+
func place_wall(tile_pos: Vector2i) -> void:
|
|
497
|
+
walls_layer.set_cell(tile_pos, 0, Vector2i(0, 0)) # source_id, atlas_coords
|
|
498
|
+
|
|
499
|
+
func remove_wall(tile_pos: Vector2i) -> void:
|
|
500
|
+
walls_layer.erase_cell(tile_pos)
|
|
501
|
+
|
|
502
|
+
# Custom data layers on tiles (set in TileSet editor)
|
|
503
|
+
func is_walkable(world_pos: Vector2) -> bool:
|
|
504
|
+
var tile_pos := ground_layer.local_to_map(world_pos)
|
|
505
|
+
var data := ground_layer.get_cell_tile_data(tile_pos)
|
|
506
|
+
if data:
|
|
507
|
+
return data.get_custom_data("walkable") as bool
|
|
508
|
+
return false
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### 10. Shaders
|
|
512
|
+
|
|
513
|
+
```gdscript
|
|
514
|
+
# Applying shaders via ShaderMaterial
|
|
515
|
+
@onready var sprite: Sprite2D = $Sprite2D
|
|
516
|
+
|
|
517
|
+
func set_outline(enabled: bool, color: Color = Color.WHITE) -> void:
|
|
518
|
+
var material := sprite.material as ShaderMaterial
|
|
519
|
+
material.set_shader_parameter("outline_enabled", enabled)
|
|
520
|
+
material.set_shader_parameter("outline_color", color)
|
|
521
|
+
|
|
522
|
+
# Dissolve effect
|
|
523
|
+
func dissolve(duration: float) -> void:
|
|
524
|
+
var material := sprite.material as ShaderMaterial
|
|
525
|
+
var tween := create_tween()
|
|
526
|
+
tween.tween_method(
|
|
527
|
+
func(value: float) -> void:
|
|
528
|
+
material.set_shader_parameter("dissolve_amount", value),
|
|
529
|
+
0.0, 1.0, duration
|
|
530
|
+
)
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
```glsl
|
|
534
|
+
// Simple outline shader (outline.gdshader)
|
|
535
|
+
shader_type canvas_item;
|
|
536
|
+
|
|
537
|
+
uniform bool outline_enabled = false;
|
|
538
|
+
uniform vec4 outline_color : source_color = vec4(1.0);
|
|
539
|
+
uniform float outline_width : hint_range(0.0, 10.0) = 1.0;
|
|
540
|
+
|
|
541
|
+
void fragment() {
|
|
542
|
+
vec4 col = texture(TEXTURE, UV);
|
|
543
|
+
|
|
544
|
+
if (outline_enabled && col.a < 0.5) {
|
|
545
|
+
float a = 0.0;
|
|
546
|
+
vec2 size = TEXTURE_PIXEL_SIZE * outline_width;
|
|
547
|
+
a += texture(TEXTURE, UV + vec2(-size.x, 0)).a;
|
|
548
|
+
a += texture(TEXTURE, UV + vec2(size.x, 0)).a;
|
|
549
|
+
a += texture(TEXTURE, UV + vec2(0, -size.y)).a;
|
|
550
|
+
a += texture(TEXTURE, UV + vec2(0, size.y)).a;
|
|
551
|
+
|
|
552
|
+
if (a > 0.0) {
|
|
553
|
+
col = outline_color;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
COLOR = col;
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### 11. Multiplayer (High-Level API)
|
|
562
|
+
|
|
563
|
+
```gdscript
|
|
564
|
+
# Server setup
|
|
565
|
+
extends Node
|
|
566
|
+
|
|
567
|
+
var peer: ENetMultiplayerPeer
|
|
568
|
+
|
|
569
|
+
func host_game(port: int = 9999, max_clients: int = 4) -> void:
|
|
570
|
+
peer = ENetMultiplayerPeer.new()
|
|
571
|
+
var error := peer.create_server(port, max_clients)
|
|
572
|
+
if error != OK:
|
|
573
|
+
push_error("Failed to create server: " + str(error))
|
|
574
|
+
return
|
|
575
|
+
multiplayer.multiplayer_peer = peer
|
|
576
|
+
multiplayer.peer_connected.connect(_on_peer_connected)
|
|
577
|
+
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
|
578
|
+
|
|
579
|
+
func join_game(address: String = "localhost", port: int = 9999) -> void:
|
|
580
|
+
peer = ENetMultiplayerPeer.new()
|
|
581
|
+
var error := peer.create_client(address, port)
|
|
582
|
+
if error != OK:
|
|
583
|
+
push_error("Failed to connect: " + str(error))
|
|
584
|
+
return
|
|
585
|
+
multiplayer.multiplayer_peer = peer
|
|
586
|
+
|
|
587
|
+
func _on_peer_connected(id: int) -> void:
|
|
588
|
+
print("Peer connected: ", id)
|
|
589
|
+
spawn_player(id)
|
|
590
|
+
|
|
591
|
+
func _on_peer_disconnected(id: int) -> void:
|
|
592
|
+
print("Peer disconnected: ", id)
|
|
593
|
+
remove_player(id)
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
# RPC (Remote Procedure Calls)
|
|
597
|
+
extends CharacterBody2D
|
|
598
|
+
|
|
599
|
+
# Called on all peers
|
|
600
|
+
@rpc("any_peer", "call_local", "reliable")
|
|
601
|
+
func take_damage(amount: int) -> void:
|
|
602
|
+
health -= amount
|
|
603
|
+
if health <= 0:
|
|
604
|
+
die()
|
|
605
|
+
|
|
606
|
+
# Called only on authority (server)
|
|
607
|
+
@rpc("any_peer", "call_remote", "reliable")
|
|
608
|
+
func request_action(action: String) -> void:
|
|
609
|
+
if not multiplayer.is_server():
|
|
610
|
+
return
|
|
611
|
+
# Validate and process on server
|
|
612
|
+
process_action(action)
|
|
613
|
+
|
|
614
|
+
# Unreliable for frequent updates (position sync)
|
|
615
|
+
@rpc("authority", "call_remote", "unreliable")
|
|
616
|
+
func sync_position(pos: Vector2, vel: Vector2) -> void:
|
|
617
|
+
global_position = pos
|
|
618
|
+
velocity = vel
|
|
619
|
+
|
|
620
|
+
func _physics_process(delta: float) -> void:
|
|
621
|
+
if is_multiplayer_authority():
|
|
622
|
+
# Only the authority (owner) moves this character
|
|
623
|
+
handle_input(delta)
|
|
624
|
+
move_and_slide()
|
|
625
|
+
sync_position.rpc(global_position, velocity)
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
# MultiplayerSpawner -- automatic scene synchronization
|
|
629
|
+
# Add MultiplayerSpawner as child, configure spawn path and scenes in editor
|
|
630
|
+
# MultiplayerSynchronizer -- automatic property synchronization
|
|
631
|
+
# Add MultiplayerSynchronizer as child, configure synced properties in editor
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### 12. GDExtension for Native Code
|
|
635
|
+
|
|
636
|
+
```gdscript
|
|
637
|
+
# GDExtension allows writing performance-critical code in C/C++/Rust
|
|
638
|
+
# and calling it from GDScript
|
|
639
|
+
|
|
640
|
+
# Using a GDExtension class (after building the extension)
|
|
641
|
+
var pathfinder: NativePathfinder = NativePathfinder.new()
|
|
642
|
+
|
|
643
|
+
func find_path(from: Vector2, to: Vector2) -> PackedVector2Array:
|
|
644
|
+
return pathfinder.calculate_path(from, to)
|
|
645
|
+
|
|
646
|
+
# gdextension file (my_extension.gdextension)
|
|
647
|
+
# [configuration]
|
|
648
|
+
# entry_symbol = "my_extension_init"
|
|
649
|
+
# compatibility_minimum = "4.2"
|
|
650
|
+
#
|
|
651
|
+
# [libraries]
|
|
652
|
+
# linux.x86_64 = "res://bin/libmy_extension.so"
|
|
653
|
+
# windows.x86_64 = "res://bin/my_extension.dll"
|
|
654
|
+
# macos = "res://bin/libmy_extension.dylib"
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
### 13. Performance Patterns
|
|
658
|
+
|
|
659
|
+
```gdscript
|
|
660
|
+
# Object pooling -- reuse objects instead of creating/destroying
|
|
661
|
+
class_name ObjectPool
|
|
662
|
+
extends Node
|
|
663
|
+
|
|
664
|
+
var pool: Array[Node] = []
|
|
665
|
+
var scene: PackedScene
|
|
666
|
+
|
|
667
|
+
func _init(packed_scene: PackedScene, initial_size: int = 20) -> void:
|
|
668
|
+
scene = packed_scene
|
|
669
|
+
for i in initial_size:
|
|
670
|
+
var obj := scene.instantiate()
|
|
671
|
+
obj.set_process(false)
|
|
672
|
+
obj.visible = false
|
|
673
|
+
pool.append(obj)
|
|
674
|
+
add_child(obj)
|
|
675
|
+
|
|
676
|
+
func get_object() -> Node:
|
|
677
|
+
for obj in pool:
|
|
678
|
+
if not obj.visible:
|
|
679
|
+
obj.visible = true
|
|
680
|
+
obj.set_process(true)
|
|
681
|
+
return obj
|
|
682
|
+
# Pool exhausted -- grow it
|
|
683
|
+
var obj := scene.instantiate()
|
|
684
|
+
pool.append(obj)
|
|
685
|
+
add_child(obj)
|
|
686
|
+
return obj
|
|
687
|
+
|
|
688
|
+
func return_object(obj: Node) -> void:
|
|
689
|
+
obj.visible = false
|
|
690
|
+
obj.set_process(false)
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
# Use call_deferred for non-urgent operations
|
|
694
|
+
func _on_enemy_died(enemy: Node) -> void:
|
|
695
|
+
enemy.call_deferred("queue_free") # Defers to end of frame
|
|
696
|
+
|
|
697
|
+
# Spatial partitioning with groups
|
|
698
|
+
func get_nearby_enemies(pos: Vector2, radius: float) -> Array[Node]:
|
|
699
|
+
var nearby: Array[Node] = []
|
|
700
|
+
for enemy in get_tree().get_nodes_in_group("enemies"):
|
|
701
|
+
if enemy.global_position.distance_to(pos) <= radius:
|
|
702
|
+
nearby.append(enemy)
|
|
703
|
+
return nearby
|
|
704
|
+
|
|
705
|
+
# For large numbers, use Area2D as detection zone instead of distance checks
|
|
706
|
+
|
|
707
|
+
# Reduce draw calls
|
|
708
|
+
# - Use texture atlases (combine sprites into one texture)
|
|
709
|
+
# - Minimize CanvasItem material changes
|
|
710
|
+
# - Use visibility notifiers to disable off-screen processing
|
|
711
|
+
|
|
712
|
+
# Processing optimization
|
|
713
|
+
func _ready() -> void:
|
|
714
|
+
# Disable processing when not needed
|
|
715
|
+
set_process(false)
|
|
716
|
+
set_physics_process(false)
|
|
717
|
+
|
|
718
|
+
func activate() -> void:
|
|
719
|
+
set_process(true)
|
|
720
|
+
set_physics_process(true)
|
|
721
|
+
|
|
722
|
+
# Use VisibleOnScreenNotifier2D to auto-disable off-screen nodes
|
|
723
|
+
@onready var notifier: VisibleOnScreenNotifier2D = $VisibleOnScreenNotifier2D
|
|
724
|
+
|
|
725
|
+
func _ready() -> void:
|
|
726
|
+
notifier.screen_entered.connect(func(): set_physics_process(true))
|
|
727
|
+
notifier.screen_exited.connect(func(): set_physics_process(false))
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
## Anti-Patterns
|
|
731
|
+
|
|
732
|
+
| Anti-Pattern | Why It Is Bad | Do This Instead |
|
|
733
|
+
|-------------|--------------|----------------|
|
|
734
|
+
| `get_node()` with long absolute paths | Breaks when tree changes | Use `$RelativePath` or `%UniqueName` |
|
|
735
|
+
| Connecting signals in `_process()` | Duplicate connections every frame | Connect in `_ready()` |
|
|
736
|
+
| Using `find_child()` frequently | O(n) tree traversal each call | Cache node references with `@onready` |
|
|
737
|
+
| Hardcoding input keys | Cannot be remapped | Use Input Map action names |
|
|
738
|
+
| `queue_free()` in physics callbacks | Can cause crashes | Use `call_deferred("queue_free")` |
|
|
739
|
+
| Giant autoload scripts | God object, hard to test | Split into focused autoloads |
|
|
740
|
+
| Polling in `_process` for rare events | Wastes CPU | Use signals or timers |
|
|
741
|
+
| Raw strings for scene paths | Typo-prone, no refactor support | Use `preload()` with const |
|
|
742
|
+
|
|
743
|
+
## Project Structure
|
|
744
|
+
|
|
745
|
+
```
|
|
746
|
+
project/
|
|
747
|
+
scenes/
|
|
748
|
+
player/
|
|
749
|
+
player.tscn
|
|
750
|
+
player.gd
|
|
751
|
+
enemies/
|
|
752
|
+
goblin.tscn
|
|
753
|
+
goblin.gd
|
|
754
|
+
ui/
|
|
755
|
+
hud.tscn
|
|
756
|
+
main_menu.tscn
|
|
757
|
+
levels/
|
|
758
|
+
level_01.tscn
|
|
759
|
+
scripts/
|
|
760
|
+
autoload/
|
|
761
|
+
game_manager.gd
|
|
762
|
+
audio_manager.gd
|
|
763
|
+
scene_manager.gd
|
|
764
|
+
resources/
|
|
765
|
+
weapons/
|
|
766
|
+
sword.tres
|
|
767
|
+
materials/
|
|
768
|
+
themes/
|
|
769
|
+
assets/
|
|
770
|
+
sprites/
|
|
771
|
+
audio/
|
|
772
|
+
music/
|
|
773
|
+
sfx/
|
|
774
|
+
fonts/
|
|
775
|
+
addons/
|
|
776
|
+
shaders/
|
|
777
|
+
project.godot
|
|
778
|
+
export_presets.cfg
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
## Resources
|
|
782
|
+
|
|
783
|
+
- **Godot 4 Docs**: https://docs.godotengine.org/en/stable/
|
|
784
|
+
- **GDScript Reference**: https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/
|
|
785
|
+
- **GDQuest**: https://www.gdquest.com/
|
|
786
|
+
- **Godot Shaders**: https://godotshaders.com/
|
|
787
|
+
- **Godot Asset Library**: https://godotengine.org/asset-library/
|
|
788
|
+
- **Godot Multiplayer Docs**: https://docs.godotengine.org/en/stable/tutorials/networking/
|
|
789
|
+
- **GDExtension Docs**: https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/
|