diff --git a/src/actor.h b/src/actor.h
index df5ef3c17..833cd2c0a 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -565,6 +565,7 @@ class DDropItem : public DObject
 {
 	DECLARE_CLASS(DDropItem, DObject)
 	HAS_OBJECT_POINTERS
+	HAS_FIELDS
 public:
 	DDropItem *Next;
 	FName Name;
@@ -578,6 +579,7 @@ const double MinVel = EQUAL_EPSILON;
 class AActor : public DThinker
 {
 	DECLARE_CLASS_WITH_META (AActor, DThinker, PClassActor)
+	HAS_FIELDS
 	HAS_OBJECT_POINTERS
 public:
 	AActor () throw();
diff --git a/src/dobject.cpp b/src/dobject.cpp
index beef73c89..56d12787f 100644
--- a/src/dobject.cpp
+++ b/src/dobject.cpp
@@ -62,6 +62,7 @@ ClassReg DObject::RegistrationInfo =
 	NULL,							// ParentType
 	NULL,							// Pointers
 	&DObject::InPlaceConstructor,	// ConstructNative
+	&DObject::InitNativeFields,
 	sizeof(DObject),				// SizeOf
 	CLASSREG_PClass,				// MetaClassNum
 };
@@ -344,6 +345,18 @@ DObject::~DObject ()
 //
 //==========================================================================
 
+void DObject::InitNativeFields()
+{
+	auto meta = RUNTIME_CLASS(DObject);
+	meta->AddNativeField("bDestroyed", TypeSInt32, myoffsetof(DObject, ObjectFlags), VARF_ReadOnly, OF_EuthanizeMe);
+}
+
+//==========================================================================
+//
+//
+//
+//==========================================================================
+
 void DObject::Destroy ()
 {
 	ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe;
diff --git a/src/dobject.h b/src/dobject.h
index 91a80f9d0..ea0a44a85 100644
--- a/src/dobject.h
+++ b/src/dobject.h
@@ -111,6 +111,7 @@ struct ClassReg
 	ClassReg *ParentType;
 	const size_t *Pointers;
 	void (*ConstructNative)(void *);
+	void(*InitNatives)();
 	unsigned int SizeOf:28;
 	unsigned int MetaClassNum:4;
 
@@ -147,6 +148,9 @@ protected: \
 #define HAS_OBJECT_POINTERS \
 	static const size_t PointerOffsets[];
 
+#define HAS_FIELDS \
+	static void InitNativeFields();
+
 // Taking the address of a field in an object at address 1 instead of
 // address 0 keeps GCC from complaining about possible misuse of offsetof.
 #define DECLARE_POINTER(field)	(size_t)&((ThisClass*)1)->field - 1,
@@ -159,13 +163,14 @@ protected: \
 #	define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
 #endif
 
-#define _IMP_PCLASS(cls,ptrs,create) \
+#define _IMP_PCLASS(cls,ptrs,create, initn) \
 	ClassReg cls::RegistrationInfo = {\
 		NULL, \
 		#cls, \
 		&cls::Super::RegistrationInfo, \
 		ptrs, \
 		create, \
+		initn, \
 		sizeof(cls), \
 		cls::MetaClassNum }; \
 	_DECLARE_TI(cls) \
@@ -176,18 +181,27 @@ protected: \
 
 #define IMPLEMENT_POINTY_CLASS(cls) \
 	_IMP_CREATE_OBJ(cls) \
-	_IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor) \
+	_IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor, nullptr) \
+	const size_t cls::PointerOffsets[] = {
+
+#define IMPLEMENT_POINTY_CLASS_WITH_FIELDS(cls) \
+	_IMP_CREATE_OBJ(cls) \
+	_IMP_PCLASS(cls,cls::PointerOffsets,cls::InPlaceConstructor, cls::InitNativeFields) \
 	const size_t cls::PointerOffsets[] = {
 
 #define IMPLEMENT_CLASS(cls) \
 	_IMP_CREATE_OBJ(cls) \
-	_IMP_PCLASS(cls,NULL,cls::InPlaceConstructor) 
+	_IMP_PCLASS(cls,nullptr,cls::InPlaceConstructor, nullptr) 
+
+#define IMPLEMENT_CLASS_WITH_FIELDS(cls) \
+	_IMP_CREATE_OBJ(cls) \
+	_IMP_PCLASS(cls,nullptr,cls::InPlaceConstructor, cls::InitNativeFields) 
 
 #define IMPLEMENT_ABSTRACT_CLASS(cls) \
-	_IMP_PCLASS(cls,NULL,NULL)
+	_IMP_PCLASS(cls,nullptr,nullptr,nullptr)
 
 #define IMPLEMENT_ABSTRACT_POINTY_CLASS(cls) \
-	_IMP_PCLASS(cls,cls::PointerOffsets,NULL) \
+	_IMP_PCLASS(cls,cls::PointerOffsets,nullptr,nullptr) \
 	const size_t cls::PointerOffsets[] = {
 
 enum EObjectFlags
@@ -438,6 +452,7 @@ public:
 	virtual PClass *StaticType() const { return RegistrationInfo.MyClass; }
 	static ClassReg RegistrationInfo, * const RegistrationInfoPtr;
 	static void InPlaceConstructor (void *mem);
+	static void InitNativeFields();
 	typedef PClass MetaClass;
 private:
 	typedef DObject ThisClass;
diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp
index 53eedc456..631a7e6ee 100644
--- a/src/dobjtype.cpp
+++ b/src/dobjtype.cpp
@@ -2309,13 +2309,18 @@ PField::PField()
 {
 }
 
+
 PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue)
 	: PSymbol(name), Offset(offset), Type(type), Flags(flags)
 {
 	BitValue = bitvalue;
-	if (bitvalue > -1)
+	if (bitvalue != -1)
 	{
-		if (type->IsA(RUNTIME_CLASS(PInt)) && unsigned(bitvalue) < 8 * type->Size)
+		BitValue = 0;
+		unsigned val = bitvalue;
+		while ((val >>= 1)) BitValue++;
+
+		if (type->IsA(RUNTIME_CLASS(PInt)) && unsigned(BitValue) < 8u * type->Size)
 		{
 			// map to the single bytes in the actual variable. The internal bit instructions operate on 8 bit values.
 #ifndef __BIG_ENDIAN__
diff --git a/src/g_level.cpp b/src/g_level.cpp
index 5b0c46fa2..b13a39e20 100644
--- a/src/g_level.cpp
+++ b/src/g_level.cpp
@@ -1856,13 +1856,6 @@ void FLevelLocals::AddScroller (int secnum)
 //
 //==========================================================================
 
-inline int val2bit(int val)
-{
-	int bit = 0;
-	while ((val >>= 1)) bit++;
-	return bit;
-}
-
 void G_InitLevelLocalsForScript()
 {
 	PStruct *lstruct = NewStruct("LevelLocals", nullptr);
@@ -1884,14 +1877,14 @@ void G_InitLevelLocalsForScript()
 	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("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_MONSTERSTELEFRAG);
+	lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_ACTOWNSPECIAL);
+	lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, LEVEL_SNDSEQTOTALCTRL);
+	lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, (LEVEL2_ALLMAP));
+	lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_MISSILESACTIVATEIMPACT);
+	lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_MONSTERFALLINGDAMAGE);
+	lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, LEVEL2_CHECKSWITCHRANGE);
+	lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, 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);
diff --git a/src/p_acs.cpp b/src/p_acs.cpp
index a6197e9a6..4024bc9f9 100644
--- a/src/p_acs.cpp
+++ b/src/p_acs.cpp
@@ -5389,11 +5389,11 @@ doplaysound:			if (funcIndex == ACSF_PlayActorSound)
 						{
 							if (!looping)
 							{
-								S_PlaySound(spot, chan, sid, vol, atten, local);
+								S_PlaySound(spot, chan, sid, vol, atten, !!local);
 							}
 							else if (!S_IsActorPlayingSomething(spot, chan & 7, sid))
 							{
-								S_PlaySound(spot, chan | CHAN_LOOP, sid, vol, atten, local);
+								S_PlaySound(spot, chan | CHAN_LOOP, sid, vol, atten, !!local);
 							}
 						}
 					}
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index 08b662767..cf0a033b3 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -131,7 +131,7 @@ CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE);
 
 // CODE --------------------------------------------------------------------
 
