Jump to content

  • Log In with Google      Sign In   
  • Create Account

noizex

Member Since 04 Jul 2011
Online Last Active Today, 06:38 PM

#5302631 Rpg Stats - Temporary Changes, Harder Than I Realised!?

Posted by noizex on 26 July 2016 - 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();

       target->set_player_model(frog);

   }

 

   void remove_effect()

   {

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

       target->set_player_model(old_model);

   }

 

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.




#5302626 Rpg Stats - Temporary Changes, Harder Than I Realised!?

Posted by noizex on 26 July 2016 - 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)

    {

        target->remove_stat_modifier(str_mod);

        target->remove_stat_modifier(vit_mod);  

    }

}

 

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. 




#5302602 Rpg Stats - Temporary Changes, Harder Than I Realised!?

Posted by noizex on 26 July 2016 - 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. 




#5301389 Possible Bug In Asrun Example

Posted by noizex on 19 July 2016 - 12:08 PM

As I played with various AS concepts in a small program that I based on "asrun" sample I started getting segfaults, which I tracked to be caused by adding a simple destructor to a class that was instantiated, called some method that caused exception to be set and then exited. 

 

Took me a while, but I think I found the problem and it's probably worth fixing. This example uses callbacks to request and return context from/to a global context pool.

 

#0  0x000000000044f666 in asCContext::SetObject(void*) ()

#1  0x00000000004950d8 in asCScriptObject::CallDestructor() ()

#2  0x0000000000494ef6 in asCScriptObject::Release() const ()

#3  0x000000000047ae27 in asCScriptEngine::CallObjectMethod(void*, asSSystemFunctionInterface*, asCScriptFunction*) const ()

#4  0x000000000047ad07 in asCScriptEngine::CallObjectMethod(void*, int) const ()

#5  0x000000000045b059 in asCContext::CleanStackFrame() ()

#6  0x0000000000459f8c in asCContext::CleanStack() ()

#7  0x000000000044edac in asCContext::Unprepare() ()

#8  0x000000000040779a in ReturnContextCallback(asIScriptEngine*, asIScriptContext*, void*) ()

#9  0x000000000046cf8b in asCScriptEngine::ReturnContext(asIScriptContext*) ()

#10 0x000000000044a21b in CContextMgr::DoneWithContext(asIScriptContext*) ()

#11 0x000000000040718d in ExecuteScript(asIScriptEngine*, char const*, bool) ()

 

Key thing probably is exception and destructor and how ReturnContextCallback function returns context to the pool. Here is the function:

void ReturnContextCallback(asIScriptEngine *engine, asIScriptContext *ctx, void * /*param*/)
{
	g_ctxPool.push_back(ctx);
	// Unprepare the context to free any objects it may still hold (e.g. return value)
        ctx->Unprepare();
}

Seems like the context is first returned to the pool as "ready to use", and only then unprepared. In my situation (after exception thrown) this causes context to be cleared of objects, which causes that destructor to be called. To call destructor, it has to fetch context, which it does through callback "ReturnContextCallback" and it yields the very same context as the one that's being unprepared. 

 

I think I fixed this by just moving ctx->Unprepare() above the line that pushes the context back to the pool.

 

The script I used to reproduce this is simple, it just has to throw exception at some point, while also having a destructor.

class Player
{
   ~Player()
   {
      print("destructor\n");
   }
   
   void foo()
   {
      int x = 0;
      int y = 1 / x;
   }
}

int main()
{
   Player player();
   player.foo();                 
   return 1;
}

Btw, is this correct place to fill some possible bugs/requests or there is some system for this? 




#5297668 How to import animations from commercial models (FBX, X) into Blender

Posted by noizex on 23 June 2016 - 02:10 AM

Thanks for all replies. Turned out that there was some problem with FBX version probably, plus that file I bought was far from well organized. I upgraded Blender to 2.77 and used this tutorial:

 

https://hub.jmonkeyengine.org/t/how-to-convert-fbx-to-blender-with-animations/33705

 

and it finally worked, so I'm posting it, maybe it will help someone. Also had weird problem where everything imported but not the armature of a model, after long research and digging through FBX import addon (crazy code, thousands of lines) I managed to pin it down to a loose root bone that was encountered before the real armature root bone, and it caused only that one wrong armature to be imported to Blender. I skipped the bad one by dirty hack in addon code and suddenly the correct armature appeard. I filled bug and I'm waiting for some reply from addon's maintainer so hopefully this will be resolved for all cases.




