godot-rpg-stats by thedivergentai/gd-agentic-skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-rpg-stats基于资源的属性、修饰器堆叠和派生计算,定义了灵活的角色成长系统。
基础属性(力量、敏捷、智力)和派生缩放规则的核心数据容器。
增益/减益效果(加法、乘法、覆盖)的序列化数据定义。
使用活动修饰器堆叠进行即时属性计算的核心协调器。
使用增长因子和基础经验值定义的数据驱动升级曲线。
用于将标签同步到属性变化的响应式 UI 钩子,无需轮询。
用于复杂战斗数学和伤害计算的集中式 RefCounted 工具。
处理唯一与可堆叠增益效果以及刷新持续时间的逻辑。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
使用特殊属性(元素抗性)扩展基础属性的模式。
管理角色成长数据到 .tres 文件的序列化。
授予经验值和触发升级收益的逻辑。
critical_chance = 50?整数除法(例如在公式中)会导致截断。始终使用 float(0.0 到 1.0 或 0.0 到 100.0)[20]。pow() 缩放会迅速导致无法达到的等级或整数溢出 [24]。maxi(val, 1) [25]。_process() 中执行繁重的属性重新计算 — 仅在添加/移除修饰器或基础属性更改时重新计算。使用“响应式”模式。get_attribute("strength"))。DamageFormula 类中,以确保玩家和 NPC 之间的一致性。class_name Stats extends Resource
signal stat_changed(stat_name: String, old_value: float, new_value: float) signal level_up(new_level: int)
@export var level: int = 1 @export var experience: int = 0 @export var experience_to_next_level: int = 100
@export var strength: int = 10 @export var dexterity: int = 10 @export var intelligence: int = 10 @export var vitality: int = 10
var max_health: int: get: return vitality * 10 var attack_power: int: get: return strength * 2 var defense: int: get: return strength + (vitality / 2) var magic_power: int: get: return intelligence * 3 var critical_chance: float: get: return dexterity * 0.01
var modifiers: Dictionary = {}
func add_experience(amount: int) -> void: experience += amount
while experience >= experience_to_next_level:
level_up_character()
func level_up_character() -> void: level += 1 experience -= experience_to_next_level experience_to_next_level = int(experience_to_next_level * 1.5)
# 增加基础属性
strength += 2
dexterity += 2
intelligence += 2
vitality += 2
level_up.emit(level)
func get_stat(stat_name: String) -> float: var base_value: float = get(stat_name) var modifier_bonus := get_modifier_total(stat_name) return base_value + modifier_bonus
func add_modifier(stat_name: String, modifier_id: String, value: float) -> void: if not modifiers.has(stat_name): modifiers[stat_name] = {}
modifiers[stat_name][modifier_id] = value
func remove_modifier(stat_name: String, modifier_id: String) -> void: if modifiers.has(stat_name): modifiers[stat_name].erase(modifier_id)
func get_modifier_total(stat_name: String) -> float: if not modifiers.has(stat_name): return 0.0
var total := 0.0
for value in modifiers[stat_name].values():
total += value
return total
extends Item class_name EquipmentItem
@export var stat_bonuses: Dictionary = { "strength": 5, "dexterity": 3 }
func on_equip(stats: Stats) -> void: for stat_name in stat_bonuses: stats.add_modifier(stat_name, "equipment_" + id, stat_bonuses[stat_name])
func on_unequip(stats: Stats) -> void: for stat_name in stat_bonuses: stats.remove_modifier(stat_name, "equipment_" + id)
class_name StatusEffect extends Resource
@export var effect_id: String @export var duration: float @export var stat_modifiers: Dictionary = {}
func apply(stats: Stats) -> void: for stat_name in stat_modifiers: stats.add_modifier(stat_name, "status_" + effect_id, stat_modifiers[stat_name])
func remove(stats: Stats) -> void: for stat_name in stat_modifiers: stats.remove_modifier(stat_name, "status_" + effect_id)
func calculate_damage(attacker_stats: Stats, defender_stats: Stats) -> float: var base_damage := float(attacker_stats.attack_power) var defense := float(defender_stats.defense)
# 伤害减免公式
var damage := base_damage * (100.0 / (100.0 + defense))
# 暴击
if randf() < attacker_stats.critical_chance:
damage *= 2.0
return maxf(damage, 1.0) # 最小造成 1 点伤害
class_name Skill extends Resource
@export var required_level: int = 1 @export var required_stats: Dictionary = { "strength": 15, "intelligence": 10 }
func can_use(stats: Stats) -> bool: if stats.level < required_level: return false
for stat_name in required_stats:
if stats.get_stat(stat_name) < required_stats[stat_name]:
return false
return true
godot-combat-system、godot-inventory-system每周安装量
79
仓库
GitHub 星标数
59
首次出现
2026年2月10日
安全审计
安装于
opencode78
gemini-cli77
codex77
kimi-cli76
github-copilot76
amp76
Resource-based stats, modifier stacks, and derived calculations define flexible character progression.
Core data container for base attributes (Str, Dex, Int) and derived scaling rules.
Serialized data definition for buffs/debuffs (Additive, Multiplicative, Override).
Orchestrator for JIT (Just-In-Time) stat calculation with active modifier stacking.
Data-driven level-up curve definition using growth factors and base XP.
Reactive UI hook for syncing Labels to stat changes without polling.
Centralized RefCounted utility for complex combat math and damage calculations.
Logic for handling unique vs. stackable buffs and refreshing durations.
Pattern for extending base stats with specialized attributes (Elemental Resists).
Managing the serialization of character progression to .tres files.
Logic for awarding experience and triggering level-up benefits.
critical_chance = 50? Integer division (e.g., in formulas) causes truncation. Always use float (0.0 to 1.0 or 0.0 to 100.0) [20].pow() scaling quickly leads to unreachable levels or integer overflows [24].maxi(val, 1) [25]._process() — Only recalculate when a modifier is added/removed or base stats change. Use the "Reactive" pattern.# stats.gd
class_name Stats
extends Resource
signal stat_changed(stat_name: String, old_value: float, new_value: float)
signal level_up(new_level: int)
@export var level: int = 1
@export var experience: int = 0
@export var experience_to_next_level: int = 100
# Base stats
@export var strength: int = 10
@export var dexterity: int = 10
@export var intelligence: int = 10
@export var vitality: int = 10
# Derived stats (calculated from base)
var max_health: int:
get: return vitality * 10
var attack_power: int:
get: return strength * 2
var defense: int:
get: return strength + (vitality / 2)
var magic_power: int:
get: return intelligence * 3
var critical_chance: float:
get: return dexterity * 0.01
# Modifiers
var modifiers: Dictionary = {}
func add_experience(amount: int) -> void:
experience += amount
while experience >= experience_to_next_level:
level_up_character()
func level_up_character() -> void:
level += 1
experience -= experience_to_next_level
experience_to_next_level = int(experience_to_next_level * 1.5)
# Increase base stats
strength += 2
dexterity += 2
intelligence += 2
vitality += 2
level_up.emit(level)
func get_stat(stat_name: String) -> float:
var base_value: float = get(stat_name)
var modifier_bonus := get_modifier_total(stat_name)
return base_value + modifier_bonus
func add_modifier(stat_name: String, modifier_id: String, value: float) -> void:
if not modifiers.has(stat_name):
modifiers[stat_name] = {}
modifiers[stat_name][modifier_id] = value
func remove_modifier(stat_name: String, modifier_id: String) -> void:
if modifiers.has(stat_name):
modifiers[stat_name].erase(modifier_id)
func get_modifier_total(stat_name: String) -> float:
if not modifiers.has(stat_name):
return 0.0
var total := 0.0
for value in modifiers[stat_name].values():
total += value
return total
# equipment_item.gd
extends Item
class_name EquipmentItem
@export var stat_bonuses: Dictionary = {
"strength": 5,
"dexterity": 3
}
func on_equip(stats: Stats) -> void:
for stat_name in stat_bonuses:
stats.add_modifier(stat_name, "equipment_" + id, stat_bonuses[stat_name])
func on_unequip(stats: Stats) -> void:
for stat_name in stat_bonuses:
stats.remove_modifier(stat_name, "equipment_" + id)
# status_effect.gd
class_name StatusEffect
extends Resource
@export var effect_id: String
@export var duration: float
@export var stat_modifiers: Dictionary = {}
func apply(stats: Stats) -> void:
for stat_name in stat_modifiers:
stats.add_modifier(stat_name, "status_" + effect_id, stat_modifiers[stat_name])
func remove(stats: Stats) -> void:
for stat_name in stat_modifiers:
stats.remove_modifier(stat_name, "status_" + effect_id)
func calculate_damage(attacker_stats: Stats, defender_stats: Stats) -> float:
var base_damage := float(attacker_stats.attack_power)
var defense := float(defender_stats.defense)
# Damage reduction formula
var damage := base_damage * (100.0 / (100.0 + defense))
# Critical hit
if randf() < attacker_stats.critical_chance:
damage *= 2.0
return maxf(damage, 1.0) # Minimum 1 damage
# skill.gd
class_name Skill
extends Resource
@export var required_level: int = 1
@export var required_stats: Dictionary = {
"strength": 15,
"intelligence": 10
}
func can_use(stats: Stats) -> bool:
if stats.level < required_level:
return false
for stat_name in required_stats:
if stats.get_stat(stat_name) < required_stats[stat_name]:
return false
return true
godot-combat-system, godot-inventory-systemWeekly Installs
79
Repository
GitHub Stars
59
First Seen
Feb 10, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode78
gemini-cli77
codex77
kimi-cli76
github-copilot76
amp76
Perl 5.36+ 现代开发模式与最佳实践 | 构建健壮可维护应用程序指南
1,100 周安装
get_attribute("strength")DamageFormula class to ensure consistency across Players and NPCs.