diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp
index 57a67384a..53eedc456 100644
--- a/src/dobjtype.cpp
+++ b/src/dobjtype.cpp
@@ -2100,6 +2100,7 @@ PStruct::PStruct(FName name, PTypeBase *outer)
 {
 	mDescriptiveName.Format("Struct<%s>", name.GetChars());
 	Size = 0;
+	HasNativeFields = false;
 }
 
 //==========================================================================
@@ -2114,7 +2115,7 @@ void PStruct::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset
 	{
 		if (!(field->Flags & VARF_Native))
 		{
-			field->Type->SetDefaultValue(base, offset + field->Offset, special);
+			field->Type->SetDefaultValue(base, unsigned(offset + field->Offset), special);
 		}
 	}
 }
@@ -2216,13 +2217,13 @@ bool PStruct::ReadFields(FSerializer &ar, void *addr) const
 
 PField *PStruct::AddField(FName name, PType *type, DWORD flags)
 {
-	PField *field = new PField(name, type);
+	PField *field = new PField(name, type, flags);
 
 	// The new field is added to the end of this struct, alignment permitting.
 	field->Offset = (Size + (type->Align - 1)) & ~(type->Align - 1);
 
 	// Enlarge this struct to enclose the new field.
-	Size = field->Offset + type->Size;
+	Size = unsigned(field->Offset + type->Size);
 
 	// This struct's alignment is the same as the largest alignment of any of
 	// its fields.
@@ -2238,6 +2239,29 @@ PField *PStruct::AddField(FName name, PType *type, DWORD flags)
 	return field;
 }
 
+//==========================================================================
+//
+// PStruct :: AddField
+//
+// Appends a new native field to the struct. Returns either the new field
+// or NULL if a symbol by that name already exists.
+//
+//==========================================================================
+
+PField *PStruct::AddNativeField(FName name, PType *type, size_t address, DWORD flags, int bitvalue)
+{
+	PField *field = new PField(name, type, flags|VARF_Native, address, bitvalue);
+
+	if (Symbols.AddSymbol(field) == nullptr)
+	{ // name is already in use
+		delete field;
+		return nullptr;
+	}
+	Fields.Push(field);
+	HasNativeFields = true;
+	return field;
+}
+
 //==========================================================================
 //
 // PStruct :: PropagateMark
@@ -2286,7 +2310,7 @@ PField::PField()
 }
 
 PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue)
-	: PSymbol(name), Offset(unsigned(offset)), Type(type), Flags(flags)
+	: PSymbol(name), Offset(offset), Type(type), Flags(flags)
 {
 	BitValue = bitvalue;
 	if (bitvalue > -1)
@@ -3085,7 +3109,7 @@ PField *PClass::AddField(FName name, PType *type, DWORD flags)
 	{
 		Defaults = (BYTE *)M_Realloc(Defaults, Size);
 		memset(Defaults + oldsize, 0, Size - oldsize);
-		type->SetDefaultValue(Defaults, field->Offset, &SpecialInits);
+		type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits);
 	}
 	return field;
 }
diff --git a/src/dobjtype.h b/src/dobjtype.h
index 5aeefac50..db468870f 100644
--- a/src/dobjtype.h
+++ b/src/dobjtype.h
@@ -574,7 +574,7 @@ class PField : public PSymbol
 public:
 	PField(FName name, PType *type, DWORD flags = 0, size_t offset = 0, int bitvalue = -1);
 
-	unsigned int Offset;
+	size_t Offset;
 	PType *Type;
 	DWORD Flags;
 	int BitValue;
@@ -669,8 +669,10 @@ public:
 	PStruct(FName name, PTypeBase *outer);
 
 	TArray<PField *> Fields;
+	bool HasNativeFields;
 
 	virtual PField *AddField(FName name, PType *type, DWORD flags=0);
+	virtual PField *AddNativeField(FName name, PType *type, size_t address, DWORD flags = 0, int bitvalue = -1);
 
 	size_t PropagateMark();
 
diff --git a/src/g_level.cpp b/src/g_level.cpp
index 9e8448879..5b0c46fa2 100644
--- a/src/g_level.cpp
+++ b/src/g_level.cpp
@@ -1848,6 +1848,65 @@ void FLevelLocals::AddScroller (int secnum)
 	}
 }
 
