about summary refs log tree commit diff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/client/gc_client.cpp183
-rw-r--r--src/game/client/gc_client.h32
-rw-r--r--src/game/client/gc_hooks.cpp112
-rw-r--r--src/game/client/gc_menu.cpp16
-rw-r--r--src/game/client/gc_render.cpp30
-rw-r--r--src/game/client/gc_render.h12
-rw-r--r--src/game/client/gc_render_obj.cpp57
-rw-r--r--src/game/g_game.cpp6
-rw-r--r--src/game/g_game.h6
-rw-r--r--src/game/g_layers.cpp2
-rw-r--r--src/game/g_protocol.def211
-rw-r--r--src/game/g_protocol.h5
-rw-r--r--src/game/server/gs_common.h12
-rw-r--r--src/game/server/gs_game.cpp8
-rw-r--r--src/game/server/gs_game_ctf.cpp6
-rw-r--r--src/game/server/gs_server.cpp99
16 files changed, 543 insertions, 254 deletions
diff --git a/src/game/client/gc_client.cpp b/src/game/client/gc_client.cpp
index 20d1df7c..8446d729 100644
--- a/src/game/client/gc_client.cpp
+++ b/src/game/client/gc_client.cpp
@@ -27,7 +27,7 @@ extern "C" {
 struct data_container *data = 0;
 int64 debug_firedelay = 0;
 
-player_input input_data = {0};
+NETOBJ_PLAYER_INPUT input_data = {0};
 int input_target_lock = 0;
 
 int chat_mode = CHATMODE_NONE;
@@ -40,11 +40,16 @@ tuning_params tuning;
 vec2 mouse_pos;
 vec2 local_character_pos;
 vec2 local_target_pos;
-const obj_player_character *local_character = 0;
-const obj_player_character *local_prev_character = 0;
-const obj_player_info *local_info = 0;
-const obj_flag *flags[2] = {0,0};
-const obj_game *gameobj = 0;
+
+/*
+const NETOBJ_PLAYER_CHARACTER *local_character = 0;
+const NETOBJ_PLAYER_CHARACTER *local_prev_character = 0;
+const NETOBJ_PLAYER_INFO *local_info = 0;
+const NETOBJ_FLAG *flags[2] = {0,0};
+const NETOBJ_GAME *gameobj = 0;
+*/
+
+snapstate netobjects;
 
 int picked_up_weapon = -1;
 
@@ -54,7 +59,7 @@ void client_data::update_render_info()
 	render_info = skin_info;
 
 	// force team colors
-	if(gameobj && gameobj->gametype != GAMETYPE_DM)
+	if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM)
 	{
 		const int team_colors[2] = {65387, 10223467};
 		if(team >= 0 || team <= 1)
@@ -232,7 +237,7 @@ void chat_add_line(int client_id, int team, const char *line)
 		if(client_datas[client_id].team == -1)
 			chat_lines[chat_current_line].name_color = -1;
 
-		if(gameobj && gameobj->gametype != GAMETYPE_DM)
+		if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM)
 		{
 			if(client_datas[client_id].team == 0)
 				chat_lines[chat_current_line].name_color = 0;
@@ -261,41 +266,40 @@ void process_events(int snaptype)
 		SNAP_ITEM item;
 		const void *data = snap_get_item(snaptype, index, &item);
 
-		if(item.type == EVENT_DAMAGEINDICATION)
+		if(item.type == NETEVENTTYPE_DAMAGEIND)
 		{
-			ev_damageind *ev = (ev_damageind *)data;
+			NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)data;
 			effect_damage_indicator(vec2(ev->x, ev->y), get_direction(ev->angle));
 		}
-		else if(item.type == EVENT_AIR_JUMP)
+		else if(item.type == NETEVENTTYPE_AIR_JUMP)
 		{
-			ev_common *ev = (ev_common *)data;
+			NETEVENT_COMMON *ev = (NETEVENT_COMMON *)data;
 			effect_air_jump(vec2(ev->x, ev->y));
 		}
-		else if(item.type == EVENT_EXPLOSION)
+		else if(item.type == NETEVENTTYPE_EXPLOSION)
 		{
-			ev_explosion *ev = (ev_explosion *)data;
+			NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)data;
 			effect_explosion(vec2(ev->x, ev->y));
 		}
-		else if(item.type == EVENT_SMOKE)
+		/*else if(item.type == EVENT_SMOKE)
 		{
-			ev_explosion *ev = (ev_explosion *)data;
+			EV_EXPLOSION *ev = (EV_EXPLOSION *)data;
 			vec2 p(ev->x, ev->y);
-		}
-		else if(item.type == EVENT_PLAYERSPAWN)
+		}*/
+		else if(item.type == NETEVENTTYPE_SPAWN)
 		{
-			ev_explosion *ev = (ev_explosion *)data;
+			NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)data;
 			effect_playerspawn(vec2(ev->x, ev->y));
 		}
-		else if(item.type == EVENT_DEATH)
+		else if(item.type == NETEVENTTYPE_DEATH)
 		{
-			ev_explosion *ev = (ev_explosion *)data;
+			NETEVENT_DEATH *ev = (NETEVENT_DEATH *)data;
 			effect_playerdeath(vec2(ev->x, ev->y));
 		}
-		else if(item.type == EVENT_SOUND_WORLD)
+		else if(item.type == NETEVENTTYPE_SOUND_WORLD)
 		{
-			ev_sound *ev = (ev_sound *)data;
-			if(ev->sound >= 0 && ev->sound < NUM_SOUNDS)
-				snd_play_random(CHN_WORLD, ev->sound, 1.0f, vec2(ev->x, ev->y));
+			NETEVENT_SOUND_WORLD *ev = (NETEVENT_SOUND_WORLD *)data;
+			snd_play_random(CHN_WORLD, ev->soundid, 1.0f, vec2(ev->x, ev->y));
 		}
 	}
 }
@@ -303,12 +307,7 @@ void process_events(int snaptype)
 void clear_object_pointers()
 {
 	// clear out the invalid pointers
-	local_character = 0;
-	local_prev_character = 0;
-	local_info = 0;
-	flags[0] = 0;
-	flags[1] = 0;
-	gameobj = 0;
+	mem_zero(&netobjects, sizeof(netobjects));
 }
 
 void send_info(bool start)
@@ -526,16 +525,16 @@ void render_goals(float x, float y, float w)
 
 	// render goals
 	//y = ystart+h-54;
-	if(gameobj && gameobj->time_limit)
+	if(netobjects.gameobj && netobjects.gameobj->time_limit)
 	{
 		char buf[64];
-		str_format(buf, sizeof(buf), "Time Limit: %d min", gameobj->time_limit);
+		str_format(buf, sizeof(buf), "Time Limit: %d min", netobjects.gameobj->time_limit);
 		gfx_text(0, x+w/2, y, 24.0f, buf, -1);
 	}
-	if(gameobj && gameobj->score_limit)
+	if(netobjects.gameobj && netobjects.gameobj->score_limit)
 	{
 		char buf[64];
-		str_format(buf, sizeof(buf), "Score Limit: %d", gameobj->score_limit);
+		str_format(buf, sizeof(buf), "Score Limit: %d", netobjects.gameobj->score_limit);
 		gfx_text(0, x+40, y, 24.0f, buf, -1);
 	}
 }
@@ -560,14 +559,14 @@ void render_spectators(float x, float y, float w)
 		SNAP_ITEM item;
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-		if(item.type == OBJTYPE_PLAYER_INFO)
+		if(item.type == NETOBJTYPE_PLAYER_INFO)
 		{
-			const obj_player_info *info = (const obj_player_info *)data;
+			const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
 			if(info->team == -1)
 			{
 				if(count)
 					strcat(buffer, ", ");
-				strcat(buffer, client_datas[info->clientid].name);
+				strcat(buffer, client_datas[info->cid].name);
 				count++;
 			}
 		}
