{{TITLE}}
+{{LEAD}}
+ +diff --git a/.worktrees/agent/write-two-new-blog-posts-as-markdown-fil b/.worktrees/agent/write-two-new-blog-posts-as-markdown-fil new file mode 160000 index 0000000..f9c9c96 --- /dev/null +++ b/.worktrees/agent/write-two-new-blog-posts-as-markdown-fil @@ -0,0 +1 @@ +Subproject commit f9c9c960e0820ecefb9e1ce7116f24ffc79267d9 diff --git a/_index_template.html b/_index_template.html new file mode 100644 index 0000000..fd6deea --- /dev/null +++ b/_index_template.html @@ -0,0 +1,100 @@ + + +
+ + + +Behind-the-scenes notes on building games, forging tools, and running a small studio that punches above its weight.
+{{LEAD}}
+ +An agent harness is the layer between a raw AI model and a useful team member. It gives the agent identity, memory, tools, and guardrails. Tinqs Studio is an agent harness built specifically for game development.
+
+## What Is an Agent Harness?
+
+A raw AI model — Claude, GPT, Gemini — is powerful but stateless. It doesn't know who you are, what project you're working on, what tools are available, or what happened yesterday. Every session is a cold start. Every conversation begins with "let me explain the project..."
+
+An agent harness solves this. It wraps around the model and provides:
+
+- Identity — who the agent is, what it values, how it should behave
+- Memory — what happened in previous sessions, what was decided, what failed
+- Tools — what the agent can actually do beyond generating text
+- Context — what project this is, who's asking, what infrastructure exists
+- Guardrails — what the agent must never do, what requires human approval
+
+Without a harness, you have a chatbot. With one, you have a team member.
+
+## Why Game Dev Needs Its Own Harness
+
+Generic agent harnesses exist — LangChain, CrewAI, AutoGen. They're built for web apps, data pipelines, and customer support. Game development has different problems:
+
+Assets are binary. A web developer's PR is a text diff. A game developer's PR is a 150MB GLB file. Generic harnesses don't know how to preview 3D models, manage LFS bandwidth, or review binary assets.
+
+The pipeline is visual. Game dev goes from concept art to 3D model to rigged character to in-engine asset. Each step uses different tools — image generators, 3D modellers, auto-riggers, game engines. An agent harness for game dev needs to orchestrate this entire chain.
+
+Scale is physical. A web app's complexity is in business logic. A game's complexity is in geometry — 12km worlds, 155 vegetation prototypes, 576 terrain regions, 2000 crowd instances. The agent needs to understand spatial systems, GPU memory, and frame budgets.
+
+The team is small and cross-functional. A 4-person game studio has no dedicated DevOps, no dedicated artist, no dedicated PM. The harness needs to fill all those gaps, not just one.
+
+## How Tinqs Studio Works as a Harness
+
+Tinqs Studio is a platform built on a Gitea fork with game-specific features layered on top. But the git platform is just the foundation. The harness is everything around it.
+
+### Identity: Soul Files
+
+Every agent session starts by loading a soul file — a markdown document that defines the agent's persistent identity. Not just "you are a helpful assistant" but specific values, knowledge scope, and behavioural rules.
+
+The soul file means the agent behaves consistently whether it's triaging bugs at 9am or generating concept art at midnight. It knows what repos exist, who the team members are, what the game is about, and what decisions have been made. Identity isn't cosmetic — it's the difference between an agent that asks "what project is this?" and one that says "I see the vegetation grid was updated yesterday, want me to check the cache eviction?"
+
+### Memory: Markdown Files in Git
+
+Agent memory is plain markdown files in a git repository. No vector databases, no proprietary stores. The agent reads its memory on session start, updates it during work, and commits changes back.
+
+This is deliberately low-tech. Markdown in git gives you version history, branching, merge conflict resolution, and human readability for free. When memory goes wrong — and it will — you can git log to see what changed and git revert to fix it.
+
+### Tools: The CLI
+
+A single Go binary gives every agent access to:
+
+- Identity loading — full project context in 100ms
+- Screenshots — capture any window from outside the process
+- Cloud vision — send screenshots to a vision model, get structured descriptions
+- Health checks — verify services, repos, and tools are working
+- Service status — which URLs are live, what's reachable
+
+The CLI is the agent's hands and eyes. Without it, the agent can only read and write text. With it, the agent can see the game running, photograph bugs, and verify infrastructure.
+
+### Skills: Teachable Workflows
+
+Skills are markdown playbooks that teach agents specific procedures. Instead of hoping the model figures out how to generate concept art or create a 3D model, you write the steps once:
+
+- Image Generation — generate game art with fal.ai Flux using a 4-layer prompt pattern
+- Concept Art Pipeline — from design brief through 2D art to 3D model export
+- 3D Model Generation — Tripo Studio text-to-3D and image-to-3D
+- Video Generation — trailer clips with OpenAI Sora 2
+
+Skills compound. Every playbook you write makes the agent more capable. After six months, our agents handle art generation, competitive research, video production, project management, and code review — all from markdown files.
+
+### Git Platform: 3D Preview and LFS
+
+The Gitea fork underneath handles the game-specific git problems:
+
+- 3D asset preview — rotate GLB/FBX/STL files in the browser during code review
+- LFS-first workflows — auto-tracking for game file extensions, storage dashboards
+- OAuth2 SSO — one login for git, tools, and the game
+- 22 format support — GLB, FBX, OBJ, STL, 3DS, PLY, and more via O3DV
+
+### Guardrails: Human-in-the-Loop
+
+The harness defines what agents can and cannot do:
+
+- Agents can file issues, draft announcements, generate assets, write code
+- Agents cannot merge code, deploy builds, push to public repos, or post to external channels without human approval
+- The public blog repo requires human-approved merge requests — agents can propose changes but a person must review
+
+This isn't a limitation — it's a feature. The agent handles volume; the human handles judgement.
+
+## The Cold Start Problem
+
+The biggest problem with AI agents in production isn't capability — it's context. Every new session is blank. The agent doesn't know what happened yesterday, what's in progress, or what tools are available.
+
+Most teams solve this with long system prompts. That works until your context is 200 markdown files, 15 skills, and 3 years of project history. You can't paste all of that into a system prompt.
+
+The harness solves this with staged loading:
+
+1. CLI identity call (100ms) — loads soul file, company context, machine info, service status
+2. Memory file (instant) — loads cross-session context
+3. Skills (on demand) — loaded only when the task matches a skill name
+4. Repo context (on demand) — read files as needed, not all upfront
+
+The agent goes from cold to fully contextual in under a second. No "let me explain..." No re-reading the same onboarding doc. Just start working.
+
+## What Makes This Different from LangChain
+
+LangChain, CrewAI, and similar frameworks are code-first. You define agents in Python, chain them with function calls, and deploy them as services. They're powerful for building AI products.
+
+Tinqs Studio is file-first. Agents are defined in markdown. Skills are markdown. Memory is markdown. Identity is markdown. Everything is in git, readable by humans, editable without code changes, and version-controlled.
+
+This matters for game teams because:
+
+- Non-engineers can contribute. The designer writes a skill for concept art. The PM writes a skill for sprint planning. No Python required.
+- Everything is auditable. git log shows who changed what, when, and why. Memory changes are commits. Skill updates are diffs.
+- It works with any AI tool. The same soul files and skills work in Cursor, Claude Code, or any tool that reads markdown. You're not locked into one framework.
+
+## The Stack
+
+| Layer | What | How |
+|——-|——|—–|
+| Identity | Soul files, company context | Markdown in git, loaded via CLI |
+| Memory | Cross-session context | Markdown in git, updated by agents |
+| Skills | Teachable workflows | Markdown playbooks, loaded on demand |
+| Tools | CLI, screenshots, vision | Go binary, one install per machine |
+| Git | 3D preview, LFS, SSO | Gitea fork with game-specific features |
+| Creative | Image gen, 3D models, video | fal.ai, Tripo, Sora 2 via skills |
+| Guardrails | Human approval gates | Branch protection, MR requirements |
+
+## Getting Started
+
+If you want to build your own agent harness for game dev:
+
+1. Start with a soul file. Write 50 words about your project's identity, values, and scope. Put it in your repo root as SOUL.md.
+2. Write one skill. Pick the workflow you repeat most — concept art generation, bug triage, build verification — and write the steps as markdown.
+3. Build a CLI identity command. Even a shell script that prints "project name, repos, services" gives your agent a warm start.
+4. Put everything in git. Not a database, not a SaaS tool. Git. You already have it.
+
+The rest — 3D preview, LFS management, OAuth SSO, creative pipelines — you can add as you need it. Or use Tinqs Studio, where we've already built it.
+
+—
+
+An agent harness isn't a product category yet. But it should be. The gap between "I have an AI model" and "I have an AI team member" is infrastructure — identity, memory, tools, context, guardrails. For game development, that infrastructure needs to understand binary assets, visual pipelines, and spatial systems. That's what we're building.
We gave our AI agents persistent identities, skill playbooks, and access to our entire knowledge base. This is how a 4-person game studio built an agentic workflow that punches above its weight.
+ +When you're four people building a game, there's no room for a dedicated DevOps person, a full-time PM tool chain, or someone whose job it is to "keep things organised." Everyone wears five hats. Documentation drifts. Issues pile up. The left hand doesn't know what the right hand shipped.
+We tried the usual tools — Notion, Trello, shared Google Docs. They all had the same problem: they're passive. They sit there and wait for a human to update them. In a team of four where the lead developer is also the CTO, that human never has time.
+So we built something different. We gave AI agents persistent identities, connected them to our entire knowledge base, and let them become working members of the team.
+Our primary AI agent runs inside the IDE and has access to the full documentation repository — the game design document, backlog, meeting notes, company operations, everything. It's not a chatbot. It's a persistent team member with a soul file that defines its values and operating principles, and a memory file that persists context across sessions.
+The key insight: all knowledge lives in markdown files in one repo. No databases, no SaaS dashboards, no proprietary formats. Plain text, version-controlled, readable by humans and agents alike. When anyone on the team opens the docs repo, the agent wakes up with full context of who they are, what machine they're on, and what's been happening.
+The team talks to the agent through voice. The IDE's built-in microphone transcribes and auto-translates (multilingual team). The agent is trained to interpret messy voice-to-text artifacts and act on intent, not grammar.
+The interactive agent only runs when someone opens the IDE. But a studio doesn't sleep — bugs get reported at midnight, issues go stale, and the team chat fills up while everyone's away.
+A background daemon runs 24/7, ticking every 15 minutes. It uses a three-tier model strategy — cheap models for routine checks, medium for analysis, and premium only when it needs deep reasoning. The whole thing costs about $15/day.
+The two agents coordinate through the docs repo itself. One writes, the other reads. No API calls between them, no message queue. Just git.
+Agents don't just have instructions — they have skills. Each skill is a markdown file that teaches the agent a specific workflow: how to generate concept art through a pipeline, how to use image generation APIs, how to conduct competitive research, how to create 3D models from concept art.
+When someone asks the agent to do something that matches a skill, it reads the skill file and follows the procedure. This means you can teach the agent new capabilities without changing any code — just write a new markdown file.
+We've open-sourced several of our skills in this repo:
+Giving the agent a persistent identity isn't theatre. It creates consistency across sessions. The soul file defines:
+The agent remembers what it learned, adapts to who's asking, and maintains the same principles whether it's triaging bugs or drafting a Steam page description. The soul file is the agent's constitution.
+Plain text is the universal API. Every tool, every agent, every human can read a markdown file. We store everything — design documents, meeting notes, agent memory, team contacts — as .md files in one repository. This sounds almost too simple, but it eliminates an entire class of integration problems.
+Cheap models for routine, expensive models for thinking. Most of what an autonomous agent does is pattern matching and text formatting — you don't need the most expensive model for that. Save the premium tokens for decisions that actually require reasoning.
+The human stays in the loop for decisions. The agents can file issues, draft announcements, and generate assets — but they don't merge code, deploy builds, or post to public channels without explicit approval. The workflow is designed so the AI handles the grunt work while humans make the calls that matter.
+Voice input changes everything. When you can describe a bug while looking at the game screen, and the agent transcribes, interprets, and files an issue — that's a workflow that collapses the distance between noticing a problem and tracking it.
+Skills compound. Every skill file you write makes the agent more capable. After 6 months, our agents have 15+ skills covering art generation, competitive research, video production, and project management. Each one took 30 minutes to write and saves hours every week.
+We're not claiming this is how every studio should work. But for a small team trying to build something ambitious, having AI agents that actually understand the project — not just answer questions about it — has been transformative. The agents don't replace anyone on the team. They make it possible for four people to do the work of forty.
+We're building all of this as part of Tinqs Studio — a game development platform that brings git hosting, AI tools, and team workflows together. The blog posts and skills in this repo are part of that journey.
+ +${codeLines.join("\n")}\n`;
+ inCode = false;
+ continue;
+ }
+ }
+ if (inCode) {
+ codeLines.push(escapeHtml(line));
+ continue;
+ }
+
+ // Blank line
+ if (line.trim() === "") {
+ closeUl();
+ continue;
+ }
+
+ // Headings
+ const hMatch = line.match(/^(#{1,6})\s+(.*)$/);
+ if (hMatch) {
+ closeUl();
+ const level = hMatch[1].length;
+ html += `${inline(line)}
\n`; + } + + closeUl(); + return html; +} + +function escapeHtml(s) { + return s.replace(/&/g, "&").replace(//g, ">"); +} + +function inline(s) { + // Bold + s = s.replace(/\*\*(.+?)\*\*/g, "$1"); + // Italic + s = s.replace(/\*(.+?)\*/g, "$1"); + // Inline code + s = s.replace(/`([^`]+)`/g, "$1");
+ // Links
+ s = s.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1');
+ // Em dash
+ s = s.replace(/---/g, "—");
+ s = s.replace(/--/g, "–");
+ return s;
+}
+
+// ── Date formatting ─────────────────────────────────────────────────
+
+function formatDate(isoDate) {
+ const d = new Date(isoDate + "T00:00:00Z");
+ const months = [
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December",
+ ];
+ return `${d.getUTCDate()} ${months[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
+}
+
+// ── Build ───────────────────────────────────────────────────────────
+
+function buildPost(file) {
+ const src = fs.readFileSync(path.join(POSTS_DIR, file), "utf8");
+ const { meta, body } = parseFrontmatter(src);
+
+ // Split lead (first paragraph) from rest
+ const parts = body.split(/\n\n/);
+ const lead = parts[0].trim();
+ const rest = parts.slice(1).join("\n\n");
+
+ const html = TEMPLATE
+ .replace(/\{\{TITLE\}\}/g, meta.title)
+ .replace(/\{\{DESCRIPTION\}\}/g, meta.description || meta.title)
+ .replace(/\{\{OG_DESCRIPTION\}\}/g, meta.og_description || meta.description || meta.title)
+ .replace(/\{\{OG_IMAGE\}\}/g, meta.og_image || "https://www.tinqs.com/img/og-cover.jpg")
+ .replace(/\{\{SLUG\}\}/g, meta.slug)
+ .replace(/\{\{DATE_ISO\}\}/g, meta.date)
+ .replace(/\{\{DATE_DISPLAY\}\}/g, formatDate(meta.date))
+ .replace(/\{\{LEAD\}\}/g, inline(lead))
+ .replace(/\{\{BODY\}\}/g, md(rest))
+ .replace(/\{\{AUTHOR_NAME\}\}/g, meta.author || "Ozan Bozkurt")
+ .replace(/\{\{AUTHOR_INITIALS\}\}/g, meta.author_initials || "OB")
+ .replace(/\{\{AUTHOR_ROLE\}\}/g, meta.author_role || "CTO & Developer, Tinqs");
+
+ const outPath = path.join(BLOG_DIR, `${meta.slug}.html`);
+ fs.writeFileSync(outPath, html);
+ console.log(` ${file} → ${meta.slug}.html`);
+ return meta;
+}
+
+function buildIndex(posts) {
+ // Sort newest first
+ posts.sort((a, b) => b.date.localeCompare(a.date));
+
+ const cards = posts
+ .map(
+ (p) => `
+
+ ${formatDate(p.date)}
+ ${p.excerpt || p.description}
+ Read → + ` + ) + .join("\n"); + + const html = INDEX_TEMPLATE.replace("{{CARDS}}", cards); + fs.writeFileSync(path.join(BLOG_DIR, "index.html"), html); + console.log(" index.html (listing)"); +} + +// ── Main ──────────────────────────────────────────────────────────── + +console.log("Building blog..."); + +if (!fs.existsSync(POSTS_DIR)) { + console.error("No posts/ directory found."); + process.exit(1); +} + +const files = fs.readdirSync(POSTS_DIR).filter((f) => f.endsWith(".md")).sort(); +const posts = files.map(buildPost); +buildIndex(posts); + +console.log(`Done — ${posts.length} posts built.`); diff --git a/cloud-harness.html b/cloud-harness.html new file mode 100644 index 0000000..0962efa --- /dev/null +++ b/cloud-harness.html @@ -0,0 +1,225 @@ + + + + + + +We spent a few sessions building something that still barely exists elsewhere: a cloud agent harness where AI coding agents are first-class citizens of the platform, not bolt-on tools. The stack is a Pi fork for the brain, a Go orchestrator inside our Gitea fork for overnight work, and a browser dashboard merged into Pi for the daytime. Here is how it fits together.
+ +Every coding agent today — Claude Code, Codex, Pi, Aider — runs in your terminal. You watch it work. You close the laptop, it stops. There is no way to say "build these eight features overnight" and wake up to pull requests.
+We wanted exactly that. Not a coding assistant. An autonomous workforce — with a UI when a human needs to be in the loop.
+Cost. Claude Code runs on Opus at $15/MTok output. Codex uses GPT 5.5. Running eight agents overnight on either would cost $50–200. DeepSeek V4 Flash costs $0.28/MTok output. Eight overnight tasks: about $0.80.
+Control. Cloud tools are black boxes. We cannot add a Gitea API tool, a fal.ai image generator, or a guardrail that blocks aws ec2 terminate-instances. With our own harness, we add an extension and it is live.
Platform. We are building Tinqs Studio — a Gitea-based game development platform. Agents are not a feature we want to outsource. They are the product.
+Pi is an open-source coding agent by Mario Zechner. MIT license, TypeScript, minimal by design — four core tools (read, write, edit, bash) and an extension system.
+We forked it. Not to rewrite the core — to add first-party extensions:
+Each extension is a single TypeScript file. No extra npm dependencies on the extension side.
+Pi has four output modes. The one that matters for automation is RPC — a headless process that accepts JSON on stdin/stdout. That is how the orchestrator drives it.
+DeepSeek V4 Flash through our own inference proxy. OpenAI-compatible API, so Pi treats it like any other provider. The proxy adds:
+Cost per task: $0.02–0.10 depending on complexity.
+Inside tinqs/studio we added modules/agents/ — a Go worker pool that:
–mode rpc –no-sessionSix HTTP endpoints, same auth as git push:
+POST /api/v1/agents/tasks — submit a task
+GET /api/v1/agents/tasks — list all tasks
+GET /api/v1/agents/tasks/{id} — get task details
+DELETE /api/v1/agents/tasks/{id} — stop a task
+GET /api/v1/agents/stream — SSE live events
+GET /api/v1/agents/health — orchestrator status
+We considered bolting on a separate orchestration SaaS and rejected it. The orchestrator lives in the same binary as git — same auth, no extra service to deploy.
+The intended loop:
+Orchestrator reads task brief
+ → spawns pi --mode rpc
+ → Pi writes code using DeepSeek V4
+ → Pi pushes branch, calls ci_wait
+ → CI green → Pi opens PR via gitea_api
+ → CI red → Pi reads ci_logs, fixes, retries
+ → Human reviews PR, merges
+Git worktree integration and full push/PR automation are still being wired; the API and worker pool already run locally.
+The cloud orchestrator is for batch work while you sleep. During the day you want to see agents, chat with them, and spawn sessions without living in a terminal.
+We merged pi-agent-dashboard into the Pi monorepo — not as a second repo to install. One checkout, one command:
+npm run dashboard:dev
+Open http://localhost:33634. You get:
+ask_user dialogs from the browserThe dashboard talks to Pi sessions over a WebSocket bridge on port 9999. Inference uses the same Tinqs proxy as the CLI — register a custom provider in ~/.pi/agent/providers.json and authenticate with your existing tstudio token. No separate LLM API keys.
Dashboard (localhost:33634)
+ ↕ WebSocket (port 9999)
+Pi sessions (interactive or headless)
+ ↕ OpenAI-compatible API
+Tinqs Studio proxy (tinqs.com/api/v1/ai)
+ ↕ DeepSeek V4 Flash / Pro
+When Studio runs locally with agents enabled, the dashboard can also talk to the orchestrator API on port 3000 — submit tasks and watch SSE events in the same UI.
+One browser tab for daytime work; the orchestrator queue for overnight runs.
+Our biggest fear: an agent hallucinating instead of using tools, or running aws ec2 terminate-instances at 3 AM.
The guardrail extension monitors every agent turn:
+Hallucination detection — if the agent claims file contents without calling read, it gets corrected.
No-tool drift — three consecutive turns without a tool call triggers a warning.
+Command blocking — 29 patterns covering destructive git, AWS teardown, process killing, and production API abuse.
+A few focused sessions: about 2,000 lines of Go, 900 lines of TypeScript extensions, 52 tests, plus merging the dashboard packages into the Pi monorepo. No new servers — Pi is a Node subprocess; the dashboard is another Node process on your machine.
+| Piece | Status |
+|——-|——–|
+| Pi fork + tinqs extensions | Shipped |
+| Dashboard merged into Pi monorepo | Shipped |
+| Go orchestrator + REST/SSE API | MVP, running locally |
+| Git worktree + push + PR loop | In progress |
+| Domain routing (game / sim / platform tasks) | Designed |
+Next we are promoting studio skills from IDE playbooks into orchestrator prompt packs — so the same Pi worker behaves like a game builder, sim maintainer, or platform engineer depending on the task. Specialized agents (planner, reviewer, asset pipeline) sit on top of this foundation.
+The harness — inference proxy, guardrails, dashboard, orchestrator API — is in place. The work now is feeding it real tasks and hardening the git loop.
+Tinqs Studio is an open platform for game development — git hosting, AI inference, asset generation, and autonomous agents. We are building Ariki, a survival colony sim, using the same tools we ship.
+ +We're a small indie studio building a survival colony sim. We don't have a concept artist on staff. Every piece of character art, trailer frame, and UI icon in our game was generated with fal.ai Flux models — at roughly a penny per image.
+ +Most AI image generators produce beautiful images that are completely useless for game development. They look great on social media but fall apart when you need consistency: the same character from four angles, a UI icon that reads at 64x64, a trailer frame that matches your game's art style rather than whatever the model defaults to.
+The issue isn't the models — Flux is genuinely good. The issue is prompting. When you write "warrior on a beach," you get a different art style every time. Different skin tones, different proportions, different lighting. You can't build a game from that.
+We spent three months iterating on prompt patterns before we found something that works consistently. The result is a 4-layer system that anchors the model to your art direction and produces images you can actually ship.
+We evaluated Midjourney, DALL-E 3, Stable Diffusion (self-hosted), and fal.ai:
+API-first. Midjourney is Discord-only. DALL-E's API works but the model makes everything look like a stock photo. Self-hosted SD means maintaining GPU infrastructure. fal.ai gives you Flux models behind a simple REST API — POST a prompt, GET an image URL.
+Cost. $0.01 per image with flux-2-pro. $0.004 with schnell for rapid iteration. A full character design session — 12 variants across 3 rounds of refinement — costs $0.12. A 20-frame trailer storyboard costs $0.20. At these prices, the bottleneck is creative direction, not budget.
Speed. flux/schnell returns an image in 4 seconds. flux-2-pro in 15 seconds. Fast enough that an AI agent can generate, display, get feedback, and regenerate in a single conversation turn.
No subscription. Pay per image. No monthly fee, no credit packs that expire, no tier-gated features.
+This is the pattern that made AI art actually usable for our game. Each layer adds specificity, and the combination anchors the model to a consistent output.
+The most important layer and the one most people skip. It sets the overall art direction:
+Art direction: stylized 3D render for a survival colony sim. Warm earthy
+palette --- browns, tans, dark reds, cream, ocean blues. Carved wood
+textures, traditional patterns, woven natural fibres. Game engine quality,
+not photorealistic.
+This paragraph appears at the start of every prompt. Same paragraph whether you're generating a character, a landscape, or an icon. It anchors the model to your art style.
+The key insight: write this once, paste it everywhere. It's your art bible compressed into 50 words. Every time we skipped it — "just a quick test" — the output drifted into generic fantasy art.
+Describe exactly what should appear, element by element:
+Full body character in T-pose, front view. Young woman, mid-20s.
+Wearing a woven wrap skirt (mid-thigh length) and a fitted cloth top.
+Shell necklace with a carved bone pendant. Single bone bracelet on
+left wrist. Hair swept back over right shoulder. Bare feet.
+Matte skin, warm brown tones. Neutral confident expression ---
+not smiling, not angry. Dark grey background.
+Not "tribal clothing" but "woven wrap skirt." Not "jewelry" but "shell necklace with a carved bone pendant." Vague prompts produce vague results. Specific prompts produce usable assets.
+Always include what you don't want:
+Do not include: cartoon style, anime style, photorealistic render,
+extra text or taglines, watermark, deformed elements, modern or
+sci-fi. No extra fingers, no merged limbs, no floating accessories.
+Extend per-subject. For characters: "no stereotypical elements, no overly shiny materials." The negative prompt is as important as the positive one.
+When you need consistency — the same character from different angles, or a new character matching an existing one — pass a reference image:
+result = fal_client.subscribe("fal-ai/flux-2-pro", arguments={
+ "prompt": "Same character, side view, same clothing and accessories...",
+ "image_url": "https://your-approved-front-view.png",
+ "image_size": "square_hd",
+})
+The first approved image becomes the reference for all subsequent views. Without it, you get a different person every time.
+| Model | Cost | Speed | When |
+|——-|——|——-|——|
+| flux-2-pro | $0.01 | ~15s | Final art. Default for anything you'll ship. |
| flux/schnell | $0.004 | ~4s | Exploration and iteration. |
| ideogram/v2 | $0.008 | ~5s | Anything with readable text — logos, UI, posters. |
| flux-pro/v1.1-ultra | $0.015 | ~8s | Highest quality, but can hang. |
The workflow: explore with schnell, refine with flux-2-pro, add text with ideogram/v2.
fal.ai is the first step in a pipeline from idea to in-game asset:
+Brief --> fal.ai (2D concept art) --> Tripo Studio (3D model) --> Blender (decimate) --> Godot (in-game)
+1. Brief. The designer describes the character or asset.
+2. 2D generation. Generate 3 variants with flux-2-pro, score each on a rubric (style match, cultural accuracy, silhouette, expression, animatability), pick the best.
3. Reference sheet. Generate front, side, three-quarter, and head closeup views using the winner as reference.
+4. 3D model. Approved concept art goes into Tripo Studio for image-to-3D. Outputs ~1.5M faces with full PBR textures.
+5. Decimation. Blender CLI decimates to 25,000 faces.
+6. Rigging. Auto-rig the body (hair separated first if large).
+7. In-game. Import into the engine, set up materials, done.
+The entire pipeline from "I want a character" to "character walking around in the game" takes about 2 hours. The quality isn't AAA, but for an indie game with a stylised art style, it's more than good enough.
+The design context layer is everything. Without it, every image is a one-off. With it, every image belongs to the same game. The 50-word context block is worth more than the rest of the prompt combined.
+Negative prompts prevent drift. AI models have strong defaults — they want to make things shiny, symmetrical, and photorealistic. If your game isn't those things, say so explicitly.
+Score and iterate, don't accept the first output. Generate 3 variants, score on 5 criteria, approve only 8+/10. Three attempts at $0.01 each is $0.03 — cheaper than working around a mediocre image.
+Reference images are the consistency mechanism. Without them, every generation is independent. With them, every generation builds on the last approved output. This is how you get a roster of characters that look like they belong in the same game.
+Fast models for exploration, quality models for output. schnell at 4 seconds is for "what if..." iterations. flux-2-pro at 15 seconds is for "yes, this is the one."
Let the AI agent handle prompt engineering. We encode the 4-layer pattern, art style guide, and cultural guardrails in a skill file. The agent writes the full prompt, generates images, displays them, and asks for scores. The human's job is creative direction.
+We've published the skill files that power this workflow. A skill is a markdown document that teaches an AI agent a specific procedure — like a runbook, but the reader is an LLM.
+Drop any of these into your .cursor/skills/ directory and your AI agent can follow them. Adapt the design context block to your game's art style and you're good to go.
AI image generation isn't magic and it isn't free. But at a penny per image, with the right prompt structure, it eliminates the most expensive bottleneck in indie game development: the gap between "I know what this should look like" and "I have an image I can actually use."
+We're building all of this as part of Tinqs Studio — a game development platform that brings together git hosting, AI tools, and creative workflows for game teams.
+ +The AI developer tools space has a problem: everyone is building new things. New agents, new IDEs, new platforms, new wrappers around GPT. Meanwhile, the tools that actually run the world — git servers, game engines, CI runners — sit there unchanged, waiting for someone to open them up and let agents in. We chose to fork instead of build. Three times. Here's why.
+ +We're a four-person game studio. We don't have time to build a git platform, a coding agent, and a game engine from scratch. Nobody does. But we can take something that already works — something with years of battle-testing, thousands of contributors, and millions of users — and change it from the inside.
+The pattern is simple:
+1. Find an open-source tool that does 95% of what you need
+2. Fork it
+3. Add the 5% that makes it yours
+4. Stay close to upstream so you get their fixes for free
+We've done this three times.
+Gitea is a self-hosted git server. Single Go binary, MIT license, 45k GitHub stars. It handles repos, issues, pull requests, CI, LFS — everything a team needs.
+We forked it and built Tinqs Studio. Our changes:
+.glb file and rotate the model in your browserTotal lines changed from upstream: about 2,000 out of Gitea's 500,000. That's 0.4%. We modify templates, add Go modules, and tweak CSS variables. We never touch the database schema — we ride upstream's migrations. When Gitea releases 1.27, we rebase, fix conflicts, and ship.
+The alternative was building a git platform from scratch. That's a multi-year, multi-million dollar project. Or using GitHub/GitLab and accepting their limitations. Neither option gives you the ability to embed AI agents directly into the platform.
+Pi is an open-source coding agent. 51k stars, MIT license, TypeScript. Four core tools (read, write, edit, bash), a minimal system prompt, and an extension system.
+We forked it and added four extensions:
+Each extension is a single TypeScript file. No npm dependencies. The core Pi code is untouched — we only add files.
+The alternative was building our own agent from scratch. That means writing tool-calling logic, context management, streaming, retry handling, conversation threading — months of work to reinvent what Pi already does. Or using Claude Code / Codex as a black box and accepting that you can't add a Gitea API tool or a budget cap.
+Godot is an open-source game engine. We forked 4.6.2 and added nine C++ modules that turn the engine into an agent-aware runtime:
+These modules compile into the engine binary. A vanilla Godot user never sees them. An agent can connect to the running engine over HTTP, take a screenshot, read the scene tree, execute a console command, and capture the result — all without touching the editor UI.
+The alternative was building an engine integration from scratch. Or worse, building a custom engine. We'd still be writing a renderer instead of making a game.
+Gitea has handled millions of git pushes. Godot renders millions of frames. Pi has processed millions of LLM tokens. That battle-testing is free when you fork. When you build from scratch, you spend your first year rediscovering bugs that were fixed upstream in 2019.
+Every upstream release brings security patches, performance improvements, and new features — written by hundreds of contributors we don't pay. Our job is to rebase, resolve conflicts, and test. That's an afternoon, not a quarter.
+Building a git server from scratch means worrying about pack-file format, SSH key management, webhook delivery, and a thousand other things that have nothing to do with AI agents. Forking means you only think about the 5% that matters to you. The other 95% is someone else's problem.
+An agent that pushes to a real Gitea instance — with real CI, real code review, real permissions — produces work that humans can actually review and ship. An agent that pushes to a toy demo platform produces demos.
+The whole point of AI agents is to participate in real workflows. Real workflows run on real tools. If you want agents in your git workflow, put them in your git server. If you want agents in your game pipeline, put them in your game engine.
+Across all three forks, our total changeset is less than 0.5% of the upstream code. Tinqs Studio: 0.4% of Gitea. Pi extensions: 900 lines added to a 15,000-line codebase. Godot modules: 2,000 lines added to a 2-million-line engine.
+This isn't a coincidence. If your fork touches more than 1% of upstream, you're doing too much. Either the upstream tool is wrong for the job, or you're not trusting it enough. The power of forking is that you don't have to understand the whole codebase. You find the extension points, add your code, and leave the rest alone.
+We're not building a new IDE. Cursor and Claude Code exist. We're not building a new LLM. DeepSeek and Claude exist. We're not building a new cloud platform. AWS exists.
+We're building the layer that connects them. The git server that speaks agent. The coding agent that speaks Gitea. The game engine that speaks HTTP. Each fork is a bridge between an existing tool and the agentic future — not a replacement for either.
+The age of agents doesn't need more agents. It needs better platforms. Platforms that understand agents as first-class users — with API endpoints, safety rails, and lifecycle management. Those platforms already exist as open-source projects. They just need someone to fork them and add the wiring.
+That's the bet. Fork, don't build. Modify the foundation, don't stack another layer on top. Let the upstream community handle the 99.5% while you focus on the 0.5% that makes it yours.
+Tinqs Studio is our Gitea fork, open for game teams and indie studios. We're building Ariki — a survival colony sim — using every tool described in this post. If you're interested in self-hosted game development with built-in AI agents, come take a look.
+ +GitHub is built for web developers. Game studios need something different — LFS that works, 3D asset previews in the browser, and project management that understands sprints and milestones. So we forked Gitea and built Tinqs Studio.
+ +We used GitHub for two years. It was fine for docs — small files, text diffs, pull requests. But the game repo was a different story.
+A single character model with textures and animations is 50–200MB. A terrain heightmap is 16MB. An island's vegetation data is another 10MB. Our game repo was 12GB in LFS alone, growing every week. GitHub's LFS bandwidth limits, slow clone times, and $5/50GB pricing made it untenable.
+More importantly, nobody on the team could see what changed. A PR that modifies a GLB file shows a binary diff. You can't preview it. You can't compare before and after. The artist pushes a model, the developer approves it blindly, and three days later someone notices the normals are inverted.
+We evaluated GitLab, Forgejo, Gogs, and Gitea. The decision came down to:
+We ran vanilla Gitea for six months. It solved the cost and bandwidth problems immediately. But the UX gaps for game development were still there.
+Tinqs Studio is our fork. It tracks upstream Gitea on the main branch and keeps all customisations on a separate branch. We rebase onto upstream releases periodically, fix conflicts, and deploy.
The headline feature. When you open a PR that contains a .glb, .gltf, or .fbx file, you see a 3D viewer directly in the browser. Rotate, zoom, check materials. No downloads, no external tools. We integrated Online 3D Viewer (O3DV), which supports 22 file formats including STL, OBJ, 3DS, and PLY.
This changes the review process fundamentally. The artist pushes a model, the lead rotates it in the browser, leaves a comment about the UV seam on the shoulder, and the artist fixes it — all without leaving the git platform.
+Vanilla Gitea treats LFS as an afterthought. You configure .gitattributes manually. There's no dashboard showing LFS usage, no way to see which files are tracked, no warnings when someone commits a large file without LFS.
Tinqs Studio adds auto-LFS tracking on repository creation. Game file extensions (.fbx, .glb, .png, .wav, .ogg, .tscn, .tres) are tracked by default. An API endpoint exposes LFS storage stats per repo. The goal: LFS should be invisible. It should just work.
Tinqs Studio integrates project management — issues, sprints, time tracking — and OAuth2 SSO. One login for git, the game tools, and the team dashboard.
+Staying close to upstream is critical. We don't want to maintain a fork that diverges forever:
+main tracks upstream go-gitea/gitea. We never commit to it directly.We deliberately limit what we touch. We modify templates, locale strings, CSS variables, and a handful of Go packages. We never touch the database models — schema is owned by upstream, and we ride their migrations. This keeps rebasing manageable.
+Self-hosting git is surprisingly easy. The hard part isn't running Gitea — it's convincing yourself that you're allowed to. After years of GitHub being the default, it feels transgressive to host your own git. But a single Go binary on a $10/month server handles a small team with room to spare.
+LFS changes everything for game repos. Our clone times went from 45 minutes to 3 minutes. Developers only download the LFS objects they need. CI only pulls what changed. The bandwidth savings alone paid for the server.
+Forking is maintenance, not rebellion. The romantic version is "we forked Gitea and built our own platform." The reality is we changed 200 lines of Go, 50 template strings, and a CSS file. 99.5% of the code is upstream's. We're just customising the last half-percent for our use case.
+3D preview is a game changer. We expected it to be a nice-to-have. It turned out to be the feature that made the rest of the team actually use git. When the artist can see their work rendered in the browser, they stop asking the developer to "check if it looks right."
+Tinqs Studio is built for game teams that are tired of paying GitHub for LFS bandwidth and reviewing binary diffs blind. We're building it for ourselves first — dogfooding it on our own game — but the plan is to make it available as a platform for other studios. If you're a game team that self-hosts or wants to, we'd love to hear what features you need.
+ +Godot has no built-in asset streaming. Our game is a 12km x 12km archipelago with 9 islands, thousands of trees, hundreds of buildings, and an ocean that never ends. Here's how we made it run.
+ +We're building a survival colony sim set across 9 islands. The total world is roughly 12km x 12km. Each island is 4km across with its own terrain heightmap, biome textures, vegetation prototypes, and building grids. The player can travel between islands by canoe.
+Godot 4 is a fantastic engine, but it wasn't designed for this scale. There's no terrain streaming, no asset LOD pipeline, no distance-based loading. If you load everything at startup, you run out of VRAM before the player sees the main menu. So we built four streaming layers on top of Godot, all in C#.
+We use Terrain3D for heightmaps — a GDExtension that gives us a clipmap renderer with 7 LOD levels. Internally, Terrain3D divides each island into 512m x 512m regions. A 4km island has 64 regions. Across 9 islands, that's 576 regions total.
+The key insight: don't create all 9 terrain nodes at startup. Each node allocates a clipmap mesh, collision structures, and materials even when hidden. Our original code created all 9 in _Ready() and just toggled visibility. This wasted hundreds of megabytes on islands the player hadn't visited yet.
The fix was lazy instantiation. We create the current island's terrain on startup and defer the rest. When the player gets in a canoe and sails to a new island, we create that island's terrain node on demand, import the heightmap, and start async texture loading — all while a loading screen covers the transition.
+This is the main prop streaming system. Every island's vegetation — trees, rocks, grasses, shrubs — is divided into a spatial grid of 128m x 128m chunks.
+The camera position is checked every 0.5 seconds. When it crosses a chunk boundary, we calculate which chunks should be active within a 400m radius (roughly 39 chunks in a circle), QueueFree chunks that fell out of range, and build new chunks that entered range.
Each chunk groups vegetation instances by prototype, creates a MultiMesh per group, and places instances using height queries. A chunk with 50 palm trees and 30 rocks becomes 2 MultiMesh draw calls, not 80 individual nodes.
+Vegetation meshes and materials are cached in dictionaries keyed by prototype name. The problem: these caches are append-only. Visit all 9 islands and you accumulate every mesh and material variant permanently. With 155 unique prototypes across the archipelago, that's a lot of GPU memory that never gets freed.
+The fix is island-scoped eviction. When the player leaves an island, we clear the vegetation caches. Meshes and materials for the departed island are released. If the player returns, they reload from disk. The loading screen covers this cost.
+Godot's GD.Load() is synchronous. It blocks the main thread. During gameplay, the frame freezes. We audited the entire codebase and found 26 resource load calls across 13 files, and only 1 was async.
The worst offender was GetMeshForProto() in the vegetation grid. As the player walks across an island for the first time, every new vegetation prototype triggers a synchronous load. With 155 prototypes, the first traversal stutters visibly.
We fixed this in two ways:
+ResourceLoader.LoadThreadedRequest() with _Process() polling. The terrain renders immediately with autoshader colours, and biome textures pop in when ready. The player never notices.On top of our own caches, Godot maintains an internal resource cache. Every GD.Load() call caches the result globally. There's no API to query the cache size or evict entries.
If you load an FBX as a PackedScene, instantiate it to extract a mesh, then free the instance — the PackedScene stays cached. The mesh you extracted is fine (it's a Resource, not a Node), but the discarded scene wastes memory forever.
The rule: use ResourceLoader.Load(path, "", CacheMode.Ignore) for one-shot loads where you extract data and discard the container. Use GD.Load() only for things that should persist (shaders, shared textures).
Dynamic entities — colonists, animals, buildings, VFX — are event-driven, not streamed. They update when the simulation pushes new state, not per frame.
+QueueFree when removed. Self-cleaning.We audited every QueueFree() call in the codebase — 47 calls across 17 files. Zero RemoveChild() calls without a corresponding QueueFree(). Three patterns we follow everywhere:
Pattern 1: Chunk streaming — Deactivate out-of-range chunks by iterating the active dict, calling QueueFree(), collecting keys to remove, then removing them after iteration. Never modify a dictionary while iterating it.
Pattern 2: Extract data from PackedScene — Instantiate a scene, extract the mesh, QueueFree() the temporary instance. The mesh survives because it's a Resource, not a Node.
Pattern 3: UI rebuild — QueueFree() all children, then build new content. Safe because QueueFree is deferred — new children are added in the same frame before old ones are freed.
We're strict about what goes in _Process():
No heap allocation in any of these. Total per-frame overhead is dominated by the crowd lerp and the message queue drain.
+Two custom shaders are performance-sensitive:
+Ocean shader — 4 Gerstner wave calculations in the vertex stage, applied to a 12,000m plane. Fragment stage does depth reconstruction, caustics, foam masking, and two normal map lookups. It's the heaviest thing in the render pipeline. We pre-warm it during the loading screen to avoid shader compilation stutter.
+Wind sway shader — 6 trig ops per vertex on every vegetation mesh within 400m. The sway is invisible beyond 100m but the shader runs at full cost regardless. Future optimisation: disable sway on distant chunks.
+Our early access target is an RTX 3060 with 8GB VRAM:
+Always measure before optimising. We added VRAM logging before writing a single line of optimisation code. Half the "problems" we expected turned out to be non-issues. The other half were worse than expected. Profiling isn't optional.
+Godot 4 can handle open worlds at this scale, but it won't do it for you. You need to build streaming, manage your own caches, audit your resource loading, and be disciplined about what runs per frame. The engine gives you the primitives — MultiMesh, LoadThreadedRequest, QueueFree — and it's up to you to wire them into a system that scales.
We're building with these systems and developing the game using Tinqs Studio. If you're building something large-scale in Godot, we hope this is useful.
+ +We generate every visual asset for Ariki — concept art, app icons, trailer frames, logo variants, Steam capsules — through a single inference proxy that routes to fal.ai. No Photoshop. No Midjourney subscription. Just API calls at prices that range from $0.002 to $0.09 per image. Here's how we decide which model gets which job.
+ +Our Tinqs Studio platform includes an inference proxy that sits between agents and model providers. When an agent (or a human in Cursor) says "generate an image," the proxy routes the request to fal.ai, handles authentication, tracks usage per user, and persists the result to S3. The caller doesn't care which model runs — they describe what they want, and the proxy picks or the caller specifies.
+Agent describes what it wants
+ → tinqsProxy receives generate_image call
+ → Routes to fal.ai with the specified model
+ → Image generated, persisted to S3
+ → Permanent URL returned to caller
+One API key. One billing account. Access to every model fal.ai hosts. That's the pitch of aggregator platforms, and fal.ai delivers on it.
+Not every image needs the best model. A throwaway mockup doesn't justify $0.09. A final logo doesn't deserve $0.002. We split our usage into four tiers.
+For images that ship — hero art, app icons, trailer keyframes, print-ready designs — we use three models depending on the content:
+Flux 2 Pro ($0.03/megapixel, ~15 seconds). Our default. Best all-round quality for concept art, character illustrations, environment paintings, and anything that doesn't need text. Handles complex prompts with multiple elements well. Rarely fails.
+Ideogram v3 Quality ($0.09, ~12 seconds). The only model that renders text reliably inside images. When we need a poster with a tagline, a sign in a game scene, or a logo with readable letters, this is the only option. The QUALITY tier is expensive but worth it — text at lower tiers gets blurry.
+Recraft v3 ($0.04 raster, $0.08 vector, ~10 seconds). Built for commercial design. Clean lines, consistent style, and the only model on fal.ai that outputs SVG vectors. When we need brand assets, packaging mockups, or anything that might end up in print, Recraft produces work that doesn't need cleanup.
+For images that are good enough for internal review, social posts, or documentation:
+Ideogram v3 Balanced ($0.06, ~8 seconds). Typography quality between Turbo and Quality. Good for marketing materials where text matters but perfection doesn't.
+Seedream v4.5 ($0.04, ~8 seconds). Google's model on fal.ai. Photorealistic scenes and product shots. Different aesthetic from Flux — slightly more photographic, less painterly.
+Flux Dev ($0.025, ~10 seconds). The open-weight Flux variant. Good quality, and the base for LoRA fine-tuning if you want to train on your own style. We use it when we need custom-trained models later.
+For iteration, A/B testing, and throwing things at the wall:
+Flux Schnell ($0.003/megapixel, ~3 seconds). The workhorse for exploration. When we're figuring out composition, trying different camera angles, or generating 20 variants to pick one direction — Schnell. A hundred images costs $0.30. You can afford to be wasteful.
+SDXL Lightning (~$0.002, ~2 seconds). The absolute cheapest option. Lower quality than Schnell, but when you need 50 thumbnails to test a layout grid or generate placeholder textures, quality doesn't matter. Two cents for ten images.
+For modifying existing images rather than generating new ones:
+Flux Kontext (~$0.04, ~12 seconds). Context-aware editing. Give it an image and say "change the wood to marble" or "make it sunset lighting." Preserves composition while changing style or material. Useful for quick style transfers without regenerating from scratch.
+Nano Banana Edit ($0.039, ~12 seconds). Image-to-image restyle. We use this for our logo variant pipeline — take one carved-wood Ariki logo and produce versions in mahogany, pearl, obsidian, coral, gold. It's better than Kontext at preserving fine detail in complex images.
+BiRefNet ($0.001, ~3 seconds). Background removal. Produces clean alpha cutouts from any image. We pair it with every logo and icon generation — generate with a white background, then cut it out. A dollar gets you a thousand cutouts.
+We never start with the expensive model. Every generation session follows the same pattern:
+1. Explore with Schnell ($0.003) — 10-20 variants, different angles, compositions, color palettes. Total: $0.03-0.06.
+2. Pick 2-3 directions. Human looks at the grid, picks the promising ones.
+3. Refine with Flux 2 Pro ($0.03) — regenerate the winners at full quality with refined prompts. Total: $0.06-0.09.
+4. Post-process — BiRefNet for background removal ($0.001), maybe Recraft for a vector version ($0.08).
+A full session — from blank canvas to final assets — costs under $0.20. That's the price of a single Midjourney generation on their Pro plan.
+Our Ariki logo has 18 material variants — deep mahogany, mother-of-pearl, obsidian, molten lava, bronze with verdigris, tapa cloth, and more. Each one generated with Nano Banana Edit ($0.039) + BiRefNet ($0.001) for transparency. Total cost for 18 variants: $0.72. A designer would quote hundreds of dollars and a week of work for the same output.
+Every model except Ideogram fails at text. Flux will give you beautiful art with garbled letters. Recraft gets close but isn't consistent. SDXL doesn't try. If the image has words in it, Ideogram v3 is the only answer. We've learned to accept the $0.09 cost for text-heavy images rather than wasting $0.30 on ten failed Flux attempts.
+Over the past month:
+| Category | Images | Total Cost | Avg Cost/Image |
+|———-|——–|———–|—————-|
+| Concept art (flux-2-pro) | ~120 | $3.60 | $0.03 |
+| Exploration drafts (schnell) | ~400 | $1.20 | $0.003 |
+| Logo variants (nano-banana) | 18 | $0.72 | $0.04 |
+| Icons (nano-banana + birefnet) | 30 | $1.20 | $0.04 |
+| Typography (ideogram) | ~25 | $1.50 | $0.06 |
+| Background removal (birefnet) | ~80 | $0.08 | $0.001 |
+| Total | ~673 | $8.30 | $0.012 |
+Six hundred images for eight dollars. The infrastructure to route, authenticate, and persist them costs more than the generation itself.
+Never iterate on expensive models. The Schnell-to-Pro pipeline saves 10x. Most of the creative work happens at $0.003/image. The expensive model just polishes the decision you already made.
+Typography is a solved problem — but only on one model. Stop trying to make Flux render text. Use Ideogram v3 Quality for anything with words. Accept the cost.
+Vector output is underrated. Recraft v3's SVG export means logos and icons scale to any size without artifacts. For anything that might end up on a billboard or a business card, pay the $0.08 for vector.
+Background removal is basically free. At $0.001 per image, there's no reason to ever manually mask anything. Run BiRefNet on everything, keep both versions.
+Aggregation beats loyalty. No single model is best at everything. Flux for art, Ideogram for text, Recraft for design, Nano Banana for edits, BiRefNet for masks. The proxy pattern lets us use the right tool for each job without managing five API keys and five billing accounts.
+Image generation is built into Tinqs Studio — our Gitea-based platform for game teams. Every model above is available through the same inference proxy that handles LLM calls, authenticated with the same Gitea token. We're building Ariki with these tools, and every asset in the game touched at least one of them.
+ +Tinqs Studio is a game development platform built on a Gitea fork. It gives AI agents identity, memory, skills, and tools — so a small team can build games at scale.
-This repo contains our engineering blog and the AI agent skill files that power our creative pipeline. Everything is open, CC BY 4.0.
-Behind-the-scenes notes on building games, forging tools, and running a small studio that punches above its weight.
+We forked Pi, merged a browser dashboard into the monorepo, and built a Go orchestrator inside our Gitea fork. Agents code overnight for about $0.80 — and you can watch them from the browser.
+ Read → + -Skills are markdown playbooks that teach AI agents specific workflows. Drop them into your .cursor/skills/ directory and your agent can follow them. Think of them as runbooks where the reader is an LLM, not a human.
An agent harness gives AI agents identity, memory, tools, and guardrails. Tinqs Studio is one built for game development.
+ Read → + + + 25 May 2026 +We generate concept art, trailer frames, and UI icons with fal.ai Flux models at $0.01 per image. Here's the prompt engineering pattern that makes it work for game dev.
+ Read → + + + + 25 May 2026 +Everyone is building new AI developer tools. We forked three existing ones and modified them from the inside. Here's why that's the better bet.
+ Read → + + + + 25 May 2026 +We generate concept art, logos, icons, and trailer frames through a single API proxy. Here's how we pick between 12 models spanning $0.002 to $0.09 per image.
+ Read → + + + + 25 May 2026 +Most coding agents stop at git push. Our Pi fork watches CI, reads failure logs, and fixes its own code until the pipeline goes green.
+ Read → + + + + 25 May 2026 +We built a pre-commit hook that calls DeepSeek V4 Flash to review every commit. It catches leaked secrets, classified terms, and broken URLs --- for a tenth of a cent.
+ Read → + + + + 22 May 2026 +Four streaming layers, async resource loading, memory-safe caches, and zero leaks. How we built a 12km open world in Godot 4 with C#.
+ Read → + + + + 20 May 2026 +GitHub doesn't understand game dev. We forked Gitea to build Tinqs Studio --- with 3D asset preview, LFS-first workflows, and project management for game teams.
+ Read → + + + + 18 May 2026 +A single Go binary that gives AI agents context about who you are, what machine you're on, and what services are reachable. Screenshots, cloud vision, health checks --- one install, every machine.
+ Read → + + + + 6 March 2026 +Soul files, skill playbooks, and markdown as the universal API. How we built an agentic workflow that lets a 4-person indie studio operate at 10x scale.
+ Read → + +