solero / houdini

A Club Penguin private server written in Python 3
https://houdini.readthedocs.io/
MIT License
281 stars 54 forks source link

Update Card-Jitsu belt progression system to be accurate to the original Club Penguin #95

Closed nhaar closed 2 months ago

nhaar commented 2 months ago

Currently, the system is inacurate. If you don't believe me or want to learn about what the system was, I have written out a detailed document where I lay down all the evidence and explain what the system was, and you may read it here.

Here is what is changed:

  1. Losing is 1/5 of the winning EXP, not 1/2
  2. Mats give the same amount of EXP as random matchups
  3. Sensei gives EXP even if you lose before having a black belt
  4. EXP is not reset between levels, some is leftover and converted to a new scale when displayed on the percentages
  5. The number of wins per belt is now correct, it was slightly inacurate before

Compatibility

It is not possible to make all these changes while having a fully backward compatible database (or if it is, it would be unecessarily complicated). But, this still uses the same database schema and old databases could be fixed easily with a script that converts the numbers. If the numbers are the same from the previous system, the game will still work fine but players will report weird issues if they were not black belt already, which would eventually fix itself if they played enough games.

AllinolCP commented 2 months ago

I see that you've changed the system to use XPs instead, but is it possible to make it keep the percentage system, and then use something like an Modulus system to do Point 4, and if you're getting rid of RankSpeed you might as well as remove its definition for it. e.g. in CardJitsuMatLogic you should just remove RankSpeed and replace with pass

AllinolCP commented 2 months ago

In case if it is not possible to move to a percentage system, perhaps it would be better to make a new column instead?

nhaar commented 2 months ago

The problem with the pure percentage system currently implemented is that the truncating would make one lose information, since increments can be with decimals, for example for purple belt every loss increments by 2.857...% (1/35 to be exact). Maybe you could do some shenanigans to "convert it to EXP" from the percentage, which would be possible.

I suppose it could be removed. I was thinking maybe people might want to customize it but in that case they could readd that definition.

The EXP values fit perfectly into the current column (unless you want it to be named something like ninja_xp as opposed to ninja_progress), since the EXP are also small integers. There is also a column for the ninja rank which I'd say is almost redundant because of the EXP but it does also help keep tracking of whether you became a ninja or not.

AllinolCP commented 2 months ago

I suppose this is doable, the reason I proposed for another column is that so that existing XPs can be migrated "easily", and perhaps get_percentage_to_next_belt is probably better be in houdini/handlers/play/ninja.py instead of in the game handlers itself I think?

AllinolCP commented 2 months ago

One more thing, maybe check if the player's rank is appropriate to the amount of the progress XP maybe? So it could "autocorrect" the amount of XP to the correct amount when migrating. Other than that LGTM!

nhaar commented 2 months ago

I have implemented that autocorrection by clamping the EXP. Should make the database work with the previous version just fine after playing one game.

One thing to note about this system: I think you could technically do everything only knowing the EXP and whether or not the player is a ninja. The ninja check could be done checking their inventory for the ninja mask, and thus remove the need for a "rank" column. It would be a bit more complicated and might not be worth it just for having one less column, I am not sure, but for this PR I don't think this needs to be done

JeffTheRock commented 2 months ago

jumping in for a second, having a server sided rank is better imo as it's an extra line of defense against item hacking

having rank solely based on items makes anything that relies on that rank (such as the ninja hideout iirc) extremely vulnerable to packet spoofers

nhaar commented 2 months ago

True

The other scenario is if instead of a rank you just had a boolean for whether or not you got ninja. That would be 1 byte less than the rank column since that one uses smallint. It would be quite a lot of code to save 1 byte per penguin, so really just an observation to be made, I don`t think it's worth it at all