Jump to content

Gotisch

Members
  • Posts

    69
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

Posts posted by Gotisch

  1. feature request: mmap disabling by ZoneID\\AreaID

    Will never happen.

    We cannot deal with the consequences of disabling some tiles on map. The logic of pathfinding between tile with and one without is ill defined. As for areas : same thing, but even harder, since area detection in mangos isn't too solid.

    You can always just do what caeruleaus suggested : delete tiles you don't want. You will have problems in the borders, but its upto you.

    There is always the possibility of disabling it in code. ie. check if areaid is in blocked list (setting) and then don't even try to generate path, but tbh. not sure why this would be helpfull

  2. map#.obj = unmodified RecastDemo

    #.obj = modified RecastDemo

    I modified RecastDemo to use it with our project, so that I could load the navmesh produced by the generator, as well as the raw debug output.

    This version loads the intermediate data debug files and the #.obj file produced by the generator, and it has some functionality that allows you to display 1 tile at a time.

    It only builds on Windows (only other build I saw was Mac Xcode).

    The unmodified version only uses the map#.obj file produced by the generator. You won't get to see the generator-built navmesh.

    The generated obj file for this version had an off-by-one error in the triangle indices. It should be fixed now.

    edit: Oops, didn't see your edit. My change works fine in the binary on github.

    i added cmakefiles to build it on linux and it works fine ( i think ):

    if i put it into directory of MoveMapGen and generate with debugOutput i can launch it select debug as Sample and <mapid>.obj as input mesh. Problem is it seems to load every tile in map, wich reduces usage possibilites (i.e: my pc can't handle it :D). you said there is way to only display one tile at a time? i couldnt find anything relating to that in debug.cpp code, or did i just miss it?

    For debugging purposes optimal would probably be the display of the current tile and if wanted the 4 adjacend tiles, no?

  3. I'll work on pushing your changes today.

    I'll also make you a contributor - just try to break commits into smaller pieces so it's easier to understand what changes do. :)

    it may be possible to generate mesh with different parameters per grid (?).

    ...

    I'll try take a look at generator at weekend.

    You'll have to add parameters. I'd make the custom recast parameters optional for the --tile option

    You'll probably hate the parameter parsing code - it's a hack :(

    From a first look it shouldn't be to hard to add, the hacky code, i at least find nice to read. Relevant config settings are done in MapBuilder::buildMoveMapTile() from what i can see.

    The settings are:

    float cellSize = .5f;       // larger number => less voxels => faster build time
                                       // too large, and tight spaces won't be pathable.
    float agentHeight = 1.5f;
    float agentRadius = .1f;
    float agentMaxClimb = 1.65f;
    

    or are there any more somewhere else?

    It should be no problem to add them as parameters (--cellSize, --agentHeight, --agentRadius, --agentMaxClimb). That way generators can play around with them.

    From what i understood from code, tiles with different settings will work together.

    Anyway, these are just guessed settings, no? or taken from recast demo.

    Maybe there is a good set of settings that works well for all tiles.

    If not, one solution is to have different settings for special tiles, no?

    [edit: my english is getting really way to bad]

  4. you should be able to to generate the mesh with different arguments.

    I'm not sure how new generator is set up, but it may be possible to generate mesh with different parameters per grid (?).

    So the only problem would be to find a correct setting configuration that works well per grid, ie. that isnt to strict so that stairs cause problems but that isnt to lax either, so that mobs walk "over" fences.

    If you can only choose one set of parameters for all the navmesh would make things a bit more limited, but in the end its all about the settings. I'll try take a look at generator at weekend.

  5. well if you can go to outland or northrend and land on a roof and then attack a mob that can't reach you and tell us what happens that would probably clear things up.

    - does the mob not react at all?

    - does the mob try to attack you and then give up?

    then if you have pet, try to get on top of aggro list and then get out of reach of mob, he will attack your pet. when you get back into reachable grounds does he stop attacking pet and attack you again, or does he continue attacking pet?

  6. think of a complex situation:

    let threat list be: normal mob(reachable), taunter1(unreachable), taunter2(reachable)

    SelectHostile selects taunter1, sets target as taunter1, calls MoveChase(taunter1)

    MoveChase(taunter1) fails, movement generator either does nothing, or Chases normal mob

    next tick (though target is taunter1)

    SelectHostile skips taunter1 and selects taunter2, calls MoveChase(taunter2)

    MoveChase(taunter2) works, and we have taunter to as target, and as chased mob

    if you extend such an example further, you see that it might take many ticks till you get correct working mechanics

    Let's put it into perspective, Creature AI ticks every 100ms (yes?) So with 10 players qsa modular way would take maximum of 1 second to find reachable target, assuming that only 1 player is reachable. While at every tick only generating 1 path.

    faramirs way would take 100ms but generate 10 paths in that time.

    the logic must be:

    AI: I have my targets

    AI: which of them can I chase

    AI: which of the chaseable do I want to chase

    AI: start chasing

    MoveChase: Do Chase.

    Still same example with 10 players. you will generate 10 paths every tick (at least that is what your pseudo code suggests).

    I know it's potentially costly to generate paths in SelectHostileTarget, but in most cases it should only generate (or update) one path. I think that it will take special circumstances (exploits, bugs in pathfinding, bad navmesh, etc) to create a true bottleneck. It would be better to catch and handle these root causes. For example: count the number of incomplete paths generated in SelectHostileTarget - if there are more than 5, log an error with information about what map, location, creature, etc.

    Exactly the same applies to 2nd solution too. In most cases first target we select will also be the last.

    The same is true for my suggested way. We generate the path, it is valid, so save it somewhere where the MovementGenerator can use it.

    Do i see infinite "this is true for my way too!!" loop here?

    Here are pseudi codes as i understood them

    Creature::Update()
     Unit::Update()
       process events (might die here, damage aura or something)
       MotionMaster::UpdateMotion()
         active MovementGenerator::Update()
           (IF there is no valid path for current target)
             !generate one new path!
    
     (IF (not evading))
       UpdateAI()
         Unit::SelectHostileTarget()
           (IF current path is INCOMPLETE)
             mark target as unreachable
             (IF possible other target)
               switch to next possible target
             (ELSE)
               evade
    

    Path generation is limited to MovementGenerator.

    Target selection is limited to CreatureAI.

    Faramir proposes to rewrite Unit logic

    Creature::Update()
     (IF (not evading))
       UpdateAI()
         path Unit::SelectHostileTarget()
           Try to find valid target by checking everything in taunt/threat list
           normally and with
           path Unit::isInAccessiblePlaceFor()
             !generate one new path!
           (IF generated path is INCOMPLETE)
              drop it
           (ELSE)
              save it (But probably not from isinaccessibleplace but in AI?)
    
     Unit::Update()
       process events (might die here, damage aura or something)
       MotionMaster::UpdateMotion()
         active MovementGenerator::Update()
           !Access Saved Path from AI!
           or
           !generate same path!
    

    Path generation is limited to AI/Unit (or if path not saved movementgenerator generates path too)

    Target selection is limited to AI

    What are the differences between faramirs way and qsa's?

    faramirs way

    * might generate more then one path per iteration

    * needs "shared" memory to save path to

    * needs one iteration (100ms) to decide if it should evade

    * breaks modular coding way by mixing pathfinding into AI

    qsa's way

    * path is only generated by Movementgenerator

    * needs more then one iteration to decide if it should evade (worst case sizeof(threatlist))

    What are the real differences?

    faramir would need some field for saved path and rewrite of unit logic

    qsa needs some way to save if unit is accessible or not

    My rationale (and other random stuff) about why this way is good:

    • Creature::Update() no longer wastes an update on the wrong target when it should have switched due to threat/taunt/death/whatever.

    bonus bug fix

    • We can guarantee that we evade only if there are 0 reachable targets

    (reachable is an ugly word, thanks to ranged attacks and spells - not a huge problem, just something to be aware of)

    [rest is rambling and not advantage of good way]

    From what i understand (and remember) from official. Official mobs will run as far as possible to unreachable target and then evade if they can't reach it.

    With your way that won't happen. With qsa's way this won't happen either. Way to make it happen imo is to make isinaccessibleplace only return true, if generated path was incomplete and mob is already at last node of path for at least a few ticks.

    If Mob has to follow invalid path anyway, i don't see advantage of "not wasting updates" because to be official mob should not do anything else.

    Wasting also only happens in case of invalid path. Creature::Update() already takes care of threat/taunt/death cases.

    qsa way also garantees that mob will evade only if there are 0 reachable targets, so i don't see how this is advantage

    So to me main difference between the two methods is the mentallity where to generate path.

  7. I am not trying to say you made the changes with light heart, i was just following up on your post

    Feel free to ask for more, if you want details.

    i wanted more details cause i find it interesting :)

    I have compared database load and other stuff in various test systems, and this change was made after several weeks of trying stuff.

    how did you compare the database loads? Seems to me that it is very hard to simulate people posting to a forum. simply requesting the pages multiple times would just favour forum software with good caching systems.

    I can't really follow your argument about tables, because having a big database isnt a bad thing in itself and 500mb isn't that huge nowadays. What sort of hardware does the webserver run on that you would need dedicated db server for 500mb database?

    From what i understand the current mysql database isnt on same server as forum anyway is it?

    The error is related to the database partly. If you have 50k requests a day and each fires of 40 database queries, the database will be under a bit of load. If you can reduce that to 8 queries per request, its an improvement. And with FluxBB I am able to nail it down to even less queries with a few tricks which I could not use on vBulletin.

    What tricks do you use to reduce the number of queries?

  8. well going with new ticket system i think database structure should be something like this

    id

    parent

    player

    map

    x

    y

    z

    category

    gm (?)

    status

    ticket

    responce(1-4)

    for completly new tickets parent is 0 else it is the id of the previous ticket.

    WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) );
    data << uint32(status); // standard 0x0A, 0x06 if text present
       if (status == 6)
       {
           data << uint32(123); // unk
           data << (ticket ? ticket->GetText() : ""); // ticket text
           data << uint8(0x7); // ticket category
           data << float(0); // tickets in queue?
           data << float(0); // if > "tickets in queue" then "We are currently experiencing a high volume of petitions."
           data << float(0); // 0 - "Your ticket will be serviced soon", 1 - "Wait time currently unavailable"
           data << uint8(0); // if == 2 and next field == 1 then "Your ticket has been escalated"
           data << uint8(0); // const
       }
    

    i think in packet first could be ticket id. and second to last status.

    WorldPacket data(SMSG_GMRESPONSE_RECEIVED, 4+4+len+1+1+1);
       data << uint32(123);
       data << uint32(456);
       data << ticket->GetText(); // issue text
       data << ticket->GetResponse(); // response text 1
       data << uint8(0); // response text 2
       data << uint8(0); // response text 3
       data << uint8(0); // response text 4
    

    recv_data >> map >> x >> y >> z; // last check 2.4.3
       recv_data >> ticketText;
       recv_data.read_skip<uint32>(); // unk1, 11 - talk to gm, 1 - report problem
       recv_data >> isFollowup; // unk2, 1 - followup ticket
       recv_data.read_skip<uint32>(); // unk3, 0
       recv_data.read_skip<uint32>(); // unk4, 0
    

    first read_skip would be category, no?

    • Enjoyable code. If I am supposed to spend hours a week inside the code to fix all the tiny bits and pieces usually not seen, then it should be fun.

    From what i understand fluxbb mods need you to edit fluxbb source code itself.

    • Awesome maintenance. God, please. Being a developer myself, I really never got the point what's wrong with all those forum projects/companies?! It's as if nobody really ever uses their own food.

    maintenance with code edit inside code itself seems to be really hard to do. everytime there is a fluxbb update you will have to merge your code changes with main code changes hoping that nothing will break.

    • Speed. Too many features, to much marketing blurb and shizzle is what decreases speed. Read: mostly database performance, and template system performance.

    to me it seems fluxbb does not have a real template system, at least they write in their todo for next major version "implement real template system and rewrite core".

    Features are what make a forum software great though. the "thanks" feature for example allows easy differianciation between user and dev, etc. Since fluxbb doesnt have these features you will have to reimplement them yourself or live with less features.

    Also from the errors i got here on forum major problem seems to be database. which hasnt that much to do with forum, does it? with old system i got error message could not connect to database, and now sometimes i get same error message.

    what is your argumentation for fluxbb having good maintenance? i looked at it but didnt see any advantage over other board software that for example uses some sort of module system for extensions (fluxbb only has this in admin area)

    what was the real performance hog with old forum software? so that fluxbb works better in that reguard?

  9. I have two problems with this code:

    1. Using multiple threads to read single lines from a file seems to be totally inefficient.

    2. Using regular expressions to parse seems to be totally inefficient.

    then again if its just for learning it totally fine \\o/

    (if the parsing of one line would really take so long that it would be worth creating multiple thread correct design patter is as few locks as possible imo. so you would insert into configMap only once per thread, at the end.)

    On a AMD Phenom x4 945 (+intel ssd) this code is up to 20 times faster in parsing than the dotconfpp mangos configuration class

    how did you measure that?

    Also what would be interesting is usage statistics of each thread, are threads used the same? (each thread does 25% of the config file with 4 threads) Or is one thread doing most of the work while the rest sleep away.

    How does this class compare to the same without multithreading? ie. no linebuffer but calling the regexp (if you really want to use that which is really overkill, since initialization probably costs more then parsing the file) from

    while(std::getline(this->fileStream, line)) 
       {
        parselinehere(line);
       }
    

  10. sorry for editing my post makes yours seem a bit out of context :).

    but to see if a enemy is reachable, the function calls isInAccessablePlaceFor() which at the moment only does:

    if(IsInWater())
           return c->canSwim();
       else
           return c->canWalk() || c->canFly();
    

    here it should check if there is a path from creature to target.

  11. This touches on another subject: The aggro logic will need to be able to create paths, select a complete one, then store it where the movement generator can access it:...

    Why does the Aggro logic have to select a Path? If by Aggro Logic you mean the AI, its job is: to decide which Target to attack, if Target is in range attack him, if not set goal for movementgenerator to the Target (and lots of other high level stuff).

    Job of Movementgenerator is to decide how to get form current location to location of target and do the actual movement, or not?

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use