Back to Home

Grid Inventory GameMaker: Code and JSON

Guide to creating grid inventory in GameMaker using ds_grid and JSON item database. Describes initialization, data loading, storage with ref-coordinates, and basic operations. Suitable for middle/senior developers.

GameMaker: inventory grid like in S.T.A.L.K.E.R.
Advertisement 728x90

# Implementing a Grid Inventory in GameMaker: Step-by-Step Breakdown

The grid-based inventory system lets you place items of various sizes in a ds_grid, similar to the mechanics in Deus Ex or S.T.A.L.K.E.R. To get started, create a player object oPlayer with a sprite and a container object oContainer without a default sprite. Prepare item sprites: spApple (32x32), spWaterBottle (32x64), spMysteriousPackage (64x64), spItemError (32x32). In room rTest, set up Instances and UI layers, and add instances of oPlayer and oContainer.

Create a persistent object oGameManager in the starting room rInit. In the Create event:

global.inventoryDebugMode = true;
#macro InteractionDistance 100
global.ItemDB = {};
loadItemDefinitions();
room_goto(rTest);

This initializes debug mode, the interaction distance constant, and the item database.

Google AdInline article slot

Loading Item Database from JSON

Place the file items.json in datafiles. An item's structure includes Name, Type, Width, Height, MaxStack, Sprite, Description. The script scItemDatabase contains loadItemDefinitions():

function loadItemDefinitions()
{
	var _filename = "items.json";
	if (!file_exists(_filename) && global.inventoryDebugMode)
	{
		show_debug_message("Fayl " + _filename + " not found!");
		return;
	}
	
	var _buffer = buffer_load(_filename);
	var _jsonString = buffer_read(_buffer, buffer_string);
	buffer_delete(_buffer);

	var _parsedData = json_parse(_jsonString);

	var _itemIDs = struct_get_names(_parsedData);

	for (var i = 0; i < array_length(_itemIDs); ++i)
	{
		var _id = _itemIDs[i];
		var _item = _parsedData[$ _id];

		if (variable_struct_exists(_item, "Sprite"))
		{
			_item.Sprite = asset_get_index(_item.Sprite);
            
			if (_item.Sprite == -1)
			{
				_item.Sprite = spItemError;
				if (global.inventoryDebugMode)
					show_debug_message("Withprayt not found for predmeta " + _id);
			}
		}

		global.ItemDB[$ _id] = _item;
	}
    
	if (global.inventoryDebugMode)
		show_debug_message("Baza predmetov zagruzhena. Count: " + string(array_length(_itemIDs)));
}

The function getItemData(_itemID) returns the item struct or undefined.

  • Advantages of ds_struct: dynamic access by string keys via [$ _id].
  • Error handling: fallback to spItemError if sprite is missing.
  • Accessors: for ds_grid — [# i, j], for struct — [$ key].

Basics of Storing Items in the Grid

The inventory is a ds_grid where:

Google AdInline article slot
  • The main cell of an item stores a struct {itemID, quantity}.
  • Auxiliary cells store {refX, refY} with coordinates of the main cell.
  • Empty cells are noone.

Items account for Width/Height from the database and MaxStack for stacking.

The script scInventory starts with basic functions:

Creating and Destroying the Inventory

function inventoryCreate(_width, _height)
{
	var grid = ds_grid_create(_width, _height);
	ds_grid_clear(grid, noone);
	return grid;
}

function inventoryDestroy(_inventory)
{
	if (ds_exists(_inventory, ds_type_grid))
	{
		ds_grid_destroy(_inventory);
		return true;
	}
	else
	{
		return false;
	}
}

Grid Check and Manipulation Functions

Next, implement an emptiness check:

Google AdInline article slot
  • inventoryIsEmpty(_inventory): scans the grid for noone.

Key item operations:

  • Adding: find free space based on Width/Height, place the main cell and refs in the others.
  • Moving: check for overlaps, update refX/refY.
  • Removing: clear the main and ref cells.

For interaction: check distance < InteractionDistance from oPlayer to oContainer.

Displaying the Inventory UI

On the UI layer, draw the grid using draw_sprite_part for items. Handle mouse-over for highlighting, drag-and-drop via global.dragItem.

In oPlayer, add inventoryPlayer = inventoryCreate(10, 6); do the same for containers.

Key Points

  • Use ds_grid for efficient 2D storage with [#x,y] accessors.
  • Store only itemID/quantity in the main cell; get the rest via getItemData.
  • Ensure atomic operations: check all cells before placing.
  • DebugMode simplifies debugging loading and manipulations.
  • Persistent oGameManager ensures global ItemDB state.

— Editorial Team

Advertisement 728x90

Read Next