Giter VIP home page Giter VIP logo

jmc's Introduction

JMC · license-mit release build-passing discord-invite

(JavaScript-like Minecraft Function)

JMC (JavaScript-like Minecraft Function) is a mcfunction extension language for making Minecraft Datapack.

JMC-icon

Code example:

Text.tellraw(@a, "everything outside the function");
say "just goes into the load function";

function myFunc() { // function
    execute as @a at @s run {
        Text.tellraw(@a, "&<green,bold> this text is green and bold");
        say "this is a function executed through execute as @a";
    }
}
function varOperations() {
    // this variable x is equal to the number of items in hand
    $x = data get entity @s SelectedItem.Count;
    $y = 100; // this is the second variable
    $z = @s::SelectedItem.Count; // the same as $x
    $random_int = Math.random($x, $y);
    Text.tellraw(@a, "random number from &<$x> to 100: &<$random_int>");
}
class folder {
    function funcInFolder() {
        if ($x < $y && $random_int <= 50) {
            printf("X is less than Y and random number is less than or equal to 50");
        } else if ($y > $x || $x == 69) {
            printf("X is greater than Y or X is equal to 69 ($x is &<$x>)");
        } else {
            printf("&6other cases"); // "printf" is shortcut for "tellraw @a" but works with custom formatting
        }
    }
}
function folder.raycast() {
    Raycast.simple(
        onHit=()=>{
            printf("i hit some block");
        },
        onStep=()=>{
            particle happy_villager ~ ~ ~;
        }
        interval=0.5,
        maxIter=100,
        stopAtBlock=true,
    );
}

Documentation: https://jmc.wingedseal.com

Trailer: https://www.youtube.com/watch?v=cFgvCScpirw&ab_channel=WingedSeal


Why use JMC?

  • Avoid repetitive tasks
  • Superior Syntax
  • Low learning curve
  • Many more features

JMC allows you to write minecraft functions in a better language (.jmc) which is more readable and easier to write.

Documentation

Everything you need to know about JMC can be found at https://jmc.wingedseal.com

Installation

  • Executable

In "datapacks" folder of your world file (Usually .minecraft/saves/world_name/datapacks). Create a new datapack folder. And put JMC.exe in that folder then run it.

Installation

  • Python 3.10+
pip install jmcfunction --pre

Latest unreleased build:

pip install git+https://github.com/WingedSeal/jmc.git#subdirectory=src

Build

Executable

If you would like to build the executable yourself (on Windows).

  1. Install Python 3.10
  2. Install GNU compiler
  3. Open command prompt as administrator
  4. Go to repository directory using cd
  5. Run pip install -r build_requirements.txt
  6. Run build

Python

If you would like to use latest unreleased feature, you can install jmc directly from github repository.

  1. Install Python 3.10
  2. Open a terminal (command prompt as administrator on Windows)
  3. Go to repository directory using cd
  4. Run cd ./src
  5. Run pip install setuptools
  6. Run python setup.py install

License

MIT

jmc's People

Contributors

americanbagel avatar amqndin avatar bdke avatar nico314159 avatar wingedseal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

jmc's Issues

[BUG] Loot table only declared once, throws an error "already declared"

Describe the bug

"whip" loot table was only declared once but an error of duplicate declaration appears. this error can also be fixed if you import with a full path all the way from C: to project folder's subfolder.

To Reproduce

[Steps to reproduce the behavior]

  1. Download .zip
  2. Download beet, jmc-beet, and zip i attached in here
  3. drag the folder out of the archive
  4. open the root folder in terminal
  5. run 'beet' command in terminal

Expected behavior

To run and compile smoothly without any error messages.

Desktop

  • OS Windows 10

Additional context

i use latest unreleased JMC build from github, i compile all my code in beet environment, i use python 3.12 (but that bug first happened when i still was on 3.11).
ZIP ARCHIVE bug bug bug.zip

[BUG] Override namespaces aren't being deleted before being written to

Describe the bug

Using the #override keyword in the header file will not delete the target namespace folder before writing to it.

