A compiler to allow hot code reload in WarCraft 3. This means you can update your map script and see the changes in a running game without restarting it. Do note though that this is alpha software. Expect bugs and make backups. This works without memhack and on any patch from 1.24 upwards.
The compiler has two commands: init and update. The first command you execute has to be the init command. The init command expects atleast three arguments: Path to common.j, path to Blizzard.j and path to your maps war3map.j . If your map was compiled by jasshelper you should use the --jasshelper flag for the compiler to work correctly.
$ jhcr init common.j Blizzard.j war3map.j --jasshelper
The above usage will create a file jhcr_war3map.j. You should import this as your maps new war3map.j.
Now you can make changes to your map. Once you've done this, get the new war3map.j and call jhcr again.
$ jhcr update war3map.j --preload-path Path\To\CustomMapData --jasshelper
Again, if you've used jasshelper to compile your map, pass the --jasshelper flag. The update command will create a file called JHCR.txt in the path you've specified.
Another flag is --autoclean
. jhcr
will write a new Preload file for each
call to update with a random part. There are several reasons for this but the
consequence is that we spam quite a lot of preload files. The --autoclean
flag
will remove all Preload files not belonging to the current jhcr session. If for
some reason you are running multiple different jhcr sessions at the same time
you probably shouldn't use this flag, but as this is, i guess, rather uncommon
there should be no harm to use this with every update call.
As this tool operates only on the maps script and not on the map itself you have to extract and insert the war3map.j yourself.
To load updates to the mapscript use call ExecuteFunc("JHCR_Init_parse")
when appropiate. I use pressing escape. Do this after you've done an update
like above.
jhcr
provides a simple API which can, for now, be used to react to code being
updated and see the success or error of the latest update aswell as the current
sequence number.
jhcr
provides the following API. You can copy it into your map script to
please pjass and jhcr will fit with the correct version but it will also work
if you don't provide those empty stub functions.
// Registers a trigger to run whenever a reload finishes
function JHCR_API_RegisterReload takes trigger t returns nothing
endfunction
// Returns the current sequence number of the code being run.
// The jhcr binary will print its sequence number on each `update` call.
function JHCR_API_GetSeqNumber takes nothing returns integer
return 0
endfunction
// Returns the status of the latest reload attempt.
// Possible return values are:
// -1 There wasn't any reload yet
// 1 The reload was a success
// 2 There wasn't any data to reload.
// Probably attempted a reload when no update was available.
// 3 The reload hit the OP limit. Probably too much code to reload.
function JHCR_API_GetLastStatus takes nothing returns integer
return 0
endfunction
To build jhcr you need to provide some things:
- ghc, cabal-install, make, sed, cpp (gcc)
- A common.j file you want to target
- A patch-level you want to target
After you installed all the build-tools and cloned this repo you probably should
also run cabal update
.
The Makefile provides two build targets for the latest patch (1.33 as of
writing) and patch 1.28 because these should be the most used patches.
If you put a file called common-1.33.j (or common-1.28.j)
in the directory you can simply type make patch133
(or make patch128
) and it
should just work. You can then find the executable deeply nested in the dist-newstyle
folder. To get the exact path you could either use cabal exec which jhcr
or
if you have a newer cabal version you can use cabal list-bin jhcr
.
If you want to target any other patch you have to use the build
target and
provide two environment variables depending on your patch level.
Let's take two patch levels as an example: 1.26 and 1.31.
# To build 1.31 aka a "new" patch
PATCH_LVL=131 COMMONJ=common-1.31.j make clean build
# To build 1.26 aka a "old" patch
PATCH_LVL=126 COMMONJ=common-1.26.j make clean build
It is recommended to run clean
if you switch the patch level.
Building jhcr on windows is exactly the same as on a unix-system except that the required tools aren't as easily installed. Personally i use chocolatey to install ghc, cabal and msys2 like this
choco install ghc cabal msys2
Once msys2 is installed you have to make ghc and cabal available in msys2 shell. To do that you have to edit your msys2.ini in your msys2 install folder to have this line:
MSYS2_PATH_TYPE=inherit
Any missing build-tools can either be installed via chocolatey or msys2.
To get cpp you most likely need to install a compiler suite like gcc or
llvm/clang (pacman -S gcc
).