Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding bitwise operators functions #442

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

skenkerstel
Copy link

Bitwise Operator Functions

What I did

I added the functions for bitwise operators. You can see the list of the functions below.

  • Bitwise AND ( & operator): getBitwiseAND
  • Bitwise OR ( | operator): getBitwiseOR
  • Bitwise XOR ( ^ operator): getBitwiseXOR
  • Bitwise Left Shift ( << operator): getBitwiseLeftShift
  • Bitwise Right Shift ( >> operator): getBitwiseRightShift
  • Bitwise Unsigned Right Shift ( >>> operator): getBitwiseUnsignedRightShift
  • Bitwise Inversion ( ~ operator): getBitwiseInversion

Why it is worth adding

As some of you might know, a competent civil programmer (Goblin01) issued a similar pull request about 2 years ago. At that time, he added those operators to the "calculate" function, followed by +, -, *, /, and %. Unfortunately, it was rejected due to a lack of "possible use cases" and "hassle for users". In this essay, I will show its benefits, use cases, and why it does not perplex beginners.

Benefits

I will borrow some of Goblin's words because they were excellent.

  • It's faster than the arithmetic approach (for example (x / 256) % 256) is way slower than (x >> 8) & 255)
    Add operators take more time because of the carries, while bitwise ones can be operated in parallel, which will take less time to execute. Even though taro engine has seen great improvement in its speed, a large-scale game will require heavy calculations, which may cause lags. In this case, it'll be effective to implement these ones.

  • Less memory usage
    Boolean values internally take up a whole byte instead of 1 bit, to keep the 8-bit stride consistent. In other words, to store 8 boolean values, you have to use 8 bytes = 64 bits. And for that, using a bitfield will allow you to store 64 boolean variables in 64 bits using flags. So, instead of wasting 20+ bytes on each unit to store 20+ boolean variables on different stuff, it's more efficient to use 8 bytes and have 64 boolean variables using a bitfield.

  • No more than 61 lines of code
    It's a very simple and concise implementation, making use of the fundamental features of Javascript.

Use cases (Part 1)

Imagine you're making a multiplayer RPG.
In this game, You would like to manage 20 flags of whether you completed a certain quest.
In this case, you will have 2 traditional ways to manage the flags.

  1. Use strings
    Store a sequence of "0"s and "1"s in a string, and read/write them by using "substring of" function.

  2. Use JSON array
    Make a JSON array made up of "0"s and "1"s, and read/write them by using the functions for the array.

Yes, indeed you can do without them. But the problem is the speed.
It's both bothersome and computationally intensive to use "substring of" functions.
In the same way, making a JSON structure just for storing 0s and 1s will be a waste of memory and calculation time.
If bitwise operators are implemented, you can finish operations faster.

  • Implementation
# Initialize
set (questFlag of (Player 1) as 0)

# Mark Quest n as "cleared"
set (questFlag of (Player 1) as ((questFlag of (Player 1) | (1 << n)) )

# Check if you beat Quest n
if ( (questFlag of (Player 1)) & (1 << n) == (1 << n)):

Moreover, when you want to see which quests both 2 players have achieved, you can just do "AND" functions to get the result. If a dungeon requires both members to have cleared Quest 0, 1, 2, and 4, you can just do this to check eligibility to enter it.

if (((questFlag of (Player1)) & ((questFlag of (Player2)) & 15) == 15):

If the requirement is "EITHER of them", you can just change it to this:

if (((questFlag of (Player1)) | ((questFlag of (Player2)) & 15) == 15):

You can change the conditions very easily, with just one change!

Use cases (Part 2)

I wanted to implement hash algorithms on taro engine to make a tamper-resistant system where players can export their game data in 2020, but I gave up the idea of hashing like SHA-256 before it lacked bitwise operations (instead I used simple substitutions). These operators would have made me that system. It was a serious problem to be solved with the operator at that time...

Why Functions? (No hassle for beginners!)

Indeed, it will be bewildering to list them as well as + or - in the "calculate" function. To add them to "calculate" might not be the best option in the scope of moddio, where the main target is beginners. However, it will be resolved by adding them as functions, not operators in the calculate function. Although there are already difficult functions such as log(base 10), exponent, degree-radian conversions, and so on, there are no complaints from them about the existence of these functions. That means beginners will not be confused with bitwise operators either, so there will be no hassle for them while benefiting advanced users who have knowledge of the operators.

@m0dE
Copy link
Contributor

m0dE commented Jun 19, 2023

I love this PR, but it's currently not the priority for us to implement this in our engine. Also, it requires editor changes to accommodate this but the editor team is quite busy. Happy to revisit this again in the coming months.

@sloont sloont added the editor change Proposed changes or additions require game editor dev time label Jun 20, 2023
@skenkerstel
Copy link
Author

Thank you, I can't wait to see these commands in modd.io!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
editor change Proposed changes or additions require game editor dev time
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants