Runtime DataTable - Import/Export text CSV or Google Sheet at runtime and auto-update structs and UObjects!

Interesting, in your screenshot you print the length, then branches to print success or failure, then prints the payload. If you’re not printing the payload, can you try doing so? If there’s nothing in the payload then we aren’t connecting to Google at all, but if there is something in the payload it can give us some insight into what the error may be.


Attached image, the red box, showing I did try to print the payload, but nothing is printing from it. The exact same Google sheet URL is used in my 5.0 and 4.23. In 5.0 it works as intended but in 4.23 I’m getting this result. Is there any additional steps I need to do for 4.23 to connect to Google?

This is the Google Sheet URL: Punggol_Living - Google Sheets

I tried the plugin on a new 4.23 project just to test the plugin. It also failed the same way there. I also used a new GoogleSheet URL to test. Same result.

RDT_Debug.zip (1.8 MB)

I built this test project using your sheet and it works okay!

If this doesn’t work for you, I would take a look at VPN/Firewall settings for your UE4.23 instance. It could be that it works in 5.0 because the firewall/VPN is set up correctly for it but not UE4? That’s the only explanation I can think of at the moment. I know Google is blocked in certain countries so you may need to employ means to get around this block if that’s the case.

Hi,

Your file you sent works exactly as intended when I play in the editor. I am not sure why mine just doesn’t work. Thanks for taking the time to help me with this. I will try this again comparing it with your project.

I wish you luck! It seems like the only two things that could be different are the struct itself (I don’t know which data types you used exactly) or the link to the sheet (which seems to come from a variable, so perhaps the variable is being changed by some other function?). I’d look there first.

Hi everyone,
I have installed runtime datatable as a plugin (in the plugin folder of the project) and only use the blueprint nodes to use it.
When compiling the game, I have an error after the second time it compiles which makes it fail.

  LogModuleManager: Warning: ModuleManager: Unable to load module 'RuntimeDataTable'  - 0 instances of that module name found.
  LogModuleManager: Warning: ModuleManager: Unable to load module 'easyCSV'  - 0 instances of that module name found.

For info, this is the command line I use to compile for Android

C:\Epic\4.27.2-release\Engine\Build\BatchFiles\RunUAT.bat -ScriptsForProject="C:\Users\Flash\AppData\Local\Jenkins\.jenkins\workspace\Game_Main_Pipeline\Game\Game.uproject" BuildCookRun -nocompileeditor -nop4 -project="C:\Users\Flash\AppData\Local\Jenkins\.jenkins\workspace\Game_Main_Pipeline\Game\Game.uproject" -cook -stage -archive -archivedirectory="C:\Users\Flash\AppData\Local\Jenkins\.jenkins\workspace\Game_Main_Pipeline\Packages\Client" -package -ue4exe="C:\Epic\4.27.2-release\Engine\Binaries\Win64\UE4Editor-Cmd.exe" -ddc=DerivedDataBackendGraph -pak -prereqs -nodebuginfo -targetplatform=Android -cookflavor=ASTC -build -target=Game -clientconfig=DebugGame -utf8output -compile  

As I have the error only with Jenkins, to make it compile again I have to remove all files to compile from scratch. Any idea what I did wrong here?

Hi Gil!

I don’t have any experience with building via CI, but this does appear to be rather common for modules of all types. Do any of the solutions in this thread work for you?

New update is out for 4.27 and 5.0:

  • Added option on CSV export to sort columns alphabetically, otherwise will export in the order of the struct.
  • Moved all headers to public folders for easier API access from C++.

Thanks it worked with slightly longer build but it doesn’t break anymore :slight_smile:

1 Like

I just wanted to share the update that it s not working in the end for me. The compilation were working and I had other errors but now that it is stabilized I still get the same issue with the plugins not being detected.
I’m not sure what I could try next as just removing the -nocompileeditor parameter did not fix the issue here. It seems I can still run a build 2 times without cleaning all the files but after that I need to start building from scratch.

Here are my latest failed logs in case it gives a hint to somebody

