Code blog: Taint v2

... sit down, kick back and relax, and talk about anything that doesn't belong on one of the other forums.
Sarinda
Posts: 687
Joined: Wed Jan 12, 2022 3:10 pm
Location: Kalamazoo, MI

Re: Code blog: Taint v2

Post by Sarinda » Wed May 25, 2022 8:17 am

I always thought it would be neat if MCs hallucinated certain things happening. Like hearing a random mob or even PC name narrate something about combat, seeing someone walk into or out of the room, or seeing items on the floor or in your inventory. That would really mess with you.

Aureus
Posts: 968
Joined: Mon Dec 28, 2020 11:13 pm

Re: Code blog: Taint v2

Post by Aureus » Wed May 25, 2022 11:09 am

Sarinda wrote:
Wed May 25, 2022 8:17 am
I always thought it would be neat if MCs hallucinated certain things happening. Like hearing a random mob or even PC name narrate something about combat, seeing someone walk into or out of the room, or seeing items on the floor or in your inventory. That would really mess with you.
Funny you should say that… The next installment of this blog will be right up your alley, then.

Aureus
Posts: 968
Joined: Mon Dec 28, 2020 11:13 pm

Re: Code blog: Taint v2

Post by Aureus » Wed May 25, 2022 1:07 pm

Ok, I've carved out some more time to work on this. My hope is to wrap up primary development today, and there are only some related effects left. I've saved these for last because they mostly all function on a pulse. I will start with this group, which are designed to be atmospheric and sometimes confusing or alarming messages you receive at random.

Looking at the code, I decide to use the main heartbeat function of the game, because I don't want players to be able to use these messages as a fancy tic timer. This will also greatly increase the randomization, which is what we want if we are simulating actual behavior in the game. Carving out a space where taint effects trigger randomly is fairly straightforward.

I then get around to implementing the flavor messages. These are static, and therefore they are easiest to do. I also realize that these probably only make sense to players who are awake, so I add a check that the player isn't sleeping. I make a note to add in some disturbing dreams too.

Then I get into simulating some game input, such as random players walking in/out of the room, or people looking at you. Rarely, people trying to steal from you or backstabbing you. This is much more complex because it requires getting another player's name and treating it appropriately, but fortunately I've earlier written some functions that help get random players for the weave splash damage. I copy that function, and change it from checking players in the room to checking players globally.

I debate a bit whether I want to do all players or not, and I decide to only grab players the tainted MC can see on the wholist, so I don't reveal who is online on DS. I send Itesh a note about this asking his opinion, because on the one hand it would be very fun to have a trolloc or fade walk in, but on the other maybe we should not reveal players cross-race. He's no doubt asleep but can weigh in later. I decide no cross-race to start.

Then I realize that this is not very realistic if nobody is riding a horse, so I have to write special code to deal with horses. It is a little annoying and complicates the code. But we are done.

I also go back and add in the dreams.

This has all taken about 5 hours.

I compile, and it fails. I didn't declare several external functions that I used (meaning, they are located in different files, and I must explicitly "declare" them to use that code). I knew this was likely the case, and I let the compiler catch these errors so I would have a list of which functions still needed to be declared; this prevents having to go look for them myself, because they are scattered throughout the file (not a good code practice, mind you, but this is WoTMUD). The code now compiles.

I set the trigger threshold for these random messages ~10x higher than would occur normally, because I want to see them without a lot of waiting. I also set Atest to maximum taint again.

Let's start with his POV:
* HP:Hurt SP:Strong MV:Fresh >
Mad laughter rings in your ears. You realize the voice is your own.

* HP:Scratched SP:Strong MV:Fresh >
You feel the flows of saidin coursing through your body.
Sickening, rancid filth seeps into you.
You fight a wave of sickness, and saidin slips from your grasp.

* HP:Scratched SP:Strong MV:Fresh > rel
l
Connection closed by foreign host.
Hrm, we crashed.

I look at the crash logs, and see that my code to check for horses and handle them was misbehaving. Because no other (non-Imm) player was logged on, it could not find someone to hallucinate entering the room. However it still tried to check that non-existent person's horse, which of course did not exist, and so the game crashed because I was referencing data that didn't exist. I fix this up.

