Game Development Journal: Pin the Dexcom on the Human

Project Overview

Game Title: Pin the Needle Genre: Medical Education Simulation
Target Audience: Nursing students & diabetic patients
Development Period: April - June 2025
Tech Stack:

  • Frontend: HTML5 Canvas, CSS3, JavaScript (ES6+)
  • Backend: Python Flask, SQLAlchemy
  • Database: SQLite (Development), PostgreSQL (Production)

Phase 1: Design & Planning

Core Learning Objectives

  1. Teach proper CGM sensor placement according to FDA guidelines
  2. Visualize subcutaneous tissue layers for better understanding
  3. Reduce anxiety in first-time CGM users through gamification

User Stories

  • As a player, I want to drag and drop a Dexcom device onto a virtual human model, So that I can learn the correct placement for a continuous glucose monitor.

Frontend Wireframe

frontend Key Elements:

  • Drag-and-drop sensor interface
  • Real-time anatomical feedback
  • Scoring system based on placement accuracy

Phase 2: Frontend Development

Core Implementation

1. Drag-and-Drop System

// Enhanced drag handling with collision detection
class DexcomDragger {
  constructor() {
    this.sensor = document.getElementById('dexcom-sensor');
    this.dropZones = document.querySelectorAll('.placement-zone');
    this.initDragEvents();
  }

  initDragEvents() {
    this.sensor.addEventListener('dragstart', (e) => {
      e.dataTransfer.setData('text/plain', 'dexcom-sensor');
      this.highlightValidZones();
    });

    document.addEventListener('dragover', (e) => {
      e.preventDefault();
      this.updateGhostPosition(e.clientX, e.clientY);
    });

    document.addEventListener('drop', (e) => {
      e.preventDefault();
      this.handleDrop(e);
    });
  }

  handleDrop(e) {
    const dropZone = this.findDropZone(e.clientX, e.clientY);
    if (dropZone && dropZone.dataset.valid === 'true') {
      this.showSuccessFeedback(dropZone.dataset.anatomy);
    } else {
      this.showErrorFeedback();
    }
  }
}

2. Real-Time Feedback System

function showAnatomicalFeedback(zone) {
  const layers = {
    'abdomen': ['skin', 'fat', 'muscle'],
    'arm': ['skin', 'connective-tissue']
  };
  
  renderTissueLayers(layers[zone]);
  displayMedicalRationale(zone);
}

3. Responsive Design Solution

/* Mobile-first approach */
.placement-zone {
  position: absolute;
  width: 15vw;
  height: 15vw;
  border-radius: 50%;
  opacity: 0.3;
  transition: all 0.3s ease;
  
  &[data-valid="true"] {
    background: rgba(46, 204, 113, 0.3);
    &:hover {
      opacity: 0.6;
    }
  }
}

@media (pointer: coarse) {
  /* Touch device optimizations */
  .sensor {
    touch-action: none;
    width: 80px !important;
  }
}

Phase 3: Backend Development

Database Schema

class GlucoseRecord(db.Model):
    __tablename__ = 'glucose_records'
    
    id = db.Column(db.Integer, primary_key=True)
    value = db.Column(db.Float, nullable=False)
    time = db.Column(db.DateTime, nullable=False)
    notes = db.Column(db.String(500))
    status = db.Column(db.String(10), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

API Endpoints

| Endpoint | Method | Description | |———-|——–|————-| | /api/glucose | GET | Fetch all records | | /api/glucose | POST | Create new record | | /api/glucose/<id> | PUT | Update record | | /api/glucose/<id> | DELETE | Remove record |

CRUD Operations

# Flask API Example
@glucose_api.route('/', methods=['POST'])
def create_record():
    try:
        data = request.get_json()
        validate_glucose_data(data)  # Custom validation
        
        new_record = GlucoseRecord(
            value=data['value'],
            time=datetime.fromisoformat(data['time']),
            notes=data.get('notes', ''),
            status=get_glucose_status(data['value'])
        )
        
        db.session.add(new_record)
        db.session.commit()
        
        return jsonify(new_record.read()), 201
    except ValueError as e:
        return jsonify({"error": str(e)}), 400

Phase 4: Integration Challenges

Problem: Mobile Touch Inaccuracy

Solution: Implemented touch-specific coordinates calculation

function handleTouchMove(e) {
  const touch = e.touches[0];
  const rect = canvas.getBoundingClientRect();
  
  return {
    x: touch.clientX - rect.left,
    y: touch.clientY - rect.top,
    pressure: touch.force || 0.5
  };
}

Problem: Database Race Conditions

Solution: Added SQLAlchemy session locking

with db.session.begin():
    record = GlucoseRecord.query.with_for_update().get(record_id)
    record.value = new_value
    db.session.commit()

Educational Takeaways

For Future Students

  1. Start Simple: Begin with mock JSON data before backend integration
  2. Test Early: Use BrowserStack for cross-device drag-and-drop testing
  3. Document APIs: Use Swagger UI for API documentation

Code Review Highlights

✅ Well-structured Flask Blueprints  
✅ Proper error handling in CRUD operations  
🔧 Improvement Opportunity: Add JWT authentication  
🔧 Improvement Opportunity: Implement undo functionality

Project Resources

Future Roadmap

  1. AR Mode using TensorFlow.js
  2. Multiplayer Practice Mode
  3. Certification Badge System