+//==========================================================================
+//
+// sets up the script-side version of FLevelLocals
+// Since this is a global variable and the script compiler does
+// not allow defining them, it will be fully set up here.
+//
+//==========================================================================
+
+inline int val2bit(int val)
+{
+	int bit = 0;
+	while ((val >>= 1)) bit++;
+	return bit;
+}
+
+void G_InitLevelLocalsForScript()
+{
+	PStruct *lstruct = NewStruct("LevelLocals", nullptr);
+	PField *levelf = new PField("level", lstruct, VARF_Native | VARF_Static, (intptr_t)&level);
+	GlobalSymbols.AddSymbol(levelf);
+
+	// This only exports a selection of fields. Not everything here is useful to the playsim.
+	lstruct->AddNativeField("time", TypeSInt32, myoffsetof(FLevelLocals, time), VARF_ReadOnly);
+	lstruct->AddNativeField("maptime", TypeSInt32, myoffsetof(FLevelLocals, maptime), VARF_ReadOnly);
+	lstruct->AddNativeField("totaltime", TypeSInt32, myoffsetof(FLevelLocals, totaltime), VARF_ReadOnly);
+	lstruct->AddNativeField("starttime", TypeSInt32, myoffsetof(FLevelLocals, starttime), VARF_ReadOnly);
+	lstruct->AddNativeField("partime", TypeSInt32, myoffsetof(FLevelLocals, partime), VARF_ReadOnly);
+	lstruct->AddNativeField("sucktime", TypeSInt32, myoffsetof(FLevelLocals, sucktime), VARF_ReadOnly);
+	lstruct->AddNativeField("cluster", TypeSInt32, myoffsetof(FLevelLocals, cluster), VARF_ReadOnly);
+	lstruct->AddNativeField("clusterflags", TypeSInt32, myoffsetof(FLevelLocals, clusterflags), VARF_ReadOnly);
+	lstruct->AddNativeField("levelnum", TypeSInt32, myoffsetof(FLevelLocals, levelnum), VARF_ReadOnly);
+	//lstruct->AddNativeField("levelname", TypeString, myoffsetof(FLevelLocals, LevelName), VARF_ReadOnly);	// must use an access function to resolve string table references.
+	lstruct->AddNativeField("mapname", TypeString, myoffsetof(FLevelLocals, MapName), VARF_ReadOnly);
+	lstruct->AddNativeField("nextmap", TypeString, myoffsetof(FLevelLocals, NextMap));
+	lstruct->AddNativeField("nextsecretmap", TypeString, myoffsetof(FLevelLocals, NextSecretMap));
+	lstruct->AddNativeField("maptype", TypeSInt32, myoffsetof(FLevelLocals, maptype), VARF_ReadOnly);
+	lstruct->AddNativeField("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_MONSTERSTELEFRAG));
+	lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_ACTOWNSPECIAL));
+	lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_SNDSEQTOTALCTRL));
+	lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_ALLMAP));
+	lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MISSILESACTIVATEIMPACT));
+	lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MONSTERFALLINGDAMAGE));
+	lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_CHECKSWITCHRANGE));
+	lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_POLYGRIND));
+	lstruct->AddNativeField("music", TypeString, myoffsetof(FLevelLocals, Music), VARF_ReadOnly);
+	lstruct->AddNativeField("musicorder", TypeSInt32, myoffsetof(FLevelLocals, musicorder), VARF_ReadOnly);
+	lstruct->AddNativeField("total_secrets", TypeSInt32, myoffsetof(FLevelLocals, total_secrets), VARF_ReadOnly);
+	lstruct->AddNativeField("found_secrets", TypeSInt32, myoffsetof(FLevelLocals, found_secrets));
+	lstruct->AddNativeField("total_items", TypeSInt32, myoffsetof(FLevelLocals, total_items), VARF_ReadOnly);
+	lstruct->AddNativeField("found_items", TypeSInt32, myoffsetof(FLevelLocals, found_items));
+	lstruct->AddNativeField("total_monsters", TypeSInt32, myoffsetof(FLevelLocals, total_monsters), VARF_ReadOnly);
+	lstruct->AddNativeField("killed_monsters", TypeSInt32, myoffsetof(FLevelLocals, killed_monsters));
+	lstruct->AddNativeField("gravity", TypeFloat64, myoffsetof(FLevelLocals, gravity));
+	lstruct->AddNativeField("aircontrol", TypeFloat64, myoffsetof(FLevelLocals, aircontrol));
+	lstruct->AddNativeField("airfriction", TypeFloat64, myoffsetof(FLevelLocals, airfriction));
+	lstruct->AddNativeField("airsupply", TypeSInt32, myoffsetof(FLevelLocals, airsupply));
+	lstruct->AddNativeField("teamdamage", TypeFloat64, myoffsetof(FLevelLocals, teamdamage));
+}
+
 //==========================================================================
 //
 // Lists all currently defined maps
