Jump to content

Recommended Posts

Posted (edited)

I can confirm that there are other powers that do not report hit rolls in the log unless they are misses. Sonic cage is an example. The prevalence of these powers explains why these data have extremely sharp spikes exactly at hit rolls above 95. The fact that the slope trends upwards gradually below this point can be easily explained by the same phenomenon occurring when final to hit chance is less than 95%.

 

Edit: I imagine this hypothesis could be tested better by not truncating the decimals, since then what I would expect is a general upward trend from 5 to 95, with a sharp spike above 95 that stays approximately flat up to 99.99. Obviously you'd want a very large sample size to draw a good conclusion from this.

Edited by Elmyder
Posted (edited)
55 minutes ago, Burk said:

Even in the clamp cases, fToHit is just being set to 0.05 or 0.95. The value of fDefenseRel is not relevant to the final value of fToHit there. The CLAMP, as I suspected and you seem to verify, is only modifying the value of fDefenseRel using the value of fToHit. I'm wondering why they are bothering at that point to change a value that is not returned by the function. Of course it could be leftover code from some change they made and was actually useful previously.

Reading into this further, when character_ApplyPower calls CalcToHit, it does so with a reference/pointer on the *out_fDefense variable, but then only seems to use that variable in particular to determine the "missed by" chance, while it uses the return from CalcToHit for determining if the attack hit or not.

 

So it may very well just be the combat log showing higher numbers globally than it should be due to defense being multiplied in it.  Unless I'm reading this backwards the clamp case might only explain the ascending slope in your enemies' hit roll graph, regardless if it's a log problem or not, since I know you're often softcapped on defense.

Edited by Veracor

@Veracor - Veracor, Bio/TW Tanker on Everlasting.  Retired raid leader.

Posted (edited)

Elmyder mentioned not truncating the results. That increased the number of bins by two orders of magnitude, so RIP my Office, but here are the charts. The top one is from 0.00 to 94.99, the middle one is from 95.00 to 99.99, and the last is everything.

 

Untitled_spreadsheet_-_Google_Sheets_-_Mozilla_Fir_2020-05-12_07-49-31.thumb.png.bc6306c7db37b0022dce626323a29099.png

 

Untitled_spreadsheet_-_Google_Sheets_-_Mozilla_Fir_2020-05-12_07-47-07.thumb.png.a983385da1967e5edb5923d641c5a883.png

 

Untitled_spreadsheet_-_Google_Sheets_-_Mozilla_Fir_2020-05-12_07-45-59.thumb.png.124785b239eaf66848786a6a55a98ad2.png

 

Speaking of power rolls not showing, some powers output no logs at all. One that comes to mind is Arachnos psychic nukes.

Edited by ROBOKiTTY
  • Thanks 1

KiTTY / @ROBOKiTTY

Everlasting / Former Virtue mascot

 

How to Hamidon Raid Virtue-Style, Addendum for HC edition

Badge checklist popmenu

Posted (edited)

Thank you very much for doing this, Kitty!

 

This definitely agrees with what I would expect from a log that only outputs misses on some powers: a gradual increase from 0-95 with positive second derivative, a sudden spike at 95, and then flat from 95-100. Kitty's results from 95-100 look pretty uniform for the sample size, which indicates that both the rng and the code computing hits rolls from it are accurate. (Namely, if there was actually a bias towards larger numbers by either the rng or the code, then this should be present in the 95-100 range as well.)

Edited by Elmyder
Posted

I was curious about Burk's graph of enemy hit rolls, so I gathered some data on my own logs. My prediction is that the upward trend is the result of the same phenomenon of the log not reporting hits on certain powers. Since enemy chance to hit is much more evenly varied than players (who are usually at 95%), I figured this explains the steady upward trend. With that said, here are some results of my own.

 

Enemy hit rolls overall:

unknown.png

 

This resembles Burk's data, with a slight upward trend.

 

Enemy hit rolls when the enemy has a 5% chance to hit me:

unknown.png

 

The sample size here is relatively small so the the data is kind of jagged, but it is clearly flatter than the first. This is what I would expect if this is nothing more than a case of the log not fully reporting.

 

