If you’re not leveraging the capabilities and efficiency of AI while coding, then you are doing it the slower, old-fashioned way. Once you have the fundamentals of software development down and a familiarity with different technologies, using AI as a coding partner dramatically speeds up the development process.

Can I build an app with no development experience?

Once ChatGPT gained widespread adoption, one of the first capabilities users noticed was how well it understood programming languages and computer code. In addition to being able to give a detailed description of code you give to it, ChatGPT is great at being given a description of what you want and generating working code that meets your requirements. In light of this, I had three different friends of mine, each with no software development background, but know me as a software developer, tell me, I am going to try to have ChatGPT write an app for me. Each time, with some suspicion, but also some hope, I tell them, go for it! And let me know how it goes. Technically, this is something ChatGPT has the power to do, so they have the right idea. In the end though, they all returned to me after their coding foray to tell me different versions of the line, that didn’t go exactly as planned… I was in over my head. What went wrong for all of them? Certainly ChatGPT has the facilities to do exactly what they asked them to, right? I’ll put it to you like this: unless you have written an app the old-fashioned way – that is, actually designing, writing, compiling, running, and testing code – then it will be difficult to instruct someone (or something) to do it for you. After all, that’s essentially what you are doing when you are interacting with ChatGPT. You are asking it to develop an app. Even when I ask ChatGPT for a recipe or to write a paper or poetry, these are all things I have experience having done on my own first, enough to know what to ask it for, and then to know if what it gave back to me is along the lines of what I expected.

Let’s face it – computers or even AI chat bots cannot read our minds (although, we are not far off from emulating that technology). When you are interacting with ChatGPT to write an app, it does not necessarily know what you already do or do not know. It doesn’t know if you know any programming languages (let alone how to run/compile them), and it doesn’t know if you know how HTTP web requests work, or even if you know what they are or that they are a part of any web app. To put it simply, if you have not built an app without the use of AI, if you haven’t actually gone through the process of designing, coding, compiling, running, and testing/debugging, then ChatGPT is only going to be able to carry you so far without that knowledge or experience. Essentially, the only part ChatGPT eliminates from the development process is the coding. You still have to do those other steps yourself. At best, ChatGPT might even have a big enough imagination to design your app for you if you give it a well-defined enough purpose. I say all this to say, ChatGPT can write an app for you, but you have to be very specific about what you want it to build. This includes both the features as well as the technologies. I decided to try this myself with an idea I had for a web based multiplayer game, but first I had to go through the process of identifying technologies to work with.

An idea for a game

I got this idea to make a web-based maze game where you drag a circle through the maze from the start all the way through to the end, but the twist is that you can barely see beyond the circle that you move around. Barely having any visibility to do the maze naturally makes the completing the maze more challenging, so the game would be to see how quickly you could do the maze. It would not necessarily be an overly complicated maze to solve. Then I thought about what I could do to make it more challenging and fun. There would be a ticking clock, causing you to lose if you didn’t reach the end in time. Items you could collect to increase how much time you had, or how much visibility you have. Tigers at some of the dead ends that would eat you if you got too close!

Then I got this other idea. What if I made it a two-player game, and each player started at each end of the maze. Whoever could get to the other end first won the maze race. I’ve never played a game like that, so it seemed original. But there was one problem… I’ve never built a multiplayer network game. However, I know the basics. Simply put, you have a server that holds a single version of the truth, and all clients are constantly communicating back and forth with the server to 1. give updates about how they are interacting with the game, and 2. receive updates about how others are interacting with the game. In that aspect, it is simply an event-driven design, with the server being the central arbiter of events.