@@ -595,7 +594,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 	// render title
 	if(!title)
 	{
-		if(gameobj->game_over)
+		if(netobjects.gameobj->game_over)
 			title = "Game Over";
 		else
 			title = "Score Board";
@@ -611,10 +610,11 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 	{
 		gfx_text(0, x+10, y, 48, title, -1);
 
-		if(gameobj)
+		if(netobjects.gameobj)
 		{
 			char buf[128];
-			str_format(buf, sizeof(buf), "%d", gameobj->teamscore[team&1]);
+			int score = team ? netobjects.gameobj->teamscore_blue : netobjects.gameobj->teamscore_red;
+			str_format(buf, sizeof(buf), "%d", score);
 			tw = gfx_text_width(0, 48, buf, -1);
 			gfx_text(0, x+w-tw-30, y, 48, buf, -1);
 		}
@@ -623,16 +623,16 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 	y += 54.0f;
 
 	// find players
-	const obj_player_info *players[MAX_CLIENTS] = {0};
+	const NETOBJ_PLAYER_INFO *players[MAX_CLIENTS] = {0};
 	int num_players = 0;
 	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
 	{
 		SNAP_ITEM item;
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-		if(item.type == OBJTYPE_PLAYER_INFO)
+		if(item.type == NETOBJTYPE_PLAYER_INFO)
 		{
-			players[num_players] = (const obj_player_info *)data;
+			players[num_players] = (const NETOBJ_PLAYER_INFO *)data;
 			num_players++;
 		}
 	}
@@ -644,7 +644,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 		{
 			if(players[i]->score < players[i+1]->score)
 			{
-				const obj_player_info *tmp = players[i];
+				const NETOBJ_PLAYER_INFO *tmp = players[i];
 				players[i] = players[i+1];
 				players[i+1] = tmp;
 			}
@@ -660,7 +660,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 	// render player scores
 	for(int i = 0; i < num_players; i++)
 	{
-		const obj_player_info *info = players[i];
+		const NETOBJ_PLAYER_INFO *info = players[i];
 
 		// make sure that we render the correct team
 		if(team == -1 || info->team != team)
@@ -683,18 +683,19 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 		
 		if(config.cl_show_player_ids)
 		{
-			str_format(buf, sizeof(buf), "%d | %s", info->clientid, client_datas[info->clientid].name);
+			str_format(buf, sizeof(buf), "%d | %s", info->cid, client_datas[info->cid].name);
 			gfx_text(0, x+128, y, font_size, buf, -1);
 		}
 		else
-			gfx_text(0, x+128, y, font_size, client_datas[info->clientid].name, -1);
+			gfx_text(0, x+128, y, font_size, client_datas[info->cid].name, -1);
 
 		str_format(buf, sizeof(buf), "%4d", info->latency);
 		float tw = gfx_text_width(0, font_size, buf, -1);
 		gfx_text(0, x+w-tw-35, y, font_size, buf, -1);
 
 		// render avatar
-		if((flags[0] && flags[0]->carried_by == info->clientid) || (flags[1] && flags[1]->carried_by == info->clientid))
+		if((netobjects.flags[0] && netobjects.flags[0]->carried_by == info->cid) ||
+			(netobjects.flags[1] && netobjects.flags[1]->carried_by == info->cid))
 		{
 			gfx_blend_normal();
 			gfx_texture_set(data->images[IMAGE_GAME].id);
@@ -708,7 +709,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
 			gfx_quads_end();
 		}
 		
-		render_tee(&idlestate, &client_datas[info->clientid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
+		render_tee(&idlestate, &client_datas[info->cid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
 
 		
 		y += 50.0f;
@@ -739,21 +740,21 @@ void render_game()
 
 	if(config.cl_predict)
 	{
-		if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over))
+		if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over))
 		{
 			// don't use predicted
 		}
 		else
 			local_character_pos = mix(predicted_prev_player.pos, predicted_player.pos, client_predintratick());
 	}
-	else if(local_character && local_prev_character)
+	else if(netobjects.local_character && netobjects.local_prev_character)
 	{
 		local_character_pos = mix(
-			vec2(local_prev_character->x, local_prev_character->y),
-			vec2(local_character->x, local_character->y), client_intratick());
+			vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
+			vec2(netobjects.local_character->x, netobjects.local_character->y), client_intratick());
 	}
 	
-	if(local_info && local_info->team == -1)
+	if(netobjects.local_info && netobjects.local_info->team == -1)
 		spectate = true;
 
 	animstate idlestate;
@@ -1089,7 +1090,7 @@ void render_game()
 		gfx_quads_end();
 	}*/
 
-	if(local_character && !spectate && !(gameobj && gameobj->game_over))
+	if(netobjects.local_character && !spectate && !(netobjects.gameobj && netobjects.gameobj->game_over))
 	{
 		gfx_texture_set(data->images[IMAGE_GAME].id);
 		gfx_quads_begin();
@@ -1097,7 +1098,7 @@ void render_game()
 		// render cursor
 		if (!menu_active && !emoticon_selector_active)
 		{
-			select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_cursor);
+			select_sprite(data->weapons[netobjects.local_character->weapon%data->num_weapons].sprite_cursor);
 			float cursorsize = 64;
 			draw_sprite(local_target_pos.x, local_target_pos.y, cursorsize);
 		}
@@ -1113,10 +1114,10 @@ void render_game()
 		
 		// if weaponstage is active, put a "glow" around the stage ammo
 		select_sprite(SPRITE_TEE_BODY);
-		for (int i = 0; i < local_character->weaponstage; i++)
-			gfx_quads_drawTL(x+local_character->ammocount * 12 -i*12, y+22, 11, 11);
-		select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_proj);
-		for (int i = 0; i < min(local_character->ammocount, 10); i++)
+		for (int i = 0; i < netobjects.local_character->weaponstage; i++)
+			gfx_quads_drawTL(x+netobjects.local_character->ammocount * 12 -i*12, y+22, 11, 11);
+		select_sprite(data->weapons[netobjects.local_character->weapon%data->num_weapons].sprite_proj);
+		for (int i = 0; i < min(netobjects.local_character->ammocount, 10); i++)
 			gfx_quads_drawTL(x+i*12,y+24,10,10);
 
 		gfx_quads_end();
@@ -1127,7 +1128,7 @@ void render_game()
 
 		// render health
 		select_sprite(SPRITE_HEALTH_FULL);
-		for(; h < local_character->health; h++)
+		for(; h < netobjects.local_character->health; h++)
 			gfx_quads_drawTL(x+h*12,y,10,10);
 
 		select_sprite(SPRITE_HEALTH_EMPTY);
@@ -1137,7 +1138,7 @@ void render_game()
 		// render armor meter
 		h = 0;
 		select_sprite(SPRITE_ARMOR_FULL);
-		for(; h < local_character->armor; h++)
+		for(; h < netobjects.local_character->armor; h++)
 			gfx_quads_drawTL(x+h*12,y+12,10,10);
 
 		select_sprite(SPRITE_ARMOR_EMPTY);
@@ -1172,7 +1173,7 @@ void render_game()
 			// render victim tee
 			x -= 24.0f;
 			
-			if(gameobj && gameobj->gametype == GAMETYPE_CTF)
+			if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF)
 			{
 				if(killmsgs[r].mode_special&1)
 				{
@@ -1206,7 +1207,7 @@ void render_game()
 
 			if(killmsgs[r].victim != killmsgs[r].killer)
 			{
-				if(gameobj && gameobj->gametype == GAMETYPE_CTF)
+				if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF)
 				{
 					if(killmsgs[r].mode_special&2)
 					{
@@ -1305,34 +1306,34 @@ void render_game()
 	}
 
 	// render goals
-	if(gameobj)
+	if(netobjects.gameobj)
 	{
-		int gametype = gameobj->gametype;
+		int gametype = netobjects.gameobj->gametype;
 		
 		float whole = 300*gfx_screenaspect();
 		float half = whole/2.0f;
 		
 		gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
-		if(!gameobj->sudden_death)
+		if(!netobjects.gameobj->sudden_death)
 		{
 			char buf[32];
 			int time = 0;
-			if(gameobj->time_limit)
+			if(netobjects.gameobj->time_limit)
 			{
-				time = gameobj->time_limit*60 - ((client_tick()-gameobj->round_start_tick)/client_tickspeed());
+				time = netobjects.gameobj->time_limit*60 - ((client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed());
 
-				if(gameobj->game_over)
+				if(netobjects.gameobj->game_over)
 					time  = 0;
 			}
 			else
-				time = (client_tick()-gameobj->round_start_tick)/client_tickspeed();
+				time = (client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed();
 
 			str_format(buf, sizeof(buf), "%d:%02d", time /60, time %60);
 			float w = gfx_text_width(0, 16, buf, -1);
 			gfx_text(0, half-w/2, 2, 16, buf, -1);
 		}
 
-		if(gameobj->sudden_death)
+		if(netobjects.gameobj->sudden_death)
 		{
 			const char *text = "Sudden Death";
 			float w = gfx_text_width(0, 16, text, -1);
@@ -1340,7 +1341,7 @@ void render_game()
 		}
 
 		// render small score hud
-		if(!(gameobj && gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF))
+		if(!(netobjects.gameobj && netobjects.gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF))
 		{
 			for(int t = 0; t < 2; t++)
 			{
@@ -1355,15 +1356,15 @@ void render_game()
 				gfx_quads_end();
 
 				char buf[32];
-				str_format(buf, sizeof(buf), "%d", gameobj->teamscore[t]);
+				str_format(buf, sizeof(buf), "%d", t?netobjects.gameobj->teamscore_blue:netobjects.gameobj->teamscore_red);
 				float w = gfx_text_width(0, 14, buf, -1);
 				
 				if(gametype == GAMETYPE_CTF)
 				{
 					gfx_text(0, whole-20-w/2+5, 300-40-15+t*20+2, 14, buf, -1);
-					if(flags[t])
+					if(netobjects.flags[t])
 					{
- 						if(flags[t]->carried_by == -2 || (flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
+ 						if(netobjects.flags[t]->carried_by == -2 || (netobjects.flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
  						{
 							gfx_blend_normal();
 							gfx_texture_set(data->images[IMAGE_GAME].id);
@@ -1376,9 +1377,9 @@ void render_game()
 							gfx_quads_drawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
 							gfx_quads_end();
 						}
-						else if(flags[t]->carried_by >= 0)
+						else if(netobjects.flags[t]->carried_by >= 0)
 						{
-							int id = flags[t]->carried_by%MAX_CLIENTS;
+							int id = netobjects.flags[t]->carried_by%MAX_CLIENTS;
 							const char *name = client_datas[id].name;
 							float w = gfx_text_width(0, 10, name, -1);
 							gfx_text(0, whole-40-5-w, 300-40-15+t*20+2, 10, name, -1);
@@ -1396,15 +1397,15 @@ void render_game()
 		}
 
 		// render warmup timer
-		if(gameobj->warmup)
+		if(netobjects.gameobj->warmup)
 		{
 			char buf[256];
 			float w = gfx_text_width(0, 24, "Warmup", -1);
 			gfx_text(0, 150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1);
 
-			int seconds = gameobj->warmup/SERVER_TICK_SPEED;
+			int seconds = netobjects.gameobj->warmup/SERVER_TICK_SPEED;
 			if(seconds < 5)
-				str_format(buf, sizeof(buf), "%d.%d", seconds, (gameobj->warmup*10/SERVER_TICK_SPEED)%10);
+				str_format(buf, sizeof(buf), "%d.%d", seconds, (netobjects.gameobj->warmup*10/SERVER_TICK_SPEED)%10);
 			else
 				str_format(buf, sizeof(buf), "%d", seconds);
 			w = gfx_text_width(0, 24, buf, -1);
@@ -1439,12 +1440,12 @@ void render_game()
 		}
 	}
 	
-	if(config.debug && local_character && local_prev_character)
+	if(config.debug && netobjects.local_character && netobjects.local_prev_character)
 	{
 		gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
 		
-		float speed = distance(vec2(local_prev_character->x, local_prev_character->y),
-			vec2(local_character->x, local_character->y));
+		float speed = distance(vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
+			vec2(netobjects.local_character->x, netobjects.local_character->y));
 		
 		char buf[512];
 		str_format(buf, sizeof(buf), "%.2f", speed/2);
@@ -1453,15 +1454,15 @@ void render_game()
 
 	// render score board
 	if(inp_key_pressed(KEY_TAB) || // user requested
-		(!spectate && (!local_character || local_character->health < 0)) || // not spectating and is dead
-		(gameobj && gameobj->game_over) // game over
+		(!spectate && (!netobjects.local_character || netobjects.local_character->health < 0)) || // not spectating and is dead
+		(netobjects.gameobj && netobjects.gameobj->game_over) // game over
 		)
 	{
 		gfx_mapscreen(0, 0, width, height);
 
 		float w = 650.0f;
 
-		if (gameobj && gameobj->gametype == GAMETYPE_DM)
+		if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_DM)
 		{
 			render_scoreboard(width/2-w/2, 150.0f, w, 0, 0);
 			//render_scoreboard(gameobj, 0, 0, -1, 0);
@@ -1469,12 +1470,12 @@ void render_game()
 		else
 		{
 				
-			if(gameobj && gameobj->game_over)
+			if(netobjects.gameobj && netobjects.gameobj->game_over)
 			{
 				const char *text = "DRAW!";
-				if(gameobj->teamscore[0] > gameobj->teamscore[1])
+				if(netobjects.gameobj->teamscore_red > netobjects.gameobj->teamscore_blue)
 					text = "Red Team Wins!";
-				else if(gameobj->teamscore[1] > gameobj->teamscore[0])
+				else if(netobjects.gameobj->teamscore_blue > netobjects.gameobj->teamscore_red)
 					text = "Blue Team Wins!";
 					
 				float w = gfx_text_width(0, 92.0f, text, -1);
diff --git a/src/game/client/gc_client.h b/src/game/client/gc_client.h
index 857a9088..93a90a86 100644
--- a/src/game/client/gc_client.h
+++ b/src/game/client/gc_client.h
@@ -20,11 +20,29 @@ extern vec2 local_character_pos;
 extern vec2 local_target_pos;
 
 // snap pointers
-extern const obj_player_character *local_character;
-extern const obj_player_character *local_prev_character;
-extern const obj_player_info *local_info;
-extern const obj_flag *flags[2];
-extern const obj_game *gameobj;
+struct snapstate
+{
+	const NETOBJ_PLAYER_CHARACTER *local_character;
+	const NETOBJ_PLAYER_CHARACTER *local_prev_character;
+	const NETOBJ_PLAYER_INFO *local_info;
+	const NETOBJ_FLAG *flags[2];
+	const NETOBJ_GAME *gameobj;
+
+	const NETOBJ_PLAYER_INFO *player_infos[MAX_CLIENTS];
+	const NETOBJ_PLAYER_INFO *info_by_score[MAX_CLIENTS];
+	int num_players;
+};
+
+extern snapstate netobjects;
+
+/*
+extern const NETOBJ_PLAYER_CHARACTER *local_character;
+extern const NETOBJ_PLAYER_CHARACTER *local_prev_character;
+extern const NETOBJ_PLAYER_INFO *local_info;
+extern const NETOBJ_FLAG *flags[2];
+extern const NETOBJ_GAME *gameobj;
+* */
+
 extern tuning_params tuning;
 
 // predicted players
@@ -33,7 +51,7 @@ extern player_core predicted_player;
 
 // input
 extern int picked_up_weapon;
-extern player_input input_data;
+extern NETOBJ_PLAYER_INPUT input_data;
 extern int input_target_lock;
 
 // debug
@@ -45,7 +63,7 @@ enum
 	MAX_EXTRA_PROJECTILES=32,
 };
 
-extern obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES];
+extern NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES];
 extern int extraproj_num;
 
 void extraproj_reset();
diff --git a/src/game/client/gc_hooks.cpp b/src/game/client/gc_hooks.cpp
index a6391007..9292d08c 100644
--- a/src/game/client/gc_hooks.cpp
+++ b/src/game/client/gc_hooks.cpp
@@ -120,17 +120,17 @@ extern "C" void modc_predict()
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 		int client_id = item.id;
 
-		if(item.type == OBJTYPE_PLAYER_CHARACTER)
+		if(item.type == NETOBJTYPE_PLAYER_CHARACTER)
 		{
-			const obj_player_character *character = (const obj_player_character *)data;
+			const NETOBJ_PLAYER_CHARACTER *character = (const NETOBJ_PLAYER_CHARACTER *)data;
 			client_datas[client_id].predicted.world = &world;
 			world.players[client_id] = &client_datas[client_id].predicted;
 
 			client_datas[client_id].predicted.read(character);
 		}
-		else if(item.type == OBJTYPE_PLAYER_INFO)
+		else if(item.type == NETOBJTYPE_PLAYER_INFO)
 		{
-			const obj_player_info *info = (const obj_player_info *)data;
+			const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
 			if(info->local)
 				local_cid = client_id;
 		}
@@ -155,7 +155,7 @@ extern "C" void modc_predict()
 				// apply player input
 				int *input = client_get_input(tick);
 				if(input)
-					world.players[c]->input = *((player_input*)input);
+					world.players[c]->input = *((NETOBJ_PLAYER_INPUT*)input);
 			}
 
 			world.players[c]->tick();
@@ -230,6 +230,23 @@ extern "C" void modc_newsnapshot()
 	static int snapshot_count = 0;
 	snapshot_count++;
 	
+	// secure snapshot
+	{
+		int num = snap_num_items(SNAP_CURRENT);
+		for(int index = 0; index < num; index++)
+		{
+			SNAP_ITEM item;
+			void *data = snap_get_item(SNAP_CURRENT, index, &item);
+			if(netobj_secure(item.type, data, item.datasize) != 0)
+			{
+				if(config.debug)
+					dbg_msg("game", "invalidated %d %d (%s) %d", index, item.type, netobj_get_name(item.type), item.id);
+				snap_invalidate_item(SNAP_CURRENT, index);
+			}
+		}
+	}
+	
+	
 	process_events(SNAP_CURRENT);
 
 	if(config.dbg_stress)
@@ -256,32 +273,32 @@ extern "C" void modc_newsnapshot()
 			SNAP_ITEM item;
 			const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-			if(item.type == OBJTYPE_PLAYER_INFO)
+			if(item.type == NETOBJTYPE_PLAYER_INFO)
 			{
-				const obj_player_info *info = (const obj_player_info *)data;
+				const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
 				
-				client_datas[info->clientid].team = info->team;
+				client_datas[info->cid].team = info->team;
 				
 				if(info->local)
 				{
-					local_info = info;
-					const void *data = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_CHARACTER, item.id);
+					netobjects.local_info = info;
+					const void *data = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_CHARACTER, item.id);
 					if(data)
 					{
-						local_character = (const obj_player_character *)data;
-						local_character_pos = vec2(local_character->x, local_character->y);
+						netobjects.local_character = (const NETOBJ_PLAYER_CHARACTER *)data;
+						local_character_pos = vec2(netobjects.local_character->x, netobjects.local_character->y);
 
-						const void *p = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_CHARACTER, item.id);
+						const void *p = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_CHARACTER, item.id);
 						if(p)
-							local_prev_character = (obj_player_character *)p;
+							netobjects.local_prev_character = (NETOBJ_PLAYER_CHARACTER *)p;
 					}
 				}
 			}
-			else if(item.type == OBJTYPE_GAME)
-				gameobj = (obj_game *)data;
-			else if(item.type == OBJTYPE_FLAG)
+			else if(item.type == NETOBJTYPE_GAME)
+				netobjects.gameobj = (NETOBJ_GAME *)data;
+			else if(item.type == NETOBJTYPE_FLAG)
 			{
-				flags[item.id%2] = (const obj_flag *)data;
+				netobjects.flags[item.id%2] = (const NETOBJ_FLAG *)data;
 			}
 		}
 	}
@@ -394,7 +411,7 @@ extern "C" void modc_statechange(int state, int old)
 	}
 }
 
-obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES];
+NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES];
 int extraproj_num;
 
 void extraproj_reset()
@@ -409,6 +426,11 @@ extern "C" void modc_message(int msg)
 		int cid = msg_unpack_int();
 		int team = msg_unpack_int();
 		const char *message = msg_unpack_string();
+
+		/* check for errors and invalid inputs */
+		if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
+			return;
+			
 		dbg_msg("message", "chat cid=%d team=%d msg='%s'", cid, team, message);
 		chat_add_line(cid, team, message);
 
@@ -423,10 +445,13 @@ extern "C" void modc_message(int msg)
 		
 		for(int k = 0; k < num; k++)
 		{
-			obj_projectile proj;
-			for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+			NETOBJ_PROJECTILE proj;
+			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
 				((int *)&proj)[i] = msg_unpack_int();
 				
+			if(msg_unpack_error())
+				return;
+				
 			if(extraproj_num != MAX_EXTRA_PROJECTILES)
 			{
 				extraproj_projectiles[extraproj_num] = proj;
@@ -440,6 +465,10 @@ extern "C" void modc_message(int msg)
 		const char *name = msg_unpack_string();
 		const char *skinname = msg_unpack_string();
 		
+		/* check for errors and invalid inputs */
+		if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
+			return;
+		
 		strncpy(client_datas[cid].name, name, 64);
 		strncpy(client_datas[cid].skin_name, skinname, 64);
 		
@@ -466,13 +495,24 @@ extern "C" void modc_message(int msg)
 	}
 	else if(msg == MSG_TUNE_PARAMS)
 	{
-		int *params = (int *)&tuning;
+		// unpack the new tuning		
+		tuning_params new_tuning;
+		int *params = (int *)&new_tuning;
 		for(unsigned i = 0; i < sizeof(tuning_params)/sizeof(int); i++)
 			params[i] = msg_unpack_int();
+
+		// check for unpacking errors
+		if(msg_unpack_error())
+			return;
+			
+		// apply new tuning
+		tuning = new_tuning;
 	}
     else if(msg == MSG_WEAPON_PICKUP)
     {
         int weapon = msg_unpack_int();
+		if(msg_unpack_error())
+			return;
         picked_up_weapon = weapon+1;
     }
 	else if(msg == MSG_READY_TO_ENTER)
@@ -481,23 +521,41 @@ extern "C" void modc_message(int msg)
 	}
 	else if(msg == MSG_KILLMSG)
 	{
+		// unpack messages
+		killmsg msg;
+		msg.killer = msg_unpack_int();
+		msg.victim = msg_unpack_int();
+		msg.weapon = msg_unpack_int();
+		msg.mode_special = msg_unpack_int();
+		msg.tick = client_tick();
+
+		// check for unpacking errors
+		if(msg_unpack_error() || msg.killer >= MAX_CLIENTS || msg.victim >= MAX_CLIENTS || msg.weapon >= NUM_WEAPONS)
+			return;
+
+		// add the message
 		killmsg_current = (killmsg_current+1)%killmsg_max;
-		killmsgs[killmsg_current].killer = msg_unpack_int();
-		killmsgs[killmsg_current].victim = msg_unpack_int();
-		killmsgs[killmsg_current].weapon = msg_unpack_int();
-		killmsgs[killmsg_current].mode_special = msg_unpack_int();
-		killmsgs[killmsg_current].tick = client_tick();
+		killmsgs[killmsg_current] = msg;
 	}
 	else if (msg == MSG_EMOTICON)
 	{
+		// unpack
 		int cid = msg_unpack_int();
 		int emoticon = msg_unpack_int();
+
+		// check for errors
+		if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
+			return;
+
+		// apply
 		client_datas[cid].emoticon = emoticon;
 		client_datas[cid].emoticon_start = client_tick();
 	}
 	else if(msg == MSG_SOUND_GLOBAL)
 	{
 		int soundid = msg_unpack_int();
+		if(msg_unpack_error() || soundid < 0)
+			return;
 		snd_play_random(CHN_GLOBAL, soundid, 1.0f, vec2(0,0));
 	}
 }
diff --git a/src/game/client/gc_menu.cpp b/src/game/client/gc_menu.cpp
index 51333288..ec2cc2fe 100644
--- a/src/game/client/gc_menu.cpp
+++ b/src/game/client/gc_menu.cpp
@@ -27,10 +27,6 @@ extern "C" {
 
 extern data_container *data;
 
-// abit uglyness
-extern const obj_player_info *local_info;
-extern const obj_game *gameobj;
-
 extern bool menu_active;
 extern bool menu_game_active;
 
@@ -1614,9 +1610,9 @@ static void menu2_render_game(RECT main_view)
 	if(ui_do_button(&disconnect_button, "Disconnect", 0, &button, ui_draw_menu_button, 0))
 		client_disconnect();
 
-	if(local_info && gameobj)
+	if(netobjects.local_info && netobjects.gameobj)
 	{
-		if(local_info->team != -1)
+		if(netobjects.local_info->team != -1)
 		{
 			ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
 			ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
@@ -1628,9 +1624,9 @@ static void menu2_render_game(RECT main_view)
 			}
 		}
 		
-		if(gameobj->gametype == GAMETYPE_DM)
+		if(netobjects.gameobj->gametype == GAMETYPE_DM)
 		{
-			if(local_info->team != 0)
+			if(netobjects.local_info->team != 0)
 			{
 				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
 				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
@@ -1644,7 +1640,7 @@ static void menu2_render_game(RECT main_view)
 		}
 		else
 		{
-			if(local_info->team != 0)
+			if(netobjects.local_info->team != 0)
 			{
 				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
 				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
@@ -1656,7 +1652,7 @@ static void menu2_render_game(RECT main_view)
 				}
 			}
 
-			if(local_info->team != 1)
+			if(netobjects.local_info->team != 1)
 			{
 				ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
 				ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
diff --git a/src/game/client/gc_render.cpp b/src/game/client/gc_render.cpp
index 1d276ec3..6e001bd1 100644
--- a/src/game/client/gc_render.cpp
+++ b/src/game/client/gc_render.cpp
@@ -349,25 +349,25 @@ static void render_items()
 		SNAP_ITEM item;
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-		if(item.type == OBJTYPE_PROJECTILE)
+		if(item.type == NETOBJTYPE_PROJECTILE)
 		{
-			render_projectile((const obj_projectile *)data, item.id);
+			render_projectile((const NETOBJ_PROJECTILE *)data, item.id);
 		}
-		else if(item.type == OBJTYPE_POWERUP)
+		else if(item.type == NETOBJTYPE_POWERUP)
 		{
 			const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
 			if(prev)
-				render_powerup((const obj_powerup *)prev, (const obj_powerup *)data);
+				render_powerup((const NETOBJ_POWERUP *)prev, (const NETOBJ_POWERUP *)data);
 		}
-		else if(item.type == OBJTYPE_LASER)
+		else if(item.type == NETOBJTYPE_LASER)
 		{
-			render_laser((const obj_laser *)data);
+			render_laser((const NETOBJ_LASER *)data);
 		}
-		else if(item.type == OBJTYPE_FLAG)
+		else if(item.type == NETOBJTYPE_FLAG)
 		{
 			const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
 			if (prev)
-				render_flag((const obj_flag *)prev, (const obj_flag *)data);
+				render_flag((const NETOBJ_FLAG *)prev, (const NETOBJ_FLAG *)data);
 		}
 	}
 
@@ -393,19 +393,19 @@ static void render_players()
 		SNAP_ITEM item;
 		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
 
-		if(item.type == OBJTYPE_PLAYER_CHARACTER)
+		if(item.type == NETOBJTYPE_PLAYER_CHARACTER)
 		{
 			const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
-			const void *prev_info = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_INFO, item.id);
-			const void *info = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_INFO, item.id);
+			const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, item.id);
+			const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, item.id);
 
 			if(prev && prev_info && info)
 			{
 				render_player(
-						(const obj_player_character *)prev,
-						(const obj_player_character *)data,
-						(const obj_player_info *)prev_info,
-						(const obj_player_info *)info
+						(const NETOBJ_PLAYER_CHARACTER *)prev,
+						(const NETOBJ_PLAYER_CHARACTER *)data,
+						(const NETOBJ_PLAYER_INFO *)prev_info,
+						(const NETOBJ_PLAYER_INFO *)info
 					);
 			}
 		}