-IMPLEMENT_POINTY_CLASS (AActor)
+IMPLEMENT_POINTY_CLASS_WITH_FIELDS (AActor)
  DECLARE_POINTER (target)
  DECLARE_POINTER (lastenemy)
  DECLARE_POINTER (tracer)
@@ -151,6 +151,99 @@ AActor::~AActor ()
 	// Use Destroy() instead.
 }
 
+extern FFlagDef InternalActorFlagDefs[];
+extern FFlagDef ActorFlagDefs[];
+
+void AActor::InitNativeFields()
+{
+	PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor));
+	PType *TypeInventory = NewPointer(RUNTIME_CLASS(AInventory));
+	PStruct *sstruct = NewStruct("Sector", nullptr);
+	auto TypeSector = NewPointer(sstruct);
+	PType *array5 = NewArray(TypeSInt32, 5);
+
+	auto meta = RUNTIME_CLASS(AActor);
+
+	// Define the member variables we feel like exposing to the user
+	meta->AddNativeField(NAME_Alpha,			TypeFloat64,	myoffsetof(AActor, Alpha));
+	meta->AddNativeField(NAME_Angle,			TypeFloat64,	myoffsetof(AActor, Angles.Yaw));
+	meta->AddNativeField(NAME_Args,				array5,			myoffsetof(AActor, args));
+	meta->AddNativeField(NAME_CeilingZ,			TypeFloat64,	myoffsetof(AActor, ceilingz), VARF_ReadOnly);
+	meta->AddNativeField(NAME_FloorZ,			TypeFloat64,	myoffsetof(AActor, floorz), VARF_ReadOnly);
+	meta->AddNativeField(NAME_Health,			TypeSInt32,		myoffsetof(AActor, health), VARF_ReadOnly);
+	meta->AddNativeField(NAME_Mass,				TypeSInt32,		myoffsetof(AActor, Mass));
+	meta->AddNativeField(NAME_Pitch,			TypeFloat64,	myoffsetof(AActor, Angles.Pitch));
+	meta->AddNativeField(NAME_Roll,				TypeFloat64,	myoffsetof(AActor, Angles.Roll));
+	meta->AddNativeField(NAME_Special,			TypeSInt32,		myoffsetof(AActor, special));
+	meta->AddNativeField(NAME_TID,				TypeSInt32,		myoffsetof(AActor, tid), VARF_ReadOnly);
+	meta->AddNativeField(NAME_TIDtoHate,		TypeSInt32,		myoffsetof(AActor, TIDtoHate), VARF_ReadOnly);
+	meta->AddNativeField(NAME_WaterLevel,		TypeSInt32,		myoffsetof(AActor, waterlevel), VARF_ReadOnly);
+	meta->AddNativeField(NAME_X,				TypeFloat64,	myoffsetof(AActor, __Pos.X), VARF_ReadOnly | VARF_Deprecated);	// must remain read-only!
+	meta->AddNativeField(NAME_Y,				TypeFloat64,	myoffsetof(AActor, __Pos.Y), VARF_ReadOnly | VARF_Deprecated);	// must remain read-only!
+	meta->AddNativeField(NAME_Z,				TypeFloat64,	myoffsetof(AActor, __Pos.Z), VARF_ReadOnly | VARF_Deprecated);	// must remain read-only!
+	meta->AddNativeField(NAME_VelX,				TypeFloat64,	myoffsetof(AActor, Vel.X), VARF_ReadOnly | VARF_Deprecated);
+	meta->AddNativeField(NAME_VelY,				TypeFloat64,	myoffsetof(AActor, Vel.Y), VARF_ReadOnly | VARF_Deprecated);
+	meta->AddNativeField(NAME_VelZ,				TypeFloat64,	myoffsetof(AActor, Vel.Z), VARF_ReadOnly | VARF_Deprecated);
+	meta->AddNativeField(NAME_MomX,				TypeFloat64,	myoffsetof(AActor, Vel.X), VARF_ReadOnly | VARF_Deprecated);
+	meta->AddNativeField(NAME_MomY,				TypeFloat64,	myoffsetof(AActor, Vel.Y), VARF_ReadOnly | VARF_Deprecated);
+	meta->AddNativeField(NAME_MomZ,				TypeFloat64,	myoffsetof(AActor, Vel.Z), VARF_ReadOnly | VARF_Deprecated);
+	meta->AddNativeField(NAME_ScaleX,			TypeFloat64,	myoffsetof(AActor, Scale.X), VARF_Deprecated);
+	meta->AddNativeField(NAME_ScaleY,			TypeFloat64,	myoffsetof(AActor, Scale.Y), VARF_Deprecated);
+	meta->AddNativeField(NAME_Score,			TypeSInt32,		myoffsetof(AActor, Score));
+	meta->AddNativeField(NAME_Accuracy,			TypeSInt32,		myoffsetof(AActor, accuracy));
+	meta->AddNativeField(NAME_Stamina,			TypeSInt32,		myoffsetof(AActor, stamina));
+	meta->AddNativeField(NAME_Height,			TypeFloat64,	myoffsetof(AActor, Height));
+	meta->AddNativeField(NAME_Radius,			TypeFloat64,	myoffsetof(AActor, radius), VARF_ReadOnly);
+	meta->AddNativeField(NAME_ReactionTime,		TypeSInt32,		myoffsetof(AActor, reactiontime));
+	meta->AddNativeField(NAME_MeleeRange,		TypeFloat64,	myoffsetof(AActor, meleerange));
+	meta->AddNativeField(NAME_Speed,			TypeFloat64,	myoffsetof(AActor, Speed));
+	meta->AddNativeField("FloatSpeed",			TypeFloat64,	myoffsetof(AActor, FloatSpeed));
+	meta->AddNativeField("PainThreshold",		TypeSInt32,		myoffsetof(AActor, PainThreshold));
+	meta->AddNativeField("spriteAngle",			TypeFloat64,	myoffsetof(AActor, SpriteAngle));
+	meta->AddNativeField("spriteRotation",		TypeFloat64,	myoffsetof(AActor, SpriteRotation));
+	meta->AddNativeField(NAME_Threshold,		TypeSInt32,		myoffsetof(AActor, threshold));
+	meta->AddNativeField(NAME_DefThreshold,		TypeSInt32,		myoffsetof(AActor, DefThreshold), VARF_ReadOnly);
+	meta->AddNativeField(NAME_Damage,			TypeSInt32,		myoffsetof(AActor, DamageVal), VARF_ReadOnly);
+	meta->AddNativeField("visdir",				TypeSInt32,		myoffsetof(AActor, visdir));
+	meta->AddNativeField("Gravity",				TypeFloat64,	myoffsetof(AActor, Gravity));
+	meta->AddNativeField("FloorClip",			TypeFloat64,	myoffsetof(AActor, Floorclip));
+	meta->AddNativeField("DamageType",			TypeName,		myoffsetof(AActor, DamageType));
+	meta->AddNativeField("FloatBobPhase",		TypeUInt8,		myoffsetof(AActor, FloatBobPhase));
+	meta->AddNativeField("tics",				TypeSInt32,		myoffsetof(AActor, tics));
+	meta->AddNativeField("RipperLevel",			TypeSInt32,		myoffsetof(AActor, RipperLevel));
+	meta->AddNativeField("RipLevelMin",			TypeSInt32,		myoffsetof(AActor, RipLevelMin));
+	meta->AddNativeField("RipLevelMax",			TypeSInt32,		myoffsetof(AActor, RipLevelMax));
+	meta->AddNativeField("special2",			TypeSInt32,		myoffsetof(AActor, special2));
+	meta->AddNativeField(NAME_VisibleStartAngle, TypeFloat64,	myoffsetof(AActor, VisibleStartAngle));
+	meta->AddNativeField(NAME_VisibleStartPitch, TypeFloat64,	myoffsetof(AActor, VisibleStartPitch));
+	meta->AddNativeField(NAME_VisibleEndAngle,	TypeFloat64,	myoffsetof(AActor, VisibleEndAngle));
+	meta->AddNativeField(NAME_VisibleEndPitch,	TypeFloat64,	myoffsetof(AActor, VisibleEndPitch));
+	meta->AddNativeField("AttackSound",			TypeSound,		myoffsetof(AActor, AttackSound));
+	meta->AddNativeField("DeathSound",			TypeSound,		myoffsetof(AActor, DeathSound));
+	meta->AddNativeField("SeeSound",			TypeSound,		myoffsetof(AActor, SeeSound));
+	meta->AddNativeField("Pos",					TypeVector3,	myoffsetof(AActor, __Pos), VARF_ReadOnly);
+	meta->AddNativeField("Vel",					TypeVector3,	myoffsetof(AActor, Vel));
+	meta->AddNativeField("Scale",				TypeVector2,	myoffsetof(AActor, Scale));
+	meta->AddNativeField("CurState",			TypeState,		myoffsetof(AActor, state), VARF_ReadOnly);	// has to be renamed on the script side because it clashes with the same named type.
+	meta->AddNativeField("SeeState",			TypeState,		myoffsetof(AActor, SeeState), VARF_ReadOnly);
+	meta->AddNativeField(NAME_Target,			TypeActor,		myoffsetof(AActor, target));
+	meta->AddNativeField(NAME_Master,			TypeActor,		myoffsetof(AActor, master));
+	meta->AddNativeField(NAME_Tracer,			TypeActor,		myoffsetof(AActor, tracer));
+	meta->AddNativeField("LastHeard",			TypeActor,		myoffsetof(AActor, LastHeard));
+	meta->AddNativeField("LastEnemy",			TypeActor,		myoffsetof(AActor, lastenemy));
+	meta->AddNativeField("Sector",				TypeSector,		myoffsetof(AActor, Sector));
+
+	// synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them.
+	for (size_t i = 0; ActorFlagDefs[i].flagbit != 0xffffffff; i++)
+	{
+		meta->AddNativeField(FStringf("b%s", ActorFlagDefs[i].name), (ActorFlagDefs[i].fieldsize == 4? TypeSInt32 : TypeSInt16), ActorFlagDefs[i].structoffset, ActorFlagDefs[i].varflags, ActorFlagDefs[i].flagbit);
+	}
+	for (size_t i = 0; InternalActorFlagDefs[i].flagbit != 0xffffffff; i++)
+	{
+		meta->AddNativeField(FStringf("b%s", InternalActorFlagDefs[i].name), (InternalActorFlagDefs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), InternalActorFlagDefs[i].structoffset, InternalActorFlagDefs[i].varflags, InternalActorFlagDefs[i].flagbit);
+	}
+}
+
 //==========================================================================
 //
 // AActor :: Serialize