Running UE4Editor Cook for project C:\Users\Flash\AppData\Local\Jenkins\.jenkins\workspace\Glitch_Main_Pipeline\Glitch\Glitch.uproject
Commandlet log file is C:\Epic\4.27.2-release\Engine\Programs\AutomationTool\Saved\Cook-2022.10.11-15.44.47.txt
Running: C:\Epic\4.27.2-release\Engine\Binaries\Win64\UE4Editor-Cmd.exe C:\Users\Flash\AppData\Local\Jenkins\.jenkins\workspace\Glitch_Main_Pipeline\Glitch\Glitch.uproject -run=Cook  -TargetPlatform=Android_ASTC -fileopenlog -ddc=DerivedDataBackendGraph -unversioned -abslog=C:\Epic\4.27.2-release\Engine\Programs\AutomationTool\Saved\Cook-2022.10.11-15.44.47.txt -stdout -CrashForUAT -unattended -NoLogTimes  -UTF8Output
  LogConsoleResponse: Display: Failed to find resolution value strings in scalability ini. Falling back to default.
  LogConsoleResponse: Display: Failed to find resolution value strings in scalability ini. Falling back to default.
  LogInit: Display: Running engine for game: Glitch
  LogInit: Display: Loading text-based GConfig....
  LogTemp: Display: [GlitchOpenXRDebug] StartupModule
  LogHAL: Display: Platform has ~ 32 GB [34269618176 / 34359738368 / 32], which maps to Largest [LargestMinGB=32, LargerMinGB=12, DefaultMinGB=8, SmallerMinGB=6, SmallestMinGB=0)
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'AllDesktop'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android_ASTC'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android_DXT'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android_ETC2'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'AndroidClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android_ASTCClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android_DXTClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android_ETC2Client'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android_Multi'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Android_MultiClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'IOSClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'IOS'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Lumin'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'LuminClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'MacNoEditor'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Mac'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'MacClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'MacServer'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'TVOSClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'TVOS'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'WindowsNoEditor'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'Windows'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'WindowsClient'
  LogTargetPlatformManager: Display: Loaded TargetPlatform 'WindowsServer'
  LogTargetPlatformManager: Display: Building Assets For Android_ASTC
  LogAudioDebug: Display: Lib vorbis DLL was dynamically loaded.
  LogTextureFormatOodle: Display: Oodle Texture 2.9.0 init RDO Off
  LogShaderCompilers: Display: Using Local Shader Compiler.
  LogDerivedDataCache: Display: Max Cache Size: 512 MB
  LogDerivedDataCache: Display: Loaded Boot cache: ../../../../../Users/Flash/AppData/Local/Jenkins/.jenkins/workspace/Glitch_Main_Pipeline/Glitch/DerivedDataCache/Boot.ddc
  LogDerivedDataCache: Display: Performance to ../../../Engine/DerivedDataCache: Latency=0.02ms. RandomReadSpeed=1245.40MBs, RandomWriteSpeed=256.25MBs. Assigned SpeedClass 'Local'
  LogAudioCaptureCore: Display: No Audio Capture implementations found. Audio input will be silent.
  LogAudioCaptureCore: Display: No Audio Capture implementations found. Audio input will be silent.
  LogModuleManager: Warning: ModuleManager: Unable to load module 'RuntimeDataTable'  - 0 instances of that module name found.
  LogModuleManager: Warning: ModuleManager: Unable to load module 'easyCSV'  - 0 instances of that module name found.
  LogShaderCompilers: Display: === FShaderJobCache stats ===
  LogShaderCompilers: Display: Total job queries 0, among them cache hits 0 (0.00%)
  LogShaderCompilers: Display: Tracking 0 distinct input hashes that result in 0 distinct outputs (0.00%)
  LogShaderCompilers: Display: RAM used: 0.00 MB (0.00 GB) of 1638.40 MB (1.60 GB) budget. Usage: 0.00%
  LogShaderCompilers: Display: ================================================
  LogShaderCompilers: Display: Shaders left to compile 0
  LogHttp: Display: cleaning up 0 outstanding Http requests.
  LogTemp: Display: [GlitchOpenXRDebug] ShutdownModule
  LogContentStreaming: Display: There are 1 unreleased StreamingManagers
Took 4,4169596s to run UE4Editor-Cmd.exe, ExitCode=1
ERROR: Cook failed.
       (see C:\Epic\4.27.2-release\Engine\Programs\AutomationTool\Saved\Logs\Log.txt for full exception trace)
AutomationTool exiting with ExitCode=25 (Error_UnknownCookFailure)
BUILD FAILED

Update pushed today! changelog:

10-16-2022 (5.0.3.2, 4.27.2.4): Fix crash in iOS calling “sign” in jwt twice in one instance by reserving string memory ahead of append; added Linux support; updated to latest jwt-cpp, Execute CallOnComplete even when InTokenInfo is invalid when downloading Sheet

Additionally, deprecated functions and members have been removed as of this update. Please ensure that your code has been updated before upgrading to the new version!

1 Like

New update submitted for approval! (Merge from EasyCsv)

10-28-2022 (5.0.3.4, 4.27.2.5): Remove deprecated functions from EasyCsv module

New update submitted for approval!

11-19-2022 (5.1.0.0, 5.0.3.4, 4.27.2.6): FRuntimeDataTableCallbackInfo now includes the error code returned from Google.

New update submitted for approval!

11-24-2022 (5.1.0.1, 5.0.3.5, 4.27.2.7): Fixed an issue with token validation preventing writes and private reads.

Hi Jared,
I’ve tried to read the entire thread but am not sure I have my question covered so let me ask.
I have a csv file that is updated (new line added) every 1 second. Can i use the Runtime DataTable plugin to import the new line value each second? In this thread i saw something related to the fact that a new CSV should be created each time i need to read it’s new values… Could you elaborate on that please?
Thanks in advance,
Sergey.

Hi Sergey,

I’m not 100% sure what you’re asking. Do you mean to ask if you can import just a single line of a CSV? If so, the answer is no. The way file I/O works is we have to open and read the entire file at once, so there’s no way to ask the I/O subsystem to grabs the last line of the CSV. If you’re asking about RDT only parsing the last line, the answer is also no, there’s no mechanism for this built into the plugin as of now.