diff --git a/src/g_level.h b/src/g_level.h
index 2b0de7b68..790eba344 100644
--- a/src/g_level.h
+++ b/src/g_level.h
@@ -260,7 +260,7 @@ struct FOptionalMapinfoDataPtr
 typedef TMap<FName, FOptionalMapinfoDataPtr> FOptData;
 typedef TMap<int, FName> FMusicMap;
 
-enum EMapType
+enum EMapType : int
 {
 	MAPTYPE_UNKNOWN = 0,
 	MAPTYPE_DOOM,
diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp
index 77082f3a4..833732008 100644
--- a/src/p_enemy.cpp
+++ b/src/p_enemy.cpp
@@ -1790,6 +1790,13 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params)
 	}
 }
 
+DEFINE_ACTION_FUNCTION(AActor, LookForPlayers)
+{
+	PARAM_SELF_PROLOGUE(AActor);
+	PARAM_BOOL(allaround);
+	ACTION_RETURN_BOOL(P_LookForPlayers(self, allaround, nullptr));
+}
+
 //
 // ACTION ROUTINES
 //
diff --git a/src/p_map.cpp b/src/p_map.cpp
index a2e83b73f..d7bffa589 100644
--- a/src/p_map.cpp
+++ b/src/p_map.cpp
@@ -444,6 +444,17 @@ bool	P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modi
 	return true;
 }
 
+DEFINE_ACTION_FUNCTION(AActor, TeleportMove)
+{
+	PARAM_SELF_PROLOGUE(AActor);
+	PARAM_FLOAT(x);
+	PARAM_FLOAT(y);
+	PARAM_FLOAT(z);
+	PARAM_BOOL(telefrag);
+	PARAM_BOOL_DEF(modify);
+	ACTION_RETURN_BOOL(P_TeleportMove(self, DVector3(x, y, z), telefrag, modify));
+}
+	
 //==========================================================================
 //
 // [RH] P_PlayerStartStomp
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index bd78fdcef..08b662767 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -990,6 +990,15 @@ void AActor::CopyFriendliness (AActor *other, bool changeTarget, bool resetHealt
 	level.total_monsters += CountsAsKill();
 }
 
+DEFINE_ACTION_FUNCTION(AActor, CopyFriendliness)
+{
+	PARAM_SELF_PROLOGUE(AActor);
+	PARAM_OBJECT(other, AActor);
+	PARAM_BOOL_DEF(changetarget);
+	PARAM_BOOL_DEF(resethealth);
+	self->CopyFriendliness(other, changetarget, resethealth);
+	return 0;
+}
 //============================================================================
 //
 // AActor :: ObtainInventory
@@ -6515,6 +6524,12 @@ DDropItem *AActor::GetDropItems() const
 	return GetClass()->DropItems;
 }
 
+DEFINE_ACTION_FUNCTION(AActor, GetDropItems)
+{
+	PARAM_SELF_PROLOGUE(AActor);
+	ACTION_RETURN_OBJECT(self->GetDropItems());
+}
+
 double AActor::GetGravity() const
 {
 	if (flags & MF_NOGRAVITY) return 0;
diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp
index 620d9feed..50cd7699b 100644
--- a/src/scripting/codegeneration/codegen.cpp
+++ b/src/scripting/codegeneration/codegen.cpp
@@ -5067,6 +5067,12 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
 			ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global constant\n", Identifier.GetChars());
 			newex = FxConstant::MakeConstant(sym, ScriptPosition);
 		}
+		else if (sym->IsKindOf(RUNTIME_CLASS(PField)))
+		{
+			// internally defined global variable
+			ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global variable\n", Identifier.GetChars());
+			newex = new FxGlobalVariable(static_cast<PField *>(sym), ScriptPosition);
+		}
 		else
 		{
 			ScriptPosition.Message(MSG_ERROR, "Invalid global identifier '%s'\n", Identifier.GetChars());
@@ -5303,6 +5309,72 @@ ExpEmit FxSelf::Emit(VMFunctionBuilder *build)
 }
 
 
