Skip to content
Quinton Ashley edited this page May 16, 2024 · 76 revisions

Hi I'm Quinton Ashley and this is my journal about the creation of p5play. I'll be updating it periodically with behind the scenes info!

Project Roadmap

https://github.com/quinton-ashley/p5play/projects/1

"Learn p5play" is finished! : May 15, 2024

The "Learn" section of p5play.org is an interactive textbook I've been writing for the past two years. 👨‍🏫 Making it publicly available during this time provided me with a lot of useful feedback, which I'm grateful for! 📖

Now that it’s finished, this resource will still be free for personal use, but educators/schools need to become Pro members to use it in class or coursework. The monthly subscription cost is fair and affordable: starting at only ~25¢ per student per month. Far less even, than a paperback book! 📚

I'm trying to strike a balance here between open source and monetization. I don't want the p5play library to lack core features that users would need to pay a premium for. I think the only way to deeply learn how software works is being able to look at the source code. Additionally, teachers can still teach about p5play for free using their own lesson material, as long as it’s made open source in compliance with the AGPL.

But I also believe that the hundreds of hours I've put into writing the Learn pages has resulted in something of real value for CS educators. I hope you agree and will support my development of p5play.

If your school or university would prefer a custom one time invoice instead of a subscription, I can make one. Let me know how many students will use p5play and the duration of use.

Some p5play users have suggested I put advertisements before running student’s code or on the Learn pages instead of charging schools to use them. I will never do that! I think it’s unethical to sell student's attention to advertisers during instructional time or when they're doing coursework. I believe that schools should pay to provide high quality educational resources for their students, not essentially forcing their students to pay via ads.

I also don't expect teachers to have time to cover all of p5play's features during class, so charging for beyond the basics wouldn't be an incentive. My intent behind including so many core features is to entice students to learn p5play. It's what makes p5play different from a lot of Ed Tech platforms that are so basic they're only good for teaching intro level CS. As a student I felt like everything I was doing in school was just eternal preparation for the next thing. I want students to feel empowered by p5play. Students wouldn't pay just to access features like controller input, animation sequencing, etc.

If you think your school or district will not pay, please still petition them to do so. I can answer any questions they might have to try to persuade them. If they deny your request, don’t misdirect your anger at me. I don’t think any teacher should have to pay out of pocket for learning resources and supplies. If the cost of the p5play PRO membership is a legitimate barrier for you or your school, please let me know.

p5play isn’t some big corporation, I need to find a way to sustain my work so the project doesn’t die again. I promise that if p5play ever gets institutional funding, I will make the Learn pages completely free again.

Until then, I need grassroots funding to continue working on p5play’s upcoming mobile development and multiplayer server features. I hope you'll confirm your support!

https://p5play.org/pro/

iOS App Templates released : April 25, 2024

Patreon supporters now have access to iOS app templates!

WebGPU support? : February 3, 2024

WebGPU is the latest and greatest graphics API for the web.

If you have a chromium based browser, check out this WebGPU demo. It can draw millions of flocking boids using BabylonJS! https://www.reddit.com/r/GraphicsProgramming/comments/13cemv5/webgpu_millions_of_flocking_boids_with_babylonjs/

Dec 21, 2023 : Starting in Safari Technology Preview 185, WebGPU can be enabled for early testing and development. https://webkit.org/blog/14879/webgpu-now-available-for-testing-in-safari-technology-preview/ https://mil-tokyo.github.io/webdnn/docs/tips/enable_webgpu_ios.html

January 17, 2024 : The Chrome team is excited to announce that WebGPU is now enabled by default in Chrome 121 on devices running Android 12 and greater powered by Qualcomm and ARM GPUs. https://developer.chrome.com/blog/new-in-webgpu-121

WebGPU will probably be supported by all major browsers later this year. But when will p5.js support WebGPU? Probably much later... maybe never.