The next question is what technologies do I leverage to make this happen? If you have read any of the other posts on this site, then you will know I fancy JavaScript as both a client-side and server-side technology. But let’s zoom out even further. Why did I choose to make this a web app versus a native iOS or Android app? Here’s why:

  • It makes the app tremendously more portable. As long as a device has a browser, I can go straight to the web address, and play the game right there – no app download or install required. This is the approach I took for my budgeting app as well as my paintbuddy.cc drawing app.
  • One set of source code. In our modern era of converging web standards, you can be rest assured that the web technologies (HTML/CSS/JavaScript) that you are using will be cross-browser compatible, something that wasn’t true 20 years ago in the infancy of the World Wide Web, and only kinda true 10 years ago. Thank goodness IE is finally dead!
  • It performs very well. Unless I am doing something that is intensively graphics heavy or computationally heavy, or rely on a lot of the peripherals (camera, GPS, microphone), I get excellent performance. Consider the online game bloxd.io. That is a fairly graphics heavy 3D animated game that is written in TypeScript and runs directly in the browser.

One of the obvious setbacks to making this a webapp is that I have a dependency on having an internet connection, which means I cannot load the game if I am ever offline. However, I am trying to make a simple multiplayer game, so I do not need to worry about that in this case. Being offline would defeat the purpose.

Now that that’s all laid out, if I am building a web game and using JavaScript as the language, how do I manage the back and forth event-driven communication between the server and all of the clients? In the web technology world, there are technically a few ways to accomplish this:

  • AJAX (XMLHttpRequest) – Since there is already a server running, I can make HTTP requests to the server for state updates, and to give updates on my state. This is cumbersome in execution though, because it requires me to constantly poll the server for updates, even in the case that nothing has really happened. This would be overkill from a network and browser perspective. The few advantages here are that most web developers are already very comfortable with AJAX, so there is no need to learn a new technology, and that I can use the exact same port for all web requests.
  • WebSockets – WebSockets are the obvious choice here for me. They allow me to fulfill my objective of having back and forth event-driven communication between the client and the server, and are fairly simple to implement. I’ll admit, at the time of this writing, I had never actually used them before, which is why I am writing this post. This relieves the requirement of needing polling when compared to AJAX, but the one downside is that you are required to run your HTTP server and your WebSocket on two different ports. This is typically not a big issue, since both ports can be externally exposed as one port using a reverse proxy.
  • WebRTC – This technology gives a huge advantage over the other two for a multiplayer game because it relies on UDP instead of TCP. In simpler terms, if I am sending and receiving a lot of state updates, and for some reason there are momentary network lag issues, the whole event thread doesn’t have to stall waiting for a response. This is a very common problem to have to solve with multiplayer games. Furthermore, I do not actually need a server with WebRTC – it can be completely peer-to-peer. However, the biggest disadvantage with this one is that it is tremendously more complex to implement. Both AJAX and WebSockets are relatively code-light, natively supported by JavaScript, and wrapped up in a pretty box with a neat bow for using.

Having determined that WebSockets were the way to go, the one thing I needed to do was learn how to use them. I’ll admit, I haven’t had experience with them in the past, because most of the web apps I have written in my spare time or professionally have been variations on CRUD apps. That is, I have written apps that display information pulled from a database, allow for user input, process that input based on business logic, and make database updates as necessary. The exception to this is paintbuddy.cc, which is a client only app. I have made it till now simply not having needed to know how to use this technology.

ChatGPT to the rescue!

Rather than lookup a tutorial on how to build a multiplayer web game with WebSockets, this is where I decided to have ChatGPT generate one for me! Having also used ChatGPT a number of times in the past to learn new technologies like Dart and Flutter, I figured it would be perfect for this task. What I thought would have been really cool is to see if ChatGPT could write the entire game for me! But I figured I would start much smaller.