If you’re worried about performance, don’t be! RDT can read and import tens of thousands of lines in less than a second. If you do run into a real-world performance issue, please send me a private message so I can gather more specifics about your project.

If you’re doing something advanced like changing the data you’ve imported but still want to add new lines from the updated CSV, I’d recommend keeping two separate struct arrays - one that is constantly updated from the CSV and one that is used for the actual application so changes can occur. When the first array is updated, check its length against the other array and if it’s longer, copy its contents to the application-relevant array.

Does that all make sense or did I misunderstand the question?

Hi Jared! Thank you for a detailed reply. Let me give more details on what i am trying to accomplish.
I have a python script that connects to a BLE device, gets some information from this device (basically just 1 parameter) and then adds this parameter to a CSV file approximately once a second.
As far as i know UE cant connect to a BLE device in realtime so i was thinking of a workaround using BLE->Python->CSV->UE.
So I wonder if Its possible to use the RDT plugin to read the last value of the CSV row/cell and import it in runtime to UE(once a second). If needed I can delete and create a new CSV file with one value from my BLE device each second. That is not ideal but I guess its possible.

So yes, RDT can do this. Depending on your operating system, you may encounter a file lockout issue where UE can’t read the file because another stream has it open already. In this case you would need to create a new file each time but isn’t necessarily an issue that will affect you. It’s a Windows thing. And as long as your python script closes the filestream after it updates the CSV you shouldn’t have any issue at all.

RDT will read the whole file and close it each time then add all results to an array, so to get the latest one in your application you just get the last element of the array. Each element corresponds to one row of the CSV.

Thank you. I bought the plugin , and everything works perfectly!
Live longer and prosper :slight_smile: :vulcan_salute:

1 Like

Greetings @JaredTherriault.

RTD is awesome! I’m working with version for UE4.27. Downloaded and worked with the Demo project to get my bearing on function and features until comfortable enough to modify for my own Structures/Datatables/GSheets.

I Created a Google Service Account, Json Key, Enabled Google Sheets API, Shared GSheets with Service Account Email to read/write to Private GSheets. There are slight changes from instructions to whats on Google Cloud, but I think all appears to correct.

Moment of Truth. Retrieve GSheet and update local CSV file. I’m experience Validation Failure with Retrieving Private and Public Data from Google.

I viewed the Project Log to see whats going on. This is what I see (Sensitive Data redacted for security purposes)

Private GSheet Retrieval ERROR

[2022.12.07-02.23.25:833][932]LogRuntimeDataTable: URuntimeDataTableObject::CreateJavaWebToken: Token:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczpcL1wvb2F1dGgyLmdvb2dsZWFwaXMuY29tXC90b2tlbiIsImV4cCI6MTY3MDM3OTg2NSwiaWF0IjoxNjcwMzc5ODA1LCJpc3MiOiJ2YXBvci03OThAaGVhZGxlc3MtMTY1MTAzLmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2NvcGUiOiJodHRwczpcL1wvd3d3Lmdvb2dsZWFwaXMuY29tXC9hdXRoXC9zcHJlYWRzaGVldHMifQ.bQLxivfcvPyqkBYNB11zrA_F9ij_YKVOO-WHSMn2uDzaZaCl8Ztp_IxcagK7_4Zh_PKfI_Ua4pIywlV9jHTmRLbWNtmMOnunPlA26N2s3FxfbjezAIHnESYYS85B2ZqVTJntaznaAROYdf7nwEBO91NbkTVHlMW6EzbUY5sfGP3hL1PniaPqpO0dXv67CgUOgFVc0sfabC8KA7M89cXB6N4-AoOr8dtIRiRnikIdnl4r25SjrMLRuSIYhZeWzPLFI5T1yxZVbZqJarkgaS7f1haUeNgxq98C9GFDN8yjOzLW3AIG_Nd3jO766AZb9Gg7qH2gRsVJ2ACNpYuSOxttHA
[2022.12.07-02.23.25:962][948]LogRuntimeDataTable: URuntimeDataTableObject::GenericValidateHttpResponse: POST Response received, success: true, Response code: 200, Response:
{“access_token”:“ya29.c.b0Aa9Vdyns_tIc1Bx8FQhPIKBqW5FgNQwMtMVDBfbAjjwgtiSyNwRoQrmla2klPO8PYqMOOJLbDRPCFciSqK76A9NCHLcqFK1yqK1P29FbIbB6_QqqxmoZysh0ApLmrS25ZwGgklBmvMpgurdjh3hvv9aXLqrs9tcygjcH2b-tzyrwJxx2oasCn5WQ-7fS1RCtHMiQ2g_jl3wYd0s37rB-k_1BMDhV_Yc…”,“expires_in”:3599,“token_type”:“Bearer”}
[2022.12.07-02.23.25:962][948]LogRuntimeDataTable: Error: URuntimeDataTableObject::BuildGoogleSheetDownloadLinkAndGetAsCsv_AfterToken: ERROR: InToken has expired or was not successfully created.

Any and all assistance/recommendations welcomed. Thank you for this Awesome Asset (and reading this post). I can be reached on Discord for live chat.