@@ -6707,10 +6800,21 @@ DEFINE_ACTION_FUNCTION(AActor, Vec2OffsetZ)
 // DropItem handling
 //
 //----------------------------------------------------------------------------
-IMPLEMENT_POINTY_CLASS(DDropItem)
+IMPLEMENT_POINTY_CLASS_WITH_FIELDS(DDropItem)
  DECLARE_POINTER(Next)
 END_POINTERS
 
+void DDropItem::InitNativeFields()
+{
+	auto meta = RUNTIME_CLASS(DDropItem);
+	PType *TypeDropItem = NewPointer(RUNTIME_CLASS(DDropItem));
+	meta->AddNativeField("Next", TypeDropItem, myoffsetof(DDropItem, Next), VARF_ReadOnly);
+	meta->AddNativeField("Name", TypeName, myoffsetof(DDropItem, Name), VARF_ReadOnly);
+	meta->AddNativeField("Probability", TypeSInt32, myoffsetof(DDropItem, Probability), VARF_ReadOnly);
+	meta->AddNativeField("Amount", TypeSInt32, myoffsetof(DDropItem, Amount));
+}
+
+
 void PrintMiscActorInfo(AActor *query)
 {
 	if (query)
diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp
index 38bf2bcf6..8c42e8987 100644
--- a/src/scripting/thingdef.cpp
+++ b/src/scripting/thingdef.cpp
@@ -215,7 +215,6 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id,
 //==========================================================================
 void ParseScripts();
 void ParseAllDecorate();
-void G_InitLevelLocalsForScript();
 
 void LoadActors ()
 {
@@ -224,7 +223,6 @@ 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 4d18a083b..f628dec3c 100644
--- a/src/scripting/thingdef_data.cpp
+++ b/src/scripting/thingdef_data.cpp
@@ -62,7 +62,7 @@ static TArray<AFuncDesc> AFTable;
 #define DEFINE_DUMMY_FLAG(name, deprec) { DEPF_UNUSED, #name, -1, 0, deprec? VARF_Deprecated:0 }
 
 // internal flags. These do not get exposed to actor definitions but scripts need to be able to access them as variables.
-static FFlagDef InternalActorFlagDefs[]=
+FFlagDef InternalActorFlagDefs[]=
 {
 	DEFINE_FLAG(MF, INCHASE, AActor, flags),
 	DEFINE_FLAG(MF, UNMORPHED, AActor, flags),
@@ -91,10 +91,11 @@ static FFlagDef InternalActorFlagDefs[]=
 	DEFINE_FLAG(MF6, INTRYMOVE, AActor, flags6),
 	DEFINE_FLAG(MF7, HANDLENODELAY, AActor, flags7),
 	DEFINE_FLAG(MF7, FLYCHEAT, AActor, flags7),
+	{ 0xffffffff }
 };
 
 
-static FFlagDef ActorFlagDefs[]=
+FFlagDef ActorFlagDefs[]=
 {
 	DEFINE_FLAG(MF, PICKUP, APlayerPawn, flags),
 	DEFINE_FLAG(MF, SPECIAL, APlayerPawn, flags),
@@ -328,6 +329,7 @@ static FFlagDef ActorFlagDefs[]=
 	DEFINE_FLAG2(BOUNCE_MBF, MBFBOUNCER, AActor, BounceFlags),
 	DEFINE_FLAG2(BOUNCE_AutoOffFloorOnly, BOUNCEAUTOOFFFLOORONLY, AActor, BounceFlags),
 	DEFINE_FLAG2(BOUNCE_UseBounceState, USEBOUNCESTATE, AActor, BounceFlags),
+	{ 0xffffffff }
 };
 
 // These won't be accessible through bitfield variables
@@ -433,7 +435,7 @@ static FFlagDef PowerSpeedFlagDefs[] =
 
 static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; } FlagLists[] =
 {
-	{ &RUNTIME_CLASS_CASTLESS(AActor), 		ActorFlagDefs,		countof(ActorFlagDefs) },
+	{ &RUNTIME_CLASS_CASTLESS(AActor), 		ActorFlagDefs,		countof(ActorFlagDefs)-1 },	// -1 to account for the terminator
 	{ &RUNTIME_CLASS_CASTLESS(AActor), 		MoreFlagDefs,		countof(MoreFlagDefs) },
 	{ &RUNTIME_CLASS_CASTLESS(AInventory), 	InventoryFlagDefs,	countof(InventoryFlagDefs) },
 	{ &RUNTIME_CLASS_CASTLESS(AWeapon), 	WeaponFlagDefs,		countof(WeaponFlagDefs) },
@@ -634,6 +636,7 @@ static int funccmp(const void * a, const void * b)
 // Initialization
 //
 //==========================================================================
+void G_InitLevelLocalsForScript();
 
 void InitThingdef()
 {
@@ -679,101 +682,14 @@ void InitThingdef()
 	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);
-	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)));
-	symt.AddSymbol(new PField(NAME_CeilingZ,		TypeFloat64,	VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, ceilingz)));
-	symt.AddSymbol(new PField(NAME_FloorZ,			TypeFloat64,	VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, floorz)));
-	symt.AddSymbol(new PField(NAME_Health,			TypeSInt32,		VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, health)));
-	symt.AddSymbol(new PField(NAME_Mass,			TypeSInt32,		VARF_Native,				myoffsetof(AActor, Mass)));
-	symt.AddSymbol(new PField(NAME_Pitch,			TypeFloat64,	VARF_Native,				myoffsetof(AActor, Angles.Pitch)));
-	symt.AddSymbol(new PField(NAME_Roll,			TypeFloat64,	VARF_Native,				myoffsetof(AActor, Angles.Roll)));
-	symt.AddSymbol(new PField(NAME_Special,			TypeSInt32,		VARF_Native,				myoffsetof(AActor, special)));
-	symt.AddSymbol(new PField(NAME_TID,				TypeSInt32,		VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, tid)));
-	symt.AddSymbol(new PField(NAME_TIDtoHate,		TypeSInt32,		VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, TIDtoHate)));
-	symt.AddSymbol(new PField(NAME_WaterLevel,		TypeSInt32,		VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, waterlevel)));
-	symt.AddSymbol(new PField(NAME_X,				TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, __Pos.X)));	// must remain read-only!
-	symt.AddSymbol(new PField(NAME_Y,				TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, __Pos.Y)));	// must remain read-only!
-	symt.AddSymbol(new PField(NAME_Z,				TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, __Pos.Z)));	// must remain read-only!
-	symt.AddSymbol(new PField(NAME_VelX,			TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, Vel.X)));
-	symt.AddSymbol(new PField(NAME_VelY,			TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, Vel.Y)));
-	symt.AddSymbol(new PField(NAME_VelZ,			TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, Vel.Z)));
-	symt.AddSymbol(new PField(NAME_MomX,			TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, Vel.X)));
-	symt.AddSymbol(new PField(NAME_MomY,			TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, Vel.Y)));
-	symt.AddSymbol(new PField(NAME_MomZ,			TypeFloat64,	VARF_Native|VARF_ReadOnly|VARF_Deprecated,	myoffsetof(AActor, Vel.Z)));
-	symt.AddSymbol(new PField(NAME_ScaleX,			TypeFloat64,	VARF_Native|VARF_Deprecated,	myoffsetof(AActor, Scale.X)));
-	symt.AddSymbol(new PField(NAME_ScaleY,			TypeFloat64,	VARF_Native|VARF_Deprecated,	myoffsetof(AActor, Scale.Y)));
-	symt.AddSymbol(new PField(NAME_Score,			TypeSInt32,		VARF_Native,				myoffsetof(AActor, Score)));
-	symt.AddSymbol(new PField(NAME_Accuracy,		TypeSInt32,		VARF_Native,				myoffsetof(AActor, accuracy)));
-	symt.AddSymbol(new PField(NAME_Stamina,			TypeSInt32,		VARF_Native,				myoffsetof(AActor, stamina)));
-	symt.AddSymbol(new PField(NAME_Height,			TypeFloat64,	VARF_Native,				myoffsetof(AActor, Height)));
-	symt.AddSymbol(new PField(NAME_Radius,			TypeFloat64,	VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, radius)));
-	symt.AddSymbol(new PField(NAME_ReactionTime,	TypeSInt32,		VARF_Native,				myoffsetof(AActor, reactiontime)));
-	symt.AddSymbol(new PField(NAME_MeleeRange,		TypeFloat64,	VARF_Native,				myoffsetof(AActor, meleerange)));
-	symt.AddSymbol(new PField(NAME_Speed,			TypeFloat64,	VARF_Native,				myoffsetof(AActor, Speed)));
-	symt.AddSymbol(new PField("FloatSpeed",			TypeFloat64,	VARF_Native,				myoffsetof(AActor, FloatSpeed)));
-	symt.AddSymbol(new PField("PainThreshold",		TypeSInt32,		VARF_Native,				myoffsetof(AActor, PainThreshold)));
-	symt.AddSymbol(new PField("spriteAngle",		TypeFloat64,	VARF_Native,				myoffsetof(AActor, SpriteAngle)));
-	symt.AddSymbol(new PField("spriteRotation",		TypeFloat64,	VARF_Native,				myoffsetof(AActor, SpriteRotation)));
-	symt.AddSymbol(new PField(NAME_Threshold,		TypeSInt32,		VARF_Native,				myoffsetof(AActor, threshold)));
-	symt.AddSymbol(new PField(NAME_DefThreshold,	TypeSInt32,		VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, DefThreshold)));
-	symt.AddSymbol(new PField(NAME_Damage,			TypeSInt32,		VARF_Native|VARF_ReadOnly,  myoffsetof(AActor, DamageVal)));
-	symt.AddSymbol(new PField("visdir",				TypeSInt32,		VARF_Native,				myoffsetof(AActor, visdir)));
-	symt.AddSymbol(new PField("Gravity",			TypeFloat64,	VARF_Native,				myoffsetof(AActor, Gravity)));
-	symt.AddSymbol(new PField("FloorClip",			TypeFloat64,	VARF_Native,				myoffsetof(AActor, Floorclip)));
-	symt.AddSymbol(new PField("DamageType",			TypeName,		VARF_Native,				myoffsetof(AActor, DamageType)));
-	symt.AddSymbol(new PField("FloatBobPhase",		TypeUInt8,		VARF_Native,				myoffsetof(AActor, FloatBobPhase)));
-	symt.AddSymbol(new PField("tics",				TypeSInt32,		VARF_Native,				myoffsetof(AActor, tics)));
-	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)));
-	symt.AddSymbol(new PField("CurState",			TypeState,		VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, state)));	// has to be renamed on the script side because it clashes with the same named type.
-	symt.AddSymbol(new PField("SeeState",			TypeState,		VARF_Native|VARF_ReadOnly,	myoffsetof(AActor, SeeState)));
-	symt.AddSymbol(new PField(NAME_Target,			TypeActor,		VARF_Native,				myoffsetof(AActor, target)));
-	symt.AddSymbol(new PField(NAME_Master,			TypeActor,		VARF_Native,				myoffsetof(AActor, master)));
-	symt.AddSymbol(new PField(NAME_Tracer,			TypeActor,		VARF_Native,				myoffsetof(AActor, tracer)));
-	symt.AddSymbol(new PField("LastHeard",			TypeActor,		VARF_Native,				myoffsetof(AActor, LastHeard)));
-	symt.AddSymbol(new PField("LastEnemy",			TypeActor,		VARF_Native,				myoffsetof(AActor, lastenemy)));
+	G_InitLevelLocalsForScript();
 