Rather than having ChatGPT generate the entire maze game for me, I asked it to generate a much smaller playable interface for me, just so I could see what it would put together and what the code looked like. I had ChatGPT give me a tutorial on the exact scenario I was trying to apply this to! If it sounds too good to be true, ChatGPT’s ability to generate a suitable code tutorial for me is largely based on how well I am able to explain to it what I wanted it to generate. I had to break the features of this simplified web game down into the smallest components I could think of. This is something that I already have experience doing, both professionally and personally. This is a skill that is very important to have as a developer, and one required to go professionally from being a junior developer to an intermediate or senior developer. Even if you are not attempting to type up requirements for an AI chatbot to automatically generate code for you, knowing how to turn ideas for features into finite individual requirements to be coded one-at-a-time is a necessary skill to have to be an effective developer.

Having decided to reduce what I wanted ChatGPT to generate for me, I gave ChatGPT this specific prompt:

I wanted to learn more about HTTP web sockets and how I could use them to make a 2 player browser based game. What I was hoping you could do is produce a code tutorial for me. I would like to use JavaScript in the front end and NodeJS as a server. I want the server to serve me a webpage that displays a canvas element where all 2D graphics will be drawn. The size of the canvas element will be a standard 800 pixels wide by 600 pixels tall, centered in the browser window. The page will have a white background but the canvas element will have a light gray background. When I first load this page, I will have a solid filled green circle displaying at the top center of the canvas element adjacent to the edge, 20 pixels in diameter. This circle will represent the character that I control. When I move the cursor over to my green circle I am able to drag it around within the bounds of the canvas element, using either mouse or touch events to click, drag and release it. The boundaries of the canvas element must also be the boundaries of the movable space of the circle. That is, the edge of the circle can never go off the edge of the canvas. When an additional user loads this page in their browser, they will see the same, only their character will be represented by a mustard yellow circle, appearing at the bottom center of the canvas element adjacent to the edge upon load. The other user will have the same restrictions and capabilities about moving their circle around. The other user will be able to see the position of my green circle, and it will be drawn on their canvas, but they will not be able to move it. Likewise, once they load the page, I will now see their mustard yellow circle on my page’s canvas element. As I move my green circle, it will update the position of the green circle on their page. Likewise, when they move their mustard yellow circle, the position of the mustard yellow circle on my canvas element will update too to match. Additional users can load the page, and they will each be able to control their own circle, which will be displayed on every other user’s page who is connected. As they move their circle around, the corresponding circle on other user’s pages moves, and that user can see other user’s circles moving around. For the 3rd user that joins, their circle will be blue and initially appear on the center left side of the canvas element adjacent to the edge. The 4th user that joins will be red and appear on the center right side of the canvas adjacent to the edge upon load. If a user stops moving for 1 minute, they should be disconnected, and it will cause all circles (including theirs) on their page and canvas to disappear, and their light gray canvas now becomes a dark gray background. This circle will now disappear from all other active user’s canvas elements. There will be no limit to the number of users who can join simultaneously. Which ever user becomes disconnected, their color (and position) become available for the next user who connects and loads the page. The order of available circle colors and positions will always be the following for the first four: 1. Green, starting in the top center. 2. Mustard yellow, starting in the bottom center. 3. Blue, starting on the left center. 4. Red, starting on the right center. After 4 simultaneous players join, the color and position will always be random, though never the same light gray as the background. I imagine the server will need to keep track of the position of all active users, as well as how long since they last moved, so they can be disconnected after 1 minute. I plan on using web sockets for communication between the clients and server, and for distinct messages/events being passed back and forth indicating 1. that a new user has joined (and their color and starting position), 2. an update in a user’s position, and 3. that a user has been disconnected. Based on this description and all of these constraints, will you generate source code files that accomplish this behavior?

Woah! That was a mouthful! But it had to be, because I had to specifically describe what I wanted to a computer who has no idea what I am thinking in my head – well, it may have some idea, based on the fact that what I am thinking in my head is likely similar to the metric tons of written text online that ChatGPT has scoured. This is what it what it responded with:

Server (Node.js with ws library):

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

const colors = ['green', 'yellow', 'blue', 'red'];
let availableColors = [...colors];
let users = {};

