Leopotam 11 Posted June 2, 2011 (edited) ArmaResourceOptimizator - tool to automate localization and minimize mission-files size. Requirements .Net framework v4 Limitations Do not use in any commercial projects and projects with a profit. Usage Localization Add prefix "_LOCALIZE_" to all localizable strings: // Before hint "bla-bla-in-any-language"; // After hint "_LOCALIZE_bla-bla-in-any-language"; "_LOCALIZE_"-prefix case sensitive! Run tool browse your resource folder, change options and press "Process".In csv and xml - language will be detected from user locale. Optimization Just check "Optimize files" options and run tool. ArmaResourceOptimizator v1.0.9 Download History v1.0.9: Fix for global variables replacement.v1.0.8: Fix for special local variable "_pos". Add more preprocessor commands. All preprocessor commands starts from new line. Add command line interface. Usage (always >=3 arguments!):ArmaResourceOptimizator.exe "mission-folder-path" flags "global-vars-rules-splitted-by-comma".Flags: olbx, where o - optimize, l - localize, x - export to xml file when localize, b - backup old files.v1.0.7: Fix for special local variable "_target". Global variables optimizations with rules. One string - one rule. Rule can be simple variable as "AAS_IsWestAttacking" and can be mask with wildcard as "AAS_*" (Only "*" supported).v1.0.6: Preprocess commands bugfixes. Undo removing ";" before "}". Correct detection variables with different case size when optimize.v1.0.5: Workarounds for sqm cleanup.v1.0.4: Macros compatibility.v1.0.3: Macros support (#include / # define).v1.0.2: Localization process use first 3 words in localizable phrase.v1.0.1: "Optimization"-feature realized. Macroses not supported! xml-format use user locale name too.v1.0.0: Initial release. ---------- Post added at 02:25 PM ---------- Previous post was at 02:23 PM ---------- Post here your suggestions for improvement. Edited September 7, 2011 by Leopotam 1 Share this post Link to post Share on other sites
Leopotam 11 Posted June 2, 2011 v1.0.1: Optimize realized. Macroses not supported! xml-format use user locale name too. Share this post Link to post Share on other sites
.kju 3245 Posted June 2, 2011 Leopotam can you please explain: How is removing whitespaces and reducing variable names to short generic naming an optimization? Yes it reduces the file size, yet 7z compression does the job. There is non for direct server download, yet for most people a mission size less than 1 MB is hardly a problem. And if missions are bigger, it is mostly due to pictures and sound files. Also it makes the mission completely unreadable to mission editors. Sure you can offer a source version for download next to it, yet not always people will find it. Thanks for the explanation Leopotam! As for suggestions - the localization could need some more explanation. Does it make sure to become a valid identifier (no spaces and special characters), and to make it really useful it should dump the strings and the identifier into an external file (csv/xml) in one go. The processing itself is very fast. Well done. Share this post Link to post Share on other sites
Leopotam 11 Posted June 2, 2011 (edited) Leopotam can you please explain:How is removing whitespaces and reducing variable names to short generic naming an optimization? Yes it reduces the file size, yet 7z compression does the job. You cant use 7z data as game resources. There is non for direct server download, yet for most people a mission size less than 1 MB is hardly a problem. And if missions are bigger, it is mostly due to pictures and sound files. Smaller size = faster loading and code parsing. Only useful for script engine information must be saved. Gamers != (Testers || Debuggers) Also it makes the mission completely unreadable to mission editors. Sure you can offer a source version for download next to it, yet not always people will find it. Main goal - prepare resources before release, not useful when debugging. 1. Create your addon / mission. 2. Cleanup garbage before release (really garbage, arma can use your data without it). As for suggestions - the localization could need some more explanation. Does it make sure to become a valid identifier (no spaces and special characters), and to make it really useful it should dump the strings and the identifier into an external file (csv/xml) in one go. Main problem - international support. Mission makers can use native language in scripts. Maybe, in next releases. The processing itself is very fast. Well done. Not sure, can be tuned to speed up 1.5 or more times (100% data streaming through memory, not files). Edited June 5, 2011 by Leopotam Share this post Link to post Share on other sites
Leopotam 11 Posted June 5, 2011 (edited) v1.0.2: Localization process use first 3 words in localizable phrase. Edited June 5, 2011 by Leopotam Share this post Link to post Share on other sites
winse 22 Posted June 5, 2011 There is a problem with garbage removing: Code with preprocessor instructions like this #include "defines.sqf"; #define KEY_TANK_SMOKE 19 //R #define KEY_GP_UP 199 //HOME #define KEY_GP_DOWN 207 //END #define KEY_ENGINE_OFF 41 //~ #define KEY_WPN_PRIMARY 2 //1 #define KEY_WPN_GL 3 //2 #define KEY_WPN_SECONDARY 4 //3 #define KEY_WPN_TRETIARY 5 //4 #define KEY_WPN_GRENADE 6 //5 #define KEY_TANK_ORDERS 57//Space #define KEY_BTN_ESCAPE 1//Esc if (UAV_CameraActive) exitWith {false}; _hint= { hintSilent parseText format["<t align='center' shadow='true' size='1.0' color='#dddddd'>%1</t><br/><t align='center' size='4.5' color='#ffffff'><img image='%2'></t>",_this select 0,_this select 1]; player setVariable ["hint_time",time+2]; was converted to the next line: #include "defines.sqf";#define KEY_TANK_SMOKE 19 #define KEY_GP_UP 199 #define KEY_GP_DOWN 207#define KEY_ENGINE_OFF 41#define KEY_WPN_PRIMARY 2#define KEY_WPN_GL 3#define KEY_WPN_SECONDARY 4#define KEY_WPN_TRETIARY 5#define KEY_WPN_GRENADE 6#define KEY_TANK_ORDERS 57#define KEY_BTN_ESCAPE 1if(UAV_CameraActive)exitWith{false};_l0={hintSilent parseText format["<t align='center' shadow='true' size='1.0' color='#dddddd'>%1</t><br/><t align='center' size='4.5' color='#ffffff'><img image='%2'></t>",_this select 0,_this select 1];player setVariable["hint_time",time+2]; The problem is - preprocessor instructions shouldn't be written on the same line, or it will cause errors. Converted code had to look like this: #include "defines.sqf"; #define KEY_TANK_SMOKE 19 #define KEY_GP_UP 199 #define KEY_GP_DOWN 207 #define KEY_ENGINE_OFF 41 #define KEY_WPN_PRIMARY 2 #define KEY_WPN_GL 3 #define KEY_WPN_SECONDARY 4 #define KEY_WPN_TRETIARY 5 #define KEY_WPN_GRENADE 6 #define KEY_TANK_ORDERS 57 #define KEY_BTN_ESCAPE 1 if(UAV_CameraActive)exitWith{false};_l0={hintSilent parseText format["<t align='center' shadow='true' size='1.0' color='#dddddd'>%1</t><br/><t align='center' size='4.5' color='#ffffff'><img image='%2'></t>",_this select 0,_this select 1];player setVariable["hint_time",time+2]; Share this post Link to post Share on other sites
Leopotam 11 Posted June 5, 2011 (edited) winse: v1.0.1: optimize realized. macroses not supported! xml-format use user locale name too. Edited June 5, 2011 by Leopotam Share this post Link to post Share on other sites
Guest Posted June 5, 2011 (edited) Release frontpaged on the Armaholic homepage. ArmaResourceOptimizator v1.0.3.Net framework v4 Edited June 5, 2011 by Guest new version Share this post Link to post Share on other sites
Leopotam 11 Posted June 5, 2011 v1.0.3: Macros support (#include / # define). Share this post Link to post Share on other sites
Leopotam 11 Posted June 6, 2011 v1.0.4: Macros compatibility. Share this post Link to post Share on other sites
Guest Posted June 6, 2011 (edited) Updated release frontpaged on the Armaholic homepage. ArmaResourceOptimizator v1.0.7.Net framework v4 Edited September 6, 2011 by Guest updated with new version Share this post Link to post Share on other sites
.kju 3245 Posted September 1, 2011 Leopotam here are some observations: 1) Spaces from brackets removed in briefing name (sqm). OLD: briefingName="A&S ProMode (24): [T] Test Mission (2011-07-28)"; NEW: briefingName="A&S ProMode(24):[T]Test Mission(2011-07-30)"; 2) File mpmissions\__cur_mp.Desert_E\mission.sqm, line 0: '/Mission/Intel.minute': Missing ';' prior '}' OLD: minute=0;}; NEW: minute=0}; 3) File mpmissions\__cur_mp.Desert_E\mission.sqm, line 0: '/Mission/Groups/Item0/Vehicles/Item0.text': Missing ';' prior '}' OLD: text="playerEast1";};};}; NEW: text="playerEast1"}}}; 4) ErrorMessage: File mpmissions\__cur_mp.Desert_E\mission.sqm, line 0: /Mission/Groups/Item1/Vehicles/Item0.synchronizations: '}' encountered instead of ';' OLD: synchronizations[]={2};};};}; NEW: synchronizations[]={2}}}}; a) Do you need the mission source/sqm file? b) Any chance to preprocess the code too (eliminate defines, include etc)? c) Any chance to reduce/optimize global variable names? tx :bounce3: Share this post Link to post Share on other sites
Leopotam 11 Posted September 3, 2011 v1.0.5: Workarounds for sqm cleanup.---------- Post added at 12:41 PM ---------- Previous post was at 12:35 PM ---------- 1) Spaces from brackets removed in briefing name (sqm). OLD: briefingName="A&S ProMode (24): [T] Test Mission (2011-07-28)"; NEW: briefingName="A&S ProMode(24):[T]Test Mission(2011-07-30)"; 2) File mpmissions\__cur_mp.Desert_E\mission.sqm, line 0: '/Mission/Intel.minute': Missing ';' prior '}' OLD: minute=0;}; NEW: minute=0}; 3) File mpmissions\__cur_mp.Desert_E\mission.sqm, line 0: '/Mission/Groups/Item0/Vehicles/Item0.text': Missing ';' prior '}' OLD: text="playerEast1";};};}; NEW: text="playerEast1"}}}; 4) ErrorMessage: File mpmissions\__cur_mp.Desert_E\mission.sqm, line 0: /Mission/Groups/Item1/Vehicles/Item0.synchronizations: '}' encountered instead of ';' OLD: synchronizations[]={2};};};}; NEW: synchronizations[]={2}}}}; Check last version. b) Any chance to preprocess the code too (eliminate defines, include etc)? Why? Code size (loading time) will enlarge. c) Any chance to reduce/optimize global variable names? Can you sure for 100% that any global variable is global only in mission and not global for any mods? How? :) Share this post Link to post Share on other sites
.kju 3245 Posted September 5, 2011 Thanks Leopotam :bounce3: SQM works now. Problems in sqf now: 1) #ifdef + #endif broken - missing spaces OLD: #ifdef AAS_RANDOM_MISSION AAS_RandomMission = true; #endif if (AAS_RandomMission) then NEW: #ifdef AAS_RANDOM_MISSIONAAS_RandomMission=true;#endifif(AAS_RandomMission)then{ 2) Missing semicolon before }. OLD: if (AAS_Params_AttackerStartLocation != -1) then { _westZonesInControl = _westZonesInControl - AAS_Params_AttackerStartLocation; if (AAS_IsWestAttacking) then { _westZonesInControl = 1 + AAS_Params_AttackerStartLocation; }; }; NEW: if(AAS_Params_AttackerStartLocation !=-1)then{_l4=_l4-AAS_Params_AttackerStartLocation;if(AAS_IsWestAttacking)then{_l4=1+AAS_Params_AttackerStartLocation}}; While the engine is still OK for the statement without semicolon before }, once you have nested brackets, this is no longer acceptable. Please don't drop any semicolons. 3) Broken variable naming - variable case does not matter: Error in expression <rom(AAS_FirstZone)to(AAS_LastZone)do{if(_l6>_l4)then{((saas_baselist select(_l6)> Error position: <_l6>_l4)then{((saas_baselist select(_l6)> Error Undefined variable in expression: _l6 File mpmissions\__cur_mp.Desert_E\init.sqf, line 1 OLD: for "_zoneindex" from (AAS_FirstZone) to (AAS_LastZone) do { if (_zoneIndex > _westZonesInControl) then { SETBASEA(_zoneIndex,TEAM,TEAM_RED); } else { SETBASEA(_zoneIndex,TEAM,TEAM_BLUE); }; }; NEW: for"_l5"from(AAS_FirstZone)to(AAS_LastZone)do{if(_l6>_l4)then{SETBASEA(_l6,TEAM,TEAM_RED)}else{SETBASEA(_l6,TEAM,TEAM_BLUE)}}}; 4) Broken include - missing space Error in expression <19","_l20","_l21","_l22","_l23","_l24"];#include"gdtmod_hdr.hpp"; gdtmod_hdr_nvg> Error position: <#include"gdtmod_hdr.hpp"; gdtmod_hdr_nvg> Error Invalid number in expression File mpmissions\__cur_mp.Desert_E\features\gdtmod_hdr\gdtmod_hdr_init.sqf, line 1 OLD: private["_daytime_01","_daytime_02","_daytime_03","_daytime_04","_daytime_05","_daytime_06","_daytime_07","_daytime_08","_daytime_09","_daytime_10","_daytime_11","_daytime_12","_daytime_13","_daytime_14","_daytime_15","_daytime_16","_daytime_17","_daytime_18","_daytime_19","_daytime_20","_daytime_21","_daytime_22","_daytime_23","_daytime_24","_nightvision"]; #include "gdtmod_hdr.hpp"; gdtmod_hdr_nvg = _nightvision; NEW: private["_l0","_l1","_l2","_l3","_l4","_l5","_l6","_l7","_l8","_l9","_l10","_l11","_l12","_l13","_l14","_l15","_l16","_l17","_l18","_l19","_l20","_l21","_l22","_l23","_l24"];#include"gdtmod_hdr.hpp"; gdtmod_hdr_nvg=_l24; ---------- Post added at 09:42 ---------- Previous post was at 09:37 ---------- b) Any chance to preprocess the code too (eliminate defines, include etc)? Why? Code size (loading time) will enlarge. Hm why do you think so? If the engine has to preprocess define, ifdef, include itself, it will take longer. As it is static replacement and code addition, it should be done not by the engine but your tool. :) c) Any chance to reduce/optimize global variable names? Can you sure for 100% that any global variable is global only in mission and not global for any mods? How? No you cannot. My suggestion: The user can supply tags that get replaced. Example: I say replace all GV with tag AAS_. :cool: Share this post Link to post Share on other sites
Leopotam 11 Posted September 5, 2011 (edited) v1.0.6: Preprocess commands bugfixes. Undo removing ";" before "}". Correct detection variables with different case size when optimize. PvPscene, 1-4 - fixed. Global variables replacement - maybe in future releases. If the engine has to preprocess define, ifdef, include itself, it will take longer. Macroses looks like functions without limits in reuse. If macroses will be unwrapped - code size will enlarged. :) Edited September 5, 2011 by Leopotam Share this post Link to post Share on other sites
t_d 47 Posted September 5, 2011 If the engine preprocesses the "small code size" it recreates the big code again. So why not just skip the preprocessing for the engine by doing it offline with your tool? It also could be just an option instead of a default behaviour, so the user can decide if code size or fast processing has higher priority. Share this post Link to post Share on other sites
Leopotam 11 Posted September 6, 2011 (edited) It's not possible without code analyze - this tool just static string replacer based on regular expressions. If the engine preprocesses the "small code size" it recreates the big code again. Main goal - external "resource optimizator" - not engine internal operations. Edited September 6, 2011 by Leopotam Share this post Link to post Share on other sites
Leopotam 11 Posted September 6, 2011 (edited) v1.0.7: Fix for special local variable "_target". Global variables optimizations with user rules. One string - one rule. Rule can be simple variable as "AAS_IsWestAttacking" and can be mask with wildcard as "AAS_*" (Only "*" supported). Edited September 6, 2011 by Leopotam Share this post Link to post Share on other sites
.kju 3245 Posted September 6, 2011 (edited) Source: 1,70 MB (1.786.581 Bytes) Preprocessed with gcc: 1,64 MB (1.727.945 Bytes) Note I use mainly define, ifdef and include in many many files. Almost no macros. So as you can see, preprocessing would make the pbo smaller in my case. --- Testing 1.0.6 and 1.0.7 now. Thanks Leopotam! :bounce3: ---------- Post added at 08:35 ---------- Previous post was at 08:20 ---------- One problem left with 1.0.6: Error in expression <Parameters.sqf";AAS_RandomMission=false;#ifdef AAS_RANDOM_MISSION AAS_RandomMiss> Error position: <#ifdef AAS_RANDOM_MISSION AAS_RandomMiss> Error Invalid number in expression File mpmissions\__cur_mp.Desert_E\init.sqf, line 2 OLD: AAS_RandomMission = false; #ifdef AAS_RANDOM_MISSION AAS_RandomMission = true; #endif NEW: AAS_RandomMission=false;#ifdef AAS_RANDOM_MISSION//line2 AAS_RandomMission=true;#endif I am not quite sure what the arma engine doesn't like here. Maybe #ifdef must be at the start of a line? ---------- Post added at 08:36 ---------- Previous post was at 08:35 ---------- Fix for special local variable "_target". Same problem with _pos in onMapSingleClick. There might be a few more. Will report back. Edited September 6, 2011 by .kju [PvPscene] Share this post Link to post Share on other sites
sickboy 14 Posted September 6, 2011 I am not quite sure what the arma engine doesn't like here.Maybe #ifdef must be at the start of a line? Yes should be line-based, spaces/tabs dont matter, of course. Share this post Link to post Share on other sites
Leopotam 11 Posted September 6, 2011 v1.0.8: Fix for special local variable "_pos". Add more preprocessor commands. All preprocessor commands starts from new line. Add command line interface. Usage (always >=3 arguments!):ArmaResourceOptimizator.exe "mission-folder-path" flags "global-vars-rules-splitted-by-comma".Flags: olbx, where o - optimize, l - localize, x - export to xml file when localize, b - backup old files. P.S. Foxhound, are you tired? :) Share this post Link to post Share on other sites
.kju 3245 Posted September 6, 2011 thanks a lot Leopotam :bounce3: Share this post Link to post Share on other sites
Guest Posted September 6, 2011 (edited) Updated release frontpaged on the Armaholic homepage. ArmaResourceOptimizator v1.0.9.Net framework v4 P.S. Foxhound, are you tired? Hehe, nah, your to slow for that. ;) All versions were nicely mirrored. Edited September 7, 2011 by Guest updated version Share this post Link to post Share on other sites
Leopotam 11 Posted September 7, 2011 v1.0.9: Fix for global variables replacement. PvPscene, special thanks for you. :) Share this post Link to post Share on other sites