Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
Except UnitApplyTimedLife has a variety of different function parameters. The one your requesting has none? I do not see how it is meant to work, especially without a description.
For new structs/class feature, will this be a truly dynamic memory allocation (heap) and not like the vJASS structs that just uses array with unique indices or am I asking too much?
It only has 'BTLF' parameter, if you put anything else in wont work, so actually only has 1 function
DestroyTimedEffect(effect whichEffect, real time), in extension tho costumizeable effects would be perfect but is not of the highest priority I suppose. Would make my life a bunch easier tho.
Right now we assign assign model on unit and then treat it as a unit which kill with timedlife. If we could set color and size on effect else well as timed"life" in 1 wrapper would be ideal. Bunch of work that could be avoided and bunch of overhead too.
DestroyTimedEffect(effect whichEffect, real time)
SetEffectColor(r, g, b, a)
SetEffectSize(x, y, z)
I've heard that there exists a pathing cost function in the Starcraft 2 editor. It would be a very useful addition.
vJASS:
// GetPathing returns the pathing cost between two points and returns -1 if it's unreachable.
function GetPathingCost takes real x1 real y1 real x2 real y2 returns int
This limit is needed for performance reasons. More parallel sound channels means more CPU time needed to compose the sound. If it were to be changed it would need to be done in the user options.
But so? I didn't even recommend to remove the limit, but to reconsider it, potentially increasing. If developers face the task, they will decide if it can/should be increased or not, but that's nothing you can easily decide for not to even check it.
Thanks for the theme, Kam. Although it is repetitive what I am going to post, maybe these functions could be inside the natives:
vJASS:
//Change the effect (birth,attack,walk,etc) of launch SFX model how a normal model.
native SetSpecialEffectAnimation takes effect fx, string whichAnimation returns nothing
native QueueSpecialEffectAnimation takes effect fx, string whichAnimation returns nothing
....//Include, ByIndex
//Update of lightning size effects and triggers.
native SetLightningScale takes lightning whichBolt, real scale returns nothing
//Native Show Unit with GetLocalPlayer() work to hide a unit for a single player.
native ShowUnitLocalPlayer takes unit whichUnit, player pUnit, boolean show returns nothing
//Add more functions in multiboard as (SetMultiboardX / SetMultiboardY) also add more than one multiboard and leaderboard in the game.
native SetMultiboardXY takes multiboard mb, real Xmb, real Ymb returns nothing
native SetLeaderboardXY takes leaderboard lb, real Xlb, real Ylb returns nothing
...//Include more functions
//New functions to change in jass "angX, angY, height", "scale", "color, sound", etc to "WeatherEffect" and no longer create climates with the same effect with different angles or different sizes with different colors, etc in the main Exel.
native SetHeightWeatherEffect takes weathereffect whichEffect, real height returns nothing
native SetAngXWeatherEffect takes weathereffect whichEffect, real angleX returns nothing
native SetAngYWeatherEffect takes weathereffect whichEffect, real angleY returns nothing
native etc...
//Functionality full of the function native: SetUnitScale(unit, X, Y, Z) -> Enable Y and Z. or derivatives.
native SetUnitScaleY takes unit whichUnit, real scaleY returns nothing
native SetUnitScaleZ takes unit whichUnit, real scaleZ returns nothing
//Add to Vertex coloring the white hues for models.
native SetUnitVertexAlphaColor takes unit whichUnit, integer red, integer green, integer blue, integer alpha returns nothing
//Increase rendering angle if possible, so that the models do not desaparescan with small camera angles.
//http://www.hiveworkshop.com/forums/world-editor-help-zone-98/disappearing-doodad-help-195504/
native SetRenderingModelRect takes player p, real renderX1, real renderY1, real renderX2, real renderY2 returns nothing
Maybe there are functions that can not be performed, but it would be good to be taken into account. Regards...
Honestly, before you add anything new... fix many natives memory leaks... I suspect their coding its just like in blizzard.j cause many of them leak. The difference is, we can just bypass blizzard.j or even remake them and fix them, but we can't do same with the existing natives. If we had access to them, I would do it myself. Anw, please fix those memory leaks.
This should be priority 1, and then add anything new.
^^ In light of that, the terraineffect variable type or something like that cannot be used effectively since it leaks and it has no way of being cleaned up, either by functions or natives.
SetUnitMaxSpeed and minspeed
What exactly are they referring to?
function GetLocalTargetAttachmentX takes widget who, string attachmentname returns real //Get the map relative x coordinate of the specified attachment site. Not net safe.
What is LocalTargetAttachment?
GetUnitAbilityCooldownTimeout, is it GetUnitAbilityCooldown?
Is it the cooldown of the ability?
I have no idea sorry. They were on the original list and undocumented. I think it is meant to be a native that sets the maximum movement speed on a per unit basis.
When attaching a model to a unit at an attachment site the attached model is offset in the game world to be at the attachment site. It follows this attachment site around. This returns the immediate global position of an attachment site for a widget. Since this depends on animation state it is local, meaning the result is different between clients like the GetLocalPlayer native.
I am not sure what people would use this for, but this was a better defined version of something on the old list.
There are twoparts to cooldown. The current cooldown remaining and the total cooldown that the current cooldown started from. These are both important because they define the UI cooldown state of an ability.
GetUnitAbilityCooldownTimeout returns the total cooldown time for an ability, what current cooldown is set to when an ability is cast.
GetUnitAbilityCooldownRemaining returns the current cooldown time for an ability, the amount of cooldown time remaining before it is ready to cast again.
GetUnitAbilityCooldownTimer <- I have no idea what this is supposed to be, but generating a timer like this is just really bad design. Instead of this, the "ability cooldown finished" event is way better and more versatile.
Which is why I called it GetUnitAbilityCooldownTimeout. It is so one can read the current cooldown status of abilities, including calculating the percentage completion of cooldown.
GetUnitAbilityCooldownTimeout
GetUnitAbilityCooldownRemaining
These are functionally required as separate as they refer to the current state of a unit. Similar to the StarCraft II natives to read cooldown references of a unit. One gets the starting cooldown time, the other gets the cooldown time remaining. Together with natives to change cooldowns this would allow one to exactly set the cooldown state of an ability for a unit, including the fraction completed in the UI. An example use case could be a trigger enhanced ability that when over 50% cooldown completion gives bonus damage.
GetUnitAbilityCooldown is required if SetUnitAbilityCooldown is implemented, otherwise it is pointless and the above two will work.
GetAbilityCooldown is only required if SetAbilityCooldown is implemented, otherwise it can be replaced by the Object Editor API natives.
Thank you all for the continued support. An engineer is currently going through these.
More clarification:
function UnitHideAbility takes unit u, integer abilityId, boolean flag returns nothing
function UnitDisableAbility takes unit u, integer abilityId, boolean flag returns nothing
What does flag stand for in these 2 functions?
What's the difference between "SetUnitArmor" and "ModifyUnitArmor"
Edit:
for example
an ability: cd: 10sec, cd remaining: 6 sec
what's GetUnitAbilityCooldownTimeout
is it 10 or 6 or 4 or 40% or 60%?
But GetUnitAbilityCooldown is also 10?
If now I set cooldown to 20sec
cd remaining is 6sec
what will GetUnitABliityCooldown and GetUnitAbilityCooldownTimeout become?
When true it does the native's name sake. UnitHideAbility will hide the ability from the command card of that unit when flag is true. UnitDisableAbility will disable the ability (shaded icon) on that unit when the flag is true.
Set unit armor changes the white base value. Modify unit armor changes the green/red bonus value. To fit with WC3 convention some times one wants green/red bonys numbers to show modifications from buffs or passives. Other times one wants to modify the base value, eg for a custom progression system.
10 seconds. The reason I choose the term "timeout" is because it follows the convention of TimerGetTimeout which returns the timeout parameter used to start a timer.
Yes but its to go with modifying ability base cooldown for a specific unit. Without the capability to do so (its accompanying set native) its redundant. I tried to group the natives together so ones that compliment each other are near each other.
Be aware that the source material was quite vague. I tried to give all the natives sensible names, parameters and a description however if the underlying concept is practical is another issue. This is especially the case for all the "Local" ones since I am not entirely sure if the people suggesting them were aware the return values might not be synchronized as they would depend on local state.
Okay, I think there has been a mixup with the old list itself. Sorry about that. There are currently five functions that deal with ___UnitAbilityCooldown:
JASS:
function GetUnitAbilityCooldownTimeout takes unit u, integer abilityId returns real //Returns the cooldown time for an ability if the unit were to use it.
function GetUnitAbilityCooldownRemaining takes unit u, integer abilityId returns real //Returns the remaining cooldown time of an ability on a unit.
function SetUnitAbilityCooldown takes unit u, integer abilityId, real timeout, real remaining returns nothing
function GetUnitAbilityCooldown takes unit u, integer abilityId, integer level returns real
function SetUnitAbilityCooldown takes unit u, integer abilityId, integer level, integer newcool returns integer
GetUnitAbilityCooldown seems to do the same thing as with GetUnitAbilityCooldownRemaining so we could potentially axe one of them. Having Remaining in the function name is more descriptive but some might see it as unnecessary.
SetUnitAbilityCooldown is repeated once, but they take a different amount of arguments. The first one seems able to modify both the FULL cooldown of a unit's ability (which btw would mean that abilities will be per-unit rather than referenced from a global cache) and the remaining cooldown all in one. Seems a bit unnecessary. @Dr Super Good wouldn't it be preferable if the cooldown 'setters' were separated into two different functions?
Eg:
SetUnitAbilityCooldownTimeout takes unit u, integer abilityId, real timeout returns nothing SetUnitAbilityCooldown takes unit u, integer abilityId, real remaining returns nothing
I have no idea sorry. They were on the original list and undocumented. I think it is meant to be a native that sets the maximum movement speed on a per unit basis.
This might cause ordering issues. For example someone trying to set the cooldown before setting a timeout. Cooldown should be clamped to timeout for logical reasons, and so in such a case it would likely not do what was intended. Having them as a single native forces the player to consider both timeout and remaining time and performs the set in an atomic way which will work as intended.
If these new natives will be included, the API for Memory Hack will be reborn (well, the way it was used in its thread and not the security issues and such, to be exact) as a hardcoded, Blizzard-sanctioned set of natives. Nice!
This might cause ordering issues. For example someone trying to set the cooldown before setting a timeout. Cooldown should be clamped to timeout for logical reasons, and so in such a case it would likely not do what was intended. Having them as a single native forces the player to consider both timeout and remaining time and performs the set in an atomic way which will work as intended.
Also to respond to the min/max movement speed thing, if you look at the Movement section of a unit in the Object Editor, you will find there is a Speed Maximum field and Speed Minimum field. I don't think these actually work, but if Blizzard feels so inclined, they could 'activate' them so that units can be made to accelerate and decelerate like they do in Starcraft 2.
Also to respond to the min/max movement speed thing, if you look at the Movement section of a unit in the Object Editor, you will find there is a Speed Maximum field and Speed Minimum field. I don't think these actually work
Would it not be better that all getters are replaced by a ReadMemory() function with internal boundary checks? This would obviously go with unveiling how wc3 objects are structured. It takes less work to accomplish, is more efficient and allows further optimization of code.
Sorry if I'm saying something that doesn't make sense; I've been out of the loop for a while. Just food for thought.
It's about new natives being suggested to Blizzard. The posts above are talking about modifying the maximum speed and minimum speed of a certain unit at runtime.
Well the idea of this patch is basically to make memhack obsolete by adding its functionalities. But it'll take a few patches before all parties involved are satisfied. My wishes are heavy on the UI/control change, so this means having control over UI elements and being able to detect keyboard/mouse input easily.
That would be just bad design in a lot of ways, and lots of bugs could be created through this. If people are actually writing natives that utilize the actual data structures as saved in the programmed model, then there'll be less bugs and more safety in general. Even the mem hack has a lot of bugs/really hard to offset things due to this, if people making it could use the programmed model it'd be much easier.
Also do realize that it isn't all about just reading memory, it has to be structured after being read, and memhack does this, so this means that wc3 devs would also have to restructure "randomly read" memory. So it's just easier for them to return things from the program model, rather than hacking around the memory themselves, without any knowledge of what it really represents (since this knowledge was created through countless hours of hacking around the wc3 engine, which they have not put into it).
Also, this update is going to create lots of bugs, and people who implement natives as "readmemory" won't be able to debug anything, if they implement them properly, they will be able to debug this.
I didn't specify parameters, but logically one of them would specify what we're extracting^^ Anyhow, as I said, this would come with unveiling object structure. I mean, if the engine as a whole is optimized, then you may as well overload the API with natives, but last I checked the resulting bytecode is quite inefficient.
I like meddling with low-level stuff .
I didn't specify parameters, but logically one of them would specify what we're extracting^^ Anyhow, as I said, this would come with unveiling object structure. I mean, if the engine as a whole is optimized, then you may as well overload the API with natives, but last I checked the resulting bytecode is quite inefficient.
I like meddling with low-level stuff .
Low level stuff has no place here, though, and that's my point. Unless you're talking about loading mouse/keyboard stuff directly from the drivers, most of what's needed here is high level stuff that deals with the object structure that's present in wc3 source code.
This is all presuming that blizzard has access to the source code. If they don't, then hackers will be greatly appreciated.
^Yes, but BonusMod stuff is something that's easy to integrate into a map anyways. Most features I want are things that are impossible to do with wc3 right now.
Yeah, in most case if JNGP or WEX(?) with the LUA stuff available to deal with the 198 abilities of BonusMod. I don't know, but Wurst might be able to handle this field.
Exposing tooltip modification mid-game would be pretty great. Trigger wise at least, if applicable. Less percentage stuff to write, and more precise tooltips.
I'm currently working on a bonus mod system for wurst that lets you define a whole bonus in a few lines of code, so it is more than possible, it's easy as hell. That's why I am not so hard pressed to ask to be able to do stuff bonus mod does. But if those improvements were to be made, then I would just turn all ability mods into code mods in my bonus system, which would benefit me, too. I just don't need it. As I said, things that cannot be done at the moment like detecting key press/release and mouse coordinates, as well as cooldown control/detection are more up my alley, but I do understand that most people want other sorts of convenience or new features.
Exposing tooltip modification mid-game would be pretty great. Trigger wise at least, if applicable. Less percentage stuff to write, and more precise tooltips.
Well, yeah, for example wurst allows you to easily edit tooltips in compiletime, but it can't edit tooltips in runtime, hence why I would really like this feature, but it is kind of included in my "allow us to edit ui elements" request, since tooltips are an UI element.
I didn't know you were a coder, HappyTauren. Man of many talents.
I don't care about any of those things, so I'm perhaps the most impartial between you; I gotta say, HT makes a good argument for adding functionalities that can't currently exist, rather than ones that don't but currently can be made.
Of course, that's only if implementing those things that can currently exist require too much additional effort to code on blizzard's part. Most of the things that are also already possible (through workarounds) would probably be easy to implement alongside the whole "allow people to access all unit's data" theme. Meaning that beside the fact that bonus systems exist and are pretty powerful and easy to use, if a system to access all object's properties is introduced, then it is going to be pretty good.
As I said, returning unit's data from its data table/object should be uniform as Get/SetUnitData[String|Real|Int|Bool](unit u, string data, setterdata) and not require 100 functions. All we need is to access the unit's data table, not 10235345 functions for everything specifically. But we already went over that in this thread, I just want to repeat the importance of this because Kam is inquiring about things.
Thank you all for the continued support. An engineer is currently going through these.
More clarification:
function UnitHideAbility takes unit u, integer abilityId, boolean flag returns nothing
function UnitDisableAbility takes unit u, integer abilityId, boolean flag returns nothing
What does flag stand for in these 2 functions?
What's the difference between "SetUnitArmor" and "ModifyUnitArmor"
Edit:
for example
an ability: cd: 10sec, cd remaining: 6 sec
what's GetUnitAbilityCooldownTimeout
is it 10 or 6 or 4 or 40% or 60%?
But GetUnitAbilityCooldown is also 10?
If now I set cooldown to 20sec
cd remaining is 6sec
what will GetUnitABliityCooldown and GetUnitAbilityCooldownTimeout become?
I would like to offer a few separate propositions, each of which would individually facilitate working with save/load systems in WC3 and make them easier to write and use.
Currently, it is already possible to do most of what I am about to offer - you can look in Wurst's StdLib2 "Network" and "MultifileIO" packages to have a taste of how it can be done, but there are some issues with what can be currently achieved:
1. There is no nice way of reading/saving files. You can exploit the Preload API, but it is far from being even remotely nice to use:
1.1 You have to use SetPlayerName to be able to read data from files, which limits you to 16 lines per file. This means that if you want to write more than that, you have to split your data into multiple files (You can see in Wurst's StdLib2 how I accomplish this, for instance),
1.2 There is no way to check the existence of a file or directory,
1.3 There is no way to write binary (or even text) data to a file without "dead weight" of the Preload API,
1.4 There is no way to read contents from a file other than using GetPlayerName or other stateful APIs,
1.5 You have to enable a specific registry value in order to be able to read files,
2. There is no nice way of sending data over the network. You can use GameCaches and the Sync natives, but:
2.1 The SyncStoredString native is broken, requiring you to serialize strings as int-streams,
2.2 The API is weird and unintuitive, keys are strings (would be more convenient to have them as ints for this use-case),
2.3 GameCaches are very slow compared to even HashTables, making syncing code rather resource-intensive, especially for large payloads,
2.4 The API is not synchronous and is very hard to use in JASS or even vJASS. You can write an asynchronous API using callbacks in Wurst, which is nicer, but it is still not very easy to use,
2.5 You are requried to constantly restart threads if you want to handle large payloads
3. There is no nice way of working with raw binary data. This issue is actually not specific to just save/load, but also other applications:
3.1 No bitwise operations. Bitwise ops have to be coded in using lookup tables or MemoryHack,
3.2 No char-int conversions. To get an int value of a char you have to use lookup tables, and vice-versa
Hence, I propose several additions, each of which addresses these issues. The simplest to implement here would be #3, so let's start with that:
JASS:
// Each function will be annotated with it's C++ equivalent
// ~a
native BitwiseNot takes integer a returns integer
// a & b
native BitwiseAnd takes integer a, integer b returns integer
// a | b
native BitwiseOr takes integer a, integer b returns integer
// a ^ b
native BitwiseXor takes integer a, integer b returns integer
// a << b
native BitwiseShl takes integer a, integer b returns integer
// a >> b
native BitwiseShr takes integer a, integer b returns integer
// Returns the byte value of the first character in the string, or -1 if string is empty
// Return value is guaranteed to be in the bound of [0, 256)
native Char2Byte takes string a returns integer
// Converts the byte into a single character corresponding to that character's value
// The argument should be in the bound of [0, 256), if it is not, the returned string should be null
native Byte2Char takes integer a returns string
Next is a proposal for a File IO API. This API should work out of the box, without requiring any tweaks to the registry:
JASS:
constant integer FILEMODE_READ = 1
constant integer FILEMODE_WRITE = 2
constant integer FILEMODE_READWRITE = 3
type file extends handle
type directory extends handle
native FileExists takes string path returns boolean
native DirectoryExists takes string path returns boolean
// Returns an iterator to a directory's contents
// Returns null if path doesn't exist or isn't a directory
native GetDirectory takes string path returns directory
// Callback-style iteration
native ForDirectory takes directory dir, code callback returns nothing
native GetEnumPath takes nothing returns string
// Pops a single path from this directory object, allowing us to iterate it using a while loop
native PopDirectoryPath takes directory dir returns string
// Opens a new file, creating it if necessary
// There should probably be a restriction on which extensions are allowed
// Good candidates are probably ".txt" and ".dat"
native OpenFile takes string path, integer mode returns file
// Opens a new file only for a certain player
// This is necessary to allow reading/writing locally, because creating a handle locally would desync, so
// we need to create it in shared code
// Reading/Writing for other players on this handle will have no effect, unless SyncFile has been called,
// then reading operations should become available
native OpenFile takes string path, integer mode, player owner returns file
// (I'm not sure if this should be added or not) Tries to send the contents of an entire file from one players to the rest
// Calling this in a local block will read the whole file and start sending it to other players, allowing us to read the file
// synchronously in shared code without issues
native SyncFile takes file f, player sender returns nothing
// If this can be implemented, it'd be really neat
// Pauses the current thread until the file has finished syncing
native SyncFileWait takes file f returns nothing
// Async events for syncing to signal when it's finished
native TriggerRegisterFileSync takes trigger t returns nothing
native GetSyncedFile takes nothing returns file
// Flushes the changes and closes the file
native CloseFile takes file f returns nothing
native GetFileSize takes file f returns integer
native SetFileSeekPos takes file f, integer pos returns nothing
native GetFileSeekPos takes file f returns integer
// Checks whether the file has hit EOF
native IsFileEOF takes file f returns boolean
// Reads the contents of the file into a string, up to specified amount of characters
native FileReadString takes file f, integer max returns string
// Writes the contents of the string into the file as-is, without null-terminators
native FileWriteString takes file f, string s returns nothing
// Natives for reading and writing bytes directly, rather than using a string
// Since WC3 runs only on little-endian platforms, these too should probably be little-endian
native FileWriteUInt8 takes file f, integer a returns nothing
native FileWriteUInt16 takes file f, integer a returns nothing
native FileWriteUInt32 takes file f, integer a returns nothing
native FileWriteInt8 takes file f, integer a returns nothing
native FileWriteInt16 takes file f, integer a returns nothing
native FileWriteInt32 takes file f, integer a returns nothing
// Natives for reading bytes directly
native FileReadUInt8 takes file f returns integer
native FileReadUInt16 takes file f returns integer
native FileReadUInt32 takes file f returns integer
native FileReadInt8 takes file f returns integer
native FileReadInt16 takes file f returns integer
native FileReadInt32 takes file f returns integer
// Writing/Reading reals
native FileWriteReal takes file f, real a returns nothing
native FileReadReal takes file f returns real
Last is the proposal to address the issue of networking data across players. There are two solutions I'd like to offer:
The first one is the most straightforward and requires minimal new natives
But for it to be worth it, the code should be optimized to make most use of the bandwidth available, and the fact that we are sending
data in a batch (instead of how SyncStored* GameCache natives seem to work, which are very slow, only 1-4 kbps max)
JASS:
// When called locally, will start syncing the contents of this hashtable to other players
native SyncHashtableParent takes hashtable ht returns nothing
// Same as SyncHashtable, but only for a child hashtable
native SyncHashtableChild takes hashtable ht, integer parentKey returns nothing
// Pauses the thread until the specified hashtable has finished syncing
native SyncHashtableWait takes hashtable ht returns nothing
// Events for hashtable syncs
native TriggerRegisterHashtableSync takes trigger t returns nothing
native GetSyncedHashtable takes nothing returns hashtable
Another way, which could turn out more efficient, would be to create a new type specifically for syncing
This type would be something like a byte-buffer with natives for reading, writing and syncing it's contents
It's internal C++ representation could be something as simple as std::vector<uint8_t>, allowing us to use it
as a dynamic array type, which has also been long since requested in the community
JASS:
type bytes extends handle
// self-explanatory
native CreateBytes takes nothing returns bytes
native DestroyBytes takes bytes b returns nothing
native BytesWriteUInt8 takes bytes b, integer pos, integer a returns nothing
native BytesWriteUInt16 takes bytes b, integer pos, integer a returns nothing
native BytesWriteUInt32 takes bytes b, integer pos, integer a returns nothing
native BytesWriteInt8 takes bytes b, integer pos, integer a returns nothing
native BytesWriteInt16 takes bytes b, integer pos, integer a returns nothing
native BytesWriteInt32 takes bytes b, integer pos, integer a returns nothing
native BytesReadUInt8 takes bytes b, integer pos returns integer
native BytesReadUInt16 takes bytes b, integer pos returns integer
native BytesReadUInt32 takes bytes b, integer pos returns integer
native BytesReadInt8 takes bytes b, integer pos returns integer
native BytesReadInt16 takes bytes b, integer pos returns integer
native BytesReadInt32 takes bytes b, integer pos returns integer
native BytesWriteReal takes bytes b, integer pos, real r returns nothing
native BytesReadReal takes bytes b, integer pos returns nothing
native BytesWriteString takes bytes b, integer pos, string s returns nothing
native BytesReadString takes bytes b, integer pos, integer amount returns string
// Get the amount of data in this buffer
native GetBytesSize takes bytes b returns integer
// Reserve capacity for this buffer
native ReserveBytesCapacity takes bytes b, integer capacity returns nothing
// Get capacity for this buffer
native GetBytesCapacity takes bytes b returns bytes
// Tries to sync the local contents of this bytes object to other players
native SyncBytes takes bytes b returns nothing
// Pauses the current thread until syncing has finished
native SyncBytesWait takes bytes b returns nothing
// Events
native TriggerRegisterBytesSync takes trigger t returns nothing
native GetSyncedBytes takes nothing returns bytes
Since it just happened to me once again, something I would prefer over 99% of the native suggestions in this thread: Crash/Critical error debug information!
It would be superb if the "critical error" window with the report function after wc3 crashes would also display the last Jass execution point or ideally a stacktrace, so we have some idea what caused it.
While there are some known causes, like units out of bounds, others like endless execution loops can be very hard to prevent without any idea where/why they happen.
For pre 1.24 there existed a tool named "war3err" which allowed exactly that.
It would be superb if the "critical error" window with the report function after wc3 crashes would also display the last Jass execution point or ideally a stacktrace, so we have some idea what caused it.
^Patching JASS to make it impossible to crash the game through it probably requires too much work, and it'd be dumb for blizzard to dump too many resources into a thing like that. Even this patch is dumb from a business perspective. On the other hand, even if jass VM crashes, it is likely pretty easy to retrieve the last function from the call stack, or even the stack trace.
Another big quality of life improvement you might want to consider is a few more AI natives. One of the biggest problems with the AI is the very inflexible use of captain widgets.
Currently, captain widgets are a "middleman" in charge of orders given to the computer player. The AI player moves, or teleports, the captain widget to a target location and the units assigned to the captain follow. There are two captains: attack and defense, each with it's own problems.
The units assigned to the defense captain will stay still even when given an order to change location, until one of three cases: aggroed, player town under attack, another unit is added to the defense captain. But the bigger problem is with the attack captain: once a unit has been added to the attack captain, it cannot be removed manually. If it is injured, and the attack group requires units with a higher health percentage, then the unit will be removed, but it cannot be done manually.
I have two ideas for solutions in mind, both in a way that should not break backwards compatibility and enhance the AI greatly:
1. Add an Empty attack group native. A simple native that will allow one to manually remove all units from the attack group. That alone will not change existing scripts and will remove a lot of limitations.
2. Allow multiple captains. This one is a bit more radical change, but it will make the AI far better and more flexible. The thing with captains is that you can only have one of each, but that is not to say that you can't create more. In fact, you can use the native CreateCaptains as many times as you want, and it will create new captains. Also, it doesn't remove the old captains, as units assigned to them cannot be added to the new captains, and will continue following the old captain to the last target it received. The problem here, is that referencing the captains is done by constant integers set in the common.ai file:
Once you create new captains, these variables will reference the new captains instead of the old ones. If you could allow users to reference older captains (for example allocating another 3 numbers for older captains for every time CreateCaptains is called), AI will be much more usable.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.