For the relatively simple graphics processing required by the typical p5play game, the 2D and WebGL 2 canvas modes are already great. Perhaps in the future I could make a new version of q5.js, which could implement p5's 2D API with WebGPU. Only one problem, I know nothing about low level graphics programming lol. Ideally someone will re-implement the 2D canvas context in WebGPU and then I could just use it! That's probably wishful thinking though.

Another idea is using an existing library like BablyonJS and then make a q5 wrapper on top for the 2D canvas p5.js API. That'd still be a ton of work.

For now there are more important things I need to prioritize.

Resources:

https://www.youtube.com/watch?v=m6T-Mq1BPXg https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext/configure https://codelabs.developers.google.com/your-first-webgpu-app https://webgpufundamentals.org/webgpu/lessons/webgpu-orthographic-projection.html

Keep using planck under the hood? : February 3, 2024

Many moons ago I wanted v4 of p5play to use liquidfun-play-2 under the hood. It's the latest version of box2d-wasm with google's liquidfun extension. https://github.com/Birch-san/liquidfun-play-2

Since then planck.js v1 was released, it performs significantly better compared to the alpha versions. Also there are benefits to having direct access to the physics simulation in JS. For example, advanced users can do things in planck that I haven't put a nice p5play wrapper on yet, for example Discord user @ coding 's recent use of world.rayCast.

JavaScript is actually really fast at doing math nowadays and in a head to head test with emscripten compiled C code running in wasm, the results are basically the same! https://jtiscione.github.io/webassembly-wave/

I'd need to do a real test comparing planck.js and liquidfun-play-2 to actually see the difference.

For now I'll be sticking with planck!

Mobile Dev Progress Update : January 16, 2024

Back in August, I had rather naively hoped to release a p5play iOS app template in late September. But a LOT of work needed to be done before I could provide p5play users a proper mobile development experience.

Here's a summary of my progress:

  • achieved feature parity between p5.js v1.9.0 and q5.js, a smaller and faster implementation of the 2D p5.js API
  • implemented a text image caching system that improved rotated text performance by 90x
  • refactored the core of p5play, its contact (collision and overlap) handling system, for better readability and performance
  • fixed all known issues with p5play, the next release will be marked as stable
  • wrote the p5play Novice and Professional licenses, which will legally enable app store publishing

This is what I plan to do by the end of this month:

  • implement p5play input functions presses, pressing, released for touch objects
  • release the iOS app template project for Patreon members
  • add mobile development features to the p5play Visual Studio Code extension
  • publish the "p5play dev" iOS app that will enable users to test out their projects on mobile for free

NEW and improved contact handling! : November 22, 2023

My second attempt at creating a new collision and overlap handling system is so much simpler and just better in every way than the previous ones. After I figured it out I thought, "Why hadn't I thought of this before?", but such clarity was only achieved after slogging through 2 months of refactoring. I was not having a good time by the end of it lol but it really had to be done and I'm quite happy with the results!

There were unfortunately quite a few bugs with v3.16 though, despite all my new tests. v3.17 is finally holding water though!

q5.js global mode workflow upgraded : November 22, 2023

Until now, I actually haven't attempted to create a full game with p5play myself. It's been great to analyze the library as a whole, after spending so long hyper-focussing on individual parts.

My biggest issue with p5.js in terms of workflow, is the necessity of the preload and setup functions, because it forces users to create variables on the file level but define them separately. In q5 I've implemented a global mode that solves this issue. Just put new Q5() at the top of a sketch and everything you'd normally put in preload can go after that. If a setup function is defined, it'll run after loading is complete. (I found that it's necessary to create sprites in setup if they use group animations, which need to be loaded before they're copied internally for use by group sprites.)

Using q5's improved global mode is so nice, I'm definitely going to make a YouTube video about it!

Failed Attempt at Refactoring Contact Handling : November 6, 2023

I recently did a big overhaul of the collision and overlap system in p5play v3.15, but I think I could do better.

The main issue with the previous system, in v3.14 and before, was inside the sprites' _step function, which gets run on every physics world step. If a callback was not found between the sprites, it'd search between their groups starting from their first group: allSprites. Searching for callbacks on every frame is inefficient, especially when one might not even exist. It'd actually search twice, since the order of inputs to the callback function matters.