My data on overall hit rolls, player hit rolls, and player hit rolls for specific powers that do log fully perfectly mirror the data shared by other people.

 

Posted

I just had another interesting idea. I ran the same log search on my farming account. Literally all I do on this account is farm, and the vast majority of the time, it's afk farming. This means a couple things: 1. My final to hit chance is NOT 95% most of the time. Not unless I tab in and eat all the reds/yellows in my tray. 2. A great deal of these hit rolls are coming from auras, which only log the hit roll on misses. Now check the results. Basically what you'd expect, an upward trend that sharply curves up around 80 (where my hit chance is at most of the time), and then has the characteristic spike at 95, after which it appears to flatline.

 

image.png.589527217347f9519c634ab3bda34519.png

Posted

Can anyone explain what happened in this case? I was in a low-level mission using Sands of Mu (prestige power), where part of the attack missed, but then part of the attack was recorded as a hit. My previous attack had been a Hit (with a 95% chance to Hit).

 

Spoiler

You activated the Sands of Mu power.
Sands of Mu missed!

MISSED Mook Hitman!! Your Sands of Mu power had a 95.00% chance to hit, you rolled a 99.85.
HIT Mook! Your Sands of Mu power was forced to hit by streakbreaker.
You hit Mook with your Sands of Mu for 5.59 points of Smashing damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Negative Energy damage over time.
Assassin's Impaler is recharged.
You hit Mook with your Sands of Mu for 5.59 points of Smashing damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Negative Energy damage over time.

Mook MISSES! Revolver power had a 24.73% chance to hit, but rolled a 61.07.
Mook Hitman MISSES! Automatic Pistol power had a 40.09% chance to hit, but rolled a 98.32.

You hit Mook with your Sands of Mu for 5.59 points of Smashing damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Negative Energy damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Smashing damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Negative Energy damage over time.

 

Posted
1 hour ago, tidge said:

Can anyone explain what happened in this case? I was in a low-level mission using Sands of Mu (prestige power), where part of the attack missed, but then part of the attack was recorded as a hit. My previous attack had been a Hit (with a 95% chance to Hit).

 

  Hide contents

You activated the Sands of Mu power.
Sands of Mu missed!

MISSED Mook Hitman!! Your Sands of Mu power had a 95.00% chance to hit, you rolled a 99.85.
HIT Mook! Your Sands of Mu power was forced to hit by streakbreaker.
You hit Mook with your Sands of Mu for 5.59 points of Smashing damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Negative Energy damage over time.
Assassin's Impaler is recharged.
You hit Mook with your Sands of Mu for 5.59 points of Smashing damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Negative Energy damage over time.

Mook MISSES! Revolver power had a 24.73% chance to hit, but rolled a 61.07.
Mook Hitman MISSES! Automatic Pistol power had a 40.09% chance to hit, but rolled a 98.32.

You hit Mook with your Sands of Mu for 5.59 points of Smashing damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Negative Energy damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Smashing damage over time.
You hit Mook with your Sands of Mu for 5.59 points of Negative Energy damage over time.

 

You aimed Sands at two guys.  The first one you missed.  Because 95% chance to hit, the streakbreaker forced a hit on the second guy.

  • Thanks 1
Posted (edited)

Ah, that is very possible (and what the log shows "Mook" and "Mook Hitman"). During the actual attack I only had one target (per my view) but I must have run past a position (with the power clicked) where two were able to be targeted simultaneously. This was during a low-level mission with very few targets (and very few attacks).

Edited by tidge
  • 1 month later
Posted (edited)

Revisiting this thread as a request to help me understand something from the logs. I was running in the Tunnel of the Trolls for some defeat badges.

 

This is from a Spines/Bio Stalker with the following toggles running (no damage aura that I am aware of)

 

Spoiler

Hide

Boundless Energy (auto)

Adaptation (Offensive)

Hardened Carapace

Environmental Modification

Weave

Tough

Sprint

Ninja Run

 

The curious portion of the logs:
 

Spoiler

(Spine Burst (1) is activated here)