-	// synthesize a symbol for each flag.
-	for (size_t i = 0; i < countof(ActorFlagDefs); i++)
+	FAutoSegIterator probe(CRegHead, CRegTail);
+
+	while (*++probe != NULL)
 	{
-		int bit = 0;
-		unsigned val = ActorFlagDefs[i].flagbit;
-		while ((val >>= 1)) bit++;
-		symt.AddSymbol(new PField(FStringf("b%s", ActorFlagDefs[i].name), (ActorFlagDefs[i].fieldsize == 4? TypeSInt32 : TypeSInt16), ActorFlagDefs[i].varflags, ActorFlagDefs[i].structoffset, bit));
+		if (((ClassReg *)*probe)->InitNatives) 
+			((ClassReg *)*probe)->InitNatives();
 	}
-	for (size_t i = 0; i < countof(InternalActorFlagDefs); i++)
-	{
-		int bit = 0;
-		unsigned val = InternalActorFlagDefs[i].flagbit;
-		while ((val >>= 1)) bit++;
-		symt.AddSymbol(new PField(FStringf("b%s", InternalActorFlagDefs[i].name), (InternalActorFlagDefs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), InternalActorFlagDefs[i].varflags, InternalActorFlagDefs[i].structoffset, bit));
-	}
-
-	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("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, 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*/));
 
 }