Now that the crash is solved, let's check in on how Atest is doing, from Aureus' perspective:
* R:1035 S:Inside HP:Healthy SP:Full MV:Fresh >
Atest mutters and stares warily into the distance.

* R:1035 S:Inside HP:Healthy SP:Bursting MV:Fresh >
Atest sways unsteadily and loses his balance.
You sense Atest connecting to the True Source.

* R:1035 S:Inside HP:Healthy SP:Bursting MV:Fresh >
Atest panics, and attempts to flee!

* R:1035 S:Inside HP:Healthy SP:Bursting MV:Fresh >
Atest mutters and stares warily into the distance.

* R:1035 S:Inside HP:Healthy SP:Bursting MV:Fresh >
Atest claws at his own skin.

* R:1035 S:Inside HP:Healthy SP:Bursting MV:Fresh >
Atest throws his head back in mad laughter.
Hrm, not doing so hot, it would seem! That's what we like to see. Let's try from his perspective.
* HP:Healthy SP:Good MV:Fresh >
You hear muffled voices coming from the north.

* HP:Healthy SP:Good MV:Fresh >
You see a black-cloaked rider on a dark horse, watching you. When you look again, he's gone.

* HP:Healthy SP:Good MV:Fresh >
A master blacksmith tried to steal something from you!

* HP:Healthy SP:Good MV:Fresh >
Spiders! Spiders are crawling under your skin.

* HP:Healthy SP:Good MV:Fresh >
*Afriend* leaves west.

* HP:Healthy SP:Good MV:Fresh >
*Afriend* has arrived from the west.

* HP:Healthy SP:Good MV:Fresh >
You have the unnerving sensation of being watched.

* HP:Healthy SP:Good MV:Fresh >
*Afriend* leaves west.

* HP:Healthy SP:Good MV:Fresh >
Mad laughter rings in your ears. You realize the voice is your own.

* HP:Healthy SP:Good MV:Fresh >
*Afriend* has arrived from above.

* HP:Healthy SP:Good MV:Fresh >
You see a black-cloaked rider on a dark horse, watching you. When you look again, he's gone.

* HP:Healthy SP:Good MV:Fresh >
*Afriend* has arrived from the south, riding a hairy aurochs.

* HP:Healthy SP:Good MV:Fresh >
You hear muffled voices coming from below.

* HP:Healthy SP:Good MV:Fresh >
You are already in touch with saidin, can't you feel it?

* HP:Healthy SP:Good MV:Fresh >
Suddenly *Afriend* places a blackened steel kris in your back!
Ouch! That Really did HURT!

* HP:Healthy SP:Good MV:Fresh >
You hear faint whispers tickling at the back of your mind.

* HP:Healthy SP:Good MV:Fresh >
Suddenly *Afriend* places a silver sai in your back!
Ouch! That Really did HURT!

* HP:Healthy SP:Good MV:Fresh >
You hear muffled voices coming from the south.

* HP:Healthy SP:Good MV:Fresh >
You have the unnerving sensation of being watched.

* HP:Healthy SP:Good MV:Fresh >
You hear faint whispers tickling at the back of your mind.

* HP:Healthy SP:Good MV:Fresh >
Bargle looks at you.

* HP:Healthy SP:Good MV:Fresh >
Aureus tried to steal something from you!

* HP:Healthy SP:Good MV:Fresh >
Spiders! Spiders are crawling under your skin.

* HP:Healthy SP:Good MV:Fresh >
*Afriend* has arrived from the south.

* HP:Healthy SP:Good MV:Fresh >
You hear muffled voices coming from below.

* HP:Healthy SP:Good MV:Fresh >
Suddenly *Afriend* places a dagger of green jade in your back!
Ouch! That Really did HURT!

* HP:Healthy SP:Good MV:Fresh >
You hear faint whispers tickling at the back of your mind.

* HP:Healthy SP:Good MV:Fresh >
Aureus looks at you.

* HP:Healthy SP:Good MV:Fresh >
You hear faint whispers tickling at the back of your mind.

* HP:Healthy SP:Good MV:Fresh >
You see a black-cloaked rider on a dark horse, watching you. When you look again, he's gone.