+//==========================================================================
+//
+//
+//
+//==========================================================================
+
+FxGlobalVariable::FxGlobalVariable(PField* mem, const FScriptPosition &pos)
+	: FxExpression(EFX_GlobalVariable, pos)
+{
+	membervar = mem;
+	AddressRequested = false;
+	AddressWritable = true;	// must be true unless classx tells us otherwise if requested.
+}
+
+//==========================================================================
+//
+//
+//
+//==========================================================================
+
+bool FxGlobalVariable::RequestAddress(bool *writable)
+{
+	AddressRequested = true;
+	if (writable != nullptr) *writable = AddressWritable && !(membervar->Flags & VARF_ReadOnly);
+	return true;
+}
+
+//==========================================================================
+//
+//
+//
+//==========================================================================
+
+FxExpression *FxGlobalVariable::Resolve(FCompileContext &ctx)
+{
+	CHECKRESOLVED();
+	ValueType = membervar->Type;
+	return this;
+}
+
+ExpEmit FxGlobalVariable::Emit(VMFunctionBuilder *build)
+{
+	ExpEmit obj(build, REGT_POINTER);
+
+	build->Emit(OP_LKP, obj.RegNum, build->GetConstantAddress((void*)(intptr_t)membervar->Offset, ATAG_GENERIC));
+	if (AddressRequested)
+	{
+		return obj;
+	}
+
+	ExpEmit loc(build, membervar->Type->GetRegType(), membervar->Type->GetRegCount());
+
+	if (membervar->BitValue == -1)
+	{
+		int offsetreg = build->GetConstantInt(0);
+		build->Emit(membervar->Type->GetLoadOp(), loc.RegNum, obj.RegNum, offsetreg);
+	}
+	else
+	{
+		build->Emit(OP_LBIT, loc.RegNum, obj.RegNum, 1 << membervar->BitValue);
+	}
+	obj.Free(build);
+	return loc;
+}
+
+
 //==========================================================================
 //
 //
@@ -5377,11 +5449,21 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
 			classx = nullptr;
 			return x;
 		}
+		else if (classx->ExprType == EFX_GlobalVariable)
+		{
+			auto parentfield = static_cast<FxGlobalVariable *>(classx)->membervar;
+			auto newfield = new PField(membervar->SymbolName, membervar->Type, membervar->Flags | parentfield->Flags, membervar->Offset + parentfield->Offset, membervar->BitValue);
+			static_cast<FxGlobalVariable *>(classx)->membervar = newfield;
+			classx->isresolved = false;	// re-resolve the parent so it can also check if it can be optimized away.
+			auto x = classx->Resolve(ctx);
+			classx = nullptr;
+			return x;
+		}
 		else if (classx->ExprType == EFX_LocalVariable && classx->IsVector())	// vectors are a special case because they are held in registers
 		{
 			// since this is a vector, all potential things that may get here are single float or an xy-vector.
 			auto locvar = static_cast<FxLocalVariable *>(classx);
-			locvar->RegOffset = membervar->Offset / 8;
+			locvar->RegOffset = int(membervar->Offset / 8);
 			locvar->ValueType = membervar->Type;
 			classx = nullptr;
 			delete this;
@@ -5816,13 +5898,15 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
 	case NAME_Name:
 	case NAME_Color:
 	case NAME_Sound:
+	case NAME_State:
 		if (CheckArgSize(MethodName, ArgList, 1, 1, ScriptPosition))
 		{
 			PType *type = MethodName == NAME_Int ? TypeSInt32 :
 				MethodName == NAME_uInt ? TypeUInt32 :
 				MethodName == NAME_Double ? TypeFloat64 :
 				MethodName == NAME_Name ? TypeName :
-				MethodName == NAME_Color ? TypeColor : (PType*)TypeSound;
+				MethodName == NAME_Color ? TypeColor :
+				MethodName == NAME_State? TypeState :(PType*)TypeSound;
 
 			func = new FxTypeCast((*ArgList)[0], type, true, true);
 			(*ArgList)[0] = nullptr;
@@ -6615,14 +6699,19 @@ ExpEmit FxVectorBuiltin::Emit(VMFunctionBuilder *build)
 FxExpression *FxSequence::Resolve(FCompileContext &ctx)
 {
 	CHECKRESOLVED();
+	bool fail = false;
 	for (unsigned i = 0; i < Expressions.Size(); ++i)
 	{
 		if (nullptr == (Expressions[i] = Expressions[i]->Resolve(ctx)))
 		{
-			delete this;
-			return nullptr;
+			fail = true;
 		}
 	}
+	if (fail)
+	{
+		delete this;
+		return nullptr;
+	}
 	return this;
 }
 
diff --git a/src/scripting/codegeneration/codegen.h b/src/scripting/codegeneration/codegen.h
index ee792e5bf..b118b8d5d 100644
--- a/src/scripting/codegeneration/codegen.h
+++ b/src/scripting/codegeneration/codegen.h
@@ -269,6 +269,7 @@ enum EFxType
 	EFX_VectorBuiltin,
 	EFX_TypeCheck,
 	EFX_DynamicCast,
+	EFX_GlobalVariable,
 	EFX_COUNT
 };
 
@@ -1136,6 +1137,25 @@ public:
 };
 
 