To Reproduce

  1. Add a namespace override to the project header file. (eg: #override namespace2)
  2. Create a function within the namespace scope in your main.jmc file. (eg: function namespace2.test() {...})
  3. Compile the project. It should generate the new namespace folder and function within it.
  4. Go back to main.jmc and delete/comment out the function we just created.
  5. Recompile project. The new namespace folder and function file will not be deleted.
  6. (Optional) Add another function to the main.jmc file with a different name (eg: function namespace2.test2() {...})
  7. (Optional) Recompile the project. The second function gets appended to the new namespace without deleting the first.

Expected behavior

The namespaces declared by the #override header keyword should be deleted prior to being written to, which isn't currently happening.

Screenshots

image
image

Desktop

  • Windows 10

Additional context

It should be noted this only seems to happen to namespaces that are affected by the #override header, as the main namespace used for the project is overwritten correctly.

JMC thinks `[-1]` is a string slice

summon::entity.Pos = summon::objectives[-1].Pos;

raises

Unexpected token (Token(token_type=<TokenType.KEYWORD: 'Keyword'>, line=175, col=56, string='.Pos', _macro_length=0, quote='')) at line 175 col 56.

[BUG]

Describe the bug

Error telling me that the directory is not empty.
Unexpected error causes program to crash OSError [WinError 145] El directorio no está vacío: 'C:\\Users\\me\\AppData\\Roaming\\com.modrinth.theseus\\profiles\\Datapacking\\datapacks\\no-elytra-take-off\\src\\..\\data\\no_elytra_take_off\\functions' Traceback (most recent call last): File "C:\Users\me\anaconda3\Lib\site-packages\jmc\terminal_commands.py", line 62, in compile_ compile_jmc(global_data.config, debug=True) File "C:\Users\me\anaconda3\Lib\site-packages\jmc\compile\compiling.py", line 40, in compile_jmc build(lexer.datapack, config, is_delete, cert_config, cert_file) File "C:\Users\me\anaconda3\Lib\site-packages\jmc\compile\compiling.py", line 288, in build rmtree(folder, statics) File "C:\Users\me\anaconda3\Lib\site-packages\jmc\compile\compiling.py", line 159, in rmtree folder.rmdir() File "C:\Users\me\anaconda3\Lib\pathlib.py", line 1156, in rmdir os.rmdir(self) OSError: [WinError 145] El directorio no está vacío: 'C:\\Users\\me\\AppData\\Roaming\\com.modrinth.theseus\\profiles\\Datapacking\\datapacks\\no-elytra-take-off\\src\\..\\data\\no_elytra_take_off\\functions'

To Reproduce

[Steps to reproduce the behavior]

  1. Add #static "predicates" to your main.hjmc
  2. Create predicates folder under namespace
  3. not sure wether you need these inside predicates/, but I added two json files here one called works.json and another should_work_as_well.json both filled with:
    { "condition": "minecraft:random_chance", "chance": 1 }
  4. Add this function to main.jmc
    function works() { if (predicate __namespace__:works) { say "hi"; } else if(predicate __namespace__:should_work_as_well) { say "hello"; } }
  5. Compile 2 or 3 times until the error appears

Expected behavior

not crash as soon as I add the predicates folder in combination with calling the predicates in an if else block?

Desktop

  • Windows 10

Screenshot

dafdsaf

Switch statements don't fully compile with curly braced anon function cases

Describe the bug

Switch statements that use an anonymous function (specifically with curly brackets) within a case will prevent any subsequent cases from being compiled. Since it needs curly brackets for it to bug, it seems like it's an error in the parser picking up the curly bracket to end the switch when it shouldn't.

To Reproduce

  1. Create a switch statement in any .jmc file.
  2. Use an anonymous execute function within a case that uses curly brackets. Any following cases will be ignored by the compiler.

Screenshots

JMC code:
image

Transpiled result:
image

Desktop

  • Windows 10

Add `#enum` for header

#enum ClassName ITEM_1 ITEM_2 ITEM_3
#enum OtherClass 1 ITEM_1 ITEM_2 ITEM_3

is equivalent to

#define ClassName.ITEM_1 0
#define ClassName.ITEM_2 1
#define ClassName.ITEM_3 2
#define OtherClass.ITEM_1 1
#define OtherClass.ITEM_2 2
#define OtherClass.ITEM_3 3

Timer.set() using a scoreboard value creates an invalid command

Describe the bug

When using Timer.set() to set a value for a timer scoreboard, if you use a scoreboard value as the timer value it will properly swap the command with a scoreboard player operation command, but will not parse the keywords properly for the command to work.

When calling the function Timer.set(Timers, test_player, test_objective:value);, instead of producing a result like this:

scoreboard players operation test_player Timers = value test_objective

it will instead insert it as:

scoreboard players operation test_player Timers = test_objective:value

To Reproduce

  1. Set a Timer scoreboard using the Timer.add() function
  2. Set a value to the Timer scoreboard using a scoreboard value as the length

Desktop

  • Windows 10

[BUG] switch case does not accept negative number

Describe the bug
switch case with negative number not worked as intended

To Reproduce
Steps to reproduce the behavior:

  switch ($rotation_1) {
      case 1:
          tp @s ~ ~ ~ ~ ~1;
      case -1:
          tp @s ~ ~ ~ ~ ~-1;
  }

It throws

JMCSyntaxException
In <FilePath>
Expected case number at line 140 col 22.
                case - <-

Expected behavior
accept neagative number as switch case

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Windows

Additional context
N/A

Adding multiple timers to a single target causes problems

Describe the bug

The Timer.add() allows the user to add multiple timers to a single entity, which causes buggy and unintended behavior.

image

In __load__.mcfunction:

image

In __private__/timer_add/main.mcfunction:

image

To Reproduce

  1. Use Timer.add() to add a timer to the same target twice

Expected behavior

Should probably throw an exception, telling the user the timer already existed prior and should use Timer.set() instead.

Desktop

  • Windows 10

Additional context

Timer.add() also adds an additional scoreboard to the datapack, even when the scoreboard has already been created. This only occurs in the first instance of using the scoreboard within a Timer.add() call, so it seems Timer properly caches previously scoreboard its created but doesn't recognize scoreboards created by other means.

Prevent wildcard import from doubling a previous named import

Description

Right now using the wildcard import character (*) to import an entire folder, it doesn't take into consideration any possible files that have already been previously imported from within that folder.

It will cache the usage of that exact wildcard import to prevent it from being imported twice, same as if you were to name the specific module (wouldn't be imported twice if imported again) but when using them in tandem, the wildcard will still pull everything from a folder including any named files you've already imported.

It would be a really nice feature if the wildcard would be able to cross reference any previously imported files from the list of files its trying to import and prevent doubly importing any files that have already been loaded. The purpose of this feature is to be able to ensure a load order of the modules you need to load first without needing to isolate them from the rest of your source.

Python input formatter built into the compiler

Description

The addition of a built-in python code string formatter for the JMC.python module would allow users to have an arbitrary amount of indentation whitespace when coding python in a JMC file. This would prevent always needing to format the python code to align directly with the left-most column.

It should be noted that all subsequent indentation should still align with python's indentation protocol, but as long as each line is indented relative to the same uniform length, it should still work just fine.

Example of current implementation:

image

Example of desired implementation:

image

I've written up a mock-up example of how this formatting function could be written, although of course use your own discretion.

python_string = """
        a = 2
        def hello():
            print("Hello!")
            print("World!")
        hello()
"""


def indent_format(inp: str) -> str:
    _type = _minimum = None
    res = ""
    
    for ln in inp.splitlines():
        if not ln:
            continue
        
        _count = 0
        for i,c in enumerate(ln):
            if c == " " or c == "\t":
                _type = c if _type is None else _type
                if _type != c:
                    raise IndentationError("Mismatch use of spaces and tabs")
                _count += 1
            else:
                _minimum = _count if _minimum is None else _minimum
                if i < _minimum:
                    raise IndentationError("Left indentation not aligned properly")
                break

        res += ln[_minimum:] + "\n"

    return res


fmt_string = indent_format(python_string)

print("Unformatted code:")
print(python_string)

print("Formatted code:")
print(fmt_string)

print("Executing code:")
exec(fmt_string)

[BUG] `Advancement.grant()` does not detect advancements

Describe the bug

when using Advancement.grant(@s, only, story/enter_the_end, minecraft) no advancement found

To Reproduce

  1. use Advancement.grant(@a, only, story/enter_the_end, minecraft)
  2. compile

Expected behavior

Advancement.grant() should detect advancements

Screenshots

advancement_grant

Desktop

  • Windows 10

Macro Factories with multiple parameters will merge results

Describe the bug

Creating a new macro factory using #define that has more than one parameter will produce commands that have their arguments concatenated together instead of being separated by a space.

To Reproduce

  1. Create a macro factory with more than one parameter. eg: #define tp_to(x, y) tp x y
  2. Use the macro factory somewhere within your project and compile it. If the example was used, the resulting command will incorrectly have both player names/selectors merged together.

Screenshots

image
image
image

Desktop

  • Windows 10

Additional context

One thing that does fix this behavior is by adding an extra space in the macro factory wherever the space is missing from the end result (eg: #define tp_to(x,y) to x y -- notice the two spaces between x and y). Obviously this fix isn't ideal, I just thought that it might help debug the behavior.

[BUG] Unhandled Error

Describe the bug

it does not return a valid error message

To Reproduce

setup invalid path

Expected behavior

throw an JMCError

Screenshots

NA

Desktop

  • OS: Windows

Additional context

ValueError
'D:\\MultiMC\\instances\\1.19.4\\.minecraft\\saves\\New World\\datapacks\\main\\src\\main.jmc' is not in the subpath of 'F:\\MultiMC\\instances\\1.19.4\\.minecraft\\saves\\New World\\datapacks\\main' OR one path is relative and the other is absolute.
Traceback (most recent call last):
  File "C:\Users\User\AppData\Local\Temp\ONEFIL~1\jmc\terminal_commands.py", line 62, in compile_
  File "C:\Users\User\AppData\Local\Temp\ONEFIL~1\jmc\compile\compiling.py", line 31, in compile_jmc
  File "C:\Users\User\AppData\Local\Temp\ONEFIL~1\jmc\terminal\configuration.py", line 125, in toJSON
  File "C:\Users\User\AppData\Local\Temp\ONEFIL~1\pathlib.py", line 818, in relative_to
ValueError: 'D:\\MultiMC\\instances\\1.19.4\\.minecraft\\saves\\New World\\datapacks\\main\\src\\main.jmc' is not in the subpath of 'F:\\MultiMC\\instances\\1.19.4\\.minecraft\\saves\\New World\\datapacks\\main' OR one path is relative and the other is absolute.

Please report this error at https://github.com/WingedSeal/jmc/issues/new/choose or https://discord.gg/PNWKpwdzD3

Switch cases throw an exception when using scoreboard:selector values

Describe the bug

When using a scoreboard value (using the scoreboard:selector syntax) as a variable in a switch case, the compiler will throw a syntax exception saying the colon is an unexpected token.

To Reproduce

  1. Use a scoreboard:selector value in a switch case and try to compile the project.

Screenshots

image
image

Desktop

  • Windows 10

Add a dedicated "this" keyword for classes

Description

The addition of a dedicated this keyword could be used as a means to access the currently accessed "class" address when writing classes in JMC.

For example, instead of having to write this:

image

You could just write it like this:

image

[BUG] `weather clear` syntax does not work

Describe the bug

I tried to use weather clear but it only lets me use execute run weather clear.

To Reproduce

[Steps to reproduce the behavior]

  1. use weather clear
  2. compile

Expected behavior

Allow the use of weather clear.

Screenshots

weather_clear

Desktop

  • Windows 10

Extends keyword

Inheriting properties from an already defined file using extends keyword

In simple terms, allow modifying values of a file created using the new keyword without copying the whole file.
This would be really useful for custom advancements that are different by a single line or the likes.

new advancement(blue_reward) {
  "display": {
    "icon": {
      "item": "minecraft:blue_concrete"
    },
    "title": "Example",
    "description": "example",
    "frame": "goal"
  },
  "criteria": {
    "requirement": {
      "trigger": "minecraft:tick",
      "conditions": {
        "player": {
          "team": "blue"
        }
      }
    }
  },
  "rewards": {
    "function": "example:reward"
  }
}

new advancement(red_reward) extends(blue_reward) {
  "display": {
    "icon": {
      "item": "minecraft:red_concrete"
    },
  },
  "criteria": {
    "requirement": {
      "conditions": {
        "player": {
          "team": "red"
        }
      }
    }
  }
}

This would allow one to copy and modify files that require minor changes without completely copying the contents of the file.
This also allows making the same changes to the files faster for example if the reward were changed to also include experience, all the files extending the parent would get the change.

[FEATURE_REQUEST] Null coalescing assignment

Description

In JavaScript, the x ??= y operator will assign x the value of y only if x is null. This is highly useful for setting default values of variables.
To Minecraft-ify this, I propose that the syntax be:

$<variable> ??= <integer>;
$<variable> ??= $<variable>;

which compiles down to

execute unless score <foo> <objective> = <foo> <objective> run scoreboard players set <foo> <objective> <integer>;
execute unless score <foo> <objective> = <foo> <objective> run scoreboard players set <foo> <objective> = <bar> <objective>;

This would be useful for the same reason as in the original JavaScript, as initializing scoreboard variables is a common need.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.