function getRandomColor() {
  if (availableColors.length === 0) {
    return '#' + Math.floor(Math.random() * 16777215).toString(16);
  }
  const index = Math.floor(Math.random() * availableColors.length);
  return availableColors.splice(index, 1)[0];
}

function resetUserColor(color) {
  availableColors.push(color);
}

function updateUserPosition(userId, position) {
  users[userId].position = position;
}

function disconnectUser(userId) {
  const color = users[userId].color;
  delete users[userId];
  resetUserColor(color);
  broadcast({ type: 'disconnect', userId });
}

function broadcast(message) {
  wss.clients.forEach(client => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(JSON.stringify(message));
    }
  });
}

wss.on('connection', ws => {
  const userId = Math.random().toString(36).substring(2, 10);
  const color = getRandomColor();
  const position = { x: 0, y: 0 }; // Initial position, adjust as needed

  users[userId] = { color, position };

  ws.send(JSON.stringify({ type: 'init', userId, color, position }));

  broadcast({ type: 'join', userId, color, position });

  ws.on('message', message => {
    const data = JSON.parse(message);
    if (data.type === 'updatePosition') {
      updateUserPosition(userId, data.position);
      broadcast({ type: 'updatePosition', userId, position: data.position });
    }
  });

  ws.on('close', () => {
    disconnectUser(userId);
  });
});

Client (HTML/JavaScript):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Multiplayer Game</title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
      background-color: white;
    }
    canvas {
      display: block;
      margin: auto;
      background-color: lightgray;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="800" height="600"></canvas>
  <script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    let userId;
    let users = {};

    const ws = new WebSocket('ws://localhost:8080');

    ws.onmessage = event => {
      const data = JSON.parse(event.data);
      switch (data.type) {
        case 'init':
          userId = data.userId;
          users[userId] = { color: data.color, position: data.position };
          draw();
          break;
        case 'join':
          users[data.userId] = { color: data.color, position: data.position };
          draw();
          break;
        case 'updatePosition':
          users[data.userId].position = data.position;
          draw();
          break;
        case 'disconnect':
          delete users[data.userId];
          draw();
          break;
      }
    };

    canvas.addEventListener('mousemove', event => {
      if (userId) {
        const rect = canvas.getBoundingClientRect();
        const position = {
          x: event.clientX - rect.left,
          y: event.clientY - rect.top
        };
        ws.send(JSON.stringify({ type: 'updatePosition', position }));
      }
    });

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      Object.values(users).forEach(user => {
        ctx.beginPath();
        ctx.arc(user.position.x, user.position.y, 20, 0, Math.PI * 2);
        ctx.fillStyle = user.color;
        ctx.fill();
        ctx.closePath();
      });
    }
  </script>
</body>
</html>

After I glanced over it once or twice, I was pretty impressed. The code is pretty clean, it has proper indentation, and that makes it easy to follow, which fulfills its tutorial requirement well. One thing it assumes is that I already have a web server to serve the Client HTML file. Otherwise, there is no way to take these two files alone and “run” them. Though I do have a web server set up at my household, configuring it to run these two files would also require modifying the web server configuration, which I didn’t feel like doing. Instead, I took the Server JavaScript file and set it up to use the ExpressJS web server, which allows me to serve files in just a few lines of code. All of this required me to set up a Node.js project and install Express using npm. These are the lines of code I prepended to the Server JavaScript file, index.js:

const express = require('express');

const app = express();

// Static HTML Resources
app.use('/static', express.static('static'));

const port = 8079

// Start Server
console.log('Starting server');
app.listen(port);

console.log(`Listening on port ${port}`);

ChatGPT arbitrarily chose port 8080 to host the WebSocket server (not totally arbitrary, 8080 is the default web application server port), so I happened to go one number lower and choose 8079 as the HTTP web server. Like I mentioned before, the HTTP web server and WebSocket server cannot bind to the same port simultaneously, so I have to choose two different ports. I chose “static” as a path to serve the HTML file, which I named index.html, because it is a static resource. This is in contrast to dynamic resources – of which this project has none – that are computed by the application server each time they are requested.