HIT Trollkin Gunner! Your Spine Burst power had a 95.00% chance to hit, you rolled a 74.96.
HIT Gardvord! Your Spine Burst power had a 95.00% chance to hit, you rolled a 69.62.
HIT Trollkin Buckshot! Your Spine Burst power was forced to hit by streakbreaker.
HIT Ogre! Your Spine Burst power had a 95.00% chance to hit, you rolled a 46.45.
HIT Trollkin Buckshot! Your Spine Burst power had a 95.00% chance to hit, you rolled a 82.47.
HIT Trollkin Buckshot! Your Spine Burst power had a 95.00% chance to hit, you rolled a 92.05.
HIT Caliban! Your Spine Burst power had a 95.00% chance to hit, you rolled a 8.51.
Spine Burst missed!
MISSED Trollkin Buckshot!! Your Spine Burst power had a 95.00 % chance to hit, you rolled a 95.57.

HIT Gardvord! Your Spine Burst power had a 95.00% chance to hit, you rolled a 32.17.

You hit Trollkin Buckshot with your Spine Burst for 439.59 points of Lethal damage.
You Immobilize Trollkin Buckshot with your Spine Burst.
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You hit Trollkin Buckshot with your Spine Burst for 439.59 points of Lethal damage.
You Immobilize Trollkin Buckshot with your Spine Burst.
You hit Trollkin Buckshot with your Spine Burst for 439.59 points of Lethal damage.
You Immobilize Trollkin Buckshot with your Spine Burst.
You hit Trollkin Buckshot with your Armageddon: Chance for Fire Damage for 503.31 points of Fire damage.
You hit Gardvord with your Spine Burst for 439.59 points of Lethal damage.
You Immobilize Gardvord with your Spine Burst.
You hit Gardvord with your Spine Burst for 439.59 points of Lethal damage.
You Immobilize Gardvord with your Spine Burst.
You hit Trollkin Gunner with your Spine Burst for 439.59 points of Lethal damage.
You Immobilize Trollkin Gunner with your Spine Burst.
You hit Ogre with your Spine Burst for 439.59 points of Lethal damage.
You Immobilize Ogre with your Spine Burst.

Trollkin Buckshot MISSES! Shotgun power had a 5.00% chance to hit, but rolled a 92.27.
(Spine Burst (2) is activated here)

HIT Caliban! Your Spine Burst power had a 95.00% chance to hit, you rolled a 90.43.
HIT Ogre! Your Spine Burst power had a 95.00% chance to hit, you rolled a 28.68.
HIT Ogre! Your Spine Burst power had a 95.00% chance to hit, you rolled a 76.62.
HIT Caliban! Your Spine Burst power had a 95.00% chance to hit, you rolled a 58.72.

You hit Ogre with your Spine Burst for 566.2 points of Lethal damage.
You Immobilize Ogre with your Spine Burst.
You hit Ogre with your Offensive Adaptation for 57.84 points of Toxic damage.
You hit Caliban with your Spine Burst for 566.2 points of Lethal damage.
You Immobilize Caliban with your Spine Burst.
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You reduce your targets damage resistance temporarily
You hit Caliban with your Armageddon: Chance for Fire Damage for 524.73 points of Fire damage.
You hit Caliban with your Offensive Adaptation for 57.84 points of Toxic damage.
You hit Caliban with your Spine Burst for 566.2 points of Lethal damage.
You Immobilize Caliban with your Spine Burst.
You hit Caliban with your Armageddon: Chance for Fire Damage for 524.73 points of Fire damage.
You hit Caliban with your Offensive Adaptation for 57.84 points of Toxic damage.

(Spine Burst (3) is activated here)

HIT Ogre! Your Spine Burst power was forced to hit by streakbreaker.

HIT Ogre! Your Spine Burst power was forced to hit by streakbreaker.
Spine Burst missed!
MISSED Ogre!! Your Spine Burst power had a 95.00% chance to hit, you rolled a 97.71.

