A technical overview of a C# tool that automates card game asset generation from CSV data, eliminating manual image editing and accelerating prototyping.
During the development of a physical card game, our team established the core game mechanics and compiled all card data—names, descriptions, types, and abilities—into a master spreadsheet (CSV). We also had a standardized card layout.
The next step was to create physical prototypes for playtesting. The initial workflow was entirely manual:
This process was a significant bottleneck. After creating just two cards, it was clear this approach was unsustainable due to three main factors:
To solve this, I developed a custom command-line tool in C# that automates the entire card generation process. The tool reads the master CSV file, programmatically generates a high-resolution image for each card, and then arranges them onto print-ready sheets.
Demonstration of the C# tool generating card images from data.
The core of the application leverages the System.Drawing
library (now available in the System.Drawing.Common
NuGet package for modern .NET) to perform image manipulation.
The Workflow:
card_data.csv
file, which contains all the text and references to associated image assets (like icons).Bitmap
object is created in memory to serve as the canvas for the card.Graphics
object is created from the Bitmap
, providing a suite of drawing methods (FillRectangle
, DrawString
, DrawImage
) to render the card's components.Bitmap
is saved to disk as a .png
file.The following C# snippet demonstrates how the Graphics
class is used to draw the colored header panel and an icon onto the card canvas.
using System.Drawing;
using System.Drawing.Imaging;
// Define card dimensions and colors
const int CARD_WIDTH_PIXELS = 825;
const int CARD_HEIGHT_PIXELS = 1125;
Color BACKGROUND_COLOR = Color.FromArgb(211, 211, 211);
// Create a blank canvas for a single card
using Bitmap canvas = new Bitmap(CARD_WIDTH_PIXELS, CARD_HEIGHT_PIXELS);
using Graphics marker = Graphics.FromImage(canvas);
// Set rendering quality
marker.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
marker.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
// Draw the header panel
using Brush panelBrush = new SolidBrush(BACKGROUND_COLOR);
Rectangle headerPanel = new Rectangle(0, 0, CARD_WIDTH_PIXELS, 150);
marker.FillRectangle(panelBrush, headerPanel);
// Draw the card type icon onto the header
string iconPath = "path/to/icon.png";
using Image cardTypeIcon = Bitmap.FromFile(iconPath);
Rectangle iconRect = new Rectangle(25, 25, 100, 100);
marker.DrawImage(cardTypeIcon, iconRect);
// ... additional drawing logic for text, etc. ...
// Save the final card image
canvas.Save("output/card_name.png", ImageFormat.Png);
The implementation of this tool had a transformative impact on our development process:
This project is a clear example of how a small investment in creating a custom development tool can yield massive returns in productivity and quality, turning a tedious manual task into a streamlined, automated pipeline.