The grand unveiling

I wired this all together, turned it on, and loaded it in a browser, and voila! I got a circle that followed my cursor.

The ChatGPT generated multiplayer game when open in a web browser

I loaded a few more separate windows (as additional players) just to test out if the multiplayer nature of it worked. And, it kind of worked! The problem with the code ChatGPT gave me is that when additional users joined, they did not see the users that were already present. The existing users could see the new users join, but the new users could not see all of the existing users. A bug. Not to worry, it is simple enough to fix.

There are two approaches I could have taken to fix the bug. On one hand, I could have responded to ChatGPT about the behavior discrepancy between what I requested and what actually happened. I have had luck with this in the past, but on a far less complex scale. On the other hand, a quick code modification would make this go away.

In the Server JavaScript file, index.js, on the original line 47, I changed it to also send out the entire users array upon init:

ws.send(JSON.stringify({ type: 'init', userId, color, position, users }));

Then in the HTML file, index.html, I had it receive the users array from the init response, adding this right between lines 34 and 35:

users = data.users;

Now in the init, the new user also becomes aware of all of the existing users. Upon re-running the app with these edits, I was able to load the app in four separate pages. As I drug the cursor over the canvas, the corresponding circle in each window moved.

That was pretty neat to see that it worked! With the addition of a simple web server, and a small code modification, I was able to have ChatGPT write me all of the code to produce this simple game tutorial. It even understood that this was for a multiplayer game and made the title of the HTML page Multiplayer Game. One of the best parts though is how concise and simple the code was that it produced. Each file generated is give or take around 70 lines of code, and in my opinion very easy to follow. In previous experiences I have had with ChatGPT, it would give a lot of explanation about the code it generated, but in this case, after generating the code, it wrapped its response all up with:

This code provides a basic structure for your multiplayer game using WebSockets. You’ll need to adapt and expand it to fit your specific requirements and add additional features as needed.

Let’s see how you did, ChatGPT

If you actually took a second to read through my very dense and lengthy request to ChatGPT to create this multiplayer game, you would notice that it didn’t actually do everything I asked it to do. It did the most important things I needed it to do, which first and foremost was to create a code tutorial, use WebSockets, and create a game with simple graphics. Let’s go back through my request and highlight things that it got right, strikethrough things that it missed, and do both when it only partially meets the requirement:

I wanted to learn more about HTTP web sockets and how I could use them to make a 2 player browser based game. What I was hoping you could do is produce a code tutorial for me. I would like to use JavaScript in the front end and NodeJS as a server. I want the server to serve me a webpage that displays a canvas element where all 2D graphics will be drawn. The size of the canvas element will be a standard 800 pixels wide by 600 pixels tall, centered in the browser window. The page will have a white background but the canvas element will have a light gray background. When I first load this page, I will have a solid filled green circle displaying at the top center of the canvas element adjacent to the edge, 20 pixels in diameter. This circle will represent the character that I control. When I move the cursor over to my green circle I am able to drag it around within the bounds of the canvas element, using either mouse or touch events to click, drag and release it. The boundaries of the canvas element must also be the boundaries of the movable space of the circle. That is, the edge of the circle can never go off the edge of the canvas. When an additional user loads this page in their browser, they will see the same, only their character will be represented by a mustard yellow circle, appearing at the bottom center of the canvas element adjacent to the edge upon load. The other user will have the same restrictions and capabilities about moving their circle around. The other user will be able to see the position of my green circle, and it will be drawn on their canvas, but they will not be able to move it. Likewise, once they load the page, I will now see their mustard yellow circle on my page’s canvas element. As I move my green circle, it will update the position of the green circle on their page. Likewise, when they move their mustard yellow circle, the position of the mustard yellow circle on my canvas element will update too to match. Additional users can load the page, and they will each be able to control their own circle, which will be displayed on every other user’s page who is connected. As they move their circle around, the corresponding circle on other user’s pages moves, and that user can see other user’s circles moving around. For the 3rd user that joins, their circle will be blue and initially appear on the center left side of the canvas element adjacent to the edge. The 4th user that joins will be red and appear on the center right side of the canvas adjacent to the edge upon load. If a user stops moving for 1 minute, they should be disconnected, and it will cause all circles (including theirs) on their page and canvas to disappear, and their light gray canvas now becomes a dark gray background. This circle will now disappear from all other active user’s canvas elements. There will be no limit to the number of users who can join simultaneously. Which ever user becomes disconnected, their color (and position) become available for the next user who connects and loads the page. The order of available circle colors and positions will always be the following for the first four: 1. Green, starting in the top center. 2. Mustard yellow, starting in the bottom center. 3. Blue, starting on the left center. 4. Red, starting on the right center. After 4 simultaneous players join, the color and position will always be random, though never the same light gray as the background. I imagine the server will need to keep track of the position of all active users, as well as how long since they last moved, so they can be disconnected after 1 minute. I plan on using web sockets for communication between the clients and server, and for distinct messages/events being passed back and forth indicating 1. that a new user has joined (and their color and starting position), 2. an update in a user’s position, and 3. that a user has been disconnected. Based on this description and all of these constraints, will you generate source code files that accomplish this behavior?