You hit Ogre with your Spine Burst for 533.68 points of Lethal damage.
You Immobilize Ogre with your Spine Burst.
You hit Ogre with your Spine Burst for 533.68 points of Lethal damage [CRITICAL].
You hit Ogre with your Armageddon: Chance for Fire Damage for 503.31 points of Fire damage.
You hit Ogre with your Offensive Adaptation for 55.48 points of Toxic damage.
You hit Ogre with your Spine Burst for 533.68 points of Lethal damage.
You Immobilize Ogre with your Spine Burst.
You hit Ogre with your Armageddon: Chance for Fire Damage for 503.31 points of Fire damage.

You hit Ogre with your Offensive Adaptation for 55.48 points of Toxic damage.
HIT ______! Your Hasten power is autohit.
_____ HITS you! Hasten power was autohit.

(perhaps unironically, the followup attack on the missed Ogre was ALSO a miss!)

Assassin's Impaler missed!
MISSED Ogre!! Your Assassin's Impaler power had a 95.00% chance to hit, you rolled a 96.75.

(but then the next attack was forced to hit, as expected)

HIT Ogre! Your Moonbeam power was forced to hit by streakbreaker.
You hit Ogre with your Moonbeam for 1444.64 points of Negative Energy damage.
You hit Ogre with your Moonbeam for 1444.64 points of Negative Energy damage [CRITICAL].
You hit Ogre with your Sting of the Manticore: Chance for Toxic Damage for 337.22 points of Toxic damage.
You hit Ogre with your Offensive Adaptation for 232.61 points of Toxic damage.

 

The logs show three consecutive attackes: Spine Burst (1),  Spine Burst (2) and Spine Burst (3) each with 95% final chance to hit.

 

Spine Burst (1) had 9 targets: it hit 8 (one via strakebreaker) and missed 1.

Spine Burst (2) had 4 targets: it hit all 4 (none via streakbreaker)

Spine Burst (3) had 3 targets: It missed 1 target and hit BOTH the other two via streakbreaker!

 

The quote from paragonwiki on the mechanics/pitfalls of streakbreaker:

 

Spoiler

This is a direct quote from Cryptic developer Weirdbeard explaining the details. (Just to be clear, when he says "to-hit" here, he means the final chance of hitting.)

Final to-hit : misses allowed

>.9 : 1
.8-.9 : 2
.6-.8 : 3
.4-.6 : 4
.3-.4 : 6
.2-.3 : 8
0 -.2 : 100
Auto-hit powers are not included in the system.
Critters get the benefits of the system as well.
The system does not track each power individually; instead it tracks every miss you make in a row, regardless of power (or target). Otherwise you could have nine different powers, each with a 0.95 to-hit, and if you executed them all in a row you could miss each attack (note a caveat at the bottom of the post regarding this).
[AoE] attacks are considered distinct sequential attacks on indivudual targets for the purpose of the system (so if you [AoE'ed] two targets and had 0.95 to-hit for both, you be guaranteed to hit one of them).

To determine the to-hit used in the table above, you take either the current to-hit, or the worst to-hit in your current miss series, whichever is lower.

Here is a list of things to keep in mind about the streakbreaker, how it works, and pitfalls when trying to apply it:

  1. Zoning resets the streakbreaker.
  2. The streakbreaker ignores autohitting powers entirely. They do not count as either hits or misses.
  3. The number of misses the system tolerates before forcing the next attack to hit depends on the lowest chance of hitting in your miss streak so far, or the attack you're about to make, whichever is worse. As soon as you make a single low-accuracy attack, you shift to a worse category, and the streakbreaker will let you miss more before it helps you.
  4. The streakbreaker only breaks miss streaks by forcing hits. It does not break hit streaks by forcing misses. It can only help you hit.
  5. The streakbreaker affects all entities that are allowed to attack. This includes players and enemies. Also, each of your pets and pseudopet powers has its own streakbreaker record, tracked separately from attacks that come directly from you.
  6. The streakbreaker tracks attackers, not powers.
  7. AoEs roll one attack check per target, starting from the closest target to the center of the AoE (or the origin for cones) and working outward.
  8. Damage auras make attack rolls, and are often overlooked when observing streakbreaker behavior.
  9. Unslotted Brawl and the minor ranged Origin Powers are some of the biggest killers of the streakbreaker, since they can have a very low chance to hit a target without accuracy slotting. See rule #3 above.

 

My questions:

 

1) Why wasn't there a streakbreaker result as part of Spine Burst (2)? Is there a pseudopet in play which I'm not aware of? The %chance to Recharge Build up is slotted (in another attack power). Is Adaptation using a pseudopet?

 

2) Why are there two consecutive Streakbreakers as part of Spine Burst (3)? Even if there is a pseudopet that is involved, it strikes me as unlikely that there would be enough time to trigger 'enough' misses between the each ToHit check of the AoE targets, such that a second streakbreaker would be used on the second target of the AoE.

 

 