In v3.15, I kind of solved the issue by using more memory to save sprite-to-group or group-to-group contact callbacks inside every sprite in a group. The contact relationships of the group are inherited by any sprite added to it as well.

But it has a big problem, take a look at the following example:

let group0 = new Group();
let group1 = new Group();

let spriteA = new group0.Sprite();
let spriteB = new group1.Sprite();

group0.overlaps(group1, cb1);
spriteA.overlaps(spriteB, cb0);

Only cb0 would get run on overlap. If the last two lines are reversed, then the group overlap would override the sprite overlap. I don't like that! So my first attempt at refactoring the contact handling system has failed, it's not going to stick.

I want to implement a new contact handling system that could run both overlap callbacks. I'm going to try a hybrid approach that will consume less memory and only do a little searching to get group callbacks. Stay tuned!

The Elusiveness of Stability : October 26, 2023

For the past 2 months, as soon as I fixed an issue with p5play I'd find another one... 🐞🐛🪲🪳🪳🪳🪳😭

It felt like I'd never be able to finish this update, and yet here we are! 😅

And yeah... it seems like every month I re-announce that p5play v3 is "quite nearly finished"TM, but then I get some other idea for something that'd be cool to add to it. 😆

But p5play now has over 1,000 users per day, so I'm going to start prioritizing stability and performance over adding new features. The rate of mainline releases will decrease, and I'll make incremental progress in https://p5play.org/v3/p5play.beta.js so people can opt-in to beta testing or not.

It's a bit demoralizing to find mistakes in my code, but as the old saying goes, "You have to break a few eggs to make an omelette!". That means, "In order to achieve something, it's inevitable and necessary that some mistakes are made or some sacrifices must occur." 🥚🍳

So please continue reporting any issues with p5play on Discord or GitHub, it really helps me out.

My #1 goal is to make using p5play a great experience, so I hope you all enjoy the update! 🎊

Why does p5play have its own input system? : September 3rd, 2023

p5.js has event functions such as mousePressed and keyPressed which give developers an easy way to respond to input events, similar to plain ol' JavaScript. But, it'd be a bit cumbersome to program combinatory input actions (Ex. do x when mouse pressing and the 'up' key being held) if developers were limited to these event functions.

So p5.js also provides variables like mouseX and key which developers can access in anywhere in their sketch. The problem is that games often require more precise tracking of what state the input is in, not just if a user is pressing a key or not.

p5play has its own InputDevice paradigm that solves both of these issues, enabling developers to easily check for a combination of inputs and the status of the input. See the Input page for examples.

changeAni : August 3rd, 2023

I had examples on p5play.org that used sprite.ani = 'name' to change which animation a sprite was currently displaying. I realized that's actually super confusing because the primary purpose of sprite.ani is to enable users to easily access the sprite's current animation. This caused users to be confused about how to check the animation's name (via sprite.ani.name).

I've changed all the examples on p5play.org so they use the sprite.changeAni('name') function for changing which animation the sprite displays and sprite.ani is only accessed, not set.

The Future of p5play : August 2nd, 2023

p5play v3 is basically finished! 🎊

Its performance is great on my M1 MacBook Air, achieving 60fps fullscreen, even with 500+ sprites on screen. But it leaves much to be desired on older hardware. Although, I am impressed that it can do ~60fps on my wife's iPhone 11, albeit with low sprite counts.

When I started working on p5play v3, I knew that planck.js was slow compared to matter.js, but my main goal was to use the highest quality JS physics simulator available. Yet, v3 technically could've been made in 2017. It doesn't take advantage of WASM, which has been available in all modern browsers (most recently including Safari) since March 2023. Physics engines basically just do a bunch of intensive math problems, so taking advantage of WASM represents a huge leap in performance.