* HP:Healthy SP:Good MV:Fresh >
You have the unnerving sensation of being watched.
...and so on. It seems to be working well, though my first thought it will still be too spammy even slowed-down. These aren't as interesting or alarming when they happen all the time, and it also starts to make the game unplayable. So I tinker with how often it goes off (I settle on ~1 hallucination every ~10 minutes on average at max taint), and boot the test mud back up to let it run for a bit.

I also observe that the 3rd party messages, while cool, are unique and so they will immediately reveal a male channeler who is around other people. I think we want him to quietly go mad before he publicly goes insane. Preferably accusing everyone of stealing from him and/or demanding people stop looking at him. So I adjust the effects so that it doesn't give a message to witnesses at lower levels of taint (at high levels it's fine to look batty to everyone around you). I move that to the same taint threshold as the first special line on their description when a player is looking at them.

That done, I move onto some effects I want to add into "look". Hallucinations should also appear there. These are fairly straightforward to add since I already have the code for grabbing random players and simulating some game output. I just need to apply it in a different context, and the hardest part is figuring out where to add it and making sure I am formatting it properly. This takes about an hour. This code compiles the first time.

Now let's move on to testing some effects I added to "look":
* HP:Healthy SP:Trickling MV:Fresh > l
Execution Square
The streets open up into a large square meant for executions. Large steel
cages hang in corners, and very few of the stocks remain empty. Several
mean looking guards stand watch in the crowd. A large wooden platform has
been erected in the center of the square, and a bloodied block of wood
rests on top. Several strange sharp utensils can be seen on a table nearby,
and a large axe rests against the platform.
[ obvious exits: N E ]
The dismembered corpse of Afriend is lying here.
A master blacksmith is here, hard at work.
Aureus the Creator is standing here.
Bargle the Room Mobol is standing here, grinning.
...wait a minute...
* HP:Healthy SP:Trickling MV:Fresh > l
Execution Square
The streets open up into a large square meant for executions. Large steel
cages hang in corners, and very few of the stocks remain empty. Several
mean looking guards stand watch in the crowd. A large wooden platform has
been erected in the center of the square, and a bloodied block of wood
rests on top. Several strange sharp utensils can be seen on a table nearby,
and a large axe rests against the platform.
[ obvious exits: N E ]
A master blacksmith is here, hard at work.
Aureus the Creator is standing here.
Bargle the Room Mobol is standing here, grinning.
Aha, I'm going insane quite excellently.

Let's spam a bit more.
* HP:Healthy SP:Fading MV:Fresh > l
Execution Square
The streets open up into a large square meant for executions. Large steel
cages hang in corners, and very few of the stocks remain empty. Several
mean looking guards stand watch in the crowd. A large wooden platform has
been erected in the center of the square, and a bloodied block of wood
rests on top. Several strange sharp utensils can be seen on a table nearby,
and a large axe rests against the platform.
[ obvious exits: N E ]
*Afriend* is standing here.
A master blacksmith is here, hard at work.
Aureus the Creator is standing here.
Bargle the Room Mobol is standing here, grinning.

<cut out spam>

* HP:Healthy SP:Fading MV:Fresh > l
Execution Square
The streets open up into a large square meant for executions. Large steel
cages hang in corners, and very few of the stocks remain empty. Several
mean looking guards stand watch in the crowd. A large wooden platform has
been erected in the center of the square, and a bloodied block of wood
rests on top. Several strange sharp utensils can be seen on a table nearby,
and a large axe rests against the platform.
[ obvious exits: N E ]
The corpse of a well-dressed boy is lying here.
A fade emerges from the shadows as you pass by.
A master blacksmith is here, hard at work.
Aureus the Creator is standing here.
Bargle the Room Mobol is standing here, grinning.
Etc. You get the idea. I’ve added a few others as well that might make people look twice but won’t be show-stopping.

We are now done with primary development! Woohoo!

Now comes a lot of detailed testing. I did some testing along the way, but there are now some edge cases I need to review. I also made notes to take a second look at some of the earlier design choices with a fresh set of eyes. I will do all this another day, as I've spent a good 6 hours on this today.