Edited by tidge
Posted
5 hours ago, tidge said:

My questions:

 

1) Why wasn't there a streakbreaker result as part of Spine Burst (2)? Is there a pseudopet in play which I'm not aware of? The %chance to Recharge Build up is slotted (in another attack power). Is Adaptation using a pseudopet?

 

2) Why are there two consecutive Streakbreakers as part of Spine Burst (3)? Even if there is a pseudopet that is involved, it strikes me as unlikely that there would be enough time to trigger 'enough' misses between the each ToHit check of the AoE targets, such that a second streakbreaker would be used on the second target of the AoE.

 

 

For the first question, you didn't miss, so streak breaker simply didn't trigger. Had you missed it [probably] would have. AFAIK streak breaker still does a regular to-hit check, then if it would have failed it does a check against streak breaker. 

For the second one, hard for me to say for sure, based on the content you said you were running I'm going to assume you don't have Genetic Corruption, which might be able to cause it. Also curious if Genetic Corruption shows it's hit rolls in the logs at all, since it does no damage, and if to-hit checks that don't apply damage count towards streak-breaker.

Posted
2 hours ago, Eclipse. said:

For the first question, you didn't miss, so streak breaker simply didn't trigger. Had you missed it [probably] would have. AFAIK streak breaker still does a regular to-hit check, then if it would have failed it does a check against streak breaker. 

For the second one, hard for me to say for sure, based on the content you said you were running I'm going to assume you don't have Genetic Corruption, which might be able to cause it. Also curious if Genetic Corruption shows it's hit rolls in the logs at all, since it does no damage, and if to-hit checks that don't apply damage count towards streak-breaker.

 

On the first point, are you saying that for cases where "Final ToHit > 0.9" the system is keep track of rolls, and waiting for the next "miss" to trigger? My interpretation of Streakbreaker is that for such cases, that the next attack roll will always be forced to hit. The end of the log I posted has always been my experiences with single-target attacks. that is, after a miss from a 95% chance attack, the next attack (always using a 95% attack again) always occurs with streakbreaker (with no hit roll shown).

 

The character build does not include Genetic Corruption.

Posted (edited)
1 hour ago, tidge said:

 

On the first point, are you saying that for cases where "Final ToHit > 0.9" the system is keep track of rolls, and waiting for the next "miss" to trigger?

Correct. that is my understanding of it, at least.

Excuse the pseudo code, I'm @ work and don't have the source on this system to be able to confirm. My understanding of how it works is as folllows:

Spoiler

If rolled_hit > chance_hit
    streak_count +=1
    If streak_count >= 10
        return hit = true

        log( "STREAK BREAKER! ____ ")
    else

        return hit = false

        log(" You MISSED! _______")
    end
    
else
  streak_count = 0
  return hit = true
  log("You HIT! ______")
end

 

So it wouldn't log the missed check until checking streak breaker (and logging that accordingly if streak breaker forces a hit).


Edit:

Looks like I was mistaken.

"Streak Breaker" Code:
 

Spoiler

/**********************************************************************func*
 * ForceHitDueToMisses
 *
 */
