Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 04 Jul 2011
Offline Last Active Yesterday, 05:50 PM

Posts I've Made

In Topic: Rpg Stats - Temporary Changes, Harder Than I Realised!?

Yesterday, 08:11 AM

Looks nice, but if the main point of Effects is to apply (and de-apply) StatModifiers, why not just have Effects contain a list of Stat/value pairs, so you don't have to implement start_effect and remove_effect each time you define a new Effect?


Main point of effects is to give total flexibility on implementing various effects that can affect character - permanent curses, diseases, poisons, buffs and debuffs, spells - so these functions are just hooks that writer of effect uses for a starting/ending point of an effect. This goes way beyond stat modifiers, so I wanted to keep stats and effects separated, because some effects won't even touch stats but change appearance of character, modify it's behavior and so on. The effect could for example do this:


   void start_effect()


       print("You slowly turn into a frog!");

       old_model = target->get_player_model();




   void remove_effect()


       print("You turn back into " + old_model->get_race() + "!");




Though I guess it's a good idea for a base effect that only affects stats :) So instead of creating separate Effect classes I could write StatChangeEffect() and just pass array of stats to affect, without the need to care about adding/removing modifiers for each one. But the general idea is for the effect class to be as flexible as possible in terms of how it affects target.

In Topic: Rpg Stats - Temporary Changes, Harder Than I Realised!?

Yesterday, 07:46 AM

In my implementation I have two layers - stat modifiers and effects. Stat modifier may be caused by effect, but effects can do much much more (anything really, from various disease effects, to just lowering certain stats). So the idea is that effect has start_effect() and remove_effect() methods which in case of pure stat modifiers are the ones responsible for adding and removing them. So it looks a bit like this (some Angelscript pseudocode):


class NastyDisease: Effect

    StatModifier @str_mod, @vit_mod;


    void start_effect(object target)


        @str_mod = target->add_stat_modifier(Stat::Strength, -20);

        @vit_mod = target->add_stat_modifier(Stat::Vitality, -30);  



    // Called when effect expires

    void remove_effect(object target)







This makes StatModifier class just a dumb storage for how much and what stat is modified, and the expiration is handled by Effect class (on a usual timer basis, I don't check upon requsting stat that I should remove some modifier, if the effect expires appropriate function is called and it removes these modifiers.


There is slight problem with this, because if something goes wrong in remove_effect() function (runtime error), it may keep the effects on the player, but I guess if that happens something is really wrong. 

In Topic: Rpg Stats - Temporary Changes, Harder Than I Realised!?

Yesterday, 03:19 AM

You can cache the result once per frame but it should be cheap by just ask it each time. In this way you avoid all kinds of bugs, note that even Morrowind and Oblivion had tons of bugs related to temporary stats, so I would go the "slow" but safe way, and later optimize only if needed.


If you have a single point where buff is added and removed, why not keep a dirty flag and recompute only when it's set to true? If buff can't be changed outside of those two methods, there is no reason why the value would change from one call to another. 


I would remove any logic governing lifetime of an effect from this function though, just iterate over array of effects, set current value, clear dirty flag. If any effect is added or removed, set dirty flag, which forces stat to be recalculated. I just am not sure that function returning strength should care whether the effect should be removed or not, it just goes over effects in the array and applies them. Other part of code guards the lifetime and removes the modifier from the array at appropriate time. 

In Topic: Angelscript Features

Yesterday, 03:05 AM

Hm, for #2 you don't need to #include anything if you are compiling all the scripts in the same module. If that's what you mean?


No, I'm compiling each script in separate module like: "base_a.as", "base_b.as", "mixin_a.as", "mixin_b.as", "derived_c.as" (inherits from base_a, mixin_a, mixin_b). And for example in derived_c.as I have to do:


#include "base_a.as"

#include "mixin_a.as"

#include "mixin_b.as"


because it's a new module (my module name is usually path to a file). Of course all classes/mixins here are marked as shared. If I don't include these files it will throw compile error that it can't find BaseA, MixinA and MixinB.


The problem is - if there is a lot of mixins to include, or base class is quite big, it may be unecessary parsing for compiler, if all used classes/mixins are guaranted by the engine to be available (and if they're not, we throw error and that's clear sign that the base classes were not compiled correctly). 

In Topic: Passing "this" As Argument ?&in

24 July 2016 - 01:19 PM

Allright, I did some more test and I'm not sure I understand handles properly.


Lets assume code:


class Foo{ int a = 0; }

Foo foo();:




1. Foo@ h = @foo   -> it creates a handle that points to "foo" instance, so it also increases refcount, right? But what is the refcount now? Is there a way to check refcount of asIScriptObject for debugging purposes?


2. h.method() will execute method on object "foo", but what about @h.method() ? Both seem to work, but is it allright?


3. @h = foo or @h = @foo ? Documentation uses second with @ prefixing the object instance, but both seem to compile and work?


4.  When accessing object's properties through handle, again - @h.prop or h.prop?


I'm a bit confused by this notation and I'm not sure when the handle is really a handle, when object is really an object and what happens when I add/skip @ prefix.


This leads me to a weird problem with my function that takes "?&in" generic parameters. When I pass a handle to it like this:


Foo @h = foo;

my_func(h);   // assuming my_func(?&in) on C++ side


it tries to create a temporary copy of object Foo, instead of passing a "handle" type to the call. Which completly undermines what I understand about how to refer to a handle and how it works. If "h" is not a handle but the object, then why I can pass it like the above example to any script function for example:


Foo @h = foo;

my_script_func(h); // with my_script_func(Foo@)


When I changed my_func(h) to my_func(@h) it seems to work, but then I have no idea what is really passed there. Isn't @h a handle of a handle, since h is a handle, not an object? And when really passing handle, why does it think it's actually an object Foo, not a Foo@ handle and tries to copy the object, not the handle?



PS. I'm starting to think that doesn't really refer to a handle, but the object, unless I prefix it with @h which then means the "handle to object"? So even though I declare it Foo @h, but then use it as just "h" I'm really refering to the object itself? So handle is handle only when @h is used, and that's why it complains when I pass just "h" to a function, because it's basically the same as passing "foo" object? Is this correct? And if so, what does @h.a mean when I access property. Shouldn't this throw some error that I'm accessing a handle, and force me to use h.a syntax?