DEV Community

Cover image for From Ink.js to Phaser.js: Rebuilding Black Market Protocol's Core Systems
Xion Apex Academy
Xion Apex Academy

Posted on

From Ink.js to Phaser.js: Rebuilding Black Market Protocol's Core Systems

Hi everyone! It's Creator X here. I wanted to share my experience transitioning my cyberpunk RPG Black Market Protocol from Ink.js to Phaser.js, and the technical challenges I faced along the way.

Why I Migrated from Ink.js

When I started Black Market Protocol, Ink.js seemed perfect for a text-based narrative game. But as the game grew more complex, I hit some major limitations:

The Function Integration Problem: Every game mechanic required:

  1. An Ink function in the story file
  2. A JavaScript bridge function
  3. Manual state synchronization between both

This worked fine for simple story choices, but became a nightmare when trying to implement complex systems like dynamic combat, inventory management, and realistic hacking mechanics. As the story progressed deeper, managing these connections became exponentially harder.

Challenge 1: From Quiz to Real Hacking Simulation

The Ink.js Approach: Simple but Static

Here's what my hacking terminal looked like in Ink.js this was using inky as the base:

=== enhancement_app ===
QuickHack 101 module. Pattern: 1, 4, 7, ?
* [Enter 10]
    # notification: Pattern Matched!
    Pattern matched! Hacking skills improved.
    ~ hacking += 2
    -> docks
* [Enter 7]
    # notification: Incorrect Pattern
    Basic training completed.
    ~ hacking += 1
    -> docks
* [Skip Training]
    # notification: Skipping Training...
    ~ hacking += 1
    -> docks
Enter fullscreen mode Exit fullscreen mode

And the JavaScript side:

function handleSubmitPattern() {
    const answer = patternAnswerInput.value.trim();
    let choiceTextToSelect = null;

    if (answer === '10') {
        hackResultDiv.innerHTML = '<p class="success">Pattern matched! Hacking skills improved significantly.</p>';
        choiceTextToSelect = "APP_HACKING_CORRECT";
        playSoundEffect("app_success");
    } else {
        hackResultDiv.innerHTML = '<p class="failure">Incorrect pattern. Basic training completed.</p>';
        choiceTextToSelect = "APP_HACKING_INCORRECT";
        playSoundEffect("app_fail");
    }
}
Enter fullscreen mode Exit fullscreen mode

The Problem: This was just a quiz with predetermined outcomes. Players quickly realized they weren't actually "hacking" anything - just answering pattern questions.

The Phaser.js Solution: Dynamic Defense Systems

Now I have real-time defensive monitoring:

startDefenseMonitoring() {
    // Simulate defensive systems monitoring and responding
    setInterval(() => {
        if (this.currentSystem !== 'local' && this.systems[this.currentSystem].aiDefense) {
            this.processDefensiveActions();
        }
    }, 3000 + Math.random() * 5000); // Random intervals to keep it unpredictable
}
Enter fullscreen mode Exit fullscreen mode

And actual counter-attack consequences:

resolveCounterAttack(system) {
    const severity = system.defenseLevel / 100;

    if (Math.random() < severity) {
        // Counter-attack succeeded
        this.printLine('COUNTER-ATTACK SUCCESSFUL! Severe consequences:', 'error');
        this.stealth = Math.max(0, this.stealth - 30);
        this.skill = Math.max(0, this.skill - 10);
        this.credits = Math.max(0, this.credits - 50);

        if (this.stealth <= 0) {
            this.printLine('CRITICAL: Complete stealth failure! Force disconnecting...', 'error');
            setTimeout(() => {
                this.forceDisconnect();
            }, 2000);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Now players face real stakes based on their tech abilities, the target's defense systems, and their own stealth management.

Challenge 2: Building Interconnected Systems

The Stats Foundation

In Ink.js, stats were just numbers that incremented. In Phaser.js, they drive actual gameplay mechanics:

// Character Stats - everyone starts at zero
stats: {
    giftOfGab: 0,         // Talking, charm, manipulation (0-100)
    charisma: 0,          // General influence and perception (0-100)
    fightingAura: 0,      // Physical presence, intimidation (0-100)
    streetKnowledge: 0,   // Understanding streets, spotting scams (0-100)
    reputation: 0,        // How the world views Cipher (0-100)
    health: 100,          // Physical wellbeing (0-100)
    stamina: 100,         // Daily action capacity (0-100)
    tech: 0               // Digital skills, hacking ability (0-100)
}
Enter fullscreen mode Exit fullscreen mode

The key insight: Your tech stat directly affects your hacking stealth ability. Starting at zero means every stat point you earn has real mechanical impact.

Equipment-Gated Progression

I couldn't create meaningful equipment systems in Ink.js. Now I have:

this.equipmentCosts = {
    'Basic Laptop': { cost: 1500, description: 'Unlocks basic hacking jobs (5 new jobs)' },
    'Encrypted Router': { cost: 2800, description: 'Unlocks data theft jobs (7 new jobs)' }
};
Enter fullscreen mode Exit fullscreen mode

This creates a progression loop: Stats → Equipment Access → Job Availability → Better Pay → Better Equipment.

Challenge 3: Preventing Exploitation with Smart Gating

To prevent players from grinding high-level jobs immediately, I implemented multi-layered requirements:

// Initialize available jobs based on current stats and equipment
this.updateAvailableJobs(); // Matches your stats against job requirements
Enter fullscreen mode Exit fullscreen mode

Players need both the right equipment AND sufficient stats to access higher-paying jobs. Plus, the AI defense system scales with the target - some companies are just inherently harder to hack regardless of your abilities.

The Results

The migration was challenging, but worth it. I went from a simple choose-your-own-adventure with fake progression to a complex cyberpunk job market simulator with:

  • Real consequences for player actions
  • Interconnected systems where stats, equipment, and jobs all affect each other
  • Dynamic opposition that responds to player behavior
  • Meaningful progression that can't be easily exploited

The Phaser.js framework gave me the flexibility to build the complex, interconnected systems that Ink.js simply couldn't handle elegantly.

What's Next

I'm still refining the counter-attack defense system and plan to add more sophisticated AI behavior based on different corporation types. The demo is live now if you want to experience these systems firsthand!

You can check out the updated Black Market Protocol demo at: https://creator-xi.itch.io/the-black-market-protocol

What challenges have you faced when outgrowing a framework? I'd love to hear about your migration experiences!


Black Market Protocol is a cyberpunk text-based RPG focusing on realistic hacking mechanics and meaningful player progression. Follow the development journey for more technical deep-dives like this one.

Top comments (0)