static bool ForceHitDueToMisses(Character *pSrc, float fToHit)
{
	int iDecile;
	int aHitForcedCount[] =
		// 0,  10,  20,  30, 40, 50, 60, 70, 80, 90
		{ 100, 100,  8,   6,  4,  4,  3,  3,  2,  1 };

	if(fToHit < pSrc->fSequentialMinToHit
		|| pSrc->fSequentialMinToHit < 0.05f)
	{
		pSrc->fSequentialMinToHit = fToHit;
	}

	iDecile = (int)(pSrc->fSequentialMinToHit*10.0f);
	if(iDecile<0) iDecile=0;
	if(iDecile>9) iDecile=9;

	return (aHitForcedCount[iDecile]<=pSrc->iSequentialMisses);
}

This is around ./MapServer/entity/character_combat.c:1299

Appears to  indeed  be called before the toHit roll:
 

Spoiler

ctx.bAlwaysHit = character_PowerAlwaysHits(pSrc, pTarget, ppow);

				if(!ctx.bAlwaysHit)
					ctx.bForceHit = ForceHitDueToMisses(pSrc, ctx.mf.fToHit);

				// This is done here (instead of in GetTargetEntities) since the
				// target character is in the target zone, they just aren't hit.
				bAllowedToHit = ppow->ppowBase->bShootThroughUntouchable
								|| ((pTarget->attrCur.fUntouchable<=0.0f
									 || pSrc==pTarget)
									&& character_TargetIsInCombatPhase(pSrc, pTarget));

				fRandRoll = ctx.mf.fToHitRoll = (float)rand()/(float)RAND_MAX;

				if(ctx.bAlwaysHit || ctx.bForceHit || ctx.mf.fToHitRoll < ctx.mf.fToHit)
				{
					// It's a hit

This is around ./MapServer/entity/character_combat.c:3157


BUT both are checked at the same time -- so a to-hit roll is still done, but not logged.


Also to the original post, there is this lovely comment that confirms what many have already noticed about only misses being logged for some powers:

       
Quote

 

        // Ugh, re-use the hacky workaround for this being called on a per-attribmod basis for hits.
        // Seems to be needed for now at least, since by design hit messages aren't sent for powers
        // that have no mods with combat spam (but misses are, so this might should be changed
        // anyway).

 

 

 

Edited by Eclipse.
include end for if.
  • Like 1
Posted

Thanks for checking, as there was no way to reconcile every other log report that shows the streakbreaker not relying on the tohit roll (for single target attacks).

 

It occurs to me that some of the peculiarity in my log results could be due to an asynchronous relationship between logging and checking streakbreaker, but I don't know why that would be the case.

 

Do we know if there were any compromises made (for speed) to be able to resolve AoE attacks?

 

 

Posted
9 hours ago, tidge said:

Do we know if there were any compromises made (for speed) to be able to resolve AoE attacks?

 

Disclaimer: at a VERY quick glance

It does not appear that they did. Appears that Single Target, AoE, and Chain attacks use the exact same code for their to-hit checks (which makes sense), which is inside a loop with the constraint of "max targets", so that's set to 1 for a ST attack, and >1 for anything else:


 

Spoiler

            //Line 3046 in ./MapServer/entity/character_combat.c
		    // Loop over every target and apply the power
			//

			PERFINFO_AUTO_START(“ForEachTarget”, 1);
			pref=charlist_GetFirst(&listTargets, &iter);
			while(pref!=NULL && (iMaxTargetsHit == 0 || iNumHit < iMaxTargetsHit) &&
				(!bIsChain || iTotalHit < ppow->ppowBase->iMaxTargetsHit))
            {

Which is nested inside 2 additional loops, starting at line 2963:
 


	// Handle chain jumps. Loop only runs once for non-chain effect areas
	for (iChainJump = 1; iChainJump <= (bIsChain ? ppow->ppowBase->iMaxTargetsHit : 1)
		&& (!bIsChain || iTotalHit < ppow->ppowBase->iMaxTargetsHit); iChainJump++)
	{
		bAnyForkHit = false;

		// Now loop through each fork, but do it backwards. That's because we might add
		// more for next time, or remove the current fork.
		for (iChainFork = (bIsChain ? eaSize(&eaChainForks) : 1) - 1; iChainFork >= 0; iChainFork--)
		{


Some of the comments in this code are great peeks into the minds of the devs at the time feeling like they were dealing with spaghetti.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...