Just a few months after I started working on p5play v3 back in 2022, I found out about Birch-san's box2d-wasm, the latest version of which is liquidfun-play-2, released in 2021. It only has 26 stars on GitHub. I think it's not very popular because it's even harder to use than planck.js, but it's truly on the cutting edge of both performance and quality among JS physics engines.

The reason I didn't immediately stop working on p5play v3 to work on a v4 with box2d-wasm is that I'd already put a ton of work into v3 and wanted to "finish" it. I also thought I'd make v4 a Pro version, only available to paying Patreon members. But if I had developed v3 and v4 concurrently and made any mistakes, it'd be prohibitively time consuming to do bug fixes for both versions. I opted to focus on making v3 solid first so I could use it as a base for v4. In hindsight that was a great decision because user issue reports (especially from Raj Raizada, @ Tezumie, @ Day, and Caleb Foss) have been critical in helping me find bugs that I might've never encountered on my own. It's also become apparent that to really compete with Phaser and Unity, p5play v4 will need to be free to use.

Also currently, mobile app publishing on iPhone is prohibitively expensive for many students and schools. Apple requires developers pay them a $100 fee for the privilege of publishing apps. But that will change soon, since the EU ruled that Apple must allow other app stores on iOS.

Part of the problem with performance on iPhone was that for years I think Apple purposefully made iOS Safari's HTML5 canvas implementation slow, so that users could only download performant games from Apple's App Store. Currently every other browser on iOS must use WebKit (Safari) under the hood, due to Apple's restrictions. But the EU has also outlawed Apple's monopoly on iOS web browsing. My dream is that Google will implement a completely custom version of Chrome on iOS. They'd write a better HTML5 canvas implementation, which could cause Apple to improve theirs, or perhaps Google will release a ChromeKit module for Swift.

All of this is great news for the future of p5play game development on mobile devices!

But personally, the thought of implementing v4 right now, even with the benefit of using v3 as a base, is quite daunting.

Here are my plans for the future (in no particular order):

  • update the p5play.org homepage
  • finish editing and publish a few videos about p5play on social media
  • release an iOS app template to Patreon members, enabling them to publish apps
  • publish the "p5play dev" iOS app, which is basically just the template app but it will enable users test out games on iPhone for free
  • try to get more funding for p5play by reaching out to Universities
  • develop my own game using p5play and publish it on the App Store

Upgrade v3.9 : July 22nd, 2023

Officially introducing Joints! https://p5play.org/learn/joints.html

On a personal note, v3.9 feels like the culmination of over a year's worth of work since I released v3. At the time, I was honestly worried that it could be a fruitless attempt to revive the project. 😬

I'm so grateful that my new version has been embraced by so many people around the world. It's been a great gift to see all of your creations made with p5play! 🎁 Also, a few days ago I found out that CodeHS created a course called "Introduction to Game Design with p5play" that includes videos and interactive lessons, cool stuff!

In the coming months I want to focus on growing this community via YouTube, Instagram, and TikTok. ☺️ I have BIG plans for mobile development! If you've enjoyed using p5play and appreciate my work, please consider supporting me on Patreon: https://www.patreon.com/p5play

Verb Consistency : October 13, 2022

I will be releasing v3.1.0, a big update to p5play, soon! This update will contain changes to the input system. I'm sorry to make these changes kind of late in p5play v3's development but I think it's important p5play uses the same verb conjugations for all timing related functions.

I was inspired to make these changes because I'm adding a new paradigm for custom collide and overlap event handling that won't require the use of callback functions and can be used in if statements. This feature has been highly requested by my students!

In technical terms, single frame initiative timing functions will use present simple tense naming. Continuous timing functions will use present continuous tense naming. Single frame cessation timing functions will use past simple tense naming. For example collides, colliding, and collided. This will allow users greater control over customizing collision and overlap event response!

The past tense functions pressed and held will become alternatives to released. Their old functionality will be replaced by the new presses and holds functions. presses will return true on the first frame the user presses an input. holds will return true when the users holds an input for 12 frames (by default). The mouse functions for detecting hovering will be changed to hovers, hovering, and hovered.

