How do I detect when mappers pull dumb shit like this?



  • Here's a map called *Paranoia: Unexpected Encounter*. This picture is a top-down view of the whole map, and we'll use this as the "control group". Here's the first image with the locations of all the AI pathing nodes overlayed on it. These cyan dots are places where NPCs can walk. Here's the first image with all the AI positioning hints overlayed on it. These white arrows are places where player ally NPCs can stand to avoid being in the player's way while they follow the player.

    I can easily detect the situation when the mapper hasn't put any of these in and then use the pathing nodes as positioning hints. But this mapper managed to break my code before I even wrote it. How should I determine (at runtime) if the mapper did something stupid with pathing nodes/positioning hints so I can ignore the positioning hints and use the pathing nodes instead?



  • Why can "places where you can walk" be specified by dots instead of areas? It's not free-roam walking?



  • It is free roam. The NPCs can walk anywhere within a short range of their current position. The dots are used for longer-range movement because the short range pathing is significantly more expensive.


  • Java Dev

    If I'm reading the pics correctly (hints only in one place) the mapper may be trying to help the automated system in problematic spots without switching to doing everything manually.

    Would you be able to use both at the same time, such as by using the pathing nodes if there are no positioning hints nearby?



  • My current solution as of late yesterday is to count the number of nodes that can be reached from another node by a human walking, count the number of hints, and if the second number is less than 10% of the first number, I use the nodes I counted as hints in addition to the ones that are explicitly hints.



  • What type of image is it? Does it support layering information? Do you have the clean original map so you can do a hash diff?

    (Is it just this map, or the concept? )



  • @Matches said:

    What type of image is it?

    It's a Source Engine Binary Space Partition file.

    @Matches said:

    Does it support layering information?

    The pictures above are a top-down screenshot of the map. The actual map contains brushes (solids) and entities (solids or points with specific purposes like "light" or "alien swarm spawner"). Here's a random YouTube video I found of what looks like an earlier version of the map:

    [Let's Play] Alien Swarm - Custom Map #01: Paranoia Episode 1 & 2 (German) – 33:08
    — alanandflo

    @Matches said:

    Do you have the clean original map

    I don't have any of the original maps, but I can decompile them and then fix up the stuff the decompiler didn't get right and work from there. The thing is, I can't do that for every map in the future, and I have the source code of the game, so I can fix this stuff on the fly if I can detect it right.

    At the moment, my code checks to see if the map has 10+ times the number of white arrow positioning hints of cyan dot pathing nodes, and if so, it pretends the pathing nodes are also positioning hints. As a fallback, if the marines can't find a nearby positioning hint after this, they just follow the squad leader with a preset offset.



  • That's a pretty big stack of text that I don't have time to read through right now (I might take a look when I get home) - can you post a short code sample of how you define a character on the map, and how you define an alien?

    Basically just need to see enough so I can get a starting point for the bsp file format since there's a lot of things defined in it.

    [Reminder: GitHub is blocked from work]

    Maybe something with this?

    unsigned short PropType; // index into model name dictionary



  • You define them by using the point entity tool (the white pawn between the red camera and the white cube on the left) and then changing the class to asw_drone for a swarm drone, or info_player_start for where the player starts, or light for a static light source.



  • How does asw_drone / info_player_start get saved to the bsp file?

    My buttumption is that it's creating a new prop item, associated with the model mesh/textures/etc that you should be able to look for and see if there's at least one (or however many you're trying to get as a minimum)

    Maybe similar to how gary's mod prop hunt works?



  • Hopefully this will onebox:



  • 	// ---------------------------------------------------------------------------------
    	// Add info_node as marine hints for maps that forgot to add marine hinting.
    	// ---------------------------------------------------------------------------------
    	if ( ClassMatches( "info_node" ) )
    	{
    		Assert( MarineHintManager() );
    		if ( MarineHintManager() )
    		{
    			MarineHintManager()->AddHint( this, true );
    		}
    	}
    


  • @ben_lubar said:

    https://github.com/BenLubar/SwarmDirector2/blob/master/src/game/server/ai_initutils.cpp#L241-L251

    I tried to hax it by using ask.com, but ask couldn't find it.

    Is the posted code your current solution?



  • @Matches said:

    Is the posted code your current solution?

    Part of it. Here's the actual logic that figures out if we need those nodes:

    		// Fixes maps without marine hints being confusing for marines. The hints are added in ai_initutils.cpp.
    		Assert( MarineHintManager() );
    		if ( MarineHintManager() && MarineHintManager()->m_LastResortHints.Count() )
    		{
    			CUtlVector<HintData_t *> &hints = MarineHintManager()->m_LastResortHints;
    			FOR_EACH_VEC_BACK( hints, i )
    			{
    				HintData_t *pHint = hints[i];
    				Assert( pHint );
    				Assert( g_pBigAINet );
    				int nNode = g_pBigAINet->NearestNodeToPoint( pHint->m_vecPosition, false );
    				CAI_Node *pNode = g_pBigAINet->GetNode( nNode );
    				Assert( pNode );
    
    				bool bAccessible = false;
    
    				if ( pNode )
    				{
    					// We consider nodes "accessible" if a marine can walk from there to any other node.
    					FOR_EACH_VEC( pNode->m_Links, j )
    					{
    						if ( pNode->m_Links[j]->m_iAcceptedMoveTypes[HULL_HUMAN] & bits_CAP_MOVE_GROUND )
    						{
    							bAccessible = true;
    							break;
    						}
    					}
    				}
    
    				if ( !bAccessible )
    				{
    					hints.FastRemove( i );
    					delete pHint;
    				}
    			}
    
    			if ( hints.Count() * asw_follow_ignore_hints.GetFloat() > MarineHintManager()->m_Hints.Count() )
    			{
    				// We have less than 10% marine hints. The mapper either forgot to add hints or added a few and forgot about it. Use the nodes instead.
    				MarineHintManager()->m_Hints.AddVectorToTail( hints );
    				hints.Purge();
    
    				// Reset the indices because we may have removed some from the middle.
    				FOR_EACH_VEC( MarineHintManager()->m_Hints, i )
    				{
    					MarineHintManager()->m_Hints[i]->m_nHintIndex = i;
    				}
    			}
    			else
    			{
    				hints.PurgeAndDeleteElements();
    			}
    		}
    


  • This looks like C++, correct assumption?



  • Yes, your buttumption is correct.



  • Discourse is helpfully truncating your first quote.

    [edit] actually, it looks like it went back and oneboxed it, and you posted the actual code below it.

    That's not confusing. Thanks discourse.



  • That's a onebox. For some reason this one oneboxed but the other one didn't.



  • // We have less than 10% marine hints. The mapper either forgot to add hints or added a few and forgot about it. Use the nodes instead.

    So if I'm understanding this correctly, if they don't meet the magic 10% threshhold, you throw out the mappers work and use your node system instead?

    Maybe a stupid question, is there a reason you don't just use nodes only? (Is there custom behavior associated with the hints that can't happen with nodes?)

    What's your ultimate goal here,

    1. All marines should act (reasonably) intelligently
    2. All marines should do (something)
    3. There should be marines on the map! (And aliens!)

    Basically is this for AI or validation of units?



  • The mapper might have places where they don't want the marines to stand, and nodes don't have angles in Hammer so they all point to the right.

    The magic 10% threshold just means I add the nodes to the list of hints as long as they have at least one node reachable by humanoids walking from them.



  • I would guess that the behavior closest to what the mapper was expecting would be to ignore nodes within a certain radius of hints.


Log in to reply