#5268966 RakNet still alive?

Posted by noizex on 03 January 2016 - 05:07 AM

 

there is supposedly a ton of buffer overflow bugs

 

Don't believe everything you hear on the internet, unless there is verifiable evidence.
Can you link to one active bug report about a buffer overflow bug in RakNet (that shows a problem in the code)?

Second, if you need reliability over UDP, use Enet.
If you are using a particular game engine, like Unity or Unreal, then look at the default solutions for those engines.

 

 

Hence "supposedly" smile.png I just got that impression by looking at issues on github, and haven't really checked&confirmed any of those (I just need library that works, if I were to spend time checking for these things in every thing I use I would never get past main() in my project):

 

https://github.com/OculusVR/RakNet/issues/73

https://github.com/OculusVR/RakNet/issues/25

https://github.com/OculusVR/RakNet/issues/2

https://github.com/OculusVR/RakNet/pull/36

https://github.com/OculusVR/RakNet/issues/57

 

Some are not very detailed, but one can get the impression there are more such bugs than should be in mature library. Saying this, I'm still hoping RakNet is stable enough to be used in my project, I already integrated it and it worked in development settings for these years, but these signs (selling RakNet, new owner just letting it go on GitHub where noone even approves PR) made me a little worried. Every time I upgraded to new RakNet version in the past I struggled with issues like errors/warnings, problems with CMake generation, so every time it left a feeling that lib may not be as polished as other 3rd party things i use.

 

I considered Enet but at the time I made the decision it was slightly too low-level for my present knowledge and what I needed - reliable UDP client-server architecture, but also some helper methods for packing data specific to games (vectors, quaternions), so some nice way to read/write data into packets (like RakNet's BitStream), way to prioritize packets, channels etc. This means that right now I'm probably using 5% of what RakNet has to offer, and probably won't be using much more - I will handle object sync myself, not using some ReplicaMaster, same for chats and all other in-game activity. I may need some secure crypted data connection for logging too (I think RakNet also has it).

 

I'm staring to wonder what would be better in such case:

 

1) staying with RakNet, as it works, even if I'm using just a small percent of functionality and there are previously mentioned issues with the current state of project

2) trying to convert to some lower level lib like Enet, and adding needed functionality that I'd lack compared to RakNet (plus making it more in object oriented manner). Are there any libraries based on Enet that are slightly more high-level, but not as big as RakNet?




#5268805 RakNet still alive?

Posted by noizex on 02 January 2016 - 04:00 AM

RakNet is one of the most mature pieces of middleware around. I wouldn't be that worried that the pace of development has slowed.

 

Besides, Unity uses RakNet, so on that alone, I doubt it is going to die off anytime soon - if there's any danger of it, someone will fork the codebase.

 

Sorry for resurrecting this thread, but recently I had to rebuild my project from scratch and found out RakNet is no longer "alive". I'm not sure how this is possible. I've been using RakNet for 3 years now, and to be honest it always seemed like really messy framework (but it worked so far with my limited needs). Build files are terrible and always require some hand-tweaking, and there is supposedly a ton of buffer overflow bugs and few other major problems. Source has been abandoned by OculusVR and only some life can be found in forks, which have their own problems and don't compile out of the box on popular compilers like MSVC2015. 

 

How library that has been around for so many years can end like this? Are there really no alternatives? Should I stick to RakNet since I already use it in my project and try to somehow fix the problems and follow some pull requests from the community, or there is some reasonable alternative (in terms of functionality, I need some UDP network layer with reliability options for client-server architecture). 




#5207386 Standard structure of a large scale game

Posted by noizex on 29 January 2015 - 04:12 AM

That's a question I was going to ask many times myself but can't even phrase it clear enough. I started with small project but now it's grown, has over 300+ classes and client-server architecture. More and more I'm finding myself pondering how to approach something in terms of data-object interaction and it takes many hours to figure some things. For example, I have network synchronized modifiable terrain. I needed it to synchronize when player moves and changes grid position, but I didn't want to clutter player movement logic (which is tricky in itself, as it's over network with authoritative server) so I created some TerrainDb class that receives network messages and deals with response and updating terrain caches. What is my major problem is relation between different systems and classes. Then it turns out such class needs some networking access to receive/send data to server, requires access to World/Terrain and so on. And it starts to get messy already.

 

