Jump to content
🛡️FORUMS ARE IN READ-ONLY MODE Read more... ×
Sign in to follow this  
Leopotam

ArmaResourceOptimizator

Recommended Posts

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 by Leopotam
  • Like 1

Share this post


Link to post
Share on other sites

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

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 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 by Leopotam

Share this post


Link to post
Share on other sites

v1.0.2:

  • Localization process use first 3 words in localizable phrase.

Edited by Leopotam

Share this post


Link to post
Share on other sites

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

winse:

v1.0.1:

  • optimize realized. macroses not supported!
  • xml-format use user locale name too.

Edited by Leopotam

Share this post


Link to post
Share on other sites

v1.0.3:

  • Macros support (#include / # define).

Share this post


Link to post
Share on other sites

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

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

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

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 by Leopotam

Share this post


Link to post
Share on other sites

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

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 by Leopotam

Share this post


Link to post
Share on other sites

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 by Leopotam

Share this post


Link to post
Share on other sites

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 by .kju [PvPscene]

Share this post


Link to post
Share on other sites
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

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

thanks a lot Leopotam :bounce3:

Share this post


Link to post
Share on other sites

v1.0.9:

  • Fix for global variables replacement.

PvPscene, special thanks for you. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

×