{"name":"createHashMapObject","title":"createHashMapObject","type":"command","url":"https://community.bistudio.com/wiki/createHashMapObject","revid":377952,"updated":"2026-01-15T10:26:48Z","groups":["HashMap"],"status":"ok","games":{"arma3":"2.14"},"since":"arma3 2.14","arma3_since":"2.14","description":"Create a HashMap with an [Object-Oriented Programming](https://en.wikipedia.org/wiki/Object-oriented_programming) behaviour.\nInside a object, Methods (if they are called correctly, either by engine or via call - Syntax 3) will have the objects instance inside the `_self` variable.\nThe Destructor (\"#delete\" method) will be executed when the last reference to the objects variable gets deleted. (Except when the mission is ended and all variables are deleted at once)\n\nInheritance: HashMap objects support a simple form of Inheritance.\nIt behaves similar to the merge command with overwriteExisting enabled. Sub-class methods and properties with same name, overwrite their Base-class values.\nConstructor/Destructor/Clone methods will be merged together and executed in sequence.\nFlags entry will use overwrite behaviour.","syntaxes":[{"syntax":"createHashMapObject [classDefinition, constructorArguments]","params":[{"name":"classDefinition","type":"HashMap or Array of Arrays, format [name, value]:","description":"HashMap or Array of Arrays, format [name, value]:\n*name* can be anything like any other HashMap, but it must be a String for it to be used like an OOP object method (see call - Syntax 3).\nSome special values, starting with `#`, are reserved and expect a specific *value* type (they are all optional):\n\n- `\"#create\"`: Code - this is the hashmap object's constructor\n- `\"#clone\"`: Code - this is code happening when cloning is done on this hashmap object\n- `\"#delete\"`: Code - this is the hashmap object's destructor. It will always be executed inside missionNamespace.\n- `\"#str\"`: Code - code that is used to evaluate what is displayed when the str function is called on the object - **must** return String\n- `\"#flags\"`: Array of Strings - case-*in*sensitive flags regarding this hashmap object\n  - \"noCopy\": forbids copying, `+_hashMapObject` will throw an error\n  - \"sealed\": prevents from adding and removing any keys - key values can still be edited\n  - \"unscheduled\": all methods (including `#clone` and `#create`) will be executed in unscheduled environment\n- `\"#base\"`: Array or HashMap - declaration of base class for inheritance\n- `\"#type\"`: String - can be used to give a object a \"type name\", on inheritance types will be merged into an Array\n\nNote that all entries beginning with `#` are reserved, the engine might use these internally without their use being documented.","type_expr":"HashMap | Array<Array>","text":"classDefinition: HashMap or Array of Arrays, format [name, value]:\n*name* can be anything like any other HashMap, but it must be a String for it to be used like an OOP object method (see call - Syntax 3).\nSome special values, starting with `#`, are reserved and expect a specific *value* type (they are all optional):\n\n- `\"#create\"`: Code - this is the hashmap object's constructor\n- `\"#clone\"`: Code - this is code happening when cloning is done on this hashmap object\n- `\"#delete\"`: Code - this is the hashmap object's destructor. It will always be executed inside missionNamespace.\n- `\"#str\"`: Code - code that is used to evaluate what is displayed when the str function is called on the object - **must** return String\n- `\"#flags\"`: Array of Strings - case-*in*sensitive flags regarding this hashmap object\n  - \"noCopy\": forbids copying, `+_hashMapObject` will throw an error\n  - \"sealed\": prevents from adding and removing any keys - key values can still be edited\n  - \"unscheduled\": all methods (including `#clone` and `#create`) will be executed in unscheduled environment\n- `\"#base\"`: Array or HashMap - declaration of base class for inheritance\n- `\"#type\"`: String - can be used to give a object a \"type name\", on inheritance types will be merged into an Array\n\nNote that all entries beginning with `#` are reserved, the engine might use these internally without their use being documented."},{"name":"constructorArguments","type":"Anything","optional":true,"default":"Nothing","description":"passed as `_this` argument to the \"#create\" method.","type_expr":"Anything","text":"constructorArguments: Anything - (Optional, default Nothing) passed as `_this` argument to the \"#create\" method."}],"returns":{"type":"HashMap","type_expr":"HashMap"},"form":"unary","right":{"text":"[classDefinition, constructorArguments]"}}],"examples":[{"text":"```sqf\nprivate _declaration = [\n    [\"#flags\", [\"sealed\"]],\n    [\"#create\", { hint \"Hello!\" }],\n    [\"#clone\", { hint \"We were copied!\" }],\n    [\"#delete\", { hint \"Goodbye\" }],\n    [\"#str\", { \"My HashMap Object\" }],\n    [\"Method\", { hint \"Method has been called\" }]\n];\n\nprivate _hashMapObject = createHashMapObject [_declaration];    // hints \"Hello!\"\n_hashMapObject call [\"Method\"];                                    // hints \"Method has been called\"\nhint str _hashMapObject;                                        // hints \"My HashMap Object\"\nprivate _shallowCopy = _hashMapObject;                            // no hint\nprivate _deepCopy = +_hashMapObject;                            // hints \"We were copied!\"\n// at the end of the scope, _hashMapObject is deleted and hints \"Goodbye\"\n```","code":["private _declaration = [\n\t[\"#flags\", [\"sealed\"]],\n\t[\"#create\", { hint \"Hello!\" }],\n\t[\"#clone\", { hint \"We were copied!\" }],\n\t[\"#delete\", { hint \"Goodbye\" }],\n\t[\"#str\", { \"My HashMap Object\" }],\n\t[\"Method\", { hint \"Method has been called\" }]\n];\n\nprivate _hashMapObject = createHashMapObject [_declaration];\t// hints \"Hello!\"\n_hashMapObject call [\"Method\"];\t\t\t\t\t\t\t\t\t// hints \"Method has been called\"\nhint str _hashMapObject;\t\t\t\t\t\t\t\t\t\t// hints \"My HashMap Object\"\nprivate _shallowCopy = _hashMapObject;\t\t\t\t\t\t\t// no hint\nprivate _deepCopy = +_hashMapObject;\t\t\t\t\t\t\t// hints \"We were copied!\"\n// at the end of the scope, _hashMapObject is deleted and hints \"Goodbye\""]},{"text":"Inheritance constructor/destructor/copy orderings:\n\n```sqf\nprivate _animalDeclaration = [\n    [\"#type\", \"IAnimal\"],\n    [\"#create\", { systemChat \"Animal Init\" }],\n    [\"#clone\", { systemChat \"Animal Copied\" }],\n    [\"#delete\", { systemChat \"Animal Bye\" }]\n];\n\nprivate _pigDeclaration = [\n    [\"#base\", _animalDeclaration],\n    [\"#type\", \"Pig\"],\n    [\"#create\", { systemChat \"Pig Init\" }],\n    [\"#clone\", { systemChat \"Pig Copied\" }],\n    [\"#delete\", { systemChat \"Pig Bye\" }]\n];\n\nprivate _smolPigDeclaration = [\n    [\"#base\", _pigDeclaration],\n    [\"#type\", \"SmolPig\"],\n    [\"#create\", { systemChat \"SmolPig Init\" }],\n    [\"#clone\", { systemChat \"Smol Copied\" }],\n    [\"#delete\", { systemChat \"Smol Bye\" }]\n];\n\nprivate _smolPigInstance = createHashMapObject [_smolPigDeclaration]; // prints \"Animal Init\", \"Pig Init\", \"SmolPig Init\"\nprivate _copy = +_smolPigInstance; // prints \"Animal Copied\", \"Pig Copied\", \"SmolPig Copied\"\n_copy = nil; // prints \"SmolPig Bye\", \"Pig Bye\", \"Animal Bye\"\n```","code":["private _animalDeclaration = [\n\t[\"#type\", \"IAnimal\"],\n\t[\"#create\", { systemChat \"Animal Init\" }],\n\t[\"#clone\", { systemChat \"Animal Copied\" }],\n\t[\"#delete\", { systemChat \"Animal Bye\" }]\n];\n\nprivate _pigDeclaration = [\n\t[\"#base\", _animalDeclaration],\n\t[\"#type\", \"Pig\"],\n\t[\"#create\", { systemChat \"Pig Init\" }],\n\t[\"#clone\", { systemChat \"Pig Copied\" }],\n\t[\"#delete\", { systemChat \"Pig Bye\" }]\n];\n\nprivate _smolPigDeclaration = [\n\t[\"#base\", _pigDeclaration],\n\t[\"#type\", \"SmolPig\"],\n\t[\"#create\", { systemChat \"SmolPig Init\" }],\n\t[\"#clone\", { systemChat \"Smol Copied\" }],\n\t[\"#delete\", { systemChat \"Smol Bye\" }]\n];\n\nprivate _smolPigInstance = createHashMapObject [_smolPigDeclaration]; // prints \"Animal Init\", \"Pig Init\", \"SmolPig Init\"\nprivate _copy = +_smolPigInstance; // prints \"Animal Copied\", \"Pig Copied\", \"SmolPig Copied\"\n_copy = nil; // prints \"SmolPig Bye\", \"Pig Bye\", \"Animal Bye\""]},{"text":"Inheritance type checking:\n\n```sqf\nprivate _animalDeclaration = [\n    [\"#type\", \"IAnimal\"],\n    [\"FurType\", { \"None\" }] // default implementation\n];\n\nprivate _pigDeclaration = [\n    [\"#base\", _animalDeclaration],\n    [\"#type\", \"Pig\"],\n    [\"FurType\", { \"Bristles\" }] // override the base class method\n];\n\nprivate _catDeclaration = [\n    [\"#base\", _animalDeclaration],\n    [\"#type\", \"Cat\"],\n    [\"FurType\", { \"Hair\" }] // override the base class method\n];\n\nprivate _instance = createHashMapObject [selectRandom [_pigDeclaration, _catDeclaration]];\n\nif (\"IAnimal\" in (_instance get \"#type\")) then // check if a object instance is or inherits from a specific type\n{\n    _instance call [\"FurType\"]; // now that we know it implements IAnimal, we know that \"FurType\" method will be present\n};\n```","code":["private _animalDeclaration = [\n\t[\"#type\", \"IAnimal\"],\n\t[\"FurType\", { \"None\" }] // default implementation\n];\n\nprivate _pigDeclaration = [\n\t[\"#base\", _animalDeclaration],\n\t[\"#type\", \"Pig\"],\n\t[\"FurType\", { \"Bristles\" }] // override the base class method\n];\n\nprivate _catDeclaration = [\n\t[\"#base\", _animalDeclaration],\n\t[\"#type\", \"Cat\"],\n\t[\"FurType\", { \"Hair\" }] // override the base class method\n];\n\nprivate _instance = createHashMapObject [selectRandom [_pigDeclaration, _catDeclaration]];\n\nif (\"IAnimal\" in (_instance get \"#type\")) then // check if a object instance is or inherits from a specific type\n{\n\t_instance call [\"FurType\"]; // now that we know it implements IAnimal, we know that \"FurType\" method will be present\n};"]},{"text":"Destructor:\n\n```sqf\nprivate _temporaryVehicle = [\n    [\"#create\", {\n        params [\"_vehicleType\", \"_vehiclePos\", \"_lifetimeSeconds\"]; // handle constructor arguments\n        private _newVehicle = _vehicleType createVehicle _vehiclePos;\n        _self set [\"MyVehicle\", _newVehicle]; // Store the vehicle inside the object for later\n\n        // because _self is passed as parameter, it will be referenced by the spawned script until it ends.\n        [_lifetimeSeconds, _self] spawn { params [\"_lifetimeSeconds\", \"_self\"]; sleep _lifetimeSeconds; };\n    }],\n    [\"#delete\", {\n        deleteVehicle (_self get \"MyVehicle\"); // delete the vehicle when we go away\n    }],\n    [\"MyVehicle\", objNull] // placeholder, this is not needed\n];\n\n// create a temporary RoadCone, at player position, that will delete itself after 5 seconds.\ncreateHashMapObject [_temporaryVehicle, [\"RoadCone_F\", getPos player, 5]];\n```","code":["private _temporaryVehicle = [\n\t[\"#create\", {\n\t\tparams [\"_vehicleType\", \"_vehiclePos\", \"_lifetimeSeconds\"]; // handle constructor arguments\n\t\tprivate _newVehicle = _vehicleType createVehicle _vehiclePos;\n\t\t_self set [\"MyVehicle\", _newVehicle]; // Store the vehicle inside the object for later\n\n\t\t// because _self is passed as parameter, it will be referenced by the spawned script until it ends.\n\t\t[_lifetimeSeconds, _self] spawn { params [\"_lifetimeSeconds\", \"_self\"]; sleep _lifetimeSeconds; };\n\t}],\n\t[\"#delete\", {\n\t\tdeleteVehicle (_self get \"MyVehicle\"); // delete the vehicle when we go away\n\t}],\n\t[\"MyVehicle\", objNull] // placeholder, this is not needed\n];\n\n// create a temporary RoadCone, at player position, that will delete itself after 5 seconds.\ncreateHashMapObject [_temporaryVehicle, [\"RoadCone_F\", getPos player, 5]];"]}],"see_also":["call","createHashMap"]}