diff --git a/src/game/client/gc_render.h b/src/game/client/gc_render.h
index b62206f7..a6f57b7b 100644
--- a/src/game/client/gc_render.h
+++ b/src/game/client/gc_render.h
@@ -54,13 +54,13 @@ void render_particles();
 
 // object render methods (gc_render_obj.cpp)
 void render_tee(class animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos);
-void render_flag(const struct obj_flag *prev, const struct obj_flag *current);
-void render_powerup(const struct obj_powerup *prev, const struct obj_powerup *current);
-void render_projectile(const struct obj_projectile *current, int itemid);
-void render_laser(const struct obj_laser *current);
+void render_flag(const struct NETOBJ_FLAG *prev, const struct NETOBJ_FLAG *current);
+void render_powerup(const struct NETOBJ_POWERUP *prev, const struct NETOBJ_POWERUP *current);
+void render_projectile(const struct NETOBJ_PROJECTILE *current, int itemid);
+void render_laser(const struct NETOBJ_LASER *current);
 void render_player(
-	const struct obj_player_character *prev_char, const struct obj_player_character *player_char,
-	const struct obj_player_info *prev_info, const struct obj_player_info *player_info);
+	const struct NETOBJ_PLAYER_CHARACTER *prev_char, const struct NETOBJ_PLAYER_CHARACTER *player_char,
+	const struct NETOBJ_PLAYER_INFO *prev_info, const struct NETOBJ_PLAYER_INFO *player_info);
 	
 // map render methods (gc_render_map.cpp)
 void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result);
