@leejungkiin/awkit 1.7.1 → 1.7.4
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/awk.js +576 -84
- package/core/CLAUDE.md +1 -1
- package/core/GEMINI.md +148 -167
- package/core/GEMINI.md.bak +149 -116
- package/core/skill-runtime-manifest.json +3 -0
- package/docs/Claude Fable 5.md +3826 -0
- package/docs/android_kotlin_system_instruction.md +210 -0
- package/docs/brainstorm_ponytail_integration.md +146 -0
- package/docs/brainstorm_smart_setup.md +113 -0
- package/docs/deep-research-report (1).md +293 -0
- package/docs/history/GEMINI.v1.md +135 -0
- package/docs/history/brainstorm_antigravity_unified_architecture.v1.md +105 -0
- package/docs/history/implementation_plan.v1.md +58 -0
- package/package.json +4 -1
- package/scripts/artifact-storage.js +130 -0
- package/scripts/automation-gate.js +35 -2
- package/scripts/claude-plan.js +76 -0
- package/scripts/dependency-manager.js +210 -0
- package/scripts/exec-rtk.js +11 -5
- package/scripts/i18n-helper.js +381 -0
- package/scripts/multi-model-pipeline.js +144 -0
- package/skill-packs/mobile-ios/pack.json +4 -2
- package/skill-packs/reverse-engineering/pack.json +1 -0
- package/skills/CATALOG.md +20 -0
- package/skills/GEMINI.md +9 -1
- package/skills/TRIGGER_INDEX.md +10 -0
- package/skills/ai-music/SKILL.md +275 -0
- package/skills/android-re-analyzer/SKILL.md +238 -0
- package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
- package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
- package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
- package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
- package/skills/android-re-analyzer/references/setup-guide.md +221 -0
- package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
- package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
- package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
- package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
- package/skills/animal-island-ui-style/SKILL.md +1450 -0
- package/skills/app-store-review-agent/SKILL.md +164 -0
- package/skills/app-store-review-agent/references/guidelines/README.md +154 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/ai_apps.md +37 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/all_apps.md +50 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/crypto_finance.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/games.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/health_fitness.md +31 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/kids.md +27 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/macos.md +38 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/social_ugc.md +32 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/subscription_iap.md +34 -0
- package/skills/app-store-review-agent/references/guidelines/by-app-type/vpn.md +18 -0
- package/skills/app-store-review-agent/references/rules/design/minimum_functionality.md +96 -0
- package/skills/app-store-review-agent/references/rules/design/sign_in_with_apple.md +54 -0
- package/skills/app-store-review-agent/references/rules/entitlements/unused_entitlements.md +83 -0
- package/skills/app-store-review-agent/references/rules/metadata/accurate_metadata.md +54 -0
- package/skills/app-store-review-agent/references/rules/metadata/apple_trademark.md +99 -0
- package/skills/app-store-review-agent/references/rules/metadata/china_storefront.md +72 -0
- package/skills/app-store-review-agent/references/rules/metadata/competitor_terms.md +56 -0
- package/skills/app-store-review-agent/references/rules/metadata/subscription_metadata.md +81 -0
- package/skills/app-store-review-agent/references/rules/privacy/privacy_manifest.md +84 -0
- package/skills/app-store-review-agent/references/rules/privacy/unnecessary_data.md +60 -0
- package/skills/app-store-review-agent/references/rules/subscription/misleading_pricing.md +63 -0
- package/skills/app-store-review-agent/references/rules/subscription/missing_tos_pp.md +54 -0
- package/skills/awf-ponytail/SKILL.md +91 -0
- package/skills/awf-ponytail-review/SKILL.md +67 -0
- package/skills/awf-session-restore/SKILL.md +3 -3
- package/skills/brainstorm-agent/SKILL.md +11 -2
- package/skills/brainstorm-agent/templates/brief-template.md +8 -0
- package/skills/claude-planner/SKILL.md +47 -0
- package/skills/code-review/SKILL.md +87 -0
- package/skills/expo-game-development/SKILL.md +163 -0
- package/skills/flutter/LICENSE.txt +202 -0
- package/skills/flutter/SKILL.md +127 -0
- package/skills/flutter-project-creater/LICENSE.txt +202 -0
- package/skills/flutter-project-creater/SKILL.md +106 -0
- package/skills/game-developer/SKILL.md +163 -0
- package/skills/game-developer/references/ecs-patterns.md +501 -0
- package/skills/game-developer/references/multiplayer-networking.md +475 -0
- package/skills/game-developer/references/performance-optimization.md +422 -0
- package/skills/game-developer/references/unity-patterns.md +271 -0
- package/skills/game-developer/references/unreal-cpp.md +352 -0
- package/skills/generate-gui-assets/SKILL.md +305 -0
- package/skills/generate-gui-assets/agents/openai.yaml +4 -0
- package/skills/generate-gui-assets/references/catalog-schema.md +58 -0
- package/skills/generate-gui-assets/references/extraction-techniques.md +21 -0
- package/skills/generate-gui-assets/references/prompt-patterns.md +58 -0
- package/skills/generate-gui-assets/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/generate-gui-assets/scripts/build_gui_contact_sheet.py +51 -0
- package/skills/generate-gui-assets/scripts/clean_chroma_edges.py +262 -0
- package/skills/generate-gui-assets/scripts/copy_approved_icons.py +64 -0
- package/skills/generate-gui-assets/scripts/prepare_gui_asset_run.py +91 -0
- package/skills/generate-gui-assets/scripts/suggest_grid_options.py +63 -0
- package/skills/generate-gui-assets/scripts/validate_gui_catalog.py +50 -0
- package/skills/godot-game-development/SKILL.md +142 -0
- package/skills/hatch-pet/LICENSE.txt +201 -0
- package/skills/hatch-pet/SKILL.md +420 -0
- package/skills/hatch-pet/agents/openai.yaml +4 -0
- package/skills/hatch-pet/references/animation-rows.md +29 -0
- package/skills/hatch-pet/references/codex-pet-contract.md +35 -0
- package/skills/hatch-pet/references/qa-rubric.md +60 -0
- package/skills/hatch-pet/scripts/__pycache__/clean_chroma_edges.cpython-311.pyc +0 -0
- package/skills/hatch-pet/scripts/clean_chroma_edges.py +262 -0
- package/skills/hatch-pet/scripts/compose_atlas.py +150 -0
- package/skills/hatch-pet/scripts/derive_running_left_from_running_right.py +143 -0
- package/skills/hatch-pet/scripts/extract_strip_frames.py +323 -0
- package/skills/hatch-pet/scripts/finalize_pet_run.py +382 -0
- package/skills/hatch-pet/scripts/generate_pet_images.py +287 -0
- package/skills/hatch-pet/scripts/inspect_frames.py +246 -0
- package/skills/hatch-pet/scripts/make_contact_sheet.py +96 -0
- package/skills/hatch-pet/scripts/package_custom_pet.py +108 -0
- package/skills/hatch-pet/scripts/pet_job_status.py +117 -0
- package/skills/hatch-pet/scripts/prepare_pet_run.py +673 -0
- package/skills/hatch-pet/scripts/queue_pet_repairs.py +172 -0
- package/skills/hatch-pet/scripts/record_imagegen_result.py +250 -0
- package/skills/hatch-pet/scripts/render_animation_videos.py +134 -0
- package/skills/hatch-pet/scripts/render_animation_videos.sh +5 -0
- package/skills/hatch-pet/scripts/validate_atlas.py +139 -0
- package/skills/i18n-orchestrator/SKILL.md +37 -0
- package/skills/ios-simulator-skill/SKILL.md +390 -0
- package/skills/ios-simulator-skill/scripts/accessibility_audit.py +300 -0
- package/skills/ios-simulator-skill/scripts/app_launcher.py +326 -0
- package/skills/ios-simulator-skill/scripts/app_state_capture.py +400 -0
- package/skills/ios-simulator-skill/scripts/appearance.py +385 -0
- package/skills/ios-simulator-skill/scripts/build_and_test.py +348 -0
- package/skills/ios-simulator-skill/scripts/clipboard.py +103 -0
- package/skills/ios-simulator-skill/scripts/common/__init__.py +61 -0
- package/skills/ios-simulator-skill/scripts/common/cache_utils.py +289 -0
- package/skills/ios-simulator-skill/scripts/common/device_utils.py +462 -0
- package/skills/ios-simulator-skill/scripts/common/env_config.py +35 -0
- package/skills/ios-simulator-skill/scripts/common/hang_pipeline.py +862 -0
- package/skills/ios-simulator-skill/scripts/common/hang_sessions.py +490 -0
- package/skills/ios-simulator-skill/scripts/common/idb_utils.py +180 -0
- package/skills/ios-simulator-skill/scripts/common/screenshot_utils.py +338 -0
- package/skills/ios-simulator-skill/scripts/container.py +668 -0
- package/skills/ios-simulator-skill/scripts/gesture.py +394 -0
- package/skills/ios-simulator-skill/scripts/hang_watcher.py +1533 -0
- package/skills/ios-simulator-skill/scripts/keyboard.py +391 -0
- package/skills/ios-simulator-skill/scripts/localization_audit.py +483 -0
- package/skills/ios-simulator-skill/scripts/location.py +467 -0
- package/skills/ios-simulator-skill/scripts/log_monitor.py +493 -0
- package/skills/ios-simulator-skill/scripts/model_inspector.py +645 -0
- package/skills/ios-simulator-skill/scripts/navigator.py +461 -0
- package/skills/ios-simulator-skill/scripts/privacy_manager.py +310 -0
- package/skills/ios-simulator-skill/scripts/push_notification.py +240 -0
- package/skills/ios-simulator-skill/scripts/screen_mapper.py +296 -0
- package/skills/ios-simulator-skill/scripts/sim_health_check.sh +245 -0
- package/skills/ios-simulator-skill/scripts/sim_list.py +299 -0
- package/skills/ios-simulator-skill/scripts/simctl_boot.py +312 -0
- package/skills/ios-simulator-skill/scripts/simctl_create.py +316 -0
- package/skills/ios-simulator-skill/scripts/simctl_delete.py +357 -0
- package/skills/ios-simulator-skill/scripts/simctl_erase.py +351 -0
- package/skills/ios-simulator-skill/scripts/simctl_shutdown.py +290 -0
- package/skills/ios-simulator-skill/scripts/simulator_selector.py +375 -0
- package/skills/ios-simulator-skill/scripts/status_bar.py +250 -0
- package/skills/ios-simulator-skill/scripts/test_recorder.py +323 -0
- package/skills/ios-simulator-skill/scripts/visual_diff.py +235 -0
- package/skills/ios-simulator-skill/scripts/xcode/__init__.py +13 -0
- package/skills/ios-simulator-skill/scripts/xcode/builder.py +397 -0
- package/skills/ios-simulator-skill/scripts/xcode/cache.py +204 -0
- package/skills/ios-simulator-skill/scripts/xcode/config.py +178 -0
- package/skills/ios-simulator-skill/scripts/xcode/reporter.py +343 -0
- package/skills/ios-simulator-skill/scripts/xcode/xcresult.py +451 -0
- package/skills/ios-visual-qa-strategist/SKILL.md +111 -0
- package/skills/ios-visual-qa-strategist/agents/openai.yaml +4 -0
- package/skills/ios-visual-qa-strategist/references/ios-tool-selection.md +61 -0
- package/skills/ios-visual-qa-strategist/references/minimal-capture-policy.md +56 -0
- package/skills/ios-visual-qa-strategist/references/visual-reasoning-heuristics.md +53 -0
- package/skills/orchestrator/SKILL.md +0 -20
- package/skills/persistent-storage/SKILL.md +55 -0
- package/skills/short-maker/SKILL.md +23 -0
- package/skills/short-maker/scripts/effects.js +56 -0
- package/skills/short-maker/scripts/shortmaker-bridge.js +332 -0
- package/skills/short-maker/scripts/videomix.js +601 -0
- package/skills/short-maker/templates/hyperframes/cinematic-character.template.html +172 -0
- package/skills/short-maker/templates/hyperframes/index.template.html +194 -0
- package/skills/smali-to-kotlin/SKILL.md +128 -0
- package/skills/smali-to-kotlin/examples/getting-started/tech-stack.md +58 -0
- package/skills/smali-to-kotlin/examples/pipeline/data-ui-parity.md +118 -0
- package/skills/smali-to-kotlin/examples/pipeline/scanner-and-bootstrap.md +106 -0
- package/skills/smali-to-kotlin/library-patterns.md +189 -0
- package/skills/smali-to-kotlin/phase-0-discovery.md +128 -0
- package/skills/smali-to-kotlin/phase-1-architecture.md +166 -0
- package/skills/smali-to-kotlin/phase-2-blueprint-ui.md +347 -0
- package/skills/smali-to-kotlin/phase-2-blueprint.md +228 -0
- package/skills/smali-to-kotlin/phase-3-build.md +248 -0
- package/skills/smali-to-kotlin/phase-3-logic-build.md +268 -0
- package/skills/smali-to-kotlin/smali-reading-guide.md +310 -0
- package/skills/smali-to-kotlin/templates/app-map.md +101 -0
- package/skills/smali-to-kotlin/templates/architecture.md +142 -0
- package/skills/smali-to-kotlin/templates/blueprint.md +145 -0
- package/skills/spec-gate/SKILL.md +6 -2
- package/skills/symphony-enforcer/SKILL.md +8 -0
- package/skills/symphony-enforcer/examples/mindful-stop.md +2 -0
- package/skills/symphony-enforcer/examples/three-phase.md +16 -0
- package/skills/symphony-enforcer/examples/trigger-points.md +7 -1
- package/skills/unity-game-development/SKILL.md +231 -0
- package/skills/video-edit/SKILL.md +36 -0
- package/skills/video-edit/scripts/video_edit.py +324 -0
- package/templates/project-identity/android.json +2 -2
- package/templates/project-identity/backend-nestjs.json +2 -2
- package/templates/project-identity/expo.json +2 -2
- package/templates/project-identity/ios.json +2 -2
- package/templates/project-identity/web-nextjs.json +2 -2
- package/templates/setup-mapping.json +48 -0
- package/templates/specs/design-template.md +161 -71
- package/templates/specs/requirements-template.md +65 -133
- package/templates/specs/task-spec-template.xml +3 -0
- package/workflows/_uncategorized/critic.md +40 -0
- package/workflows/_uncategorized/git-rebase-flow.md +81 -0
- package/workflows/_uncategorized/image-gen.md +118 -0
- package/workflows/_uncategorized/multi-model-pipeline.md +60 -0
- package/workflows/_uncategorized/pixel-gen.md +86 -0
- package/workflows/_uncategorized/pixel-setup.md +90 -0
- package/workflows/_uncategorized/ponytail-review.md +59 -0
- package/workflows/_uncategorized/reverse-android-build.md +222 -0
- package/workflows/_uncategorized/reverse-android-design.md +139 -0
- package/workflows/_uncategorized/reverse-android-discover.md +150 -0
- package/workflows/_uncategorized/reverse-android-scan.md +158 -0
- package/workflows/_uncategorized/reverse-android.md +143 -0
- package/workflows/_uncategorized/reverse-ios-build.md +240 -0
- package/workflows/_uncategorized/reverse-ios-design.md +112 -0
- package/workflows/_uncategorized/reverse-ios-discover.md +120 -0
- package/workflows/_uncategorized/reverse-ios-scan.md +155 -0
- package/workflows/_uncategorized/reverse-ios.md +152 -0
- package/workflows/_uncategorized/safety-router.md +34 -0
- package/workflows/_uncategorized/teach.md +89 -0
- package/workflows/_uncategorized/verify-ui.md +53 -0
- package/workflows/_uncategorized/visualize-screenshots.md +34 -0
- package/workflows/ads/ads-analyst.md +201 -0
- package/workflows/ads/ads-audit.md +106 -0
- package/workflows/ads/ads-optimize.md +97 -0
- package/workflows/ads/ads-targeting.md +241 -0
- package/workflows/ads/adsExpert.md +160 -0
- package/workflows/ads/smali-ads-config.md +400 -0
- package/workflows/ads/smali-ads-flow.md +331 -0
- package/workflows/ads/smali-ads-interstitial.md +377 -0
- package/workflows/ads/smali-ads-native.md +382 -0
- package/workflows/context/teach.md +89 -0
- package/workflows/gitnexus.md +8 -8
- package/workflows/lifecycle/brainstorm.md +43 -0
- package/workflows/lifecycle/code.md +5 -0
- package/workflows/lifecycle/init.md +23 -5
- package/workflows/lifecycle/multi-model-pipeline.md +60 -0
- package/workflows/quality/ponytail-review.md +59 -0
- package/workflows/roles/critic.md +40 -0
- package/workflows/roles/safety-router.md +34 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# Unreal Engine C++ Development
|
|
2
|
+
|
|
3
|
+
## Actor Component Pattern
|
|
4
|
+
|
|
5
|
+
```cpp
|
|
6
|
+
// Header file: MyCharacter.h
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include "CoreMinimal.h"
|
|
10
|
+
#include "GameFramework/Character.h"
|
|
11
|
+
#include "MyCharacter.generated.h"
|
|
12
|
+
|
|
13
|
+
UCLASS()
|
|
14
|
+
class MYGAME_API AMyCharacter : public ACharacter
|
|
15
|
+
{
|
|
16
|
+
GENERATED_BODY()
|
|
17
|
+
|
|
18
|
+
public:
|
|
19
|
+
AMyCharacter();
|
|
20
|
+
|
|
21
|
+
protected:
|
|
22
|
+
virtual void BeginPlay() override;
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
virtual void Tick(float DeltaTime) override;
|
|
26
|
+
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
|
|
27
|
+
|
|
28
|
+
private:
|
|
29
|
+
// Exposed to Blueprints
|
|
30
|
+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement", meta = (AllowPrivateAccess = "true"))
|
|
31
|
+
float WalkSpeed = 600.0f;
|
|
32
|
+
|
|
33
|
+
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true"))
|
|
34
|
+
class UCameraComponent* CameraComponent;
|
|
35
|
+
|
|
36
|
+
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true"))
|
|
37
|
+
class USpringArmComponent* SpringArm;
|
|
38
|
+
|
|
39
|
+
void MoveForward(float Value);
|
|
40
|
+
void MoveRight(float Value);
|
|
41
|
+
};
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```cpp
|
|
45
|
+
// Implementation: MyCharacter.cpp
|
|
46
|
+
#include "MyCharacter.h"
|
|
47
|
+
#include "Camera/CameraComponent.h"
|
|
48
|
+
#include "GameFramework/SpringArmComponent.h"
|
|
49
|
+
#include "GameFramework/CharacterMovementComponent.h"
|
|
50
|
+
|
|
51
|
+
AMyCharacter::AMyCharacter()
|
|
52
|
+
{
|
|
53
|
+
PrimaryActorTick.bCanEverTick = true;
|
|
54
|
+
|
|
55
|
+
// Create components
|
|
56
|
+
SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
|
|
57
|
+
SpringArm->SetupAttachment(RootComponent);
|
|
58
|
+
SpringArm->TargetArmLength = 300.0f;
|
|
59
|
+
SpringArm->bUsePawnControlRotation = true;
|
|
60
|
+
|
|
61
|
+
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
|
|
62
|
+
CameraComponent->SetupAttachment(SpringArm, USpringArmComponent::SocketName);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
void AMyCharacter::BeginPlay()
|
|
66
|
+
{
|
|
67
|
+
Super::BeginPlay();
|
|
68
|
+
|
|
69
|
+
GetCharacterMovement()->MaxWalkSpeed = WalkSpeed;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
|
73
|
+
{
|
|
74
|
+
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
|
75
|
+
|
|
76
|
+
PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward);
|
|
77
|
+
PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight);
|
|
78
|
+
PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
|
|
79
|
+
PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
void AMyCharacter::MoveForward(float Value)
|
|
83
|
+
{
|
|
84
|
+
if (Controller && Value != 0.0f)
|
|
85
|
+
{
|
|
86
|
+
const FRotator Rotation = Controller->GetControlRotation();
|
|
87
|
+
const FRotator YawRotation(0, Rotation.Yaw, 0);
|
|
88
|
+
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
|
|
89
|
+
AddMovementInput(Direction, Value);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Blueprint Callable Functions
|
|
95
|
+
|
|
96
|
+
```cpp
|
|
97
|
+
UCLASS()
|
|
98
|
+
class MYGAME_API UHealthComponent : public UActorComponent
|
|
99
|
+
{
|
|
100
|
+
GENERATED_BODY()
|
|
101
|
+
|
|
102
|
+
public:
|
|
103
|
+
UHealthComponent();
|
|
104
|
+
|
|
105
|
+
protected:
|
|
106
|
+
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
|
|
107
|
+
float MaxHealth = 100.0f;
|
|
108
|
+
|
|
109
|
+
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Health")
|
|
110
|
+
float CurrentHealth;
|
|
111
|
+
|
|
112
|
+
// Event dispatcher for Blueprint
|
|
113
|
+
UPROPERTY(BlueprintAssignable, Category = "Health")
|
|
114
|
+
FOnHealthChangedSignature OnHealthChanged;
|
|
115
|
+
|
|
116
|
+
public:
|
|
117
|
+
// Callable from Blueprint
|
|
118
|
+
UFUNCTION(BlueprintCallable, Category = "Health")
|
|
119
|
+
void TakeDamage(float Damage);
|
|
120
|
+
|
|
121
|
+
UFUNCTION(BlueprintCallable, Category = "Health")
|
|
122
|
+
void Heal(float Amount);
|
|
123
|
+
|
|
124
|
+
UFUNCTION(BlueprintPure, Category = "Health")
|
|
125
|
+
float GetHealthPercent() const { return CurrentHealth / MaxHealth; }
|
|
126
|
+
|
|
127
|
+
// Native event that can be overridden in Blueprint
|
|
128
|
+
UFUNCTION(BlueprintNativeEvent, Category = "Health")
|
|
129
|
+
void OnDeath();
|
|
130
|
+
virtual void OnDeath_Implementation();
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Event delegate
|
|
134
|
+
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnHealthChangedSignature, float, Health, float, MaxHealth);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Actor Component System
|
|
138
|
+
|
|
139
|
+
```cpp
|
|
140
|
+
// Custom Actor Component
|
|
141
|
+
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
|
142
|
+
class MYGAME_API UInventoryComponent : public UActorComponent
|
|
143
|
+
{
|
|
144
|
+
GENERATED_BODY()
|
|
145
|
+
|
|
146
|
+
public:
|
|
147
|
+
UInventoryComponent();
|
|
148
|
+
|
|
149
|
+
protected:
|
|
150
|
+
virtual void BeginPlay() override;
|
|
151
|
+
|
|
152
|
+
private:
|
|
153
|
+
UPROPERTY(EditAnywhere, Category = "Inventory")
|
|
154
|
+
int32 MaxSlots = 20;
|
|
155
|
+
|
|
156
|
+
UPROPERTY()
|
|
157
|
+
TArray<class UItemData*> Items;
|
|
158
|
+
|
|
159
|
+
public:
|
|
160
|
+
UFUNCTION(BlueprintCallable, Category = "Inventory")
|
|
161
|
+
bool AddItem(UItemData* Item);
|
|
162
|
+
|
|
163
|
+
UFUNCTION(BlueprintCallable, Category = "Inventory")
|
|
164
|
+
bool RemoveItem(UItemData* Item);
|
|
165
|
+
|
|
166
|
+
UFUNCTION(BlueprintPure, Category = "Inventory")
|
|
167
|
+
int32 GetItemCount() const { return Items.Num(); }
|
|
168
|
+
};
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Timers and Async Operations
|
|
172
|
+
|
|
173
|
+
```cpp
|
|
174
|
+
class AWeapon : public AActor
|
|
175
|
+
{
|
|
176
|
+
private:
|
|
177
|
+
FTimerHandle FireRateTimer;
|
|
178
|
+
|
|
179
|
+
UPROPERTY(EditAnywhere, Category = "Weapon")
|
|
180
|
+
float FireRate = 0.2f; // Seconds between shots
|
|
181
|
+
|
|
182
|
+
public:
|
|
183
|
+
void StartFiring()
|
|
184
|
+
{
|
|
185
|
+
Fire(); // Immediate first shot
|
|
186
|
+
GetWorldTimerManager().SetTimer(FireRateTimer, this, &AWeapon::Fire, FireRate, true);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
void StopFiring()
|
|
190
|
+
{
|
|
191
|
+
GetWorldTimerManager().ClearTimer(FireRateTimer);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
void Fire()
|
|
195
|
+
{
|
|
196
|
+
// Spawn projectile
|
|
197
|
+
FVector Location = GetActorLocation();
|
|
198
|
+
FRotator Rotation = GetActorRotation();
|
|
199
|
+
GetWorld()->SpawnActor<AProjectile>(ProjectileClass, Location, Rotation);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Object Pooling in Unreal
|
|
205
|
+
|
|
206
|
+
```cpp
|
|
207
|
+
UCLASS()
|
|
208
|
+
class APooledActor : public AActor
|
|
209
|
+
{
|
|
210
|
+
GENERATED_BODY()
|
|
211
|
+
|
|
212
|
+
private:
|
|
213
|
+
bool bIsActive = false;
|
|
214
|
+
|
|
215
|
+
public:
|
|
216
|
+
void Activate()
|
|
217
|
+
{
|
|
218
|
+
bIsActive = true;
|
|
219
|
+
SetActorHiddenInGame(false);
|
|
220
|
+
SetActorEnableCollision(true);
|
|
221
|
+
SetActorTickEnabled(true);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
void Deactivate()
|
|
225
|
+
{
|
|
226
|
+
bIsActive = false;
|
|
227
|
+
SetActorHiddenInGame(true);
|
|
228
|
+
SetActorEnableCollision(false);
|
|
229
|
+
SetActorTickEnabled(false);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
bool IsActive() const { return bIsActive; }
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
UCLASS()
|
|
236
|
+
class AObjectPool : public AActor
|
|
237
|
+
{
|
|
238
|
+
GENERATED_BODY()
|
|
239
|
+
|
|
240
|
+
private:
|
|
241
|
+
UPROPERTY(EditAnywhere, Category = "Pool")
|
|
242
|
+
TSubclassOf<APooledActor> PooledClass;
|
|
243
|
+
|
|
244
|
+
UPROPERTY(EditAnywhere, Category = "Pool")
|
|
245
|
+
int32 PoolSize = 50;
|
|
246
|
+
|
|
247
|
+
UPROPERTY()
|
|
248
|
+
TArray<APooledActor*> Pool;
|
|
249
|
+
|
|
250
|
+
protected:
|
|
251
|
+
virtual void BeginPlay() override
|
|
252
|
+
{
|
|
253
|
+
Super::BeginPlay();
|
|
254
|
+
|
|
255
|
+
// Pre-spawn pool
|
|
256
|
+
for (int32 i = 0; i < PoolSize; i++)
|
|
257
|
+
{
|
|
258
|
+
APooledActor* Actor = GetWorld()->SpawnActor<APooledActor>(PooledClass);
|
|
259
|
+
Actor->Deactivate();
|
|
260
|
+
Pool.Add(Actor);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
public:
|
|
265
|
+
APooledActor* GetPooledActor()
|
|
266
|
+
{
|
|
267
|
+
for (APooledActor* Actor : Pool)
|
|
268
|
+
{
|
|
269
|
+
if (!Actor->IsActive())
|
|
270
|
+
{
|
|
271
|
+
Actor->Activate();
|
|
272
|
+
return Actor;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Expand pool if needed
|
|
277
|
+
APooledActor* NewActor = GetWorld()->SpawnActor<APooledActor>(PooledClass);
|
|
278
|
+
Pool.Add(NewActor);
|
|
279
|
+
NewActor->Activate();
|
|
280
|
+
return NewActor;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
void ReturnToPool(APooledActor* Actor)
|
|
284
|
+
{
|
|
285
|
+
Actor->Deactivate();
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Data Assets and Structures
|
|
291
|
+
|
|
292
|
+
```cpp
|
|
293
|
+
// Data structure
|
|
294
|
+
USTRUCT(BlueprintType)
|
|
295
|
+
struct FWeaponStats
|
|
296
|
+
{
|
|
297
|
+
GENERATED_BODY()
|
|
298
|
+
|
|
299
|
+
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|
300
|
+
FName WeaponName;
|
|
301
|
+
|
|
302
|
+
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|
303
|
+
float Damage = 10.0f;
|
|
304
|
+
|
|
305
|
+
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|
306
|
+
float FireRate = 0.5f;
|
|
307
|
+
|
|
308
|
+
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|
309
|
+
int32 MagazineSize = 30;
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
// Data asset
|
|
313
|
+
UCLASS()
|
|
314
|
+
class UWeaponDataAsset : public UDataAsset
|
|
315
|
+
{
|
|
316
|
+
GENERATED_BODY()
|
|
317
|
+
|
|
318
|
+
public:
|
|
319
|
+
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Weapon")
|
|
320
|
+
FWeaponStats Stats;
|
|
321
|
+
|
|
322
|
+
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Weapon")
|
|
323
|
+
TSubclassOf<class AProjectile> ProjectileClass;
|
|
324
|
+
|
|
325
|
+
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Weapon")
|
|
326
|
+
USoundBase* FireSound;
|
|
327
|
+
};
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Smart Pointers
|
|
331
|
+
|
|
332
|
+
```cpp
|
|
333
|
+
// Use TSharedPtr for shared ownership
|
|
334
|
+
TSharedPtr<FGameData> GameData = MakeShared<FGameData>();
|
|
335
|
+
|
|
336
|
+
// Use TWeakPtr to avoid circular references
|
|
337
|
+
TWeakPtr<AActor> WeakActorRef = SharedActorPtr;
|
|
338
|
+
|
|
339
|
+
// Use TUniquePtr for exclusive ownership
|
|
340
|
+
TUniquePtr<FComplexSystem> System = MakeUnique<FComplexSystem>();
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Performance Best Practices
|
|
344
|
+
|
|
345
|
+
- Use `UPROPERTY()` for garbage collection (don't use raw pointers for UObjects)
|
|
346
|
+
- Cache component references in `BeginPlay()`
|
|
347
|
+
- Use `PrimaryActorTick.bCanEverTick = false` if Tick not needed
|
|
348
|
+
- Prefer Timers over Tick for periodic updates
|
|
349
|
+
- Use `BlueprintPure` for getter functions (no execution pin)
|
|
350
|
+
- Profile with Unreal Insights and stat commands (`stat fps`, `stat unit`, `stat game`)
|
|
351
|
+
- Use forward declarations in headers, includes in .cpp files
|
|
352
|
+
- Implement object pooling for frequently spawned actors
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: generate-gui-assets
|
|
3
|
+
description: Tao bo asset GUI dong nhat cho app/game, gom icon atlas, HUD UI, bo icon ung dung, va sprite sheet UI voi prompt tao anh, rang buoc chroma-key, manifest, contact sheet, QA, va quy trinh copy/extract mang tinh xac dinh. Dung khi Codex can tao hoac to chuc asset GUI cho app/game, dac biet voi bo nhieu icon, asset dang atlas, hinh anh UI can dong bo style, catalog.json/icons_manifest.json, hoac QA hinh anh truoc khi wire vao code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Generate GUI Assets
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Create GUI asset packs using a generation-first workflow: plan the pack, generate atlas imagery through `$imagegen`, preserve provenance, review a contact sheet, then run deterministic scripts only after the visuals are approved.
|
|
11
|
+
|
|
12
|
+
This skill is for app/game GUI assets: icons, HUD items, buttons, status badges, inventory icons, navigation glyphs, weather/health/habit packs, and other atlas-friendly UI assets. Use `hatch-pet` instead for animated Codex pet spritesheets or character animation rows.
|
|
13
|
+
|
|
14
|
+
## Hard Boundaries
|
|
15
|
+
|
|
16
|
+
- Use `$imagegen` for visual creation. Do not locally draw, tile, synthesize, or fabricate missing GUI assets with code.
|
|
17
|
+
- Prefer grid/atlas generation for batches. Do not generate one image per icon unless a grid fails quality after focused retries or the user asks for a single asset.
|
|
18
|
+
- When strict atlas grids repeatedly fail structure quality (merged cells, uneven columns, missing slots), switch to `large object sheet -> detect/crop -> repack` instead of repeating direct atlas retries.
|
|
19
|
+
- Keep app code wiring out of this skill. Stop at approved asset files, manifests, QA outputs, and handoff notes.
|
|
20
|
+
- Do not recut or resegment an extraction method that has already been approved. Copy/rename approved icons as-is and record provenance.
|
|
21
|
+
- Parent agent owns manifests and final file moves. Subagents may generate or review isolated packs, but should not mutate `catalog.json` or final manifests.
|
|
22
|
+
|
|
23
|
+
## Intrinsic-First Policy
|
|
24
|
+
|
|
25
|
+
- Default path is intrinsic image generation only (`image_gen` via `$imagegen`).
|
|
26
|
+
- Do not precheck, mention, or require provider API keys during normal preview/bulk flows.
|
|
27
|
+
- Fallback providers are opt-in only and require explicit user request plus both `OPENAI_API_KEY` and `OPENROUTER_API_KEY`.
|
|
28
|
+
- If fallback is not explicitly requested, continue with intrinsic generation and report only intrinsic status.
|
|
29
|
+
- Never claim preview or generation progress unless real generated images exist in `raw/`.
|
|
30
|
+
|
|
31
|
+
## Folder Contract
|
|
32
|
+
|
|
33
|
+
Use this structure for generation runs:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
assets/ui/generated/<run-id>/
|
|
37
|
+
raw/ # direct generated atlas/pack images
|
|
38
|
+
prompts/ # generated prompt text
|
|
39
|
+
qa/ # contact sheets and review notes
|
|
40
|
+
catalog.json # generation provenance and pack mapping
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
For extracted approved icons, use a separate flat package folder:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
assets/ui/generated/<run-id>/final/
|
|
47
|
+
icons/
|
|
48
|
+
icons_manifest.json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Run folders under `assets/ui/generated/<run-id>/` are staging workspaces, not the canonical app asset location. Before marking the asset work done, copy the approved files into the project's real asset family directory, for example:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
assets/ui/icons/<version>/final/
|
|
55
|
+
ic_<name>.png
|
|
56
|
+
ic_<name>@2x.png
|
|
57
|
+
ic_<name>@3x.png
|
|
58
|
+
icons_manifest.json
|
|
59
|
+
catalog.json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Use the project's existing asset maps and conventions when choosing the canonical folder. The canonical `catalog.json` and `icons_manifest.json` must describe the files in that final project directory, not only the staging run directory.
|
|
63
|
+
|
|
64
|
+
After the canonical files and manifests exist, the app points at them, and verification passes, proactively clean the staging run by moving it to Trash or an archive outside the repo. Do not delete approved canonical assets, source-controlled project manifests, or user-provided references.
|
|
65
|
+
|
|
66
|
+
## Default Workflow
|
|
67
|
+
|
|
68
|
+
1. Build canvas grid options and ask for one-time confirmation before any generation.
|
|
69
|
+
|
|
70
|
+
Always present total icon capacity from larger to smaller. These are uniform canvas grids for deterministic slicing, not arbitrary pack boxes:
|
|
71
|
+
|
|
72
|
+
- `8x6` (48 slots): maximum throughput in one image after preview approval.
|
|
73
|
+
- `8x5` (40 slots): high throughput with more vertical breathing room.
|
|
74
|
+
- `6x6` (36 slots): high throughput, square-ish canvas.
|
|
75
|
+
- `6x5` (30 slots): balanced bulk layout.
|
|
76
|
+
- `7x4` (28 slots): wide balanced layout.
|
|
77
|
+
- `5x5` (25 slots): compact dense layout.
|
|
78
|
+
- `6x4` (24 slots): wide compact layout.
|
|
79
|
+
- `4x4` (16 slots): quality-priority compact bulk.
|
|
80
|
+
- `4x3` (12 slots): fallback for difficult semantics.
|
|
81
|
+
- `3x3` (9 slots): precision fallback.
|
|
82
|
+
|
|
83
|
+
Use this helper:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
SKILL_DIR="${CODEX_HOME:-$HOME/.codex}/skills/generate-gui-assets"
|
|
87
|
+
python "$SKILL_DIR/scripts/suggest_grid_options.py" --icon-count 18 --strategy throughput
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Do not generate preview or bulk until the user confirms one canvas grid strategy.
|
|
91
|
+
|
|
92
|
+
Use this confirmation template exactly (largest to smallest, one-time confirm):
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
Canvas grid options (large -> small, uniform cells for slicing):
|
|
96
|
+
- 8x6 = 48 icons/image: max throughput, use after preview confirms style.
|
|
97
|
+
- 8x5 = 40 icons/image.
|
|
98
|
+
- 6x6 = 36 icons/image.
|
|
99
|
+
- 6x5 = 30 icons/image.
|
|
100
|
+
- 7x4 = 28 icons/image.
|
|
101
|
+
- 5x5 = 25 icons/image.
|
|
102
|
+
- 6x4 = 24 icons/image.
|
|
103
|
+
- 4x4 = 16 icons/image: compact quality-priority option.
|
|
104
|
+
- 4x3 = 12 icons/image.
|
|
105
|
+
- 3x3 = 9 icons/image.
|
|
106
|
+
|
|
107
|
+
Recommend: 8x6 for this run if the preview style is approved.
|
|
108
|
+
Please confirm one canvas grid for the whole run.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
2. Create a preview run and catalog first:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
SKILL_DIR="${CODEX_HOME:-$HOME/.codex}/skills/generate-gui-assets"
|
|
115
|
+
python "$SKILL_DIR/scripts/prepare_gui_asset_run.py" \
|
|
116
|
+
--run-id gui-v1-preview \
|
|
117
|
+
--output-root assets/ui/generated \
|
|
118
|
+
--phase preview \
|
|
119
|
+
--style-notes "cozy mobile wellness garden icons, crisp rounded vector style" \
|
|
120
|
+
--pack "ui_weather_core:3x3:sun,sunCloud,cloud,rain,wind,hot,mild,good,bad"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
3. Read preview prompts in `prompts/` and invoke `$imagegen`.
|
|
124
|
+
|
|
125
|
+
Before generating, load the installed image generation skill:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
${CODEX_HOME:-$HOME/.codex}/skills/.system/imagegen/SKILL.md
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Use the generated prompt as the authoritative visual spec. Save selected `$imagegen` outputs into `raw/` and update `catalog.json` provenance.
|
|
132
|
+
|
|
133
|
+
4. Build a contact sheet and review with the user:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
python "$SKILL_DIR/scripts/build_gui_contact_sheet.py" \
|
|
137
|
+
--run-dir assets/ui/generated/gui-v1-preview
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
5. Wait for explicit user confirmation. Do not run bulk generation before preview is approved.
|
|
141
|
+
|
|
142
|
+
6. After approval, create the bulk run using locked style language:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
python "$SKILL_DIR/scripts/prepare_gui_asset_run.py" \
|
|
146
|
+
--run-id gui-v1-bulk \
|
|
147
|
+
--output-root assets/ui/generated \
|
|
148
|
+
--phase bulk \
|
|
149
|
+
--style-notes "<approved preview style language>" \
|
|
150
|
+
--pack "ui_nav_core:4x3:home,garden,journal,profile,settings,search,back,next,add,close,alert,help" \
|
|
151
|
+
--pack "ui_health_core:4x3:heart,water,sleep,steps,mood,warning,aid,trend,info,check,flame,medical"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
7. Validate the catalog:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
python "$SKILL_DIR/scripts/validate_gui_catalog.py" \
|
|
158
|
+
--run-dir assets/ui/generated/gui-v1-bulk
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
8. After visual approval and extraction, copy approved icons without recutting:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
python "$SKILL_DIR/scripts/copy_approved_icons.py" \
|
|
165
|
+
--source-dir assets/ui/generated/gui-v1/manual_crop/extracted_icons_mask \
|
|
166
|
+
--run-dir assets/ui/generated/gui-v1-bulk \
|
|
167
|
+
--mapping path/to/icon_mapping.json
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
9. Promote approved assets into the canonical project asset directory and write canonical manifests there. Treat the staging run's `final/` folder as a transfer source only; update code asset maps against the canonical directory.
|
|
171
|
+
|
|
172
|
+
10. After verification, move obsolete staging runs, preview runs, raw atlases, prompts, and QA-only outputs out of the repo. Keep a recoverable copy in Trash or an archive when the cleanup is destructive from git's point of view.
|
|
173
|
+
|
|
174
|
+
## Large Object Sheet Workflow (High-Throughput Fallback)
|
|
175
|
+
|
|
176
|
+
Use this path when the user wants one large generation request and strict direct grid output is unstable.
|
|
177
|
+
|
|
178
|
+
1. Generate one large `object sheet` image, not a direct atlas.
|
|
179
|
+
- Flat `#FF00FF` chroma background only.
|
|
180
|
+
- No grid lines, no panels, no scenery, no labels.
|
|
181
|
+
- Exactly one isolated icon object per semantic item.
|
|
182
|
+
- Large empty chroma spacing between icons to avoid touching components.
|
|
183
|
+
|
|
184
|
+
2. Detect and crop icons from the object sheet.
|
|
185
|
+
- Use connected-component or contour detection with magenta-threshold masking.
|
|
186
|
+
- Remove tiny specks/fragments with area and size thresholds.
|
|
187
|
+
- If symbols are split into multiple small components, merge nearby components before crop.
|
|
188
|
+
|
|
189
|
+
3. Normalize and repack into a deterministic atlas.
|
|
190
|
+
- Resize each icon into a fixed cell canvas (for example `256x256`) using consistent max side ratio.
|
|
191
|
+
- Center-align icon in each cell with constant padding.
|
|
192
|
+
- Compose final `8x6` atlas from normalized cells.
|
|
193
|
+
- Export both atlas and per-icon PNG files for QA.
|
|
194
|
+
|
|
195
|
+
4. Produce mapping artifacts.
|
|
196
|
+
- `icons_manifest.json` must include packed index, semantic name, source bbox/component id, and output file path.
|
|
197
|
+
- Build a numbered contact sheet for human semantic verification.
|
|
198
|
+
|
|
199
|
+
## Chroma Edge Cleanup
|
|
200
|
+
|
|
201
|
+
Run this deterministic cleanup after extraction or promotion when transparent PNG icons still show magenta/chroma fringe, pink-purple baked edge spill, or dirty hidden RGB that can appear during app scaling.
|
|
202
|
+
|
|
203
|
+
Use the bundled cleaner, not ad hoc per-file edits:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
SKILL_DIR="${CODEX_HOME:-$HOME/.codex}/skills/generate-gui-assets"
|
|
207
|
+
python "$SKILL_DIR/scripts/clean_chroma_edges.py" path/to/icons --edge-despill
|
|
208
|
+
python "$SKILL_DIR/scripts/clean_chroma_edges.py" path/to/icons --edge-despill --apply
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Default behavior:
|
|
212
|
+
|
|
213
|
+
- Recurses through PNG files under every provided directory.
|
|
214
|
+
- Soft-keys low-alpha pixels near `#FF00FF`.
|
|
215
|
+
- Bleeds nearby foreground RGB into transparent edge pixels so scaling cannot sample hidden chroma.
|
|
216
|
+
- With `--edge-despill`, repairs opaque baked-in pink/purple spill along the alpha edge without changing interior pink UI colors.
|
|
217
|
+
|
|
218
|
+
Use these guardrails:
|
|
219
|
+
|
|
220
|
+
- Always run dry-run first and inspect the reported file count.
|
|
221
|
+
- Use `--edge-despill` for baked magenta outlines like pink halos around characters or icons.
|
|
222
|
+
- Skip `--edge-despill` if the asset intentionally has magenta/purple edge styling.
|
|
223
|
+
- Apply only to approved extracted/canonical PNG assets, not raw generated atlases unless they already have transparency.
|
|
224
|
+
- After applying, run the same command again as a dry-run; it should report `DRY_RUN files=0 changed=0` or only a tiny known residual that is intentional art.
|
|
225
|
+
- Build a contact sheet or composite preview on light and dark neutral backgrounds before handoff.
|
|
226
|
+
|
|
227
|
+
For canonical GUI packs, the expected verification sequence is:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
python "$SKILL_DIR/scripts/clean_chroma_edges.py" assets/ui/icons/<version>/final --edge-despill
|
|
231
|
+
python "$SKILL_DIR/scripts/clean_chroma_edges.py" assets/ui/icons/<version>/final --edge-despill --apply
|
|
232
|
+
python "$SKILL_DIR/scripts/clean_chroma_edges.py" assets/ui/icons/<version>/final --edge-despill
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Prompt Contract
|
|
236
|
+
|
|
237
|
+
Every generation prompt must include:
|
|
238
|
+
|
|
239
|
+
- Style: concise product/game style, palette, outline/edge treatment, target platform tone.
|
|
240
|
+
- Geometry: exact total canvas grid size, equal cells, centered icons, generous padding, no object touching cell edges.
|
|
241
|
+
- Semantics: explicit icon names in row order.
|
|
242
|
+
- Background: flat chroma key `#FF00FF` unless the project requires another key.
|
|
243
|
+
- Prohibitions: no text, labels, guide marks, shadows, glows, UI panels, scenery, duplicate placeholders, or unrelated decoration.
|
|
244
|
+
|
|
245
|
+
Prefer this prompt shape:
|
|
246
|
+
|
|
247
|
+
```text
|
|
248
|
+
Create one GUI icon atlas on a flat #FF00FF chroma-key background.
|
|
249
|
+
Style: <style notes>.
|
|
250
|
+
Canvas grid: <columns>x<rows> total icon cells, equal cells, centered icons, 10% safe margin.
|
|
251
|
+
Icons in row order: <comma-separated names>.
|
|
252
|
+
Quality rules: no text, no labels, no shadows, no glow, no guides, no duplicate generic placeholders, no clipping, no overlap.
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
For large object-sheet fallback, use this shape:
|
|
256
|
+
|
|
257
|
+
```text
|
|
258
|
+
Create one large icon object sheet on flat #FF00FF background.
|
|
259
|
+
Style: <style notes>.
|
|
260
|
+
Layout: no grid lines, no panels; icons arranged in loose rows with wide empty magenta spacing.
|
|
261
|
+
Objects: exactly one isolated icon per semantic item; do not touch or overlap.
|
|
262
|
+
Icons list: <comma-separated names>.
|
|
263
|
+
Quality rules: no text, no labels, no scenery, no glow, no shadows outside silhouette, no merged icons.
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Iteration Strategy
|
|
267
|
+
|
|
268
|
+
- Always run preview-first and require explicit user confirmation before bulk generation.
|
|
269
|
+
- Ask for grid confirmation exactly once per run before preview.
|
|
270
|
+
- Prefer larger total canvas grids first to reduce generation count, then step down only if preview quality is unacceptable.
|
|
271
|
+
- In throughput strategy, recommend `8x6` first for up to 48 icons per image.
|
|
272
|
+
- Treat `4x4` as a compact quality-priority option, not the default large-layout recommendation.
|
|
273
|
+
- Freeze the approved preview style language and reuse it unchanged in bulk mode.
|
|
274
|
+
- Run bulk to reduce generation count once preview is approved.
|
|
275
|
+
- Regenerate only weak packs or isolated semantic misses with style lock.
|
|
276
|
+
- If a specific semantic icon is wrong, prefer a focused pack regeneration over manual visual patching.
|
|
277
|
+
- If magenta fringing or extraction quality is the issue, treat it as post-processing, not a reason to change the approved visual direction.
|
|
278
|
+
- If direct `8x6` generation fails structure quality twice, stop retry loop and move to the large object-sheet workflow.
|
|
279
|
+
- For object-sheet workflow, prefer one large request plus deterministic repack over repeated direct-atlas retries.
|
|
280
|
+
|
|
281
|
+
## QA Checklist
|
|
282
|
+
|
|
283
|
+
Before handoff:
|
|
284
|
+
|
|
285
|
+
- `catalog.json` parses and lists every intended pack.
|
|
286
|
+
- Every raw image path exists and opens.
|
|
287
|
+
- `qa/contact_sheet.png` exists.
|
|
288
|
+
- Icons match requested semantics in row order.
|
|
289
|
+
- Style is consistent across packs.
|
|
290
|
+
- No clipped icons, shadows, glows, labels, guide marks, or duplicate placeholders.
|
|
291
|
+
- Approved extraction/copy keeps original icon pixels and records provenance.
|
|
292
|
+
- Canonical project asset directory contains the shipped icons and canonical `icons_manifest.json` plus `catalog.json`.
|
|
293
|
+
- Code asset maps reference canonical project paths, not `assets/ui/generated/<run-id>/`.
|
|
294
|
+
- Completed staging runs have been moved out of the repo or intentionally retained with a short reason.
|
|
295
|
+
- For object-sheet workflow: detected icon count must be >= intended count before selection.
|
|
296
|
+
- For object-sheet workflow: final packed atlas dimensions and cell counts must match target exactly.
|
|
297
|
+
- For object-sheet workflow: manifest must map every packed slot to a semantic name and source component.
|
|
298
|
+
- Chroma cleanup dry-run is clean or residual findings are explained as intentional art.
|
|
299
|
+
- Contact sheet or neutral-background preview shows no visible chroma fringe at the expected in-app size.
|
|
300
|
+
|
|
301
|
+
## References
|
|
302
|
+
|
|
303
|
+
- Read `references/prompt-patterns.md` when constructing or repairing prompts.
|
|
304
|
+
- Read `references/catalog-schema.md` before editing `catalog.json` or `icons_manifest.json`.
|
|
305
|
+
- Read `references/extraction-techniques.md` before copying or renaming approved extracted icons.
|