• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

ALICE 2.0 (Missiles, Physics & More)

This bundle is marked as pending. It has not been reviewed by a staff member yet.
RbeQz1.png


Complex, performant interactions made easy

RbeQz1.png



RbeQz1.png


RxeHRb.gif
wqFF8T.gif
S974Nw.gif


RbeQz1.png


Overview

Features

Installation

Getting Started

Change Log

Credits


Overview

A Limitless Interaction Caller Engine (A.L.I.C.E) is a high-performance interaction engine that can be used for physics, missiles, and much more. The core of the system is heavily optimized for speed and the outer shell provides an easy interface that allows any type of interaction to be set up quickly. ALICE makes full use of Lua's dynamically-typed nature, allowing you to pass anything from units, destructables, items, and your own classes as objects into the system.

Bundled with ALICE are multiple, ready-to-use libraries, the Complementary ALICE Templates (CATs). These libraries allow you to easily create various types of systems with a great deal of flexibility in your designs. You can create missiles that intercept other missiles, fireballs that set trees on fire as they travel to their target, or rocks that roll over the ground and collide with other objects with a never-before seen realism in Warcraft 3. And once you're ready to move past the limitations of those libraries, the ALICE API is waiting for you!

ALICE has an extensive debugging API, where you can select its interal objects in-game to see their properties and efficiently investigate why they are misbehaving.

How to use

The main task when working with ALICE is creating actors, its main internal object, and their interaction functions. An actor is a class that is attached to any type of object and interacts with other actors that were added to the system. Actors carry identifiers and function interfaces determining their interactions and with which other actors they form a pair.

The properties of actors are fully encoded in the table that is used to create them and the interaction functions you write. ALICE takes care of the entire control structure and most of the clean-up, so you can focus on the fun parts of coding. For example, here is the code used to create the reflective barrier that Jaina uses in the showcase video:

Lua:
    local function ReflectProjectile(barrier, shell, x, y, z, normalSpeed, __, __)
        local phi, theta = ALICE_PairGetAngle3D()
        local shieldEffect = AddSpecialEffect("Abilities\\Spells\\Undead\\ReplenishMana\\ReplenishManaCasterOverhead.mdl", x, y)
        BlzSetSpecialEffectZ(shieldEffect, z)
        BlzSetSpecialEffectYaw(shieldEffect, phi)
        BlzSetSpecialEffectPitch(shieldEffect, -theta + bj_PI/2)
        BlzSetSpecialEffectAlpha(shieldEffect, math.min(128, normalSpeed // 2))
        BlzSetSpecialEffectScale(shieldEffect, 1.2)
        DestroyEffect(shieldEffect)
    end

    ---@class ReflectiveBarrier
    ReflectiveBarrier = {
        --ALICE
        identifier = "reflectiveBarrier",
        interactionFunc = {
            projectile = CAT_EntityCollisionCheck3D
        },
        radius = 200,
        bindToOrder = "starfall",
        zOffset = 50,
        --CAT
        onEntityCollision = {
			shell = CAT_EntityBounce3D,
			other = CAT_EntityDevour3D
		},
        onEntityCallback = ReflectProjectile,
        mass = 500,
        collisionRadius = 160,
        elasticity = 0.2,
    }

    ReflectiveBarrier.__index = ReflectiveBarrier

    local function CreateReflectiveBarrier()
        if GetSpellAbilityId() ~= FourCC("Ashi") then
            return
        end

        local barrier = {}
        setmetatable(barrier, ReflectiveBarrier)

        local u = GetSpellAbilityUnit()
        barrier.anchor = u

        ALICE_CreateFromClass(barrier)
    end

:peasant-victory:Do not get intimidated by the complexity of this resource! While an understanding of the ALICE API is helpful, it is not necessary to build your first systems with it, as ALICE is packaged with ready-to-use libraries.

Motivation

Although the ALICE core was based on my particle system, my motivation for the development of this system was to create A.I. with it, where the interactions would be objects on the map sending data and being evaluated by a bot, who uses this data to calculate its next action. The endless possibilities of Lua soon got me hooked and I started expanding the system and now it is far beyond the scope I had originally intended (I can't stop, please send help!).

I realized that this engine could be used to solve one of the problems that has bugged me in Warcraft 3 for a long time - that you have to treat your own objects (such as particles, missiles) inherently differently from Warcraft 3 objects, since there is no native API, no enum functions, for them. Lua's dynamically typed nature provided an opportunity to remove this separation.

Unfortunately, the heavy reliance on dynamic typing means that ALICE cannot be translated into JASS. However, an interface for Lua-GUI would be a possible in the future.

Features

FeatureDescription
Complementary ALICE TemplatesThere are two ways you can work with ALICE. You can write your own systems with the ALICE API or use the ready-to-use libraries, the CATs. These libraries feature a number functions that you can use to create various objects and their interactions. They provide a good starting point for anyone who is learning the engine. Thes CATs include:
  • Units/Destructables/Items: These templates help to interface ALICE with the respective object type and are highly recommended when using ALICE with that object type.
  • Entities: This template contains several functions that help with creating and managing entities. We define entities as objects represented by a table with coordinate and velocity fields and a special effect, so these could be missiles, projectiles, bouncing balls etc.
  • Missiles: This template includes a several functions that move or accelerate entities, allowing for the creation of missiles or projectiles. It also includes the terrain collision function.
  • Collisions: This template contains various functions to detect and execute collisions. Collisions can occur between entities and other entities or between entities and units, destructables, or items.
  • Effects: This template contains various auxiliary functions to make your entities look nice. It includes functions that orient the special effect such that the object resembles an artillery shell, a homing missile, or a ball rolling over the ground, among other.
  • Ballistics: This template includes a function for realistic, ballistic and sliding movement for entities as well as helper functions for ballistic movement.
  • Forces: An advanced library that allows you to create interactions where objects are pushing or pulling other objects in the vicinity, such as a black hole sucking in nearby units, or a mage creating an explosion that pushes away nearby projectiles.
Core APIThe Core API consists of functions that govern the creation and destruction of ALICE objects, the actors.
Pair APIThe Pair API includes various functions that you can use within your interaction functions to quickly create complex interactions. The objects from the interaction currently being evaluated are implied input arguments for those functions, which is why they cannot be used from outside of ALICE. The Pair API includes math functions as well as various utility functions that allow you to put cooldowns on effects or create and clean-up effects on creation and destruction, among other.
Debug APIALICE features an extensive Debug API. By typing "downtherabbithole", you can enable debug mode and select objects to view information about the attached actors. While selected, all interactions are shown by a green lightning effect whenever they are evaluated. You can combine the ALICE debug mode with Eikonium's Debug Utils to execute code directly on the selected actor. To use debug mode efficiently, always declare your interaction functions as global variables, so that their name gets displayed correctly within the actor tooltip.
Enum APIThe enum functions work just like the enum natives, but can be used to efficiently enumerate any objects, including entities. While the enum functions are significantly slower than their native counterparts, the fact that they compile the objects into a Lua table instead of a group almost cancels out the speed difference, and even makes them faster in some situations.
Self-InteractionNot all interaction functions that we want to call with ALICE should be between two objects. Sometimes, we just want to just execute code periodically on a single object. ALICE allows for that with the convenient self-interaction function table that you can add to actors on their creation. Self-interactions can also be added or removed later on.


Performance

Unlike most other similar systems, ALICE's core avoids using enum functions entirely. Most missile systems, for example, would search for collisions with units by calling GroupEnumUnitsInRange repeatedly. But while natives are optimized and written in lightning-fast C++, Lua is a fast language itself, and calling natives is expensive. For example, GetUnitX, which presumably does nothing but look up the number in a field, is about 10x slower than a Lua function call and 50x slower than a Lua table lookup. In addition, the process of calling the natives repeatedly is inefficient itself.

Think of it this way: Calling GroupEnumUnitsInRange on every iteration is like having the most advanced GPS system there is installed in your car, but then determining the time until arrival by having a kid on the back-seat ask "Are we there yet?" over and over again.

ALICE makes use of two different optimization methods:
  1. Variable interaction intervals: Updates between two objects don't necessarily have to be performed every step. If you want to check the collision between two objects that are two screens apart, you don't need to check again for quite some time, so doing another check on the very next iteration would be a waste of resources. The interaction interval is specified in the interaction function.
  2. Cells: The map is divided into a grid of cells. Objects only interact with other objects that share a cell. This optimization is similar to the quad-trees used for collision checks in Warcraft III, but simplified.

The main advantage of this approach is that ALICE can treat all objects that are passed into it in the same way (units, destructables, items, and entities). ALICE can do not only performant missile-unit collisions, but also missile-missile collisions, and will blow every other system completely out of the water when it comes to the latter task.

For an ALICE missile system, collision detection will be only a minor fraction of the computation time of each missile in most situations. As long as graphical rendering is not a problem (missiles are spread over the entire map), ALICE is able to compute 2000+ missiles at the same time without the need to skip computation of missile instances.



Installation

Copy the ALICE Config and Script section into your map. The rest of the ALICE files are documentation and it is up to you if you want to import them or not.


Next, make sure you have all the requirements imported. These are:

RequirementDescription
Total InitializationNeeds no explanation.
HookRequired for the Units, Destructables, and Items CATs, which are highly recommended inclusions.
WidgetTypeThis handy little library allows ALICE to determine the correct types of the objects passed into it. Since it caches the result, it is fast and efficient. Included in the test maps.
Precomputed Height Map
(optional)
Highly recommended if you want to do any kind of 3D interactions with ALICE as it improves performance and ensures synchronicity in multiplayer. Otherwise not needed.
CustomTooltip.toc
CustomTooltip.fdf
These are the frame definition files for the actor tooltips in debug mode. Included in the test maps.


Complementary ALICE Templates

Lastly, import the CATs that you want to work with. These are:

CATDescription
WidgetsRequirement for Units, Destructables, and Items CATs.
ObjectsRequirement for Entities, Missiles, Collisions, Ballistics, and Forces CATs.
Units, Destructables, ItemsAutomatically create and destroy actors for objects of the respective type.
Entities, Missiles, Collisions,
Ballistics, Forces
These libraries contain various functions that you can use in the definitions of your objects.


Getting Started

After installing ALICE and its requirements, preplace some units, trees, and/or items and launch your map. Type "downtherabbithole" to enable debug mode. Now you can click on any object to view the actors attached to it. A tooltip with all the relevant information should pop up when you do. These actors are created by the respective CATs.

The actor's description lists all of its identifiers. These identifiers are important when we create interaction functions to tell ALICE which type of objects they should affect. The tooltip should also tell you that these actors are currently unpaired. Actors created by these CATs are passive; they only receive, but do no initiate any pairs.

As you move a unit around, you can see how the actor moves along with it, and how the cells it is currently in are being updated. Interactions can only occur if two actors have one or more overlapping cells.

To initiate pairs and create interactions, we need to create new actors that pair with the passive actors attached to the units, destructables, and/or items in your map. The test map and cinematic maps include many examples on how to create those types of actors.

Tutorial

Coming soon.


Change Log

Version 2.0
  • Added ready-to-use libraries - Objects, Entities, Missiles, Collisions, Ballistics, and Forces.
  • Return values in interaction functions are now optional. If the return value is omitted, ALICE will automatically put pairs using that function into the optimized EveryStep cycle.
  • Added API functions to add or remove self-interactions.
  • Added the Matrix API. These functions can be used to write data tables and share data between object pairs.
  • ALICE now uses the WidgetType library to infer the correct type of objects passed into it.
  • To improve performance with widgets, Math API functions now use cached values for object coordinates that get reset each cycle.
  • Freeze protection is now based on evaluation time instead of number of pairs.
  • ALICE_Benchmark can now be used to view the evaluation time of each cycle.
  • Added the HALT_ON_FIRST_CRASH option in the config.
  • Reorganized API into Core and Advanced API.

Credits

Cinematic Showcase Map
Fighting Spirit for Spellbringers
Edited by Vinz

Dwarf Grenadier Model by Maximal
Fire Models by Vinz
Bullet/Muzzle Flash Models by Vinz
Arcane Explosion Model by Suselishe
Starsphere by ILH
Battlecruiser and Carrier Model Imports by Daratrix
Plasma Blast Model by nGy
Missile Model by Vinz
Previews
Contents

A.L.I.C.E 2.0 Cinematic Map (Map)

ALICE 2.0 Test Map (Map)

ALICE Advanced Manual (Binary)

ALICE API (Binary)

ALICE Main Script (Binary)

ALICE Manual (Binary)

ALICE Troubleshooting (Binary)

Ballistics (Binary)

Collisions 3D (Binary)

Destructables (Binary)

Effects (Binary)

Entities (Binary)

Forces 3D (Binary)

Items (Binary)

Missiles (Binary)

Objects (Binary)

Units (Binary)

Widgets (Binary)

WidgetType (Binary)

as a casual user with knowledge only to gui this looks like basic chinese to me
but there is so much potentail here! hope it gets approved :peasant-thumbs-up-cheers:
Thanks :plol: Yea, it's a bit too technical mumbo-jumbo right now, but I hope there can be a GUI-friendly version in the future, or something built with it that is GUI-friendly.
 
Saying this resource is extensive is a severe understatement. I am glad to see someone else using spatial hashing... The performance you can get from these algorithms are amazing. I actually have the problem where the effect models themselves are more expensive to compute than the collision/pathing logic. With that being said we can reduce the number of table lookups from table[x][y] to table[index]. You can do this by doing:
index = x + y * 1e7 (works for any map size)

Edit:
You should consider doing effects all the way down. I've done it and the performance increase is stupendous.
Untitled.png
 
Saying this resource is extensive is a severe understatement. I am glad to see someone else using spatial hashing... The performance you can get from these algorithms are amazing. I actually have the problem where the effect models themselves are more expensive to compute than the collision/pathing logic. With that being said we can reduce the number of table lookups from table[x][y] to table[index]. You can do this by doing:
index = x + y * 1e7 (works for any map size)
Thank you, yes, the performance increase after I added the cell optimization was quite substantial. With my vJASS version, I was hardlocked at 181 objects (sqrt(32768), the max array size), but I estimate the maximum I could do without that restriction was 250. After translating it to Lua, I went up to 1000, so a ~16x performance increase. Then, after adding the cells, I went to 3000, so another ~10x performance increase, but probably much more, because, like you said, at such a high number of objects, rendering and moving the objects starts to take the majority of the resources.

You're right that I could improve the performance by doing linear indexing. However, I have to make sure that there are no bugs and I don't want to change anything about the core, because after converting it to linear indizes, the code becomes quite unreadable. Currently, I'm focused on getting the API to always work in the way you'd intuitively expect it to. I'm creating different scenarios and when I encounter a problem I can't solve, I change the engine such that I can.

I'm also not sure if linear indexing would make sense everywhere, because the math to get the index could be slower than the table lookup itself. I'd have to make some tests. Did you do tests on that?

Edit:
You should consider doing effects all the way down. I've done it and the performance increase is stupendous.
View attachment 468609
Holy ****, that's a lot of skeletons! :peek: With effects all the way down you mean replace units etc. with special effects? Well, I did make a map where there's like 5 units on the map and everything else are special effects... :plol: But, of course, that's not always feasible.
 
Level 2
Joined
Sep 3, 2023
Messages
7
Is there a way to automatically assign an actor for a destructible upon its creation? I can do it with unit by using a Unit Indexer library, but so far there is no function to detect a destructible entering the map if I am correct.
Does your system work on particles with different collision sizes and masses? I mean does it work if I have two spheres with radii 10000 and 100 colliding with each other?
 
Is there a way to automatically assign an actor for a destructible upon its creation? I can do it with unit by using a Unit Indexer library, but so far there is no function to detect a destructible entering the map if I am correct.
Yes, there is no trigger to detect a destructable entering, but, in the destructables library, I created hooks to create actors when the CreateDestructable functions are called. On map initialization, I loop over all destructables. A destructable being revived won't create one, though. That's a problem I haven't solved yet.

Does your system work on particles with different collision sizes and masses? I mean does it work if I have two spheres with radii 10000 and 100 colliding with each other?
Yes, that's not a problem. You can see in the video I posted above your post that there are rocks with different sizes and masses colliding with each other.

You can store the collision sizes of your particles in the table, then in your collision function do:
Lua:
local distance = ALICE_PairGetDistance()
if distance < particle1.collisionSize + particle2.collisionSize then
    DoStuff()
end
However, the engine also needs to know at which range it should start checking for collisions. That's done with the .radius field. You can take a look at the Cells example in the showcase map to see how that works.

Welcome to hive btw :plol:
 
Level 7
Joined
Sep 27, 2016
Messages
78
Haha, yea, you could build a sick RPG with it :psmile:. I'm actually looking into camera movement systems right now. Are you interested in that?

Thanks for the stars!

exactly, there no cure for that! lol

hmm.. like playing warcraft with 3d camera movement, but not always losing sight when walking under giant trees or the camera falling when walking through the hills?
 
exactly, there no cure for that! lol

hmm.. like playing warcraft with 3d camera movement, but not always losing sight when walking under giant trees or the camera falling when walking through the hills?
Hm, I'm not that far yet. Currently looking into ways to accurately track the mouse movement so you can move the camera with your mouse like in WoW. But you're talking about using the engine for the camera movement? If so, that's difficult, because camera positions are not synced and the engine needs to stay synced.

Do you have a map in mind that has that camera movement you're describing?

Thank you!
 
Level 7
Joined
Sep 27, 2016
Messages
78
Hm, I'm not that far yet.

bro, thats not too far.. you just managed to make the nearby trees faded and with physic/collision on progress..

Currently looking into ways to accurately track the mouse movement so you can move the camera with your mouse like in WoW.

that interesting.. cant wait for this.. really..

But you're talking about using the engine for the camera movement? If so, that's difficult, because camera positions are not synced and the engine needs to stay synced.

no, i meant not the camera thats moving, but my movement with 3rd camera.. sorry for my english.. maybe you can adjust the camera's distance of view when you near small trees / big trees / giant trees with accurate size of the trees or just simply hide the trees.. and adjust camera's height/offset when you walk on low/high ground with accurate height of the ground and the camera.. due to respect, you are the wizard of this matters.. im just a person who is always amazed by magic..

Do you have a map in mind that has that camera movement you're describing?

sorry, no longer have the maps, but Shadow of the Past and Daemonic's sword is not bad..
 
Last edited:
no, i meant not the camera thats moving, but my movement with 3rd camera.. sorry for my english.. maybe you can adjust the camera's distance of view when you near small trees / big trees / giant trees with accurate size of the trees or just simply hide the trees.. and adjust camera's height/offset when you walk on low/high ground with accurate height of the ground and the camera.. due to respect, you are the wizard of this matters.. im just a person who is always amazed by magic..
Ah, I see what you mean now. I totally forgot about the tree transparency thing in my video. :plol:

Yes, when you have a 3rd person camera like in WoW, it "collides" with objects and walls and goes around them. So, you'd need some kind of collision detection with the camera and the objects. Same thing if you want to make the objects transparent. The example in the video is really simple compared to a 3rd person camera in a 3D world. It's also based on the position of the hero and not on the position of the camera.

The collision detection could be done with ALICE. You would create an object that represents the camera that moves around the world. I would just need to upgrade the engine to allow interactions to be executed asynchronously if it's for a multiplayer map. One player has the camera over at location A and the camera is trying to go around tree B, the next player has the camera somewhere else and doesn't see the same collision detection being performed. This must not cause a desync.

That's my current thinking. Of course, there could be easier ways that I haven't considered yet.

sorry, no longer have the maps, but Shadow of the Past and Daemonic's sword is not bad..

They both just have regular game camera during gameplay, do they not?
 
Level 7
Joined
Sep 27, 2016
Messages
78
They both just have regular game camera during gameplay, do they not?

as i remember, they have 3rd person camera, but you know they are old maps, so i dont want to judge or anything, but sometimes i need to return the camera view back to normal view during gameplay :D ..

The collision detection could be done with ALICE. You would create an object that represents the camera that moves around the world. I would just need to upgrade the engine to allow interactions to be executed asynchronously if it's for a multiplayer map. One player has the camera over at location A and the camera is trying to go around tree B, the next player has the camera somewhere else and doesn't see the same collision detection being performed. This must not cause a desync.

that what i was talking about :D.. camera's distance get closer to the hero, if there a wall or trees behind the hero, but not change the view front the hero.. i mean it will change the field of view..
 
as i remember, they have 3rd person camera, but you know they are old maps, so i dont want to judge or anything, but sometimes i need to return the camera view back to normal view during gameplay :D ..
Well, hopefully a mouse-controlled camera doesn't turn out to be too jank, so RPG maps can use that :psmile:. With such a camera, you would also need WASD movement then. I can't get over the fact that none of these RPGs have their own movement system (at least drag-move) and it's just clicking everywhere while your hero is constantly spamming "A sound plan." "Of course." "For honor." "A sound plan." and so on.
 
Level 7
Joined
Sep 27, 2016
Messages
78
Well, hopefully a mouse-controlled camera doesn't turn out to be too jank, so RPG maps can use that :psmile:. With such a camera, you would also need WASD movement then. I can't get over the fact that none of these RPGs have their own movement system (at least drag-move) and it's just clicking everywhere while your hero is constantly spamming "A sound plan." "Of course." "For honor." "A sound plan." and so on.


check this out..
 
Last edited:
Level 2
Joined
Sep 3, 2023
Messages
7
Very nice update. I have a half-built particle system in JASS but may just give up finalizing it since this system is much more efficient.
 
The way the missiles just uncontrollably bounce off the force field is pure chef kiss.
Thank you! :psmile:

Very nice update. I have a half-built particle system in JASS but may just give up finalizing it since this system is much more efficient.
My system is Lua-only. Can you make the switch to Lua?


And here's the change log:

Version 2.0
  • Added ready-to-use libraries - Objects, Entities, Missiles, Collisions, Ballistics, and Forces.
  • Return values in interaction functions are now optional. If the return value is omitted, ALICE will automatically put pairs using that function into the optimized EveryStep cycle.
  • Added API functions to add or remove self-interactions.
  • Added the Matrix API. These functions can be used to write data tables and share data between object pairs.
  • ALICE now uses the WidgetType library to infer the correct type of objects passed into it.
  • To improve performance with widgets, Math API functions now use cached values for object coordinates that get reset each cycle.
  • Freeze protection is now based on evaluation time instead of number of pairs.
  • ALICE_Benchmark can now be used to view the evaluation time of each cycle.
  • Added the HALT_ON_FIRST_CRASH option in the config.
  • Reorganized API into Core and Advanced API.
 
Top