I’ll continue to share more as I revisit and tweak.

Aloisa
Posts: 968
Joined: Tue May 30, 2017 8:24 pm

Re: Code blog: Taint v2

Post by Aloisa » Wed May 25, 2022 3:18 pm

This is extremely cool

Aureus
Posts: 968
Joined: Mon Dec 28, 2020 11:13 pm

Re: Code blog: Taint v2

Post by Aureus » Wed May 25, 2022 8:48 pm

Well, one thing I noticed in earlier testing was that Atest was getting taint messages at the login screen, but before entering his password:
By what name do you wish to be known? atest
Passphrase: You hear muffled voices coming from the west.
Someone leaves west.
You feel the flows of saidin coursing through your body.
Sickening, rancid filth seeps into you.
Nausea engulfs you, the world spins around you.
Aureus tried to steal something from you!
Someone has arrived from above.
Someone has arrived from the south.
Whoops! So I had to dig into the arcane world of descriptors and sockets and figure that bit out. Easy enough. I do notice that one of the variables doesn't behave in a way that is intuitive, and I leave a snarky code comment as a warning to Flash and others reviewing the code. Maybe Flash will find it entertaining and commiserate, or maybe he will turn me to a pile of ash. Probably the former. Probably.

Next I added in a "barreling down" pre-charge message into the hallucinations. A player suggested it and I thought it would be fun. There were also some suggestions to essentially break tic timers by messing with messages these normally trigger off, but this felt a bit mean-spirited rather than really fitting the mechanic, so I set that idea aside.

Lastly, I thought it would be amusing if the fake backstab hallucination actually adjusted your next HP prompt to make you appear to have taken damage. I tried a simple implementation of that, with the next prompt ranging from Battered to Critical at random. It did not work, because prompts are part of a different loop through players, so I cannot easily carry a variable over between them. This means I will need to make an addition to the "runtime" player data, which I decide to do because I think otherwise the damage isn't as believable and I want the mechanic to be fun. For context, there are two portions of the player file: the permanent portion, which is very difficult to adjust or make additions to (because it requires editing how all the existing player files are stored), and the "runtime" portion, which only exists for as long as you are logged in and is easy to make changes to (since updating the code requires a reboot anyway, the "runtime" data structure is recreated). This is to save space: there is no need to permanently store data like which mount you are currently riding, your current posture and mood, etc. So I add a new flag to this structure and update the code.
* HP:Healthy SP:Full MV:Fresh >
Suddenly someone places a silver sai in your back!
Ouch! That Really did HURT!

* HP:Battered SP:Full MV:Fresh >
You hear muffled voices coming from above.

* HP:Healthy SP:Full MV:Fresh >

<snip>

* HP:Healthy SP:Full MV:Fresh >
Suddenly someone places a dagger of green jade in your back!
Ouch! That Really did HURT!

* HP:Critical SP:Bursting MV:Fresh > <I hit enter>
* HP:Healthy SP:Bursting MV:Fresh >
I also adjusted the proc rate of the hallucinations to weight more heavily towards some and less so towards others. I also make certain hallucinations (such as look, steal, and charge) prioritize the names of people in your room over random people, because I think that will cause more mischief.

I also added in a few other fun ones:
Execution Square
The streets open up into a large square meant for executions. Large steel
cages hang in corners, and very few of the stocks remain empty. Several
mean looking guards stand watch in the crowd. A large wooden platform has
been erected in the center of the square, and a bloodied block of wood
rests on top. Several strange sharp utensils can be seen on a table nearby,
and a large axe rests against the platform.
[ obvious exits: N E ]
Aureus the Creator is standing here.
Bargle the Room Mobol is standing here, grinning.

* HP:Healthy SP:Bursting MV:Fresh > l west
You see something strange...
Of course, there is no hidden exit west from here. And a few others like that. They're small touches, but I think they help reinforce the idea that you can't trust your senses when you're tainted.