Here is an example of the new collides function in action. The "old way" will still work too.

// old way
player.collide(block, () => {
	block.remove();
});

// new way
if (player.collides(block)) {
	block.remove();
}

Note my preference for if statements over callbacks. if statements are taught at the beginning of any intro level programming class and are more readable.

In the preceding example, collides returns true on the first frame a sprite collides with a target sprite, colliding returns true while a sprite collides with a target, and collided returns true on the frame when contact between the sprite and target end. overlaps, overlapping, and overlapped functions will be available too.

You all can thank my wife for these naming changes, she's an English teacher!

What is a Sprite? (more info) : August 25, 2022

A Sprite in p5play is a container that can have visual components AND/OR a physics body.

The new and old versions of p5play use this design for the Sprite class, and so do other modern game engines, even though historically the term "sprite" is more narrowly defined as a bit-map image that could move across a screen via hardware rendering. Kids don't have that preconception though.

As teachers we must always be willing to challenge our preconceptions about how things should work and be open to the possibilities of how things could work. Building on what was to teach what is. The JavaScript language itself embodies this philosophy, having received major feature updates in recent years. The JavaScript community is also, for better or worse, filled with independent thinkers that use varied programming paradigms. Thus, JavaScript programs made this year may look significantly different from JS programs made 10 years ago. That's not true for other languages like Java, which hasn't significantly changed since Java 8.

In this Dev Log I'm going to give really in-depth and technical explanations of stuff that I've seen is innate for kids learning p5play.

When young students want to create a sprite, the assumption I based p5play's new design on is that they also want a collider, so creating a sprite adds a box collider to the sprite by default. Not a super radical design choice for a physics based game engine right?

Throughout the codebase, I tried to use sensible defaults so that users can write less code. The code users write should feel impactful. I wanted to avoid forcing users to write boilerplate code which they don't understand. For example, students learning Java have to first write or at least get a template of a Java class that has a static void main method, simply for them to write their first line of code!

class MyClass {

  public static void main(String[] args) {
    System.out.print("Hello World!");
  }
}

That's a load of nonsense just to print "Hello World!" in the console. Java teachers have to hand wave away this complexity at first, telling students that they'll learn what it means in the future, which is not a good experience. Also because students don't understand it, Java's main method can be hard for students to memorize. Better designed languages like C# do not require command line programs to be inside of a main method of a class, C# encapsulates user's code behind the scenes during compilation.

On the first few Sprite reference pages I have mini-examples that don't use any inputs in the Sprite constructor or functions. My goal is to make the p5play learning curve as flat as possible by decreasing the knowledge and skill barriers required for students to start using p5play. Multi-parameter constructors and functions, even rigid ones with only one set of valid inputs, require the user to memorize how inputs must be ordered or refer to documentation. They're inherently not as readable and beginner friendly as verbosely setting property values. Also students are familiar with variables from Algebra class. They already understand that = sets the value of a variable.

sprite = new Sprite();
sprite.width = 40;
sprite.height = 20;

p5play can seamlessly replace the sprite's default box collider with a circle collider if the user sets a diameter for the sprite. This happens "behind the scenes" in the diameter setter.

let sprite = new Sprite();
sprite.diameter = 50;

This was not possible before JS property getters and setters were introduced! This is a bit remarkable for us seasoned programmers but it's irrelevant to beginner programmers. They think, "Why wouldn't setting the sprite's diameter make it have a circle collider?". Remember, they have no intellectual baggage regarding what properties, constructors, and methods are. Yet, when I learned how getters and setters could be used in JavaScript, I had to replace my old mental model I had from using Java that functions were for doing stuff and properties were for storing stuff.

Another interesting use of getters and setters in p5play is with the custom draw function. Users can set custom draw functions for sprites like this:

sprite.draw = () => {
	rect(0, 0, 30, 50);
};

The draw function can then be used to draw sprites in the p5.js draw loop:

sprite.draw();