Top game logic is handled by GameState, each of which has access to several main objects (like Connection, ScriptingEngine etc.) but most of these states are simple (Login, LoadingScreen, Character menu) until I get to "gameplay" state. This is where so many things need to happen, so many systems need to be initialized and propagated that I have no idea how to design these relations. Should I initialize them all in state's Init() func, making it 100-200 lines long? Pass dependencies to constructors? So far I avoided singletons and I have not a single one, but the net of class relationships becomes very hard to maintain. 

 

While I'm not making an "MMO" but way smaller networked "sandboxy" game, I checked Ryzom/Planeshift sources and several others that had sources available. They all seem to be just as messed and without deep knowledge you have no idea what's going and and can't even track relations. So many weird classes initialized in weird places, passed around. Is that what every project ends up as? I admit I saw WarZ source code too and was terrified - 200kB classes that do every freaking thing from rendering to physics all messed up and mixed, not even divided into sections of similar theme. 

 

Mind that I'm talking about lower level and unique things - terrain, networking, scripting etc. I don't think this can and should be done as components (terrain itself is really unique, which would lead to a special case game object that has really unique components and has systems that work just on that one object which seems silly). Component systems seems more like game logic where you fit all pieces together, but this requires some bigger things to exist first. I don't really think I could fit everything in Component-System manner. 

 

So anyone has any pointers where such design could be learned? Is it just experience? Everyone starts talking about game loop and game states but these things are nothing compared to vast net of systems/services/"managers" required for a more complex game. 




#5127752 Indie game - Town of Salem

Posted by noizex on 31 January 2014 - 09:41 AM