One that I debated a bit is concealing exits. On the one hand, this might throw you off a bit from what you are expecting. On the other, if it happens often it is very distracting (it breaks maps, etc. -- which can probably be gotten-around if you are sophisticated enough, but raises the minimum threshold for scripts for a usable map: the lack of scripting required to play WoTMUD vs some other muds is a big advantage, I think). I eventually relent and decide to do it, but I make it extraordinarily rare, which will probably make it slightly more confusing when it happens.
* HP:Healthy SP:Bursting MV:Fresh > l
Execution Square
The streets open up into a large square meant for executions. Large steel
cages hang in corners, and very few of the stocks remain empty. Several
mean looking guards stand watch in the crowd. A large wooden platform has
been erected in the center of the square, and a bloodied block of wood
rests on top. Several strange sharp utensils can be seen on a table nearby,
and a large axe rests against the platform.
[ obvious exits: E ]
Aureus the Creator is standing here.
Bargle the Room Mobol is standing here, grinning.
I think that is it for the effects of the taint for now. I still have a note to do a lot more testing, and also to re-visit the "weave swapping" effect of the taint. Because we can also swap targets, I think there is a combination of weave-swap and target-swap that will let untargeted weaves like "channel 'create food'" end up fireballing a random person in your room, but I suspect the odds of those two overlapping is quite low. I am going to take a look at weave swapping and see if I can force the random target-selection if there isn't a target. I suspect that will be messy at best.

And that's another 2 hours down the drain for now.

Aureus
Posts: 968
Joined: Mon Dec 28, 2020 11:13 pm

Re: Code blog: Taint v2

Post by Aureus » Wed May 25, 2022 9:53 pm

Various testing done, trying to make sure cross-race targeting and messages still work properly. They do. But I noticed one weird one:
* HP:Healthy SP:Fading MV:Full > l
Execution Square
The streets open up into a large square meant for executions. Large steel
cages hang in corners, and very few of the stocks remain empty. Several
mean looking guards stand watch in the crowd. A large wooden platform has
been erected in the center of the square, and a bloodied block of wood
rests on top. Several strange sharp utensils can be seen on a table nearby,
and a large axe rests against the platform.
[ obvious exits: N E ]
*Afriend* is standing here.
Aureus the Creator is standing here.
Bargle the Room Mobol is standing here, grinning.

* HP:Healthy SP:Fading MV:Full > k dark
You hit yourself...OUCH!.
This is when Afriend is a dreadlord and Atest has max taint. Atest is hitting "k dark" but this treats EVERYONE as "dark" and he is the first person in the room so he is ...hitting himself. So I add in a check to exclude yourself as a target to fix that:
Execution Square
The streets open up into a large square meant for executions. Large steel
cages hang in corners, and very few of the stocks remain empty. Several
mean looking guards stand watch in the crowd. A large wooden platform has
been erected in the center of the square, and a bloodied block of wood
rests on top. Several strange sharp utensils can be seen on a table nearby,
and a large axe rests against the platform.
[ obvious exits: N E ]
*Afriend* is standing here.
Aureus the Creator (Wizinvis 1) is standing here.
Bargle the Room Mobol is standing here, grinning.

* HP:Healthy SP:Bursting MV:Fresh > k dark
Wimpy reset to: 140 hit points.
You hit *Afriend*'s body.
*Afriend* panics, and attempts to flee!

* HP:Healthy SP:Bursting MV:Fresh - Afriend: Scratched >

Sarinda
Posts: 687
Joined: Wed Jan 12, 2022 3:10 pm
Location: Kalamazoo, MI

Re: Code blog: Taint v2

Post by Sarinda » Wed May 25, 2022 10:01 pm

This is all gloriously evil and I appreciate you both doing it, and also showing us a glimpse of what taint will look like.

Maybe this is FOFY post-changes, but with the way you are envisioning taint now, will MCs be able to weave all the way through their regular SP pool without needing to worry about weaving at Strong vs. Fading, etc. and the impact of that on the taint? I like the idea of MCs who want to slow down taint progression to simply be required to weave sparingly, rather than weaving at Bursting-Strong SPs only, while on the flip side also allowing someone to freely use their whole SP pool if they want to without it giving exponentially higher taint.

I guess I just want highly tainted MCs to be strictly playable, just with a very different mindset and more realistic approach than how it currently exists.

Thanks for all of your hard work on this system!

Aureus
Posts: 968
Joined: Mon Dec 28, 2020 11:13 pm

Re: Code blog: Taint v2

Post by Aureus » Wed May 25, 2022 10:13 pm

SP level has no effect on taint gain in the new system. Every time you touch or channel Saidin, you're exposed to the taint. As you probably saw from the debug messages in the earlier logs, this manifests as a % chance to gain 1 point of taint, with the % scaling up based on the number of SP channeled (with seizing saidin considered using 1 SP, even though it doesn't use any). This is much more bookish IMO -- MCs inevitably went insane in the books, there was no "just channeling a little" to get around it or to mitigate it.

This means there is no reason for an MC to try to stay at any particular level of SPs. Which is nice for them when e.g., fighting any Red Ajah hunters. And should make those battles more fun for everyone. Part of my goal is I want it to be dangerous for Aes Sedai/Red Ajah to go MC hunting, as opposed to today where the MC is probably about to narrate horse and fail a bunch of commands, which makes them an easy target. Similarly in the SP-management scheme, the MC only has a partial SP pool to play with, whereas his hunters have their full pools. Not very fun.

Sarinda
Posts: 687
Joined: Wed Jan 12, 2022 3:10 pm
Location: Kalamazoo, MI

Re: Code blog: Taint v2

Post by Sarinda » Wed May 25, 2022 10:22 pm

That is fantastic, and that is exactly my (admittedly selfish) reason for asking.

The changes you've coded and proposed seem like they will make the high-taint MC play experience to be competitive in PK but as a trippy experience that really will keep them on their toes. I also like the possibility of doing "splash damage" so they're more likely to harm innocent mobs and can also essentially increase their damage output against multiple targets, especially when using an AoE weave like Sonic Boom or Earthquake.

Neat stuff!

Aureus
Posts: 968
Joined: Mon Dec 28, 2020 11:13 pm

Re: Code blog: Taint v2

Post by Aureus » Wed May 25, 2022 10:36 pm

As I was thinking through edge cases, I realized that a "peaceful" male channeler might not channel around others, which would avoid the danger of being around a male channeler. They might foreswear channeling and take up, er, wisdom lore. Or swimming. This, of course, isn't what we want. So I add a new random taint effect, but only at very high levels of taint (so we're talking true madmen):
* HP:Healthy SP:Bursting MV:Fresh >
You feel the flows of saidin coursing through your body.
Sickening, rancid filth seeps into you.
Bile comes up and you empty your stomach, retching violently.

* HP:Healthy SP:Bursting MV:Fresh >
You hear faint whispers tickling at the back of your mind.

* HP:Healthy SP:Bursting MV:Fresh >
*Afriend* looks at you.

* HP:Healthy SP:Bursting MV:Fresh >
You see a black-cloaked rider on a dark horse, watching you. When you look again, he's gone.

* HP:Healthy SP:Bursting MV:Fresh >
You hear muffled voices coming from the east.

* HP:Healthy SP:Bursting MV:Fresh >
You sense someone nearby is channeling saidin.
Absently, the thought occurs to you that the flows are your own.
Ok.
*CRACK* A loud thunderclap resonates through the entire area..!
*Afriend*'s flesh rattles to the bone from the powerful thunderclap.
Bargle's flesh rattles to the bone from the powerful thunderclap.

* HP:Healthy SP:Bursting MV:Fresh - Afriend: Scratched >


<snip>


* HP:Healthy SP:Bursting MV:Fresh >
You feel the flows of saidin coursing through your body.
Along with saidin comes an oily foulness.

* HP:Healthy SP:None MV:Fresh >
You have the unnerving sensation of being watched.

* HP:Healthy SP:None MV:Fresh >
Aureus tried to steal something from you!

* HP:Healthy SP:None MV:Fresh >
Aureus looks at you.

* HP:Healthy SP:Full MV:Fresh >
You sense someone nearby is channeling saidin.
Absently, the thought occurs to you that the flows are your own.
Ok.
The earth trembles and shivers beneath your feet..!
Aureus vibrates and is knocked about.
Bargle vibrates and is knocked about.
Now we can be certain that very tainted male channelers are always (if uncommonly) a threat to everyone around them.

Post Reply