+//==========================================================================
+//
+//	FxGlobalVariab�e
+//
+//==========================================================================
+
+class FxGlobalVariable : public FxExpression
+{
+public:
+	PField *membervar;
+	bool AddressRequested;
+	bool AddressWritable;
+
+	FxGlobalVariable(PField*, const FScriptPosition&);
+	FxExpression *Resolve(FCompileContext&);
+	bool RequestAddress(bool *writable);
+	ExpEmit Emit(VMFunctionBuilder *build);
+};
+
 //==========================================================================
 //
 //	FxClassMember
diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp
index 8c42e8987..38bf2bcf6 100644
--- a/src/scripting/thingdef.cpp
+++ b/src/scripting/thingdef.cpp
@@ -215,6 +215,7 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id,
 //==========================================================================
 void ParseScripts();
 void ParseAllDecorate();
+void G_InitLevelLocalsForScript();
 
 void LoadActors ()
 {
@@ -223,6 +224,7 @@ void LoadActors ()
 	timer.Reset(); timer.Clock();
 	FScriptPosition::ResetErrorCounter();
 
+	G_InitLevelLocalsForScript();
 	InitThingdef();
 	FScriptPosition::StrictErrors = true;
 	ParseScripts();
diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp
index b0edcb167..4d18a083b 100644
--- a/src/scripting/thingdef_data.cpp
+++ b/src/scripting/thingdef_data.cpp
@@ -673,10 +673,16 @@ void InitThingdef()
 		qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp);
 	}
 
+	PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor));
+
+	PStruct *sstruct = NewStruct("Sector", nullptr);
+	auto sptr = NewPointer(sstruct);
+	sstruct->AddNativeField("soundtarget", TypeActor, myoffsetof(sector_t, SoundTarget));
+
 	// Define some member variables we feel like exposing to the user
 	PSymbolTable &symt = RUNTIME_CLASS(AActor)->Symbols;
 	PType *array5 = NewArray(TypeSInt32, 5);
-	PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor));
+	symt.AddSymbol(new PField("sector",				sptr,			VARF_Native,				myoffsetof(AActor, Sector)));
 	symt.AddSymbol(new PField(NAME_Alpha,			TypeFloat64,	VARF_Native,				myoffsetof(AActor, Alpha)));
 	symt.AddSymbol(new PField(NAME_Angle,			TypeFloat64,	VARF_Native,				myoffsetof(AActor, Angles.Yaw)));
 	symt.AddSymbol(new PField(NAME_Args,			array5,			VARF_Native,				myoffsetof(AActor, args)));
@@ -725,12 +731,14 @@ void InitThingdef()
 	symt.AddSymbol(new PField("RipperLevel",		TypeSInt32,		VARF_Native,				myoffsetof(AActor, RipperLevel)));
 	symt.AddSymbol(new PField("RipLevelMin",		TypeSInt32,		VARF_Native,				myoffsetof(AActor, RipLevelMin)));
 	symt.AddSymbol(new PField("RipLevelMax",		TypeSInt32,		VARF_Native,				myoffsetof(AActor, RipLevelMax)));