diff --git a/src/game/client/gc_render_obj.cpp b/src/game/client/gc_render_obj.cpp
index cedfc129..995994ed 100644
--- a/src/game/client/gc_render_obj.cpp
+++ b/src/game/client/gc_render_obj.cpp
@@ -11,7 +11,7 @@
 #include "gc_client.h"
 
 
-void render_projectile(const obj_projectile *current, int itemid)
+void render_projectile(const NETOBJ_PROJECTILE *current, int itemid)
 {
 	if(debug_firedelay)
 	{
@@ -34,7 +34,7 @@ void render_projectile(const obj_projectile *current, int itemid)
 	vec2 pos = calc_pos(startpos, startvel, gravity, ct);
 	vec2 prevpos = calc_pos(startpos, startvel, gravity, ct-0.001f);
 
-	select_sprite(data->weapons[current->type%data->num_weapons].sprite_proj);
+	select_sprite(data->weapons[clamp(current->type, 0, NUM_WEAPONS-1)].sprite_proj);
 	vec2 vel = pos-prevpos;
 	//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
 	
@@ -63,7 +63,7 @@ void render_projectile(const obj_projectile *current, int itemid)
 	gfx_quads_end();
 }
 
-void render_powerup(const obj_powerup *prev, const obj_powerup *current)
+void render_powerup(const NETOBJ_POWERUP *prev, const NETOBJ_POWERUP *current)
 {
 	gfx_texture_set(data->images[IMAGE_GAME].id);
 	gfx_quads_begin();
@@ -73,8 +73,8 @@ void render_powerup(const obj_powerup *prev, const obj_powerup *current)
 	if (current->type == POWERUP_WEAPON)
 	{
 		angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
-		select_sprite(data->weapons[current->subtype%data->num_weapons].sprite_body);
-		size = data->weapons[current->subtype%data->num_weapons].visual_size;
+		select_sprite(data->weapons[clamp(current->subtype, 0, NUM_WEAPONS-1)].sprite_body);
+		size = data->weapons[clamp(current->subtype, 0, NUM_WEAPONS-1)].visual_size;
 	}
 	else
 	{
@@ -107,7 +107,7 @@ void render_powerup(const obj_powerup *prev, const obj_powerup *current)
 	gfx_quads_end();
 }
 
-void render_flag(const obj_flag *prev, const obj_flag *current)
+void render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current)
 {
 	float angle = 0.0f;
 	float size = 42.0f;
@@ -125,7 +125,7 @@ void render_flag(const obj_flag *prev, const obj_flag *current)
 
 	vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
 
-	if(local_info && current->carried_by == local_info->clientid)
+	if(netobjects.local_info && current->carried_by == netobjects.local_info->cid)
 		pos = local_character_pos;
 
     //gfx_setcolor(current->team ? 0 : 1,0,current->team ? 1 : 0,1);
@@ -135,7 +135,7 @@ void render_flag(const obj_flag *prev, const obj_flag *current)
 }
 
 
-void render_laser(const struct obj_laser *current)
+void render_laser(const struct NETOBJ_LASER *current)
 {
 
 	vec2 pos = vec2(current->x, current->y);
@@ -245,19 +245,19 @@ static void render_hand(tee_render_info *info, vec2 center_pos, vec2 dir, float
 }
 
 void render_player(
-	const obj_player_character *prev_char,
-	const obj_player_character *player_char,
-	const obj_player_info *prev_info,
-	const obj_player_info *player_info
+	const NETOBJ_PLAYER_CHARACTER *prev_char,
+	const NETOBJ_PLAYER_CHARACTER *player_char,
+	const NETOBJ_PLAYER_INFO *prev_info,
+	const NETOBJ_PLAYER_INFO *player_info
 	)
 {
-	obj_player_character prev;
-	obj_player_character player;
+	NETOBJ_PLAYER_CHARACTER prev;
+	NETOBJ_PLAYER_CHARACTER player;
 	prev = *prev_char;
 	player = *player_char;
 
-	obj_player_info info = *player_info;
-	tee_render_info render_info = client_datas[info.clientid].render_info;
+	NETOBJ_PLAYER_INFO info = *player_info;
+	tee_render_info render_info = client_datas[info.cid].render_info;
 
 	float intratick = client_intratick();
 	float ticktime = client_ticktime();
@@ -267,7 +267,7 @@ void render_player(
 
 	if(info.local && config.cl_predict)
 	{
-		if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over))
+		if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over))
 		{
 		}
 		else
@@ -329,7 +329,7 @@ void render_player(
 		
 		if(player_char->hooked_player != -1)
 		{
-			if(local_info && player_char->hooked_player == local_info->clientid)
+			if(netobjects.local_info && player_char->hooked_player == netobjects.local_info->cid)
 			{
 				hook_pos = mix(vec2(predicted_prev_player.pos.x, predicted_prev_player.pos.y),
 					vec2(predicted_player.pos.x, predicted_player.pos.y), client_predintratick());
@@ -351,7 +351,8 @@ void render_player(
 
 		// render chain
 		select_sprite(SPRITE_HOOK_CHAIN);
-		for(float f = 24; f < d; f += 24)
+		int i = 0;
+		for(float f = 24; f < d && i < 1024; f += 24, i++)
 		{
 			vec2 p = hook_pos + dir*f;
 			gfx_quads_draw(p.x, p.y,24,16);
@@ -360,7 +361,7 @@ void render_player(
 		gfx_quads_setrotation(0);
 		gfx_quads_end();
 
-		render_hand(&client_datas[info.clientid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
+		render_hand(&client_datas[info.cid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
 	}
 
 	// draw gun
@@ -478,9 +479,9 @@ void render_player(
 
 		switch (player.weapon)
 		{
-			case WEAPON_GUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
-			case WEAPON_SHOTGUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
-			case WEAPON_GRENADE: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
+			case WEAPON_GUN: render_hand(&client_datas[info.cid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
+			case WEAPON_SHOTGUN: render_hand(&client_datas[info.cid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
+			case WEAPON_GRENADE: render_hand(&client_datas[info.cid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
 		}
 
 	}
@@ -507,13 +508,13 @@ void render_player(
 		gfx_quads_end();
 	}
 
-	if (client_datas[info.clientid].emoticon_start != -1 && client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() > client_tick())
+	if (client_datas[info.cid].emoticon_start != -1 && client_datas[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick())
 	{
 		gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
 		gfx_quads_begin();
 
-		int since_start = client_tick() - client_datas[info.clientid].emoticon_start;
-		int from_end = client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() - client_tick();
+		int since_start = client_tick() - client_datas[info.cid].emoticon_start;
+		int from_end = client_datas[info.cid].emoticon_start + 2 * client_tickspeed() - client_tick();
 
 		float a = 1;
 
@@ -534,7 +535,7 @@ void render_player(
 
 		gfx_setcolor(1.0f,1.0f,1.0f,a);
 		// client_datas::emoticon is an offset from the first emoticon
-		select_sprite(SPRITE_OOP + client_datas[info.clientid].emoticon);
+		select_sprite(SPRITE_OOP + client_datas[info.cid].emoticon);
 		gfx_quads_draw(position.x, position.y - 23 - 32*h, 64, 64*h);
 		gfx_quads_end();
 	}
@@ -547,7 +548,7 @@ void render_player(
 		if(config.cl_nameplates_always == 0)
 			a = clamp(1-powf(distance(local_target_pos, position)/200.0f,16.0f), 0.0f, 1.0f);
 			
-		const char *name = client_datas[info.clientid].name;
+		const char *name = client_datas[info.cid].name;
 		float tw = gfx_text_width(0, 28.0f, name, -1);
 		gfx_text_color(1,1,1,a);
 		gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1);
diff --git a/src/game/g_game.cpp b/src/game/g_game.cpp
index 25114cb7..c217b5a3 100644
--- a/src/game/g_game.cpp
+++ b/src/game/g_game.cpp
@@ -400,7 +400,7 @@ void player_core::move()
 	move_box(&pos, &vel, vec2(28.0f, 28.0f), 0);
 }
 
-void player_core::write(obj_player_core *obj_core)
+void player_core::write(NETOBJ_PLAYER_CORE *obj_core)
 {
 	obj_core->x = (int)pos.x;
 	obj_core->y = (int)pos.y;
@@ -427,7 +427,7 @@ void player_core::write(obj_player_core *obj_core)
 	obj_core->angle = (int)(a*256.0f);
 }
 
-void player_core::read(const obj_player_core *obj_core)
+void player_core::read(const NETOBJ_PLAYER_CORE *obj_core)
 {
 	pos.x = obj_core->x;
 	pos.y = obj_core->y;
@@ -445,7 +445,7 @@ void player_core::read(const obj_player_core *obj_core)
 
 void player_core::quantize()
 {
-	obj_player_core c;
+	NETOBJ_PLAYER_CORE c;
 	write(&c);
 	read(&c);
 }
diff --git a/src/game/g_game.h b/src/game/g_game.h
index a9fddde7..00870319 100644
--- a/src/game/g_game.h
+++ b/src/game/g_game.h
@@ -133,15 +133,15 @@ public:
 	int hooked_player;
 	
 	int jumped;
-	player_input input;
+	NETOBJ_PLAYER_INPUT input;
 	
 	int triggered_events;
 	
 	void tick();
 	void move();
 	
-	void read(const obj_player_core *obj_core);
-	void write(obj_player_core *obj_core);
+	void read(const NETOBJ_PLAYER_CORE *obj_core);
+	void write(NETOBJ_PLAYER_CORE *obj_core);
 	void quantize();
 };
 
diff --git a/src/game/g_layers.cpp b/src/game/g_layers.cpp
index 1595e266..6614bc90 100644
--- a/src/game/g_layers.cpp
+++ b/src/game/g_layers.cpp
@@ -33,12 +33,10 @@ void layers_init()
 				
 				if(tilemap->flags&1)
 				{
-					dbg_msg("layers", "game");
 					game_layer = tilemap;
 					p = 2;
 				}
 			}
-			dbg_msg("layers", "%d %d", i, layer->type);
 		}
 	}
 }
diff --git a/src/game/g_protocol.def b/src/game/g_protocol.def
new file mode 100644
index 00000000..8df707c3
--- /dev/null
+++ b/src/game/g_protocol.def
@@ -0,0 +1,211 @@
+
+raw_source
+	#include "g_protocol.h"
+	#include "g_protocol_ids.h"
+	#include <engine/e_common_interface.h>
+	#define max_int 100000
+end
+
+raw_header
+	enum
+	{
+		// emotes
+		EMOTE_NORMAL=0,
+		EMOTE_PAIN,
+		EMOTE_HAPPY,
+		EMOTE_SURPRISE,
+		EMOTE_ANGRY,
+		EMOTE_BLINK,
+		NUM_EMOTES,
+		
+		// playerstates
+		PLAYERSTATE_UNKNOWN=0,
+		PLAYERSTATE_PLAYING,
+		PLAYERSTATE_IN_MENU,
+		PLAYERSTATE_CHATTING,
+		NUM_PLAYERSTATES,
+
+		// game types
+		GAMETYPE_DM=0,
+		GAMETYPE_TDM,
+		GAMETYPE_CTF,
+		NUM_GAMETYPES,
+		
+		// other stuff
+		INPUT_STATE_MASK=0x1f,
+	};
+	
+	enum
+	{
+		MSG_NULL=0,
+		MSG_SAY, // client -> server
+		MSG_CHAT, // server -> client
+		MSG_SETINFO, // server -> client - contains name, skin and color info
+		MSG_KILLMSG, // server -> client
+		MSG_SETTEAM,
+		MSG_JOIN,
+		MSG_QUIT,
+		MSG_EMOTICON,
+		MSG_STARTINFO, // client -> server
+		MSG_CHANGEINFO, // client -> server
+		MSG_READY_TO_ENTER, // server -> client
+		MSG_WEAPON_PICKUP,
+		MSG_SOUND_GLOBAL,
+		MSG_TUNE_PARAMS,
+		MSG_KILL,
+		MSG_EXTRA_PROJECTILE, // server -> client
+		
+	};
+	
+end
+
+
+
+object player_input
+	any left
+	any right
+
+	any target_x
+	any target_y
+
+	any jump
+	any fire
+	any hook
+	any blink
+
+	any player_state
+
+	any wanted_weapon
+	any next_weapon
+	any prev_weapon
+end
+
+object projectile
+	any x, y
+	any vx, vy
+	range(0, NUM_WEAPONS) type
+	range(0, max_int) start_tick
+end
+
+object laser
+	any x
+	any y
+	any from_x
+	any from_y
+	range(0, max_int) eval_tick
+end
+
+object powerup
+	any x, y
+	range(0, max_int) type
+	range(0, max_int) subtype
+end
+
+object flag
+	any x, y
+	range(0, 1) team
+	clientid carried_by
+end
+
+object game
+	range(0, max_int) round_start_tick
+	
+	range(0, 1) game_over
+	range(0, 1) sudden_death
+	range(0, 1) paused
+
+	range(0, max_int) score_limit
+	range(0, max_int) time_limit
+	range(0, NUM_GAMETYPES-1) gametype
+
+	range(0, max_int) warmup
+
+	any teamscore_red
+	any teamscore_blue
+end
+
+// core object needed for physics
+object player_core
+	any x, y
+	any vx, vy
+
+	any angle
+	range(0, 2) jumped
+
+	clientid hooked_player
+	range(0, 3) hook_state
+	range(0, max_int) hook_tick
+
+	any hook_x
+	any hook_y
+	any hook_dx
+	any hook_dy
+end
+
+// info about the player that is only needed when it's on screen
+object player_character extends player_core
+	range(0, NUM_PLAYERSTATES-1) player_state
+	
+	range(0, 10) health
+	range(0, 10) armor
+	range(0, 10) ammocount
+	range(0, 10) weaponstage
+
+	range(0, NUM_WEAPONS-1) weapon
+	range(0, NUM_EMOTES-1) emote
+	
+	range(0, max_int) attacktick
+end
+
+// information about the player that is always needed
+object player_info
+	range(0, 1) local
+	clientid cid
+	range(-1, 1) team
+	
+	any score
+	
+	any latency
+	any latency_flux
+end
+
+event common
+	any x, y
+end
+
+event explosion
+	any x, y
+end
+
+event spawn
+	any x, y
+end
+
+event death
+	any x, y
+end
+
+event air_jump
+	any x, y
+end
+
+event sound_global
+	any x, y
+	range(0, NUM_SOUNDS-1) soundid
+end
+
+event sound_world
+	any x, y
+	range(0, NUM_SOUNDS-1) soundid
+end
+
+event damageind
+	any x, y
+	any angle
+end
+
+//msg say
+//	clientid cid
+//	range(-1, 1) team
+//	string message
+//end
diff --git a/src/game/g_protocol.h b/src/game/g_protocol.h
index f4878729..195f5ae2 100644
--- a/src/game/g_protocol.h
+++ b/src/game/g_protocol.h
@@ -4,7 +4,10 @@
 #ifndef GAME_PROTOCOL_H
 #define GAME_PROTOCOL_H
 
+#include <game/generated/g_protocol.h>
+
 // Network stuff
+/*
 enum
 {
 	OBJTYPE_NULL=0,
@@ -209,6 +212,6 @@ struct obj_player_info
 	int score;
 	int latency;
 	int latency_flux;
-};
+};*/
 
 #endif
diff --git a/src/game/server/gs_common.h b/src/game/server/gs_common.h
index 194751b2..ffeadecf 100644
--- a/src/game/server/gs_common.h
+++ b/src/game/server/gs_common.h
@@ -204,7 +204,7 @@ public:
 	projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner,
 		int damage, int flags, float force, int sound_impact, int weapon);
 
-	void fill_info(obj_projectile *proj);
+	void fill_info(NETOBJ_PROJECTILE *proj);
 
 	virtual void reset();
 	virtual void tick();
@@ -270,12 +270,12 @@ public:
 	int color_feet;
 
 	// these are non-heldback inputs
-	player_input latest_previnput;
-	player_input latest_input;
+	NETOBJ_PLAYER_INPUT latest_previnput;
+	NETOBJ_PLAYER_INPUT latest_input;
 
 	// input	
-	player_input previnput;
-	player_input input;
+	NETOBJ_PLAYER_INPUT previnput;
+	NETOBJ_PLAYER_INPUT input;
 	int num_inputs;
 	int jumped;
 	
@@ -332,7 +332,7 @@ public:
 	int handle_weapons();
 	int handle_ninja();
 	
-	void on_direct_input(player_input *input);
+	void on_direct_input(NETOBJ_PLAYER_INPUT *input);
 	void fire_weapon();
 
 	virtual void tick();
diff --git a/src/game/server/gs_game.cpp b/src/game/server/gs_game.cpp
index a1b5fd7b..228ae828 100644
--- a/src/game/server/gs_game.cpp
+++ b/src/game/server/gs_game.cpp
@@ -6,7 +6,7 @@
 #include "gs_common.h"
 
 gameobject::gameobject()
-: entity(OBJTYPE_GAME)
+: entity(NETOBJTYPE_GAME)
 {
 	// select gametype
 	if(strcmp(config.sv_gametype, "ctf") == 0)
@@ -260,7 +260,7 @@ void gameobject::tick()
 
 void gameobject::snap(int snapping_client)
 {
-	obj_game *game = (obj_game *)snap_new_item(OBJTYPE_GAME, 0, sizeof(obj_game));
+	NETOBJ_GAME *game = (NETOBJ_GAME *)snap_new_item(NETOBJTYPE_GAME, 0, sizeof(NETOBJ_GAME));
 	game->paused = world->paused;
 	game->game_over = game_over_tick==-1?0:1;
 	game->sudden_death = sudden_death;
@@ -272,8 +272,8 @@ void gameobject::snap(int snapping_client)
 	
 	game->warmup = warmup;
 	
-	game->teamscore[0] = teamscore[0];
-	game->teamscore[1] = teamscore[1];
+	game->teamscore_red = teamscore[0];
+	game->teamscore_blue = teamscore[1];
 }
 
 int gameobject::getteam(int notthisid)
diff --git a/src/game/server/gs_game_ctf.cpp b/src/game/server/gs_game_ctf.cpp
index 37e2baba..a703e6b6 100644
--- a/src/game/server/gs_game_ctf.cpp
+++ b/src/game/server/gs_game_ctf.cpp
@@ -99,7 +99,7 @@ void gameobject_ctf::tick()
 		else
 		{
 			player *close_players[MAX_CLIENTS];
-			int types[] = {OBJTYPE_PLAYER_CHARACTER};
+			int types[] = {NETOBJTYPE_PLAYER_CHARACTER};
 			int num = world->find_entities(f->pos, 32.0f, (entity**)close_players, MAX_CLIENTS, types, 1);
 			for(int i = 0; i < num; i++)
 			{
@@ -161,7 +161,7 @@ void gameobject_ctf::tick()
 
 // Flag
 flag::flag(int _team)
-: entity(OBJTYPE_FLAG)
+: entity(NETOBJTYPE_FLAG)
 {
 	team = _team;
 	proximity_radius = phys_size;
@@ -183,7 +183,7 @@ void flag::reset()
 
 void flag::snap(int snapping_client)
 {
-	obj_flag *flag = (obj_flag *)snap_new_item(OBJTYPE_FLAG, team, sizeof(obj_flag));
+	NETOBJ_FLAG *flag = (NETOBJ_FLAG *)snap_new_item(NETOBJTYPE_FLAG, team, sizeof(NETOBJ_FLAG));
 	flag->x = (int)pos.x;
 	flag->y = (int)pos.y;
 	flag->team = team;
diff --git a/src/game/server/gs_server.cpp b/src/game/server/gs_server.cpp
index 656609a6..514850a0 100644
--- a/src/game/server/gs_server.cpp
+++ b/src/game/server/gs_server.cpp
@@ -107,7 +107,7 @@ void event_handler::snap(int snapping_client)
 	{
 		if(cmask_is_set(client_masks[i], snapping_client))
 		{
-			ev_common *ev = (ev_common *)&data[offsets[i]];
+			NETEVENT_COMMON *ev = (NETEVENT_COMMON *)&data[offsets[i]];
 			if(distance(players[snapping_client].pos, vec2(ev->x, ev->y)) < 1500.0f)
 			{
 				void *d = snap_new_item(types[i], i, sizes[i]);
@@ -297,6 +297,7 @@ void game_world::tick()
 
 	if(!paused)
 	{
+		/*
 		static PERFORMACE_INFO scopes[OBJTYPE_FLAG+1] =
 		{
 			{"null", 0},
@@ -320,31 +321,32 @@ void game_world::tick()
 		};
 				
 		static PERFORMACE_INFO tick_scope = {"tick", 0};
-		perf_start(&tick_scope);
+		perf_start(&tick_scope);*/
 		
 		// update all objects
 		for(entity *ent = first_entity; ent; ent = ent->next_entity)
 		{
-			if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
-				perf_start(&scopes[ent->objtype]);
+			/*if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
+				perf_start(&scopes[ent->objtype]);*/
 			ent->tick();
-			if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
-				perf_end();
+			/*if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
+				perf_end();*/
 		}
 		
+		/*
 		perf_end();
 
 		static PERFORMACE_INFO deftick_scope = {"tick_defered", 0};
-		perf_start(&deftick_scope);
+		perf_start(&deftick_scope);*/
 		for(entity *ent = first_entity; ent; ent = ent->next_entity)
 		{
-			if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
-				perf_start(&scopes_def[ent->objtype]);
+			/*if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
+				perf_start(&scopes_def[ent->objtype]);*/
 			ent->tick_defered();
-			if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
-				perf_end();
+			/*if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
+				perf_end();*/
 		}
-		perf_end();
+		/*perf_end();*/
 	}
 
 	remove_entities();
@@ -380,7 +382,7 @@ static input_count count_input(int prev, int cur)
 //////////////////////////////////////////////////
 projectile::projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner,
 	int damage, int flags, float force, int sound_impact, int weapon)
-: entity(OBJTYPE_PROJECTILE)
+: entity(NETOBJTYPE_PROJECTILE)
 {
 	this->type = type;
 	this->pos = pos;
@@ -437,7 +439,7 @@ void projectile::tick()
 	}
 }
 
-void projectile::fill_info(obj_projectile *proj)
+void projectile::fill_info(NETOBJ_PROJECTILE *proj)
 {
 	proj->x = (int)pos.x;
 	proj->y = (int)pos.y;
@@ -455,7 +457,7 @@ void projectile::snap(int snapping_client)
 	if(distance(players[snapping_client].pos, curpos) > 1000.0f)
 		return;
 
-	obj_projectile *proj = (obj_projectile *)snap_new_item(OBJTYPE_PROJECTILE, id, sizeof(obj_projectile));
+	NETOBJ_PROJECTILE *proj = (NETOBJ_PROJECTILE *)snap_new_item(NETOBJTYPE_PROJECTILE, id, sizeof(NETOBJ_PROJECTILE));
 	fill_info(proj);
 }
 
@@ -464,7 +466,7 @@ void projectile::snap(int snapping_client)
 // laser
 //////////////////////////////////////////////////
 laser::laser(vec2 pos, vec2 direction, float start_energy, player *owner)
-: entity(OBJTYPE_LASER)
+: entity(NETOBJTYPE_LASER)
 {
 	this->pos = pos;
 	this->owner = owner;
@@ -554,7 +556,7 @@ void laser::snap(int snapping_client)
 	if(distance(players[snapping_client].pos, pos) > 1000.0f)
 		return;
 
-	obj_laser *obj = (obj_laser *)snap_new_item(OBJTYPE_LASER, id, sizeof(obj_laser));
+	NETOBJ_LASER *obj = (NETOBJ_LASER *)snap_new_item(NETOBJTYPE_LASER, id, sizeof(NETOBJ_LASER));
 	obj->x = (int)pos.x;
 	obj->y = (int)pos.y;
 	obj->from_x = (int)from.x;
@@ -568,7 +570,7 @@ void laser::snap(int snapping_client)
 //////////////////////////////////////////////////
 // TODO: move to separate file
 player::player()
-: entity(OBJTYPE_PLAYER_CHARACTER)
+: entity(NETOBJTYPE_PLAYER_CHARACTER)
 {
 	init();
 }
@@ -788,7 +790,7 @@ void player::try_respawn()
 
 	// check if the position is occupado
 	entity *ents[2] = {0};
-	int types[] = {OBJTYPE_PLAYER_CHARACTER};
+	int types[] = {NETOBJTYPE_PLAYER_CHARACTER};
 	int num_ents = world->find_entities(spawnpos, 64, ents, 2, types, 1);
 	for(int i = 0; i < num_ents; i++)
 	{
@@ -901,12 +903,12 @@ int player::handle_ninja()
 		core.vel = vec2(0.0f,0.0f);
 		if ((ninja.currentmovetime % 2) == 0)
 		{
-			create_smoke(pos);
+			//create_smoke(pos);
 		}
 
 		// check if we hit anything along the way
 		{
-			int type = OBJTYPE_PLAYER_CHARACTER;
+			int type = NETOBJTYPE_PLAYER_CHARACTER;
 			entity *ents[64];
 			vec2 dir = pos - oldpos;
 			float radius = phys_size * 2.0f; //length(dir * 0.5f);
@@ -990,12 +992,12 @@ void player::fire_weapon()
 				1, 0, 0, -1, WEAPON_GUN);
 				
 			// pack the projectile and send it to the client directly
-			obj_projectile p;
+			NETOBJ_PROJECTILE p;
 			proj->fill_info(&p);
 			
 			msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
 			msg_pack_int(1);
-			for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
 				msg_pack_int(((int *)&p)[i]);
 			msg_pack_end();
 			server_send_msg(client_id);
@@ -1014,12 +1016,12 @@ void player::fire_weapon()
 				1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
 
 			// pack the projectile and send it to the client directly
-			obj_projectile p;
+			NETOBJ_PROJECTILE p;
 			proj->fill_info(&p);
 			
 			msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
 			msg_pack_int(1);
-			for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
 				msg_pack_int(((int *)&p)[i]);
 			msg_pack_end();
 			server_send_msg(client_id);
@@ -1050,10 +1052,10 @@ void player::fire_weapon()
 					1, 0, 0, -1, WEAPON_SHOTGUN);
 					
 				// pack the projectile and send it to the client directly
-				obj_projectile p;
+				NETOBJ_PROJECTILE p;
 				proj->fill_info(&p);
 				
-				for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+				for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
 					msg_pack_int(((int *)&p)[i]);
 			}
 
@@ -1245,7 +1247,7 @@ int player::handle_weapons()
 		// only one that needs update (for now)
 		// do selection for the weapon and bash anything in it
 		// check if we hit anything along the way
-		int type = OBJTYPE_PLAYER_CHARACTER;
+		int type = NETOBJTYPE_PLAYER_CHARACTER;
 		entity *ents[64];
 		vec2 lookdir(direction.x > 0.0f ? 1.0f : -1.0f, 0.0f);
 		vec2 dir = lookdir * data->weapons[active_weapon].meleereach;
@@ -1278,7 +1280,7 @@ int player::handle_weapons()
 			vec2 fdir = normalize(ents[i]->pos- pos);
 
 			// set his velocity to fast upward (for now)
-			create_smoke(ents[i]->pos);
+			//create_smoke(ents[i]->pos);
 			create_sound(pos, SOUND_HAMMER_HIT);
 			if(numobjectshit < 10)
 				hitobjects[numobjectshit++] = ents[i];
@@ -1318,7 +1320,7 @@ int player::handle_weapons()
 	return 0;
 }
 
-void player::on_direct_input(player_input *new_input)
+void player::on_direct_input(NETOBJ_PLAYER_INPUT *new_input)
 {
 	mem_copy(&latest_previnput, &latest_input, sizeof(latest_input));
 	mem_copy(&latest_input, new_input, sizeof(latest_input));
@@ -1444,7 +1446,7 @@ void player::tick_defered()
 		if(events&COREEVENT_AIR_JUMP)
 		{
 			create_sound(pos, SOUND_PLAYER_AIRJUMP, mask);
-			ev_common *c = (ev_common *)::events.create(EVENT_AIR_JUMP, sizeof(ev_common), mask);
+			NETEVENT_COMMON *c = (NETEVENT_COMMON *)::events.create(NETEVENTTYPE_AIR_JUMP, sizeof(NETEVENT_COMMON), mask);
 			if(c)
 			{
 				c->x = (int)pos.x;
@@ -1580,12 +1582,12 @@ void player::snap(int snaping_client)
 {
 	if(1)
 	{
-		obj_player_info *info = (obj_player_info *)snap_new_item(OBJTYPE_PLAYER_INFO, client_id, sizeof(obj_player_info));
+		NETOBJ_PLAYER_INFO *info = (NETOBJ_PLAYER_INFO *)snap_new_item(NETOBJTYPE_PLAYER_INFO, client_id, sizeof(NETOBJ_PLAYER_INFO));
 
 		info->latency = latency_min;
 		info->latency_flux = latency_max-latency_min;
 		info->local = 0;
-		info->clientid = client_id;
+		info->cid = client_id;
 		info->score = score;
 		info->team = team;
 
@@ -1595,7 +1597,7 @@ void player::snap(int snaping_client)
 
 	if(health > 0 && team >= 0 && distance(players[snaping_client].pos, pos) < 1000.0f)
 	{
-		obj_player_character *character = (obj_player_character *)snap_new_item(OBJTYPE_PLAYER_CHARACTER, client_id, sizeof(obj_player_character));
+		NETOBJ_PLAYER_CHARACTER *character = (NETOBJ_PLAYER_CHARACTER *)snap_new_item(NETOBJTYPE_PLAYER_CHARACTER, client_id, sizeof(NETOBJ_PLAYER_CHARACTER));
 
 		core.write(character);
 
@@ -1651,7 +1653,7 @@ player *players;
 // powerup
 //////////////////////////////////////////////////
 powerup::powerup(int _type, int _subtype)
-: entity(OBJTYPE_POWERUP)
+: entity(NETOBJTYPE_POWERUP)
 {
 	type = _type;
 	subtype = _subtype;
@@ -1747,7 +1749,7 @@ void powerup::tick()
 
 				// loop through all players, setting their emotes
 				entity *ents[64];
-				const int types[] = {OBJTYPE_PLAYER_CHARACTER};
+				const int types[] = {NETOBJTYPE_PLAYER_CHARACTER};
 				int num = world->find_entities(vec2(0, 0), 1000000, ents, 64, types, 1);
 				for (int i = 0; i < num; i++)
 				{
@@ -1782,7 +1784,7 @@ void powerup::snap(int snapping_client)
 	if(spawntick != -1)
 		return;
 
-	obj_powerup *up = (obj_powerup *)snap_new_item(OBJTYPE_POWERUP, id, sizeof(obj_powerup));
+	NETOBJ_POWERUP *up = (NETOBJ_POWERUP *)snap_new_item(NETOBJTYPE_POWERUP, id, sizeof(NETOBJ_POWERUP));
 	up->x = (int)pos.x;
 	up->y = (int)pos.y;
 	up->type = type; // TODO: two diffrent types? what gives?
@@ -1805,7 +1807,7 @@ void create_damageind(vec2 p, float angle, int amount)
 	for(int i = 0; i < amount; i++)
 	{
 		float f = mix(s, e, float(i+1)/float(amount+2));
-		ev_damageind *ev = (ev_damageind *)events.create(EVENT_DAMAGEINDICATION, sizeof(ev_damageind));
+		NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)events.create(NETEVENTTYPE_DAMAGEIND, sizeof(NETEVENT_DAMAGEIND));
 		if(ev)
 		{
 			ev->x = (int)p.x;
@@ -1818,7 +1820,7 @@ void create_damageind(vec2 p, float angle, int amount)
 void create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
 {
 	// create the event
-	ev_explosion *ev = (ev_explosion *)events.create(EVENT_EXPLOSION, sizeof(ev_explosion));
+	NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)events.create(NETEVENTTYPE_EXPLOSION, sizeof(NETEVENT_EXPLOSION));
 	if(ev)
 	{
 		ev->x = (int)p.x;
@@ -1848,21 +1850,22 @@ void create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
 	}
 }
 
+/*
 void create_smoke(vec2 p)
 {
 	// create the event
-	ev_explosion *ev = (ev_explosion *)events.create(EVENT_SMOKE, sizeof(ev_explosion));
+	EV_EXPLOSION *ev = (EV_EXPLOSION *)events.create(EVENT_SMOKE, sizeof(EV_EXPLOSION));
 	if(ev)
 	{
 		ev->x = (int)p.x;
 		ev->y = (int)p.y;
 	}
-}
+}*/
 
 void create_playerspawn(vec2 p)
 {
 	// create the event
-	ev_spawn *ev = (ev_spawn *)events.create(EVENT_PLAYERSPAWN, sizeof(ev_spawn));
+	NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)events.create(NETEVENTTYPE_SPAWN, sizeof(NETEVENT_SPAWN));
 	if(ev)
 	{
 		ev->x = (int)p.x;
@@ -1873,7 +1876,7 @@ void create_playerspawn(vec2 p)
 void create_death(vec2 p)
 {
 	// create the event
-	ev_death *ev = (ev_death *)events.create(EVENT_DEATH, sizeof(ev_death));
+	NETEVENT_DEATH *ev = (NETEVENT_DEATH *)events.create(NETEVENTTYPE_DEATH, sizeof(NETEVENT_DEATH));
 	if(ev)
 	{
 		ev->x = (int)p.x;
@@ -1887,12 +1890,12 @@ void create_sound(vec2 pos, int sound, int mask)
 		return;
 
 	// create a sound
-	ev_sound *ev = (ev_sound *)events.create(EVENT_SOUND_WORLD, sizeof(ev_sound), mask);
+	NETEVENT_SOUND_WORLD *ev = (NETEVENT_SOUND_WORLD *)events.create(NETEVENTTYPE_SOUND_WORLD, sizeof(NETEVENT_SOUND_WORLD), mask);
 	if(ev)
 	{
 		ev->x = (int)pos.x;
 		ev->y = (int)pos.y;
-		ev->sound = sound;
+		ev->soundid = sound;
 	}
 }
 
@@ -2043,7 +2046,7 @@ void mods_snap(int client_id)
 void mods_client_direct_input(int client_id, void *input)
 {
 	if(!world->paused)
-		players[client_id].on_direct_input((player_input *)input);
+		players[client_id].on_direct_input((NETOBJ_PLAYER_INPUT *)input);
 	
 	/*
 	if(i->fire)
@@ -2058,11 +2061,11 @@ void mods_client_predicted_input(int client_id, void *input)
 {
 	if(!world->paused)
 	{
-		if (memcmp(&players[client_id].input, input, sizeof(player_input)) != 0)
+		if (memcmp(&players[client_id].input, input, sizeof(NETOBJ_PLAYER_INPUT)) != 0)
 			players[client_id].last_action = server_tick();
 
 		//players[client_id].previnput = players[client_id].input;
-		players[client_id].input = *(player_input*)input;
+		players[client_id].input = *(NETOBJ_PLAYER_INPUT*)input;
 		players[client_id].num_inputs++;
 		
 		if(players[client_id].input.target_x == 0 && players[client_id].input.target_y == 0)