Based on quantity alone, it looks like ChatGPT got more right than it didn’t. After all, if you watched the animation of me using the game, you’ll see that it produced working code that encapsulated the gist of my requirements. Based on that animation, I do not necessarily need to revisit all of the requirements that it got right, but I do want to discuss all the ones it got wrong, or at least partially wrong.

I would like to use JavaScript in the front end and NodeJS as a server

The word server is what is in question here. ChatGPT produced code that ran a server, but it was a WebSocket server and not a standard web server. Perhaps it seems like I was not specific enough, but then I asked for it to…

I want the server to serve me a webpage

…serve me a webpage, and the code it produced did not do that. I had to go back and add code for it to serve me a webpage.

centered in the browser window

This is one that perhaps I was not specific enough about. The front end code it produced definitely centered the canvas horizontally, but it did not vertically center it. In my head I envisioned the canvas always being in the exact center. In the animation of the working game, it is not obvious that it is only horizontally centered because the 800 pixels wide by 600 pixels tall canvas takes up the entire height of the shrunken window.

I will have a solid filled green circle

Though one of the players’ circles is green, it is not the first one. Or, at least the first one is not guaranteed to be green, though it is definitely a possibility. If we inspect the code where the color is determined, we see that it definitely adhered to the four colors I gave it:

const colors = ['green', 'yellow', 'blue', 'red'];
let availableColors = [...colors];
  const index = Math.floor(Math.random() * availableColors.length);
  return availableColors.splice(index, 1)[0];

However, ChatGPT ignored the sequence I instructed it to go in, and although the colors are listed in the right order on line 5, line 13 has it choosing one at random from that sequence.

displaying at the top center of the canvas element

I was hoping this phrasing was clear enough to convey where I wanted to circle to initially be drawn, and although it got the top part right, it ignored the center part. And in fact, starting position for all other players was ignored. All players started in the top right corner, per this line of code:

  const position = { x: 0, y: 0 }; // Initial position, adjust as needed

and ChatGPT left a comment there for me to do the work to adjust initial position. That’s what I asked you to do, ChatGPT! But I can’t be too upset. After all, it got more right than it got wrong.

using either mouse or touch events to click, drag and release it