+	symt.AddSymbol(new PField("special2",			TypeSInt32,		VARF_Native,				myoffsetof(AActor, special2)));
 	symt.AddSymbol(new PField(NAME_VisibleStartAngle, TypeFloat64,	VARF_Native,				myoffsetof(AActor, VisibleStartAngle)));
 	symt.AddSymbol(new PField(NAME_VisibleStartPitch, TypeFloat64,	VARF_Native,				myoffsetof(AActor, VisibleStartPitch)));
 	symt.AddSymbol(new PField(NAME_VisibleEndAngle,	TypeFloat64,	VARF_Native,				myoffsetof(AActor, VisibleEndAngle)));
 	symt.AddSymbol(new PField(NAME_VisibleEndPitch, TypeFloat64,	VARF_Native,				myoffsetof(AActor, VisibleEndPitch)));
 	symt.AddSymbol(new PField("AttackSound",		TypeSound,		VARF_Native,				myoffsetof(AActor, AttackSound)));
 	symt.AddSymbol(new PField("DeathSound",			TypeSound,		VARF_Native,				myoffsetof(AActor, DeathSound)));
+	symt.AddSymbol(new PField("SeeSound",			TypeSound,		VARF_Native,				myoffsetof(AActor, SeeSound)));
 	symt.AddSymbol(new PField("Pos",				TypeVector3,	VARF_Native|VARF_ReadOnly,  myoffsetof(AActor, __Pos)));
 	symt.AddSymbol(new PField("Vel",				TypeVector3,	VARF_Native,				myoffsetof(AActor, Vel)));
 	symt.AddSymbol(new PField("Scale",				TypeVector2,	VARF_Native,				myoffsetof(AActor, Scale)));
@@ -761,8 +769,11 @@ void InitThingdef()
 	PSymbolTable &symt2 = RUNTIME_CLASS(DDropItem)->Symbols;
 	PType *TypeDropItem = NewPointer(RUNTIME_CLASS(DDropItem));
 	symt2.AddSymbol(new PField("Next", TypeDropItem, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Next)));
-	symt2.AddSymbol(new PField("ItemName", TypeName, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Name)));
+	symt2.AddSymbol(new PField("Name", TypeName, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Name)));
 	symt2.AddSymbol(new PField("Probability", TypeSInt32, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Probability)));
-	symt2.AddSymbol(new PField("Amount", TypeSInt32, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Amount)));
+	symt2.AddSymbol(new PField("Amount", TypeSInt32, VARF_Native, myoffsetof(DDropItem, Amount)));
+
+	PSymbolTable &symt3 = RUNTIME_CLASS(DObject)->Symbols;
+	symt3.AddSymbol(new PField("bDestroyed", TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(DObject, ObjectFlags), 5/*OF_EuthanizeMe*/));
 
 }
diff --git a/src/scripting/vm/vmbuilder.h b/src/scripting/vm/vmbuilder.h
index 9a97c216d..c94d85f3c 100644
--- a/src/scripting/vm/vmbuilder.h
+++ b/src/scripting/vm/vmbuilder.h
@@ -30,6 +30,8 @@ public:
 
 	// Returns the constant register holding the value.
 	int GetConstantInt(int val);
+	int GetConstantInt(size_t val) { return GetConstantInt(int(val)); }
+	int GetConstantInt(unsigned val) { return GetConstantInt(int(val)); }
 	int GetConstantFloat(double val);
 	int GetConstantAddress(void *ptr, VM_ATAG tag);
 	int GetConstantString(FString str);
diff --git a/src/scripting/vm/vmdisasm.cpp b/src/scripting/vm/vmdisasm.cpp
index ea199612c..239a0dc51 100644
--- a/src/scripting/vm/vmdisasm.cpp
+++ b/src/scripting/vm/vmdisasm.cpp
@@ -199,7 +199,7 @@ static int printf_wrapper(FILE *f, const char *fmt, ...)
 
 void VMDumpConstants(FILE *out, const VMScriptFunction *func)
 {
-	char tmp[21];
+	char tmp[30];
 	int i, j, k, kk;
 
 	if (func->KonstD != NULL && func->NumKonstD != 0)
@@ -239,7 +239,7 @@ void VMDumpConstants(FILE *out, const VMScriptFunction *func)
 			for (j = 0, k = i; j < 4 && k < func->NumKonstA; j++, k += kk)
 			{
 				mysnprintf(tmp, countof(tmp), "%3d. %p:%d", k, func->KonstA[k].v, func->KonstATags()[k]);
-				printf_wrapper(out, "%-20s", tmp);
+				printf_wrapper(out, "%-22s", tmp);
 			}
 			printf_wrapper(out, "\n");
 		}
diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt
index 0b3c4d40b..091fba4b5 100644
--- a/wadsrc/static/zscript/actor.txt
+++ b/wadsrc/static/zscript/actor.txt
@@ -77,6 +77,10 @@ class Actor : Thinker native
 	native void VelFromAngle(float speed = 0, float angle = 0);
 	native bool isFriend(Actor other);
 	native void AdjustFloorClip();
+	native DropItem GetDropItems();
+	native void CopyFriendliness (Actor other, bool changeTarget, bool resetHealth = true);
+	native bool LookForPlayers(bool allaround);
+	native bool TeleportMove(Vector3 pos, bool telefrag, bool modifyactor = true);
 
 	// DECORATE compatible functions
 	native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
diff --git a/wadsrc/static/zscript/doom/bossbrain.txt b/wadsrc/static/zscript/doom/bossbrain.txt
index 641263ecc..cb30e886b 100644
--- a/wadsrc/static/zscript/doom/bossbrain.txt
+++ b/wadsrc/static/zscript/doom/bossbrain.txt
@@ -280,13 +280,12 @@ extend class Actor
 	}
 	*/
 	
-	/*
 	private void SpawnFly(class<Actor> spawntype, sound snd)
 	{
-		AActor newmobj;
-		AActor fog;
-		AActor eye = master; // The eye is the spawnshot's master, not the target!
-		AActor targ = target; // Unlike other projectiles, the target is the intended destination.
+		Actor newmobj;
+		Actor fog;
+		Actor eye = master; // The eye is the spawnshot's master, not the target!
+		Actor targ = target; // Unlike other projectiles, the target is the intended destination.
 		int r;
 			
 		// [GZ] Should be more viable than a countdown...
@@ -307,7 +306,7 @@ extend class Actor
 			if (fog) A_PlaySound(snd, CHAN_BODY);
 		}
 
-		class<Actor> SpawnName;
+		class<Actor> SpawnName = null;
 
 		DropItem di;   // di will be our drop item list iterator
 		DropItem drop; // while drop stays as the reference point.
@@ -334,7 +333,7 @@ extend class Actor
 				}
 			}
 			di = drop;
-			n = randon[pr_spawnfly](0, n);
+			n = random[pr_spawnfly](0, n);
 			while (n >= 0)
 			{
 				if (di.Name != 'none')
@@ -385,11 +384,11 @@ extend class Actor
 				// (if the player has made noise).
 				newmobj.LastHeard = newmobj.Sector.SoundTarget;
 
-				if (newmobj.SeeState != null && newmobj.LookForPlayers (true, null))
+				if (newmobj.SeeState != null && newmobj.LookForPlayers (true))
 				{
 					newmobj.SetState (newmobj.SeeState);
 				}
-				if (!(newmobj.ObjectFlags & OF_EuthanizeMe))
+				if (!newmobj.bDestroyed)
 				{
 					// telefrag anything in this spot
 					newmobj.TeleportMove (newmobj.pos, true);
@@ -401,13 +400,8 @@ extend class Actor
 		// remove self (i.e., cube).
 		Destroy ();
 	}
-	*/
 
-
-	native
-	void A_SpawnFly(class<Actor> spawntype = null)	// needs special treatment for default
-	;
-	/*
+	void A_SpawnFly(class<Actor> spawntype = null)
 	{
 		sound snd; 
 		if (spawntype != null) 
@@ -419,18 +413,13 @@ extend class Actor
 			spawntype = "SpawnFire";
 			snd = "brain/spawn";
 		}
-		SpawnFly(self, spawntype, snd);
+		SpawnFly(spawntype, snd);
 	}
-	*/
-	
-	native
-	void A_SpawnSound()
-	;
-	/*
+
+		void A_SpawnSound()
 	{
 		// travelling cube sound
 		A_PlaySound("brain/cube", CHAN_BODY);
 		SpawnFly("SpawnFire", "brain/spawn");
 	}
-	*/
 }