Reminds me of Salem (http://www.salemthegame.com/) /in art department of course/ You guys were inspired by that game or came with that art style yourself? It's weird how this look fits into "salem" theme somehow, and I can't exactly say why :)




#5081666 Game state management (C++)

Posted by noizex on 30 July 2013 - 05:48 AM

Hard to tell because you provided only partial pseudo-code for your solution. The usual way (I think) it is done is - you don't instantly change the state (especially not as a responsibility of state class itself), but you ask to change the state on next update. Then finite state machine gets updated and it processes to next state, cleaning up old one. It does not require holding any copy or anything like that. Its just: finish old state, prepare new state, switch current state to new state.




#5042718 Game entity/component system - creation argument list

Posted by noizex on 13 March 2013 - 09:01 AM

Thanks for all the answers!

 

If you can use C++11, you could use variadic templates and std::forward your arguments to constructor. If you can't you can still template arguments, though it will be a bit more work (you have to define templates for all possible numbers of arguments, or use some macro magic - with variadic templates its just one line of code).

 

The varidic templates definitily sounded interesting, but unfortunately they are not supported by Visual Studio 2012... If I were to write templates for all the possible number of arguments given, would I also need to overload the function for each of these templates (Arguments1<>, Arguments2<>, ...) or is there some way to templatize (is this a word) the templates so that I can have "Component::Component(Arguments args)" for me to pass as many arguments as I want?

 

About MSVC2012 - it supports variadic templates and few more C++11 features when you install CTP_Nov2012 (http://www.microsoft.com/en-us/download/details.aspx?id=35515) toolset and set it in your project options. Its CTP so its for testing but I use it and it works without problems. IMO having variadic templates is worth it smile.png

 

If you want to pass it around with varied number of arguments, that will be hell lot of templating. I was thinking about making a component factory with varied number of arguments that are then passed to constructor, and this factory gives you component. Something like:

 

Component* comp = compFactory->CreateComponent(SPATIAL, arg1, arg2);
Component* comp = compFactory->CreateComponent(RENDERABLE, arg1);
Component* comp = compFactory->CreateComponent(COLLIDABLE, arg1, arg2, arg3); 

 

Above code could be achieved by templating factory function "CreateComponent" to support different numbers of arguments that are passed to constructor, but as I said without variadics its a bit of crazy template magic (check this article and source code for really nice factory implementation: http://archive.gamedev.net/archive/reference/articles/article2097.html)

 

This can happen on higher level than entity, in some class that creates entities out of components. Does entity really need to know how to construct components (and itself?) or it should be responsibility of class above entity, that picks needed components (probably out of templates later, so its more automated) and creates another instance of entity by attaching necessary components. In some Entity System implementations, there is no such thing as Entity class, but its just a tag or id under which certain components are glued together by some "EntitySystem/Manager". 

 

In my implementation, I kept GameObject class but its only responsibility is to be a container of component pointers that also keeps a bitmask of what component types are attached to that entity (I use it as for very fast lookups, as such bitmask works like a key that you can latet bit-and against some mask of required components and quickly filter entites that meet these criteria).




#5042672 Game entity/component system - creation argument list

Posted by noizex on 13 March 2013 - 06:13 AM

If you can use C++11, you could use variadic templates and std::forward your arguments to constructor. If you can't you can still template arguments, though it will be a bit more work (you have to define templates for all possible numbers of arguments, or use some macro magic - with variadic templates its just one line of code).

 

And I don't think there is anything wrong with constructing component object outside and attaching it to entity - you may want to do some sort of pre-processing and set various information so why not do it this way? As long as you have clear state of ownership of such component it won't be a problem. 




#5041742 Best Practice for Values Return C/C++

Posted by noizex on 11 March 2013 - 01:57 AM

This is a bit off-topic, as the OP didn't ask about error handling but how to return from a function - but I wanted to address maxgpgpu arguments concerning error-handling. It seems nice at first, but when you start wondering about it - is there really a reason to return several errors when initializing and setting data to your VBO? Or when reading from terrain data volume to create a terrain mesh? Or when loading a texture? In all these cases, if the game is going to run properly it _has_ to succeed.

 

If you can't load texture, load default texture thats guaranteed to be loaded (or application won't start). If shader is missing - return some default shader and log error (plus this should be of course fixed for the release, because missing textures and shaders are no good). If you can't initialize VBO, something is very wrong and your application either has flaws that lead to this or its exceptional behaviour and should just result in exception thrown. 

 

What I'm trying to say is that if your code is error-driven you will spend a lot of time returning various error codes from nested functions and having to handle them. What I found way more useful is to code in a way that errors basically don't occur (as an expected result) or are very rare. Use assert() and logging in debug mode to catch possible fatal errors that result from invalid program state and fix them so they do not happen, or are handled as they should. For something that can always happen but is exceptional throw exceptions. In rare cases you may need some multiple-value error code, but I looked through my app and I can't see anything like this (I don't count functions that don't return any other result than bool for success/failure).




#5041445 Best Practice for Values Return C/C++

Posted by noizex on 10 March 2013 - 03:37 AM

I agree with Stroppy and Lightness - returning the value that is expected result of a function (instead of some error) is the way to go. Returning error codes is one of most counterintuitive ways for dealing with things. 

 

Of course it all depends on the case - in your case you just want to return Texture so go with your first suggestion, like:

std::shared_ptr<Texture> texture = textureCache.GetTexture("...");

 

I can hardly think of situation that would justify what was suggested above about using return value only for error code (and returning objects by assigning to reference). First of all, its quite hard to determine quickly what happens because you may have references that have different meaning: in, out, in/out. There is no special syntax to indicate it so you have to write a description. If you really need several error codes (which is IMO very rare and if you write code that requires it very often, something is wrong.. - there are cases where such coding is probably only way to achieve something, but I doubt that your case belongs there). 

 

If you REALLY need to use this approach, at least:

  • Make sure your references already tell your intentions, so if you're using reference as "in" only, make it const, if you use it for return value don't make it const:
    int LoadTexture(const string& name, const Type& type, Texture& texture)
    {
        if (load_from_file(name, type))
        {
            texture = <loaded texture>
            return SUCCESS;
        }
        return FAILURE;
    }
    

     

    Here references that are only for reading are marked const, while your return reference is not - its easier to know whats going to happen that way.

  • Or use std::tuple and std::tie to return multiple values from a function (for example std::tuple<Texture*, int> where int is error code)



#5037974 return std::map Question[Solved]!

Posted by noizex on 01 March 2013 - 05:51 AM

Sorry, could you rephrase your problem, because honestly I can't seem to understand what is it about. :) Attached code doesn't make any sense too, try to put here some meaningful testcase.






PARTNERS