This is one that maybe I could’ve been more specific about, but I’m looking at the words that I did write and I’m not sure how ChatGPT got the code it gave me out of that wording. The original intention was for me to be able to move my circle around by clicking on the circle, and dragging it around while clicked down, and releasing it once I stopped clicking the mouse (and likewise with touch, if I am using this app on a touch enabled device). ChatGPT disregarded the click and release aspect of moving the circle around, and though technically dragging it works to move it, it also works while not clicking either. Instead, the circle simply follows any movement of my mouse cursor over the canvas. If nothing else though, it adds to the simplicity of the tutorial.

That is, the edge of the circle can never go off the edge of the canvas

The center of the circle can never go off the edge of the canvas, but there is no code in place to stop the edge of the circle from going off of the canvas. In fact, the only thing stopping center of the circle from going off the edge of the canvas is the fact that the HTML file uses the mousemove event to control player’s position, and mousemove events can only have {x, y} coordinates within the boundaries of the HTML element they are attached to, in this case the canvas.

The other user will be able to see the position of my green circle

To give ChatGPT some credit, it was 95% of the way there with this one. However as I stated before, per the code it produced, previous players could see later players join, but later players could not see previous players that have already joined. Based on the requirement I gave ChatGPT, it did not produce code that did precisely this – I had to slightly modify it to get that working.

mustard yellow

I was skeptical yet hopeful with this one. Mustard yellow is technically a specific shade of yellow, and the only way ChatGPT would know that is based on others having referenced a certain HTML color code as “mustard yellow.” In this case, it ignored the “mustard” and kept the “yellow.”

As I move my green circle, it will update the position of the green circle on their page

I pretty much addressed this one in a previous point. However, when I first ran the code to test and debug it, and noticed that the second player did not see the first player, even though the first player could see the second player, I revisited the requirements I had given ChatGPT. Did I accidentally leave that part out? Was I not specific enough? Did I just assume it would know to implement that feature? No. The answer to all of those is no. I was specific and clear enough. It just didn’t do that.

If a user stops moving for 1 minute, they should be disconnected

There is no time keeping at all, neither on the server nor on the client, so users are connected indefinitely, as long as the server remains running. Since WebSockets do not have a built in expiration duration, this 1 minute timeout was intended to be a guard against an unlimited number of users joining. In reality though, I would never be able to test it…

* Any disconnect behavior *

…because the moment I try to disconnect from the game, the server crashes. When I say disconnect, I mean either closing the browser, or just navigating away from the game to another page within that browser tab. This is the reason there is a lot crossed out in the middle of my restated request above in this post. Since the server crashes upon one single disconnect, this halts the game for any other player. There are also no lines of code that change the light gray background to dark gray upon disconnect – which could have been done with a simple CSS or CSS class modification.

After 4 simultaneous players join, the color and position will always be random

Like I stated previously, ChatGPT gave up on the requirement to set the initial position of the player, so there was no concept of a random starting position. However, I did appreciate the code ChatGPT generated to make the color random after 4 players:

  if (availableColors.length === 0) {
    return '#' + Math.floor(Math.random() * 16777215).toString(16);
  }

This only chooses a random color if the available colors have already been used up, or in other words, 4 players have already joined. However…

though never the same light gray as the background

…there is no code that prevents it from being lightgray, which is how the background of the canvas is defined in the client/HTML code:

    canvas {
      display: block;
      margin: auto;
      background-color: lightgray;
    }

Though it is technically only a 1 in 16777215 chance that it would ever be the same color as the background (and maybe slightly higher chances due to neighboring shades of gray being visually indistinguishable), it is still possible you could join the game with a circle the same color as the background, and in effect never see yourself!

Taking a step back: what we know now

All in all, what ChatGPT was able to do with my specifications was impressive to me. But let’s go back to the original question: Can I build an app with no development experience? In light of the results of this exercise, it would be hard for me to make a case that you could.