But wait, sprite.draw, is actually a getter/setter and it's not getting and setting the same function! sprite.draw sets the user's custom sprite._draw function and sprite.draw gets the sprite._display function, which does some stuff before and after calling the default or user's custom sprite._draw function.

// p5play source

get draw() {
  return this._display;
}

set draw(val) {
  this._draw = val;
}

Beginner programmers using p5play don't need to know or care that this is happening behind the scenes but it's necessary for the user not to re-implement all the code that's in the display function. In previous versions of p5play, custom draw functions for sprites were achieved by having the user actually set the sprite.draw property but then use drawSprite(sprite); which used the private sprite.display function for displaying the sprite, which is a bit cumbersome by comparison.

Another clever use of getters and setters is with the ani property. Here's the old paradigm for changing the sprite's animation:

sprite.changeAnimation('jump');

And here's the new paradigm:

sprite.ani = 'jump';

Isn't that cool?

I also deprecated setSpeed which used to take speed and direction angle parameters.

sprite.setSpeed(5, 90);

Now users can set speed and direction separately, and the line order is not important!

sprite.speed = 5;
sprite.direction = 90;

Anyways, back to the Sprite constructor, which can be used to define the sprite's collider. p5play sprites don't need to have a p5.Image or SpriteAnimation.

let ball = new Sprite(x, y, d);

An image or animation can be added to a sprite after it gets created.

let ball = new Sprite(x, y, d);
ball.image = img;

The Sprite constructor can also be used with a loaded image or animation, from which it can derive the width and height of the collider.

let box = new Sprite(img, x, y);

...or both the visuals and physics collider of the sprite can be specified in the constructor.

let box = new Sprite(img, x, y, w, h);
let ball = new Sprite(img, x, y, d);

The flexibility that the Sprite constructor offers might seem unusual for older programmers that are used to more rigid APIs but I'd argue this flexibility is quite nice for kids learning how to code.

Yet, just because you can fully load the constructor, doesn't mean you should...

//                  (img/ani, x, y,  w,  h, collideType);
let box = new Sprite(ballImage, 0, 70, 10, 30, 'static');

If you think the Sprite constructor is able to do too much, you can just use it for less. Its flexibility means you can use it the way you want. Remember that it's not even strictly necessary to add any inputs to the Sprite constructor at all. The amount of valid use combinations that the Sprite constructor has isn't easily definable, but it doesn't need to be. Part of what makes JavaScript so great is that methods and constructors don't need to have a rigid set of valid inputs.

For the Sprite constructor I think it's pretty easy to remember the order of the inputs, which is the same regardless of the collider shape:

(animation, position, dimensions, colliderType)
                     width, height             // box
                       diameter                // circle
                  sideLength, polygonName      // regular polygons

Whenever possible I tried to keep functions simple and flexible. However, for SpriteAnimation Spritesheet atlases I went with the more standard "options in an object" approach, which I think works well for something that has sooo many different options: {width, height, size, pos, line, x, y, frames, delay, rotation}. Imagine how bad this would be:

//                                           x, y,   w, h, frames, delay, rotation)
sprite.addAni('imageFolder/spritesheet.png', 4, 6, null, null, 11, 50, 90); // BAD!!

The "options in an object" approach is great because the options can be in any order and it's easy to read what the numbers are defining.

sprite.addAni('imageFolder/spritesheet.png', { pos: [4, 6], frames: 11, delay: 50, rotation: 90 });

But this approach does require students to understand objects, so there are two other modes for loading animations, sequence and list, that don't require objects are simpler to use.

When designing the Sprite constructor I didn't want to impose upon beginners the necessity of learning object syntax or a bunch of magic constructor spells like ImageSprite, BoxSprite, CircleSprite, BoxImageSprite, CircleImageSprite, ChainSprite, PolygonSprite etc.

If you're really dying to have something like this...

new BoxSprite(x, y, w, h);
new CircleSprite(x, y, d);
new ChainSprite(x, y, lines);
new PolygonSprite(x, y, lines);

...then you could always add this to your code:

window.BoxSprite = Sprite;
window.CircleSprite = Sprite;
window.ChainSprite = Sprite;
window.PolygonSprite = Sprite;

BUT I think those constructor names would be misleading because a Sprite object can have its physics body swapped out or removed. A BoxSprite won't necessarily always have a box shape collider. In a student's game they might want the sprite to have a collider sometimes and sometimes not have a collider. The way I see it, its like if you had a Legs class you wouldn't want RunningLegs, SwimmingLegs, and JumpingLegs constructors, you just use a Legs object to do all those different actions. You may see the different collider shape types more akin to CowLegs, ChickenLegs, GooseLegs, etc. which is understandable but from a technical standpoint that's the wrong way to think about the Sprite class. A sprite is a sprite regardless of what collider shape its physics body has.

So anyway there's my super long explanation on why the Sprite constructor is the way it is. Hope you enjoyed it. 😅

New Logo : August 14, 2022

old logo ↗️

The old p5play logo was very cute, and I'm still going to keep the little asterisk guy in the examples, but I figured it didn't communicate what I'm trying to have p5play v3 represent. I still want the logo to look fun but not too childish. p5play has grown up a bit! The new logo communicates with its shape that this version of p5play has some more advanced features but it is simple too, using only two flat colors.

The Importance of Documenting p5play : August 14, 2022

I've been working on the reference documentation for the p5play website over the past few days. I created mie (mini editor) to embed p5.js sketches with instance mode previews. Even with 22 running on one page, the performance is great!

I'm making these reference pages because most documentation pages are just a big info dump and not a good way for beginners to learn about code libraries. When I first started teaching CS, I constantly made the mistake of giving my students too much information at once. I learned that I have to give kids the minimum amount of information at each step in the learning process so they have space to think of questions and thus be more interested in seeking out answers. Teachers are storytellers in a sense. Giving too much info at once is ruining the story but going too slow/being too pedantic is boring too. I want my reference pages to be an online textbook that people can use to interactively learn about p5play at their own pace.

On a personal note, one of my motivations for making p5play v3, apart from the old versions being outdated, was so that I could provide young programmers the kind of extensive documentation that I wanted, but never got, from Apple when I tried to learn how to use their SpriteKit game engine for iOS back in 2014. Objective-C was already considered a crusty old language at the time, so that certainly didn't help. But Apple's documentation was so awful that if I was a less stubborn determined person I probably would've quit programming altogether. I did end up realizing that SpriteKit was too slow and debugging was impossible (you couldn't have more than a dozen debug sprites on the screen without it crashing or frame crawling), so I quit using it. I was duped by Apple's Developer's Conference videos of SpriteKit and their promise of native performance advantages. Also I found that using Xcode was, and still is, terrible, which is a sentiment many developers agree with. If I could go back in time, I would've learned Unity instead, since their documentation and tutorials are great.

Fortunately I didn't let that awful experience with SpriteKit put me off programming in general! I learned a valuable lesson, for creatives like myself, the developer experience is much more important than resulting performance.

Why p5play? : August 13, 2022

While I was working on p5play v3 over the past few months I had a lot of time to think about why students should learn how to use p5play.

First of course, using p5play is a great way for educators to introduce students to Object Oriented programming and JavaScript is commonly taught in AP CS Principles and similar courses.

Secondly, students can just focus on the code. Everything in a p5play sketch has to be created programmatically. Although I do think having a visual level editor for placing sprites would be nice, it's also nice that students don't also have to learn how to use a big editor app. For example, Unity has tons of advanced features and huge menus that can overwhelm beginners. Users don't have to install anything to get started with p5play, since it runs in web browsers.

Thirdly, while Unity is great for experienced programmers that can type out a bunch of code before testing it, beginners benefit from being able to easily test each line they write. Beginners don't trust that they're doing the right thing unless they can see it work. I've heard from students with older computers that having to repeatedly wait, even a few seconds, for Unity to compile C# and load their game really hurts the beginner dev experience. By comparison, the immediacy of running JS is a huge asset.