File
Datapacks - Oversocialized
File
Home
Share
View
I’m creating a datapack to make a better experience for my friends and I in our next Minecraft world. Check out the original post for more context!
Oversocialized is a system that can reward the player for playing with friends and also punish them for playing alone (if you want).
I’ve made datapacks before but it’s been quite a while, so Google and ChatGPT were my friends for a bit. I have my own stance on using AI which could be its own blog post, but generally I’ll only use it to learn syntax, and not rely on it for any actual logic behind what I want to happen. Once I’m comfortable enough with writing the code, I try to use it less and less beyond anything a Google search could do just as well.
Anyways, I put together a basic system for detecting how many players were online, and executing something if that number changes:
# In tick.mcfunction
scoreboard players set .onlinePlayers playerCount 0
execute as @a run scoreboard players add .onlinePlayers playerCount 1
execute unless score .onlinePlayers playerCount matches 7.. run execute unless score .onlinePlayers playerCount = .prevOnlinePlayers playerCount run (x)
scoreboard players operation .prevOnlinePlayers playerCount = .onlinePlayers playerCount
The first two lines, after setting up dummy objectives called “playerCount” and “prevOnlinePlayers” , allow me to find the exact number of online players at any given time by having every player that’s currently online add 1 to the count. (Resetting to 0 right before, which seems like an inefficient system but it’s the best Minecraft can do.) The last line immediately changes the prevOnlinePlayers back to match the current onlinePlayers , so the function can only run once. For the third line, it will run my function every time the player count changes, unless it’s above 7 and there’s already three buffs applied, in which I would like the status effects to stay consistent.
For the actual effect to apply, I tried a few different things before settling on what worked best for me. I initially wanted to use actual potion effects, but ran into a lot of issues with applying them and not being overwritten by the player’s death, or drinking milk, or if the player just wants to have a consistent potion effect applied without it being cleared every time someone left or joined.
So I scrapped the potion effect idea, and settled on attributes. There’s a lot less attributes to use, but enough to make it a fun time. For positive effects, I increased the attributes for the following:
generic.max_health, generic.knockback_resistance, generic.movement_speed, generic.attack_damage, generic.armor, generic.attack_speed, generic.luck
And for the negative effects, I decreased the attributes for max_health, movement_speed, attack_damage, and attack_speed.
To get the logic to work behind the attributes applying depending on the player count, I first added 7 and 4 invisible armor stands for the attributes respectively. I tagged each armor stand with a common tag (eg. p_attribute_all ) and a unique tag (eg. n_attribute_0 thru 6 ). This is where the player count run (x) comes in, I run a function every time the player count changes.
Inside this function, I first reset all of the players attributes to their baselines. After that, I execute a command like this:
execute if score .onlinePlayers playerCount matches 1 run tag @e[tag=n_attribute_all,limit=1,sort=random] add picked
Basically, if the playerCount matches (x), then it tags all of the relevant armor stands with a ‘picked’ . It’s limited to one, and this is the only place Minecraft lets you pick things randomly in this version, ‘sort=random’. I’m using 1.20.1 for our modpack, so I ran into a few issues with commands that were only added in 1.20.2, such as the actual /random command, or macro lines.
Since I want two negative attributes applied if there’s only one player online, it would look something like this:
execute if score .onlinePlayers playerCount matches 1 run tag @e[tag=n_attribute_all,limit=1,sort=random] add picked
execute if score .onlinePlayers playerCount matches 1 run tag @e[tag=n_attribute_all,limit=1,sort=random,tag=!picked] add picked
If the player count is 1, it tags one negative armor stand with picked. Afterwards, it tags another negative armor stand with picked again for the second attribute, but excludes ones that are already picked.
Of course, you need to need to add these before any of the commands above, so it resets what’s picked:
tag @e[tag=n_attribute_all] remove picked
tag @e[tag=p_attribute_all] remove picked
Back in my tick.mcfunction , I run a separate function per every positive and negative attribute, executing every tick if both the x_attribute_x and picked tags exist. Each of these functions points to a separate file, with the only command inside being the actual attribute change.
# example, makes you slower (base speed is 0.1)
execute as @a run attribute @s generic.movement_speed base set 0.08
This is pretty much it for the actual functionality, though it’s a bit convoluted it’s the best I could come up with in this version of the game. To display the actual title , I set a scoreboard on the picked entities to count how many there were, then ran a title actionbar command for every combination.
Yes. Every combination.
Either I am very dumb, which I hope, or that’s actually the only way to do it in this version of the game (to look the way I want it to). Here’s one of those for example.
execute if entity @e[tag=p_attribute_0,tag=picked] run execute if entity @e[tag=p_attribute_1,tag=picked] run execute if entity @e[tag=p_attribute_2,tag=picked] run execute as @a run title @s actionbar [{"text": "You feel "},{"text": "Vigorous, ", "color": "aqua"},{"text": "Sturdy ", "color": "aqua"},{"text": "and "},{"text": "Agile", "color": "aqua"}]
I had ChatGPT help me make the rest of the combinations, though even it struggled a bit. There’s supposedly some way to concatenate strings at least in 1.20.2+, but even switching over to that version I couldn’t figure it out for the life of me. But for my purposes, this brute force method works fine.
Also, I wrote most of this before actually testing it on a server, but I had to add a timer for the actionbar titles. Because I’m silly, I had the actionbar displaying the applied attribute every tick, which obviously lagged the hell out of the server. So this basic timer was added, so it only reminds you every 30 seconds:
scoreboard players add .timer timer 1
execute if score .timer timer matches 600.. run (title)
execute if score .timer timer matches 600.. run scoreboard players set .timer timer 0
I’ve attached below two different datapacks. The second is what’s described in this post in full, with negative attributes applying when there’s 1-2 players online, and positive when there’s 4-6 players.
The first is what we switched to mid-playthrough, and has the negative attributes removed. It’s honestly what I’d recommend for most, as people playing by themselves or with another friend aren’t punished, but having many people online is still rewarded.
Tags: minecraft, datapacks
Tags: minecraft, friends
Good Morning!
Try dragging the window around!
Turn on 'Autoplay: Allow Video and Audio' in your site settings for consistent sounds!