1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

Lua Environment and Sandboxing

Lua Environment and Sandboxing

  1. Pazyryk
    There's a variable in Lua called "_G" that represents the environment. It's a table that contains all of the global variables by name and their values. Keep in mind that things like "print", "ipairs", "GameInfo" and "_G" itself are just ordinary Lua variable names that happen to be globals pointing to functions or tables. You can easily reassign those variable names with any value you like (including nil) either globally or within some scope. For example, you could add local print = function() end in a file to make print do nothing in that file, or local print = nil to "sandbox" that function so it is no longer available in that scope.

    If you are in Main State of the Live Tuner, you can print the environment (i.e., all global variables and their values) with:
    Code:
    for key, value in pairs(_G) do print(key, value) end
    This will get you the first two columns of the table below, which includes all of the standard Lua globals plus globals added by Firaxis (GameInfo and so on). Notice that _G itself is in the environment, which is why I can access it as I did.

    However, if you try this from another state (say, from your mod), it won't work. That's because _G is sandboxed along with other things like io. The third column below indicates what is visible from my mod's state, where nil means that the variable name ("_G", "io", etc.) has been reassigned a nil value so it is no longer available to us. The table gives a pretty good picture of what is and isn't available from a mod. To get a really complete picture you would need to iterate over all of the available tables below. For example, I would guess that os.remove is sandboxed (although I haven't looked).

    I'd really prefer it if this thread doesn't become an extended complaining (tried to use another word there but it vanished for some reason) session on sandboxing. Rather, there are a few Firaxis globals here that may be worth investigating. For example, I learned that it is easy to control sound volume within a mod with:
    Code:
    > SetVolumeKnobValue(GetVolumeKnobIDFromName("USER_VOLUME_MUSIC"), 5)
    OK, you could have figured that out by looking in Options.lua, but seeing the available globals here is what tipped me off in the first place. Or:
    Code:
    > GetCurCivSong()
    SONG_INDIA_PEACE_41 (Mother_Ganges_JM)
    There is perhaps some other useful functionality to be discovered here. I'd like to see folks experiment around and posting what they find. Just iterate over tables (as I did above for _G) to see what they contain (...CodeBuddy?). There may be other useful things to learn by exploring sandboxed tables (or functions?) in Main State.


    Column 1
    Keys of _G (from Main State) Value (from Main State) Value (from mod state)
    _ArtInfoListener userdata: 16AECF68 nil
    _CreateThread function: 16B8B258 nil
    _DestroyThread function: 16B8B298 nil
    _G table: 16B8A200 nil
    _VERSION Lua 5.1 Lua 5.1
    ArtInfo table: 16AECF28 table: 169ACF28
    assert function: 16B8A8D0 function: 16A4A8D0
    BeginAudioLogging void BeginAudioLogging( void ) void BeginAudioLogging( void )
    CodeBuddy table: 16B8CA68 table: 169DFE20
    collectgarbage function: 16B8A910 function: 16A4A910
    CollectLuaMemoryUsage function: 16B8FB18 nil
    ContentManager table: 16B1CBE8 table: 166D20C0
    ContentManagerEnums table: 16B1CD00 nil
    coroutine table: 16B8C360 table: 166D0E28
    DB table: 16AED428 table: 166D1418
    debug table: 16B8C810 table: 16A4C810
    dofile function: 16B8A930 nil
    EndAudioLogging void EndAudioLogging( void ) void EndAudioLogging( void )
    error function: 16B8A970 function: 16A4A970
    EventFactories table: 16AED108 nil
    ExposedMembers table: 16AE9CB0 table: 169DFF88
    ExposedTypes table: 16AE9C10 table: 169DFF38
    FLua table: 16AED040 nil
    FOW_SetAll void FOW_SetAll( uint ) void FOW_SetAll( uint )
    GameCore table: 15792EE8 nil
    GameDefines table: 16B0A908 table: 166D1F80
    GameEventFactory table: 16A168E0 nil
    GameEvents table: 16A16908 table: 166D22F0
    GameInfo table: 16AED568 table: 166D1E90
    gcinfo function: 16B8A9B0 nil
    Get3DSoundInstanceChannelInfo const char* Get3DSoundInstanceChannelInfo( int ) const char* Get3DSoundInstanceChannelInfo( int )
    GetAudioLog table GetAudioLog( void ) table GetAudioLog( void )
    GetCurCivSong const char* GetCurCivSong( void ) const char* GetCurCivSong( void )
    getEndTurnTimerLength float getEndTurnTimerLength( void ) float getEndTurnTimerLength( void )
    getfenv function: 16B8A9F0 nil
    GetLuaMemoryUsage function: 16B8FAF8 nil
    getmetatable function: 16B8AA30 function: 16A4AA30
    GetOverlayLegend CFunction: GetOverlayLegend CFunction: GetOverlayLegend
    GetSoundInstanceInfo const char* GetSoundInstanceInfo( int, int ) const char* GetSoundInstanceInfo( int, int )
    GetSoundListenerInfo const char* GetSoundListenerInfo( void ) const char* GetSoundListenerInfo( void )
    GetSoundRolloffFactor float GetSoundRolloffFactor( void ) float GetSoundRolloffFactor( void )
    GetSoundScapeInfo const char* GetSoundScapeInfo( int ) const char* GetSoundScapeInfo( int )
    GetSoundScapeQuadrantInfo const char* GetSoundScapeQuadrantInfo( int ) const char* GetSoundScapeQuadrantInfo( int )
    GetSpeakerFalloffFactor float GetSpeakerFalloffFactor( void ) float GetSpeakerFalloffFactor( void )
    GetStrategicViewIconSettings CFunction: GetStrategicViewIconSettings CFunction: GetStrategicViewIconSettings
    GetStrategicViewOverlays CFunction: GetStrategicViewOverlays CFunction: GetStrategicViewOverlays
    GetUnitSimHandle uint GetUnitSimHandle( int, int ) uint GetUnitSimHandle( int, int )
    GetVolumeKnobIDFromName int GetVolumeKnobIDFromName( const char* ) int GetVolumeKnobIDFromName( const char* )
    GetVolumeKnobValue float GetVolumeKnobValue( int ) float GetVolumeKnobValue( int )
    GridToWorld CFunction: GridToWorld CFunction: GridToWorld
    HexToWorld FGXVector4 HexToWorld( HEXVec ) FGXVector4 HexToWorld( HEXVec )
    HexVertexToWorld FGXVector4 HexVertexToWorld( HEXVec, int ) FGXVector4 HexVertexToWorld( HEXVec, int )
    Ice_Reload void Ice_Reload( void ) void Ice_Reload( void )
    IncludeFileList table: 16AED310 nil
    InStrategicView bool InStrategicView( void ) bool InStrategicView( void )
    io table: 16B8C590 nil
    ipairs function: 16B8CC08 function: 16A4CC08
    IsGameCoreBusy bool IsGameCoreBusy( void ) bool IsGameCoreBusy( void )
    IsNull CFunction: IsNull CFunction: IsNull
    IsOnLiveActive bool IsOnLiveActive( void ) bool IsOnLiveActive( void )
    IsSteamActive bool IsSteamActive( void ) bool IsSteamActive( void )
    LaunchMultiplayerGame void LaunchMultiplayerGame( void ) void LaunchMultiplayerGame( void )
    load function: 16B8AA70 nil
    LoadAudioOptions void LoadAudioOptions( void ) void LoadAudioOptions( void )
    loadfile function: 16B8AA50 nil
    loadstring function: 16B8AAB0 function: 16A4AAB0
    Locale table: 16B1C940 table: 166D2070
    LookUpControl CFunction: LookUpControl CFunction: LookUpControl
    LuaEventFactory table: 16AED360 nil
    Matchmaking table: 16B421C8 table: 166D2200
    math table: 16B8C7C0 table: 166D0F90
    MemTracker table: 16B4EE88 nil
    MemTrackerDisplayPools void MemTrackerDisplayPools( void ) void MemTrackerDisplayPools( void )
    MemTrackerDump void MemTrackerDump( const char* ) void MemTrackerDump( const char* )
    MemTrackerDumpLeaderheadStats void MemTrackerDumpLeaderheadStats( const char* ) void MemTrackerDumpLeaderheadStats( const char* )
    MemTrackerDumpPools void MemTrackerDumpPools( const char*, const char* ) void MemTrackerDumpPools( const char*, const char* )
    MemTrackerEnable void MemTrackerEnable( bool ) void MemTrackerEnable( bool )
    MemTrackerIncrementMarker void MemTrackerIncrementMarker( const char* ) void MemTrackerIncrementMarker( const char* )
    Modding table: 16B1FA10 table: 166D2110
    module function: 16B8BF48 nil
    MouseOverStrategicViewResource bool MouseOverStrategicViewResource( void ) bool MouseOverStrategicViewResource( void )
    Network table: 16B15C70 table: 166D1FD0
    newproxy function: 16B8B228 nil
    next function: 16B8AAD0 function: 16A4AAD0
    OptionsManager table: 16AE9828 table: 166D2160
    os table: 16B8C6D0 table: 166D1008
    package table: 16B8C400 nil
    pairs function: 16B8B680 function: 16A4B680
    Path table: 16B42178 table: 166D2250
    pcall function: 16B8AB10 function: 16A4AB10
    print function: 16B8FBF8 function: 16A4FBF8
    ProcessStrategicViewMouseClick bool ProcessStrategicViewMouseClick( void ) bool ProcessStrategicViewMouseClick( void )
    PublishRecordCommandStreams void PublishRecordCommandStreams( bool ) void PublishRecordCommandStreams( bool )
    quicktraceback function: 16B8FAD8 function: 16A4FAD8
    rawequal function: 16B8AB90 nil
    rawget function: 16B8ABB0 nil
    rawset function: 16B8ABF0 nil
    RefreshIncludeFileList function: 16B04828 nil
    ReloadTextures void ReloadTextures( int, int ) void ReloadTextures( int, int )
    require function: 16B8BF88 nil
    ResetAchievements void ResetAchievements( void ) void ResetAchievements( void )
    SaveAudioLog bool SaveAudioLog( const char* ) bool SaveAudioLog( const char* )
    SaveAudioOptions void SaveAudioOptions( void ) void SaveAudioOptions( void )
    select function: 16B8AC30 function: 16A4AC30
    setEndTurnTimerLength void setEndTurnTimerLength( float ) void setEndTurnTimerLength( float )
    setfenv function: 16B8AC70 nil
    setmetatable function: 16B8ACB0 function: 16A4ACB0
    SetSoundRolloffFactor void SetSoundRolloffFactor( float ) void SetSoundRolloffFactor( float )
    SetSpeakerFalloffFactor void SetSpeakerFalloffFactor( float ) void SetSpeakerFalloffFactor( float )
    SetStrategicViewIconSetting void SetStrategicViewIconSetting( int ) void SetStrategicViewIconSetting( int )
    SetStrategicViewOverlay void SetStrategicViewOverlay( int ) void SetStrategicViewOverlay( int )
    SetUnitActionCodeDebug void SetUnitActionCodeDebug( int, int, float ) void SetUnitActionCodeDebug( int, int, float )
    SetVolumeKnobValue void SetVolumeKnobValue( int, float ) void SetVolumeKnobValue( int, float )
    Steam table: 16B1C850 table: 166D2020
    StrategicViewShowFeatures void StrategicViewShowFeatures( bool ) void StrategicViewShowFeatures( bool )
    StrategicViewShowFogOfWar void StrategicViewShowFogOfWar( bool ) void StrategicViewShowFogOfWar( bool )
    string table: 16B8C748 table: 166D0EA0
    SystemBuildYield bool SystemBuildYield( void ) bool SystemBuildYield( void )
    table table: 16B8C4A0 table: 166D0F18
    Threads table: 16B8C928 nil
    TogglePauseGameplay void TogglePauseGameplay( bool ) void TogglePauseGameplay( bool )
    ToggleStrategicView void ToggleStrategicView( void ) void ToggleStrategicView( void )
    ToGridFromHex CFunction: ToGridFromHex CFunction: ToGridFromHex
    ToHexFromGrid FGXInt2 ToHexFromGrid( FGXInt2 ) FGXInt2 ToHexFromGrid( FGXInt2 )
    tonumber function: 16B8ACD0 function: 16A4ACD0
    tostring function: 16B8ACF0 function: 16A4ACF0
    TunerSetUnitState void TunerSetUnitState( int, int, const char* ) void TunerSetUnitState( int, int, const char* )
    type function: 16B8AD10 function: 16A4AD10
    TypeInfo CFunction: TypeInfo CFunction: TypeInfo
    UI table: 16B34BC8 table: 166D21B0
    UIEnumsLibrary table: 16B0AA70 nil
    UnitMoving bool UnitMoving( int, int ) bool UnitMoving( int, int )
    unpack function: 16B8AD50 function: 16A4AD50
    Water_SetAmplitude void Water_SetAmplitude( int ) void Water_SetAmplitude( int )
    Water_SetAutoReload void Water_SetAutoReload( bool ) void Water_SetAutoReload( bool )
    Water_SetFlowParameters void Water_SetFlowParameters( int, int, int ) void Water_SetFlowParameters( int, int, int )
    Water_SetGradientScale void Water_SetGradientScale( int ) void Water_SetGradientScale( int )
    Water_SetScale void Water_SetScale( int ) void Water_SetScale( int )
    Water_SetSpec void Water_SetSpec( int, int ) void Water_SetSpec( int, int )
    Water_SetSpeed void Water_SetSpeed( int ) void Water_SetSpeed( int )
    Waves_Reload void Waves_Reload( void ) void Waves_Reload( void )
    WeakThreads table: 16B8C950 nil
    where function: 16B8FC38 function: 16A4FC38
    xpcall function: 16B8AD90 function: 16A4AD90


    Note that you don't see Players, Game, MapModData, and many other such things above. I guess that is because these don't exist in the Main State environment. It would be nice to be able to iterate over the environment in a mod to see what other globals are there (and not listed above), but I can't see how to do that without access to _G.
    raen and Angryr like this.

Recent Reviews

  1. Angryr
    Angryr
    5/5,
    Very helpful!
  2. TheNimrod
    TheNimrod
    5/5,
    Thanks for the info!