PDA

View Full Version : AI in multiplayer


Shred18
02-26-2005, 01:35 AM
How come a placed enemy in JK wont be there in a multiplayer level? It seems enemies only show up if you spawn it during the game.

Would it be possible to assign a cog to the template of an npc so it would spawn itself on startup? :o

a_person
02-26-2005, 03:31 AM
Someone correct me if im wrong, but im pretty sure that if you spawn an ai in mp, every player has a different unit, eg if you kill it the other players still have to kill thiers. I think that you have to synchronise the ai, but dont ask me how its done. Try looking into the cog section at massassi.

G-Man
02-26-2005, 04:22 AM
yeah I got a cog for it

pm me on msn massassian@hotmail.de

Shred18
02-26-2005, 07:35 PM
Right.. There is a cog for placing them in custom levels (which is pretty complex, and I can't figure it out)

The goal is to play a single player level in multiplayer, without having to replace every npc with a ghost, and link it to a cog.

Shred18
02-26-2005, 09:44 PM
well, I shuffled around the templates so I dont have to change them by hand in JED :D so now all the enemy positions are ghost positions and they have a cog in thier template to spawn an enemy on startup.

But its acting odd.. no enemies spawn in the right place, but one of each spawns at the first walkplayer.

all I have in the startup message is:

CreateThingNR(rfist,GetSourceRef());

Seems like it should work
:confused:

darthslaw
02-26-2005, 11:15 PM
GetSourceRef() doesn't work for the startup message. (ie there is no source or sender for the startup message).

Try this one.
It finds all instances of some template ('oldtemp') and creates a certain enemy ('enemy') at the same position.

[edit] I really ought to be more specific :rolleyes: This is a level cog not a class cog.

flags=0x240
symbols

template enemy # enemy template to be created at all old templates
template oldtemp #old template in your level

int i local

message startup

end

code
startup:
sleep(0.1);
for(i = 0; i < GetThingCount(); i = i + 1) if(GetThingTemplate(i) == oldtemp) CreateThing(enemy, i);

return;
end

Shred18
02-27-2005, 12:50 AM
Ah, awesome :D

It doesnt work when trying to replace an enemy template, but I changed all placed instances of an enemy to my own custom ghost templates via a text editor, and it works with that.


Now.. how am I going to sync them :o

I'm thinking a trigger sent in via the killed message. Will their positions stay synced while alive though?

a_person
02-27-2005, 04:13 AM
I dont think so, since the each player has to kill his/her enemy it means that the enemy is different on all comps. Im not quite sure how to sinc it. Try asking a cog master.

LKOH_SniperWolf
02-27-2005, 11:52 AM
No, they aren't synced while alive, unless it's specifically done, which is the point of the Nightmare AI Sync cog. Problem is, syncing them generally introduces some amount of lag.

Shred18
02-27-2005, 12:25 PM
did some testing, yeah, they aren't synced at all, but the times they become most un-synced are when one player kills one, but it doesnt get killed on the other computers :)

Ok, heres what I came up with:

in the enemy templates cog ive got:

created:
reeyees=GetSenderRef();
Setpulse(3.0);
Return;

pulse:
SyncThingPos(reeyees); //sync over multi
Print("syncing!");
return;

I could probably set the pulse higher, maybe 5 or 6 seconds.

then in the killed message, I sent a trigger:

trigger:
if(GetSourceRef() == 20001)
{
Print("damagetodeath!");
if(GetThingHealth(reeyees) > 0) //call killed here.
{
DamageThing(reeyees, 200, 0x1, -1);
}

That should make sure it dies on every computer at once. Anyone think this will work?

zagibu
02-27-2005, 12:40 PM
I think the problem is, that the reeyees thing is not the same on every computer. Each player gets an own set of enemies, acting completely independent from other player's set. So it's probably not just the killing act that has to be synced.

El Scorcho
02-27-2005, 02:37 PM
Nothing is really synced. In ideal network conditions, the ai will probably make the same decisions on all machines and appear to be synced until death. But if things get a little iffy and the pos gets off...it'll get ugly.

The solution to this is of course to write an entirely new set of AI in cog, run the logic only on the server and sync the movements and reactions to everyone. Thats basically what nightmare's cog does.

Lord_Grismath
02-28-2005, 09:23 PM
...at great, great length.

Shred18
03-01-2005, 04:35 PM
OK, the positional syncing works, and quite well :D

occasionally an enemy will snap back to it's correct position (that of the hosts) It happens rarely, and its definately playable.

The death syncing on the other hand doesnt work. I've run into one situation where an enemy stayed alive on my computer after dying on the hosts.

The server is the one that creates the enemies, btw. Any ideas?

I'm thinking I should get the thing number, and destoy it if it doesnt exist on all computers or something..

darthslaw
03-01-2005, 04:40 PM
except the thing number could be different on each computer

atm, I have no ideas for you, because thing signatures could then also be different.

a_person
03-02-2005, 04:08 AM
Im not sure if it will work but you could try doing something when the thing is created, I think object = thing or something like that does it. Then check to see if object is dead on a comp and instead of destroything do the DamageThing(getthinghealth(thing),thing)

NOTE: Cog verbs I say may not, and probably are not right. It may pay to look it up.

Or the CaptureThing verb may help?

Or you could make each enemy under a different under a different template so that if one dies on someones comp you will just be able to kill everything on the template.

Would any of that work? Or am I just speaking crap.

darthslaw
03-02-2005, 07:04 PM
maybe when creating the template, set the user data to some unique value (like the thing signature that is assigned on only the host, so we don't have duplicate values). Then when suchandsuch an enemy is killed (on any comp), send a trigger with the userdata as one of the parameters and all enemy templates with that user data value will receive the trigger and die also.

El Scorcho
03-03-2005, 05:47 PM
GetThingUserData isn't synced though. Why not just just in the damaged message and have:

If(!IsServer)
{
returnex(0);
return;
}

Then it'll only die if the server got wind of it.

I'm surprised anything else is synced though, but I guess I figured it was a new thing being created on each machine not one created on the server.

Hell Raiser
03-03-2005, 06:22 PM
Originally posted by Darth Slaw
except the thing number could be different on each computer

atm, I have no ideas for you, because thing signatures could then also be different.

Thing numbers (and signatures) are the same on all computers for every Thing, so long as the template being created isn't in static.jkl

darthslaw
03-03-2005, 07:35 PM
I know userdata isn't synced.
I'm so vague sometimes... Server creates thing on host comp only, sets the userdata, then sends a trigger with the userdata to create an enemy on all clients and set their userdata as well.

I also assumed the 0x240 flag was in use, so the thing numbers wouldn't necessarily be the same on all computers (I don't think anyway... lack of experience so I dunno for sure...)

I assume too much... And to think I just had assume broken down for me the other day "if you assume you make an a** of u and me"