proposal: gain XP per distance traveled #4956
Labels
No Label
1. kind/balancing
1. kind/breaking
1. kind/bug
1. kind/construction
1. kind/documentation
1. kind/enhancement
1. kind/griefing
1. kind/invalid
1. kind/meme
1. kind/node limit
1. kind/other
1. kind/protocol
2. prio/controversial
2. prio/critical
2. prio/elevated
2. prio/good first issue
2. prio/interesting
2. prio/low
3. source/art
3. source/client
3. source/engine
3. source/ingame
3. source/integration
3. source/lag
3. source/license
3. source/mod upstream
3. source/unknown
3. source/website
4. step/approved
4. step/at work
4. step/blocked
4. step/discussion
4. step/help wanted
4. step/needs confirmation
4. step/partially fixed
4. step/question
4. step/ready to deploy
4. step/ready to QA test
4. step/want approval
5. result/cannot reproduce
5. result/duplicate
5. result/fixed
5. result/maybe
5. result/wontfix
ugh/petz
ugh/QA main
ugh/QA NOK
ugh/QA OK
No Milestone
No project
No Assignees
5 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: your-land/bugtracker#4956
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
this would be a small amount, like 1 XP per 200 nodes. travel when in a minecart or otherwise "attached" would not count. teleportation will not count. we can make use of the fact that
player:get_velocity()
is zero if a player is moving while attached to a horse or minecart, or if they teleport. instead of measuring the distance the player moved between steps, we can scale their horizontal speed to the time elapsed and "guess" how far they've moved via normal motion.i think someone proposed this idea before once, but i can't find an issue about it.
There still may be ways to abuse this, I can totally see people setting their homepoint at the top of a jumpshaft, then "fall down" for about 20 minutes and let some script or something enter
t + / + h + enter
. There is also the autoforwad feature, which could be used in long, straight tunnels. I assume "falling" and "autoforward" can be detected easily when the velocity (direction and speed) doesn't change much. The general idea is great and I'd like to make it happen.What exactly do we want to support? Exploration and adventures. The question is, how do we detect that? Is it "covered horizontal distance"? Is it "velocity change"? Is it "be close to newly emerged mapblocks" ? What other discriminators could be used to detect exploration in contrast to cheating?
If you gain xp by just walking thats the easiest thing to cheat with macro software
←↑→↓ repeat
In general I´m not against the idea but thats something that should be done at the start of a new server and not years later or is there any plan for players that explored alot before?
Rewarding "dumb" actions will always be exploited and automated.
But maybe visiting a city for the first time should give xp?
Anyway, I think it's better to reward exploration by giving people more reasons to explore - generated structures with loot, "random encounters"?, or, for populated areas: landmarks, quests, reward chests etc.
XP for simple movement may be abusable with some mechanics, but you can actually reward exploration.
You will divide YL into sectors (1 sector = 100 x 100 in XZ, unlimited in Y), so the world would consists of approx 600 x 600 sectors.
Then you track number of visited sectors within a time window (say 10 minutes). For somebody just moving on spot or falling in hellevator, the number will be low. For people actually exploring new different lands, it will be high (especially if you sprint with crystal boots :) ). At end of time window, you reward XP and clear the internal list. The XP rewards could be non-linear based on number of visited sectors.
Teleporting long distances won't affect this much, as you land on new sector (+1) and then you have to walk some distance to increase the count again. Teleporting back and forth will not help at all, as only unique sectors are counted.
(actual value of constants could vary)
This perhaps is not 100% abuse-proof, but is IMHO more robust than other proposals.
i like sixer's proposal, mostly. in my mind, we break the world into regions the size of a mapchunk (80 nodes, instead of 100), except they extend over the full y coordinates. give a player 1 xp every time they visit some point in a region they've never visited.
this would end up giving a maximum of 597529 points in total if a player visited all the places, which feels reasonably to me. a non-werewolf player sprinting and wearing crystal boots can traverse a mapblock in at best 1.3333 seconds. if you cover the map by going from x,z = MIN, MIN to MAX, MAX in a pattern like this:
it'll take a player over 1100 hours to visit all mapchunks, at best (there could be a more optimal path, but i doubt one that'd be much more optimal, maybe 1/2 of that value). but most importantly, if we consider ways of automating XP generation, this would be less exploitable than placing/breaking nodes automatically.
the major stopping issue here is in storing the relevant information. if we had access to a bitmap, we'd only need about 73KiB per player, and using compression could probably reduce that significantly (maybe 1.5KiB per player).
but lua doesn't provide access to a bitmap w/out installing a module. loading that module would require an insecure environment. so, the stopper for implementing such a feature is how willing alias is to allow access to an appropriate module.
You could have different internal representation based on number of blocks in it. i.e. a table when it has less than 500 blocks and bitmap once it has more.
If there is problem with lua capabilities, you can just modify the c++ code of the server and put the tracking there (and expose via lua api). Or use a different representation (array of integers? string?) to store the data
Alias is entirely against using insecure env, but has no issues with http env. Storing n:m values on a player has been a qestuion with whosit as well and will need to be solved at the latest for the quest API. Slow n:m access could be done via webservice and http env, but
A more optimal path is walking along a chunk border and switching over every now and then. That should cut the time in 2, coz one can cover 2 stripe of chunks in one go.
storing this as a regular lua table w/ integer indices and
true
/false
values would take about 16MiB per player. w/ 52 active players, that'd add up to 832 MiB, which is perhaps a bit too much.however, when storing the data, compression would give us pretty decent results - it'd only require about 284KiB per player, and only about 400 bytes if the player hasn't traveled anywhere.
What would happen if the webservice would get down/crash while server is running?
I'd be careful with separating important core stuff to other services.
With compression, you have to decompress and compress on any update.
For "full" representation, you can use int to represent 32 bits (in 32 consecutive blocks) to store visited/unvisited state of 32 blocks - 597529 points would be 18673 int values and 74692 bytes - and reading/writing visited state of arbitrary block is fast
Or you can start with table with integer indices and once that grows too large (i.e. memory size close to the full array), you switch the representation to full array as suggested above.
Or, if the tables would be cleared periodically (like once per day/week/month), we can rely on them being usually reasonably small.
This would then reward re-exploration after that certain time, but I don't think that would be a big problem
In this case it would return something different than OK 200, and MT would have to try again.
To the contrary, the less MT has to do, the better. I try to get rid of terrible Minetest-isms and have as much data in independent systems as possible. Still webservice is much slower than something internal, even though the webserver ofc is on the same machine.
With currently 70k accounts that might become 19.5 GB at worst and 27 MB at best.
That depends on how many updates we expect. Using webserver to store stuff will certainly not work in a "several reads and writes per serverstep" scenario. At best it could be cached ingame after login and then stored at logout. Even files would be faster or modstorage.
We'll at least need to know upper limits and we also need to prepare for at least one crazy person to reach those limits.
That is a good idea, but we can't simply ditch the whole data and call a new cycle. Additional to what was explored, we'd have to store when it was explored.
i've now implemented a bitarray class: https://github.com/fluxionary/minetest-futil/blob/main/collections/bitarray.lua
for the relevant data size, this now only takes 256KiB per active player, and only 77KiB when serialized without compression.
note that this is slow compared to a similar structure backed by c/c++, but this shouldn't be a problem for our use case.
also, remember that we don't need to serialize and compress and save these every time they change - only when a player logs out, and perhaps every 10 minutes or something to protect against server crashes.
you can use different protocol with less overhead than http.
what part of map is actually explored by someone at all? 100% or less? that would maybe give lower upper bound
storing time for keys and expiring them after some time needs non-trivial data structure. One that would likely be inefficient in lua. Maybe you need to select some reasonable approximation of original idea that can be calculated within reasonable time and is close enough in its effect
@sixer: sorry for shooting down all your ideas, i encourage you to continue to contribute.
it's easy to detect and discount falling in any of this. whether or not climbing should be incorporated is an open question.
minetest provides an insecure environment, and an http environment. alias currently will not use the insecure environment (tangent: i aim to convince him otherwise at some point, but not for this), so there's no chance of using a different protocol.
i don't have exact statistics for your-land, but i'm guessing more than half (maybe 80%?) of "players" don't get past initial spawn. as a rough estimate based on nothing more than feelings, i estimate at most 10% of the players who get past that point remain to explore beyond 100 mapchunks. with compression, nearly all of the serialized exploration parameters will require a negligible amount of storage.
well, with insecure env the scripts would have arbitrary read/write access everywhere (or limited only by unix file permissions of the user) and you do not want that unless you can isolate thoae pernissions to a single trusted mod and ensure it cannot be abused transitively, like via callbacks. but http env could be extended to allow a different protocol, either have general network-access env or another env for that protocol. of course, that would need some modification of c++ code
normal usage of the insecure environment is designed around not leaking it. it's not hard to use it safely. to break the trust, you'd have to do something like pass an insecure file handle to a public function. i'm not aware of any exploitable mods, and i've certainly tried to find exploits. there could be a bug somewhere that makes it unsafe to use at all, but i find that about as likely as there being a way to escape the sandbox w/out access to that environment. in particular, i don't really trust luajit. it's really close to the metal and there's apparently only person in the world who really understands its internals.
so far as i know, no one has tried to distribute a malicious minetest mod, outside of proof-of-concepts in bug reports. such a thing will almost certainly crop up at some point in the future, but it's really unlikely.