Let’s go back and examine what I had to do to get code that worked, ran, and allowed me to interact with it:

  1. I had to have a design for what I was doing. In reality, anyone could do this, regardless of how much experience they have. In fact, more often than not, design is done by individuals without any development experience. However, some of the things that distinguish a good design from a bad design are:
    • comprehensiveness – how complete and well thought out the design is, and how few unanswered questions it leaves
    • cohesion – how well each different aspect of the design meshes or flows with one another
    • user-centric – how well the design addresses the objective of the user, as opposed to a developer-centric design which itself is a design that makes development easier, regardless of the user’s experience (and I’m sure we have all have experience using unintuitive apps that appear to have a horrible design…)
    These aspects of design are still important steps to consider when embarking on app development. Even if you create a design that isn’t very cohesive or user-centric, not having a comprehensive design often leaves a lot open to interpretation, which may result in unintended behavior in the app you are trying to create. This is true whether you are asking ChatGPT to create an app or handing a design over to a team of developers.
  2. I knew which technologies I could leverage, and had an idea which ones were most optimally suited for my purpose. I suppose if you went to ChatGPT and asked it to write an app without specifying any particular technologies (e.g. programming language, target device/platform, how you store data, etc.), it would either ask you which one you wanted, or just suggest one and pick it for you. That may not be a big problem, because in theory you could then interact with ChatGPT to learn how to run the code it generates for you as well as learn how to install the development environment on to the device on which you are running the code. In that case, you would still first need to have a basic understanding of code, how to write it, and how to run it. Even if it picked technologies for you, an important aspect of app development is the field of computer science. That is, understanding the most optimal ways to leverage computers and computing power to best accomplish your task. You may not be building Amazon.com, which must handle millions of users every second, but you might notice that the code ChatGPT generates lags every time you do a particular action, and you might not know why or be able to properly articulate the issue back to ChatGPT. But that is also not necessarily the case either.
  3. I was very descriptive with my app requirements. You saw how big and dense my request to ChatGPT was! It was practically a novel! (Maybe a short story at best.) I went into great detail about every different thing I was hoping the app would do. And that was for a very stripped down, simplified version of the original idea I had for the game. Imagine how much larger the list of requirements would have been if I wanted it to do more. Being able to break a design down into small, simple, functional and aesthetic requirements – the comprehensive part of the design – is a skill that I have found takes practice. And all that is assuming that it gets right the things I ask it to do. We just saw that it got wrong or just ignored some of the requirements I gave it. Some of that may have been because I was not specific enough, but I can argue that was not the case every time. This is an AI Chatbot after all, and I have seen it do this for other requests, such as asking it to write poetry – which it does very well – but in a specific meter, which it tends to ignore. The takeaway with this is that even when you give it all of your requirements, there is no guarantee that it will generate code that actually fulfils them all. Perhaps an alternative approach I could have taken would’ve been to put my requirements into a list format, like you might see in a legal document (section 4.1.1, section 4.1.2, etc.), rather than a continuous paragraph like I did for this.

I may try to repeat this exercise seeing (1) how much code ChatGPT will generate given bare minimum input from me and (2) how well it could fulfill all of my requirements if I were even more explicit and delivered them in an organized, ordered fashion. In both cases, I would like to take a back and forth approach with ChatGPT, addressing additional things along the way or things that I believe it missed.

I think one of the big follow up questions to this might be, Why would you go through all the effort required to type up that lengthy list of requirements? Wouldn’t it just be faster to just write the code yourself? I will be honest and report that, even as lengthy and dense as my list of requirements were in this exercise, it took probably one third of the time it would’ve taken to generate the code, look up how to use WebSockets (which are not complicated, but I had no experience with them prior to this point), and go through a few cycles of writing code, running and debugging it. To be fair, ChatGPT only got roughly 70% of my requirements correct, and if I were to have written it from scratch, I would have aimed for 100% of the requirements being fulfilled. However, at under half the time of writing code from scratch, either incrementally requesting ChatGPT to correct the code or manually patching it would still take me less time than writing 100% of the code from scratch to meet 100% of the requirements. Overall, I am very happy to see that when put to the test, ChatGPT could deliver.

Tags:

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *