A Community discussion forum for Halo Custom Edition, Halo 2 Vista, Portal and Halo Machinima

Home  Search Register  Login Member ListRecent Posts
  
 
»Forums Index »Halo Custom Edition (Bungie/Gearbox) »Halo CE General Discussion »AI CUSTOM MAP WITH SCORE THAT COUNTS

Author Topic: AI CUSTOM MAP WITH SCORE THAT COUNTS (5 messages, Page 1 of 1)
Moderators: Dennis

Crossbow SR
Joined: May 23, 2013

-


Posted: Dec 13, 2017 06:52 PM    Msg. 1 of 5       
-
Edited by Crossbow SR on Jan 10, 2018 at 07:20 AM


MatthewDratt
Joined: Sep 11, 2010

Newly redesigned MattDratt.com


Posted: Dec 13, 2017 07:58 PM    Msg. 2 of 5       
call kirby


DeadHamster
Joined: Jun 8, 2014


Posted: Dec 14, 2017 08:08 AM    Msg. 3 of 5       
https://opencarnage.net/index.php?/topic/3683-hamp-made-ai-sync/

I've done it before, but it only works in Combat Evolved (PC), not Custom Edition. The server doing a checksum comparison doesn't allow for different mapfiles between client and host.


Example:


Server

(object_teleport SYNC_VEHI sync_point)

(sleep 15)



;;SECTION 1


(if (< SCORE 10) (sleep 1) (object_teleport veh10 tens_place) )

(if (< SCORE 20) (sleep 1) (object_teleport veh20 tens_place) )

(if (< SCORE 20) (sleep 1) (object_teleport veh30 tens_place) )
(if (< SCORE 30) (sleep 1) (object_teleport veh40 tens_place) )
(if (< SCORE 40) (sleep 1) (object_teleport veh50 tens_place) )
(if (< SCORE 50) (sleep 1) (object_teleport veh60 tens_place) )

...

(if (< SCORE 90) (sleep 1) (object_teleport veh90 tens_place) )



;;SECTION 2


(if (volume_test_object tens_place veh90) (set SCORE (- SCORE 10) ) )
(if (volume_test_object tens_place veh80) (set SCORE (- SCORE 10) ) )
(if (volume_test_object tens_place veh70) (set SCORE (- SCORE 10) ) )
(if (volume_test_object tens_place veh60) (set SCORE (- SCORE 10) ) )

...

(if (volume_test_object tens_place veh10) (set SCORE (- SCORE 10) )


;;SECTION 3


(if (< SCORE 1) (sleep 1) (object_teleport veh1 sing_place)
(if (< SCORE 2) (sleep 1) (object_teleport veh2 sing_place)
(if (< SCORE 3) (sleep 1) (object_teleport veh3 sing_place)
(if (< SCORE 4) (sleep 1) (object_teleport veh4 sing_place)
...


(if (< SCORE 9) (sleep 1) (object_teleport veh9 sing_place)


(sleep 120)

(object_teleport SYNC_VEHI restarting_point)
(object_teleport veh_1 restarting_point)
(object_teleport veh_2 restarting_point)
(object_teleport veh_3 restarting_point)

...

(object_teleport veh_90 restarting_point)


Client

(sleep_until (volume_test_object SYNC_VEHI sync_point)

(sleep 60)

(if (volume_test_object tens_place VEH_90) (set SCORE (+ SCORE 10) ) )
(if (volume_test_object tens_place VEH_80) (set SCORE (+ SCORE 10) ) )
(if (volume_test_object tens_place VEH_70) (set SCORE (+ SCORE 10) ) )


...

(if (volume_test_object tens_place VEH_10) (set SCORE (+ SCORE 10) ) )


;; Section 2

(if (volume_test_object sing_place VEH_9) (set SCORE (+ SCORE 1) ) )
(if (volume_test_object sing_place VEH_8) (set SCORE (+ SCORE 1) ) )
(if (volume_test_object sing_place VEH_7) (set SCORE (+ SCORE 1) ) )


...

(if (volume_test_object sing_place VEH_1) (set SCORE (+ SCORE 1) ) )


To make sense of that garble-guck, There's a trigger volume for the tens place, a trigger volume for the singles place, and 9 vehicles for each one (veh_1-veh_9, and for the tens-place, veh_10-veh_90)

The Server Script;

Section 1 places a named biped in if the score is high enough. A score of 46 will spawn veh_10, veh_20, veh_30 and veh_40.

Section 2 chops off the tens place of the score based on what we just placed. If we placed veh_10-veh_40, it would chop off 10 points 4 times, bringing our SCORE to 6.

Section 3 places a named vehicle into the singles area if the score is high enough. An original score of 46 turns into 6, and so will place veh_1 - veh_6. Then it sleeps long enough for clients to sync the score, before moving all vehicles to a restarting location while we wait for a while to resync the score.

So, if the score is 46, we have 4 vehicles (10-40) inside the tens-place Trigger Volume, and we have 6 vehicles (1-6) inside the single-place Trigger Volume.

On the client side, we pick up the server is about to sync us the score, give it some time to calculate that score, and then do a read for what is where. If there's a veh_10 inside the volume, we add 10 to the score, if there's a veh_20, we add another 10 (20 total). So if 46 was our server score, veh_10 - veh_40 are there, as are veh_1 - veh_6. We add 10 for each of the tens-place vehicles (total of 40), and 1 for each of the singles place (total of 6).

When it's all said and done, we added 10 4 times for the 4 vehicles, and 1 6 times for the 6 vehicles, giving us 46.

In the meantime, between syncs we use a simple tracker for keeping all players that are ingame updated. Each kill adds 1 to REALSCORE, which is handled in the AI's individual script (because yes, all 8 of my AI are running their own respawning scripts, it's not handled by a single central script).




Server

(script continuous update

(sleep_until (!= REALSCORE CLIENTSCORE) )

(object_teleport SCORE_HOG score_spot)

(sleep 30)

(set CLIENTSCORE (+ CLIENTSCORE 1)
(object_teleport SCORE_HOG somewhere_else)

(sleep 20)

)




Client


(sleep_until (volume_test_object SCORE_HOG score_volume) )


(set SCORE (+ SCORE 1)

(sleep 50) ;;total sleep time of server script



So for the most part, the players are updated point by point, and get a full sync every so often, or optionally you can set the full-sync to also occur when a player joins or exits;



(script continuous check_for_sync)

(set #newPLAYERS (list_count (players)) )

(if (!= #newPLAYERS #oldPLAYERS) (set CHANGE_BOOLEAN true) )



(set #oldPLAYERS #newPLAYERS)

(sleep 5)

)



(script continuous SYNC_OVERRIDE

(sleep 9000) ;; 5 minutes real-time

(set CHANGE_BOOLEAN true)

)


You would edit the SYNC script to add (sleep_until (= CHANGE_BOOLEAN true) ), and then at the end of each pass where you start resetting the bipeds adding a (set CHANGE_BOOLEAN false) command to reset itself. And by doing that, every time a player joins or leaves the syncing script will run, letting any new players get the updated score. Every 5 minutes, the script is also ran regardless, making sure all players are on the same page.

Mind you, I'd probably have to adjust the sleep times a lot to take into account network lag. On a LAN this would run flawlessly, Lag takes it's toll on anything that runs on a clock. However, by using a same-starting point (when the vehicle is placed), the time should match up. If my lag is 4 seconds, and it takes .5 seconds to run a code, I should recieve the next part of the code 4.5 seconds after the first part started, exactly when I should anyway.




/copypaste



I could have improves on the lagtime slightly, but end result is syncing AI in a stock Halo PC server, without any add-ons, that has the same apparent lagtime as a dial-up game. For Halo's netcode, not too bad. Also, the above is an extremely crude and inefficient counting system, I could easily change it to a bit system as opposed to a ten point counting system and achieve significantly higher data limits or use significantly less objects.





Edit:


Found the scripts that actually synced the AI, the above is just syncing the scores;



(global short bip1_health 1)
(global short bip2_health 1)
(global short bip3_health 1)
(global short bip4_health 1)
(global short bip5_health 1)
(global short bip6_health 1)
(global short bip7_health 1)
(global short bip8_health 1)

(script startup map_start





(object_create s1)
(object_create s2)
(object_create s3)
(object_create s4)
(object_create s5)
(object_create s6)
(object_create s7)
(object_create s8)





)




(script startup AI_start


(ai_attach s1 syncing)
(ai_attach s2 syncing)
(ai_attach s3 syncing)
(ai_attach s4 syncing)
(ai_attach s5 syncing)
(ai_attach s6 syncing)
(ai_attach s7 syncing)
(ai_attach s8 syncing)


(objects_attach s1 body v1 body)
(objects_attach s2 body v2 body)
(objects_attach s3 body v3 body)
(objects_attach s4 body v4 body)
(objects_attach s5 body v5 body)
(objects_attach s6 body v6 body)
(objects_attach s7 body v7 body)
(objects_attach s8 body v8 body)






)



(script continuous AI8

(objects_detach s8 v8)
(sleep 1)
(objects_attach s8 body v8 body)
(sleep_until (= bip8_health 1) 5)


)


(script continuous AI7
(objects_attach s7 body v7 body)

(sleep 1)
(objects_detach s7 v7)
(sleep_until (= bip7_health 1) 5)


)


(script continuous AI6
(objects_attach s6 body v6 body)

(sleep 1)
(objects_detach s6 v6)
(sleep_until (= bip6_health 1) 5)


)


(script continuous AI5
(objects_attach s5 body v5 body)

(sleep 1)
(objects_detach s5 v5)
(sleep_until (= bip5_health 1) 5)


)


(script continuous AI4
(objects_attach s4 body v4 body)

(sleep 1)
(objects_detach s4 v4)
(sleep_until (= bip4_health 1) 5)


)


(script continuous AI3
(objects_attach s3 body v3 body)

(sleep 1)
(objects_detach s3 v3)
(sleep_until (= bip3_health 1) 5)


)



(script continuous AI2
(objects_attach s2 body v2 body)

(sleep 1)
(objects_detach s2 v2)
(sleep_until (= bip2_health 1) 5)


)


(script continuous AI1
(objects_attach s1 body v1 body)

(sleep 1)
(objects_detach s1 v1)
(sleep_until (= bip1_health 1) 5)


)



(script continuous AI_HEALTH8

(sleep_until (= (unit_get_health s8) 0) 5)
(set bip8_health 0)
(sleep 120)
(object_destroy s8)

(object_destroy v8)
(object_create s8)
(object_create v8)
(ai_attach s8 syncing)
(set bip8_health 1)


)


(script continuous AI_HEALTH7

(sleep_until (= (unit_get_health s7) 0) 5)
(set bip7_health 0)
(sleep 120)
(object_destroy s7)

(object_destroy v7)
(object_create s7)
(object_create v7)
(ai_attach s7 syncing)
(set bip7_health 1)




)


(script continuous AI_HEALTH6

(sleep_until (= (unit_get_health s6) 0) 5)
(set bip6_health 0)
(sleep 120)
(object_destroy s6)

(object_destroy v6)
(object_create s6)
(object_create v6)
(ai_attach s6 syncing)
(set bip6_health 1)


)


(script continuous AI_HEALTH5

(sleep_until (= (unit_get_health s5) 0) 5)
(set bip5_health 0)
(sleep 120)
(object_destroy s5)

(object_destroy v5)
(object_create s5)
(object_create v5)
(ai_attach s5 syncing)
(set bip5_health 1)


)


(script continuous AI_HEALTH4

(sleep_until (= (unit_get_health s4) 0) 5)
(set bip4_health 0)
(sleep 120)
(object_destroy s4)

(object_destroy v4)
(object_create s4)
(object_create v4)
(ai_attach s4 syncing)
(set bip4_health 1)

)



(script continuous AI_HEALTH3

(sleep_until (= (unit_get_health s3) 0) 5)
(set bip3_health 0)
(sleep 120)
(object_destroy s3)

(object_destroy v3)
(object_create s3)
(object_create v3)
(ai_attach s3 syncing)
(set bip3_health 1)

)


(script continuous AI_HEALTH2

(sleep_until (= (unit_get_health s2) 0) 5)
(set bip2_health 0)
(sleep 120)
(object_destroy s2)

(object_destroy v2)
(object_create s2)
(object_create v2)
(ai_attach s2 syncing)
(set bip2_health 1)

)


(script continuous AI_HEALTH1

(sleep_until (= (unit_get_health s1) 0) 5)
(set bip1_health 0)
(sleep 120)
(object_destroy s1)

(object_destroy v1)
(object_create s1)
(object_create v1)
(ai_attach s1 syncing)
(set bip1_health 1)


)





By linking the "Body" node to the "Body" node of the other model, they orient properly.

Here's a breakdown; The V1-8 are vehicles with the model/animations of the biped. The S1-8 are the bipeds that are the actual AI. This is the host script, the clients had no scripts running at all.

The Vehicles have no collision as this would block shots towards the AI. They're basically markers for the players to know where the bipeds are, when you're shooting the AI you're hitting an invisible biped.

Once the biped dies, the script destroys the vehicle and recreates everything. Here's ALL the bugs that I know of;

Converted server map ran an exception. CE map has no issues, therefore I blame Harbinger for a poor conversion.
"Dummy" vehicles occasionally show up on client side after an AI is killed. Instead of disappearing when dead, the vehicle-marker just stays there frozen in place. This is caused by the sudden delete/respawn of the vehicles server side. This can be fixed by including a client-side script to delete all the vehicles every x minutes. Even if it deletes some of the "real" vehicles, they'll be instantly recreated for the client by the server pushing the info.
LAG. The lead on the AI is two-fold, because of standard network lag, and script lag. Specifically, the time between attach/detach and sending that data over the server. You have to aim in front of the vehicle even on LAN because the vehicle is always a few steps behind.

This can be helped by removing the (sleep) commands from AI1-AI8, and also by removing the (sleep_until) commands from those and re-writing the AI_health scripts to pause the respawning instead. So instead of checking for health, it's just always running and is stopped by the health script.

EDIT: forgot to clarify that the "dummy" vehicle problem is an occasional thing, I'd say 1 of 10 AI that's killed gets frozen. Mind you, the AI still respawns and still has it's new vehicle-marker, there's just another instance of the marker frozen where the old AI died.
Edited by DeadHamster on Dec 14, 2017 at 08:17 AM


Crossbow SR
Joined: May 23, 2013

-


Posted: Dec 14, 2017 02:22 PM    Msg. 4 of 5       
-
Edited by Crossbow SR on Jan 10, 2018 at 07:21 AM


lolslayer
Joined: Mar 21, 2015

https://www.youtube.com/watch?v=uMHbAKvPJkU


Posted: Dec 15, 2017 06:36 AM    Msg. 5 of 5       
Nice explenation Deadhamster, well done!

 

 
Previous Older Thread    Next newer Thread







Time: Sat June 23, 2018 5:33 PM 359 ms.
A Halo Maps Website