





🌟 Special thanks to our amazing supporters:
✨ $10 Tier: [Geeks Love Detail]
🌈 $5 Tier: [Arch Toasty][Benedikt][David Martínez Martí]
TL;DR
Hello,
I just extracted csv data for all my products, and the "created" column, instead of containing the full date "year, month, day, hour, minute, second", it only contains "minute, second and tens of seconds".
2017-12-01 7:34:10.5
becomes
34:10.5
Here are the steps to reproduce the bug:
- I go on a sales product page like [REDACTED]
- I choose a very old starting date to be sure everything is displayed (like 2011)
- I click the button "export csv to my email"
- I receive the email
- I download the csv
- I open the csv in a notepad tool (like Notepad++)
- I can see that only part of the date is in the "created" colmumn
I think datetime should be displayed as
YYYY-MM-DD HH:mm:ss.S
year-month-day hour(24h):minute:second.tens of seconds
Could you please fix this issue (or transfer this message to the technical team), and come back to me?
Thanks in advance.
Looks like Steam replace text by emoji in code formatting, which is either a bug or a very bad design choice. I won't fill a bug report because I cannot display a bug report.
TL;DR
public void from_phase_cutscene_to_phase_galaxy_map ()
{
end_phase_cutscene ();
begin_phase_galaxy_map ();
// display_ad ();
}
Thanks to that, any logic specific to a unique combination of two phases is entirely managed in a specific function.
The code file containing all those transitions is more than 900 lines of code. That's a lot, but thanks to that, I never got any confusion going from one phase to another.
10 zoom * (percentage ** 10 seconds) = 100 zoom
I found a first approximation of the percentage (1.259) by doing lot of tests by hand on Google, launching a Google search each time. Then I told myself I could find an online calculator. But I did not succeed to find one which could use power as well as Google, so I was quickly back to Google.
Then to find this percentage (1.259) with a real calculation, I used an inverse power :
percentage = 10 zoom ** (1 / 10 seconds) = 1.25892541179
Here is some data to show the difference in behavior between the two approaches.
TL;DR
TL;DR
#!csharp
#r "nuget: Microsoft.Data.Sqlite, 7.0.9"
#!csharp
using System.IO;
using Microsoft.Data.Sqlite;
#!csharp
// variable
string database_original_filepath = @"data_output\03-importSQLite\2023_07_08-godisacuvqube.sqlite";
string clean_folderpath = @"data_output\04-clean";
string database_clean_filepath = Path.Join(clean_folderpath, @"godisacuvqube-clean.sqlite");
string sqlite_filepath = @"C:\Program Files\SQLite\sqlite3.exe";
#!csharp
// environment
Directory.CreateDirectory(clean_folderpath);
#!csharp
File.Copy(database_original_filepath, database_clean_filepath);
#!csharp
public void ExecuteSql(string databasePath, string sqlCommand)
{
using (var connection = new SqliteConnection($"Data Source={databasePath}"))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = sqlCommand;
command.ExecuteNonQuery();
}
}
}
public void sql(string sqlCommand)
{
ExecuteSql(database_clean_filepath, sqlCommand);
}
#!csharp
public IEnumerable ExecuteQuery(string databasePath, string sqlCommand)
{
using (var connection = new SqliteConnection($"Data Source={databasePath}"))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = sqlCommand;
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
dynamic row = new ExpandoObject();
var rowDict = (IDictionary)row;
for (int i = 0; i < reader.FieldCount; i++)
{
string columnName = reader.GetName(i);
object columnValue = reader.GetValue(i);
rowDict[columnName] = columnValue;
}
yield return row;
}
}
}
}
}
public IEnumerable ExecuteQuery(string sqlCommand)
{
foreach(var x in ExecuteQuery(database_filepath, sqlCommand))
{
yield return x;
}
}
With the non query "drop table" I get rid of unnecessary data, and with the non query "VACUUM" I reduce the final size of the database.
#!csharp
string query = """
DROP TABLE IF EXISTS `LEVEL_RESULTS-ORIG`;
DROP TABLE IF EXISTS `LEVEL_RESULTS-V00-05_14_03`;
DROP TABLE IF EXISTS `LEVEL_RESULTS_DEV-ORIG`;
DROP TABLE IF EXISTS `LEVEL_FEEDBACKS-V00-05_14_03`;
DROP TABLE IF EXISTS `LEVEL_RESULTS-V00_05_13_00A`;
DROP TABLE IF EXISTS `LEVEL_SOLUTIONS-V00_05_13_00A`;
DROP TABLE IF EXISTS `LEVEL_FEEDBACKS-V00_05_13_00A`;
DROP TABLE IF EXISTS `LEVEL_SOLUTIONS-V00_05_00_11A`;
DROP TABLE IF EXISTS `LEVEL_RESULTS-V00_05_00_11A`;
DROP TABLE IF EXISTS `LEVEL_SOLUTIONS-ORIG`;
DROP TABLE IF EXISTS `LEVEL_SOLUTIONS-V00-05_14_03`;
DROP TABLE IF EXISTS `LEVEL_SOLUTIONS_DEV-ORIG`;
DROP TABLE IF EXISTS `LEVEL_SOLUTIONS_DEV_OLD`;
DROP TABLE IF EXISTS `LEVEL_FEEDBACKS-V00_05_00_11A`;
DROP TABLE IF EXISTS `LEVEL_RESULTS_DEV`;
DROP TABLE IF EXISTS `LEVEL_RESULTS_DEV_OLD`;
DROP TABLE IF EXISTS `CONNECTIONS_DEV`;
DROP TABLE IF EXISTS `LEVEL_FEEDBACKS_DEV`;
DROP TABLE IF EXISTS `LEVEL_SOLUTIONS_DEV`;
DROP TABLE IF EXISTS `CARDS_DEV`;
""";
sql(query);
#!csharp
sql("VACUUM");
Now the database is 57% smaller! This is the final file I am using to do all the stats I need.TL;DR
git clone --mirror https://github.com/marckruzik/giac
java -jar bfg.jar --delete-files "myfile.txt" giac.git
cd giac
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push
The file deletion command cannot target a precise file path, only the file name. Hopefully, the file I have to delete has a unique name.
And after all of this, the history rewrite works!
On the bad size, rewriting the git history implies to reupload the whole git history. Even compressed, that's still 500 Mb of data. Here, the big textures are once again a problem.
Besides, the upload speed is slow, around 0.8 Mbps (Mega bits per second). Please note the lower "b", it's "bits", not "bytes", so it is 0.8 MB per second. To transfer 500 MB, it takes around 1 hour 20 minutes, and needs to avoid all internet connection problems (and if it happens, do the whole upload again). Commits usually take only a few seconds, as there is usually only a few Kb of code file changed. So I hope this very slow commit process won't create too much problems in the future.
using System.Text.RegularExpressions;
string content = File.ReadAllText("godisacube_db.mysql");
// Remove engine
content = Regex.Replace(content, @"ENGINE=MyISAM DEFAULT CHARSET=utf8", "");
// Remove comments
content = Regex.Replace(content, @"^/*!\d+ .**/;", "", RegexOptions.Multiline);
// Remove other MySQL commands
content = Regex.Replace(content, @"^SET .", "", RegexOptions.Multiline);
content = Regex.Replace(content, @"^START .", "", RegexOptions.Multiline);
content = Regex.Replace(content, @"^USE .", "", RegexOptions.Multiline);
content = Regex.Replace(content, @"^CREATE DATABASE .", "", RegexOptions.Multiline);
content = Regex.Replace(content, @"^COMMIT;", "", RegexOptions.Multiline);
// Remove several-lines MySQL commands
content = Regex.Replace(content, @"(?:\r?\n|^)\sALTER TABLE .?;", "", RegexOptions.Singleline);
// Remove unsigned
content = Regex.Replace(content, @") UNSIGNED", ")");
// Change hexadecimal value into text
content = Regex.Replace(content, @"0x(01[0-9][0-9a-fA-F]+)", "X'$1'");
// Replace single quote bt two single quotes for escaping
content = Regex.Replace(content, @"\'", "''");
File.WriteAllText("mod.sql", content);
To execute this script, I am using csi.exe. I found it easily on my computer thanks to Everything, but I think a Windows search can locate it as well.
"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\csi.exe" script.csx
Then I launch the SQLite import to create a SQLite database.
sqlite3 output.sqlite ".read mod.sql"
If the SQLite commands were more complex, I could create a SQLite script.
.read "mod.sql"
.exit
And launch this SQLite script with a Windows command.
sqlite3 output.sqlite < script.txt
I'm writing down a few notes about my process. I think it is interesting for players, and it could help other developers. Maybe I will make it into a series of article! Also, it will be precious to be able to come back here in a few years, just to find a tool url or info I will have written down.
I intend to write regularly on my work on God is a Cube. Those will be small news. I think it's better to have too much news than too few. Here is the TL;DR:
God is a Cube was presented at the press event Pop Culture Days in Paris, where only journalists and influencers were allowed.
This is me, Marc Kruzik. I'm making the game.
There I met tens of journalists, blogers and influencers interested to write about the game.
Every journalist got a lot of goodies
Of course those articles will be available in french publications, and that's a first very big step. Thanks to all those who tested God is a Cube!
If you are interested to know more about this event, here is a full presentation of all geek products presented (in french):
https://www.youtube.com/watch?v=g3B5x75G1CY&t=1015s
[ 5974 ]
[ 1507 ]
[ 1901 ]