Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BodyPart-Ability-Effect属性系统的模型与计算 #43

Open
tcz717 opened this issue May 9, 2019 · 6 comments
Open

BodyPart-Ability-Effect属性系统的模型与计算 #43

tcz717 opened this issue May 9, 2019 · 6 comments
Assignees
Milestone

Comments

@tcz717
Copy link
Owner

tcz717 commented May 9, 2019

No description provided.

@tcz717 tcz717 added this to the Alpha-v1 milestone May 9, 2019
@tcz717 tcz717 self-assigned this May 9, 2019
@tcz717
Copy link
Owner Author

tcz717 commented May 14, 2019

属性模型的表达和更新方式 1 (基本实现 #46

通过UnitGrain内的私有方法更新

优点:

  • 方便快捷
  • 实现简单

缺点:

  • 每次更新公式需要重新编译
  • 运行中无法得知属性更新的依赖项
  • 太多重复代码

例子

        private void UpdateSpaceTimeMagicPower()
            => State.SpaceTimeMagicPower.Update(
                Min(
                    State.ReconstructionAbility,
                    State.ControllingAbility,
                    State.PerceptionAbility,
                    State.ResolvingAbility));

        private void UpdatePerceptionMagicPower() => State.PerceptionMagicPower.Update(State.PerceptionAbility);

        private void UpdateMagicTransformEfficiency()
            => State.MagicTransformEfficiency.Update(Min(State.PerceptionAbility, State.ControllingAbility));

        private void UpdateControllingMagicPower() => State.ControllingMagicPower.Update(State.ControllingAbility);
        private void UpdateMagicHitRate()          => State.MagicHitRate.Update(State.ControllingAbility);
        private void UpdateMagicLearningRate()     => State.MagicLearningRate.Update(State.ControllingAbility);
        private void UpdateAimingAccuracy()        => State.AimingAccuracy.Update(State.Vision);
        private void UpdateSightRange()            => State.SightRange.Update(State.Vision);

@tcz717
Copy link
Owner Author

tcz717 commented May 14, 2019

属性模型的表达和更新方式 2

通过给UnitState内的属性标注Attribute

优点:

  • 方便快捷
  • 直观,表达式和对应属性在同一位置

缺点:

  • 每次更新公式需要重新编译
  • 可能的反射开销

例子

        [Update(state => Min(state.ReconstructionAbility, state.ControllingAbility)]
        public UnitProperty SummonMagicPower
        {
            get => Effects[(int) EffectIndex.SummonMagicPower];
            set => Effects[(int) EffectIndex.SummonMagicPower] = value;
        }

@tcz717
Copy link
Owner Author

tcz717 commented May 14, 2019

属性模型的表达和更新方式 3

将模型算法抽象成一个更新表服务,并使用依赖注入获取

优点:

  • 将更新算法和数据分离并集中, 易于统一修改和替换
  • 算法和数据低耦合

缺点:

每次更新公式需要重新编译

例子

class SimpleUnitStateUpdater : IUnitStateUpdater 
{
    public void Update(UnitState state) { ... }
    private static Dictionary<AbilityIndex, Func<UnitState, float>> _model = new <AbilityIndex, Func<UnitState, float>>
    {
        [AbilityIndex.ReconstructionAbility] = state => Min(state.ReconstructionAbility, state.ControllingAbility),
        ....
    }
}

@tcz717
Copy link
Owner Author

tcz717 commented May 15, 2019

属性模型的表达和更新方式 4

将模型算法抽象成一个更新表以xml或者json保存,并使用依赖注入获取

优点:

  • 将更新算法和数据分离并集中, 易于统一修改和替换
  • 算法和数据低耦合
  • 更新公式不需要重新编译

缺点:

  • 处理xml、json、宏的额外开销
  • 潜在的多服务器间模型同步开销

例子

{
  "Effects" : {
    "SummonMagicPower" : {
      "func" : "min",
      "input": ["ReconstructionAbility", "ControllingAbility"]
    },
  }
}

... or ..

{
  "Effects" : {
    "SummonMagicPower" : "min($ReconstructionAbility, $ControllingAbility)"
  }
}

@jykgod
Copy link
Collaborator

jykgod commented May 15, 2019

属性模型的表达和更新方式 5

模型算法用Lua脚本实现,然后通过使用json、xml或excel的方式进行配置。

优点:

  • 灵活易于修改,开发效率高
  • 修改和新增都不需要重新编译

缺点:

  • 运行效率会低一点

例子

C#Part:

LuaTable luaTable = lua.DoFile(filePath)[0] as LuaTable;//检查出脚本更新时调用或者每次都重新dofile。
...
float ret = (float)(double)((luaTable[funcName] as LuaFunction).Call(arg1, arg2)[0]);

LuaPart:

local TestClass = {}
TestClass.TestFunc1 = function(arg1, arg2)
	return arg1 + arg2
end
TestClass.TestFunc2 = function(arg1, arg2)
	return arg1 - arg2
end
return TestClass

JsonPart:

{
    "luaFilePath" : "x.lua",
    "Effects" : [
         {
              "name" : "Power",
              "func" : "TestFunc1", 
              "input":  ["Ability1","Ability2"]
         }
     ]
}

@panyz522 panyz522 reopened this May 16, 2019
@panyz522
Copy link
Collaborator

panyz522 commented May 16, 2019

属性模型的表达和更新方式 6(3+5)

模型使用Json/xml etc. 配置,算法用Lua脚本实现,将模型编译为C#的data model, [并且更新相关数据表]

优点:

  • 灵活易于修改,开发效率高
  • 开发者友好,数据模型有Intellisense和refactoring支持
  • 修改算法不需要重新编译

缺点:

  • 修改模型需要重新编译
  • 运行效率低于原生算法

例子

      State4
       /  |
   State3 |
   /   \  | 
State1 State2

C#Part:

EffectState.generated.cs

public partial class EffectState
{
    private double _state1;
    private double _state2;
    private double _state3;
    private double _state4;

    public double State1 {
        get
        {
            return _state1;
        }
        set
        {
            _state1 = value;
            State3 = UpdateTable[nameof(State3)].Calculate(_state1, _state2); 
            // Evaluation tree can be optimized
        }
    }

    public double State2
    {
        get
        {
            return _state2;
        }
        set
        {
            _state2 = value;
            State3 = UpdateTable[nameof(State3)].Calculate(_state1, _state2);
            State4 = UpdateTable[nameof(State4)].Calculate(_state2, _state3);
        }
    }

    public double State3
    {
        get
        {
            return _state3;
        }
        private set
        {
            _state3 = value;
            _state4 = UpdateTable[nameof(State4)].Calculate(_state2, _state3);
        }
    }

    public double State4
    {
        get
        {
            return _state4;
        }
        private set
        {
            _state4 = value;
        }
    }

}

LuaPart:
Same as #43 (comment)

Lua scirpt template can also be generated by Json

JsonPart:
Same as #43 (comment)

{
  "luaFilePath": "x.lua",
  "Effects": [
    {
      "name": "State1",
      "type": "double",
      "summary": "The introduction of State1 is written here",
      "input": []
    },
    {
      "name": "State2",
      "type": "double",
      "summary": "The introduction of State2 is written here",
      "input": []
    },
    {
      "name": "State3",
      "type": "double",
      "summary": "The introduction of State3 is written here",
      "input": [ "State1", "State2" ] // Dependency
    },
    {
      "name": "State4",
      "type": "double",
      "summary": "The introduction of State4 is written here",
      "input": [ "State2", "State3" ] // Dependency
    }
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants