#Do My Lua Programming
Explore tagged Tumblr posts
Text
[vent tp pls ignore my insanity.]
#lua talks#i think im just not meant for accounting#like no matter how hard i try and study and think i understand somehow i still mess it up in the end#or maybe im just salty i wrote down the right answer and then went back to change it bc im a dumbass#either way moderately disheartening to feel so bad at the thing im “supposed” to be good at#like i probably did better on this one than my 60 in finance but i know i shouldve done better#and now ive just lost all motivation to study lmfao#bc like whats the point !#im gonna know the answer and still get it wrong!#its doesnt help that rn im doing an art elective and my art prof was like why didnt u study art in uni instead#and im like haha ! i truly wish ! i was not here doing accounting !#sometimes i convince myself this was the right choice but i can only cope so long bc i hated working and i hate this program#i hate accounting and i hate money#little bonus i hate my parents for making me go into accounting yay !#anyways thats all for today hehe
1 note
·
View note
Text
Trying this again:
I'll do programming odd jobs for cheap. $10/hour. You'll be given an estimate of how long it'll take to complete upfront.
Languages I can program in without prep:
Python
Java
Javascript
CSS
HTML
Lua
C++
C#
Rust
Ruby
Processing
Languages I know just a bit of but could learn more easily
R
Matlab
C
PHP
I can pick up other languages for $100/language
I can also do light remote sysadmin, so like setting up a Mastodon instance, setting up an nginx server for web hosting, stuff like that
Email: [email protected]
Samples of my work below
420 notes
·
View notes
Text
YouTube Downloads through VLC: Step by Step
[EDIT: I've been receiving reports for some time now that this method no longer works. I suspect something about the switch to YouTube Music as a separate app, and/or YouTube's ongoing attempts to force Chrome use, broke the compatibility with the Github version of youtube.luac -- I haven't managed to look into whether there's an updated working version out there yet. Sorry!]
So this guide to easily downloading off YouTube is super helpful, but there's enough important information hidden in the reblogs that (with the permission of OP @queriesntheories ) I'm doing a more step-by-step version.
Please note: these downloads will be in YouTube quality. My test video download is coming through at 360p, even though the video I'm starting from is set to 720p. They're legible, but they won't look great on a TV. For high visual quality, you'll want to seek out other methods.
This guide is written for Windows 10, since that's what I can test on. It's been tested on Firefox, Chrome, and Edge (which is a Chromium browser, so the method should work in other Chromium browsers too). So far, I haven't tracked down a way to use this download method on mobile.
BASIC KNOWLEDGE:
I'll try to make this pretty beginner-friendly, but I am going to assume that you know how to right-click, double-click, navigate right-click menus, click-and-drag, use keyboard shortcuts that are given to you (for example, how to use Ctrl+A), and get the URL for any YouTube video you want to download.
You'll also need to download and install one or more programs off the internet using .exe files, if you don't have these programs already. Please make sure you know how to use your firewall and antivirus to keep your computer safe, and google any names you don't recognize before allowing permission for each file. You can also hover your mouse over each link in this post to make sure it goes where I'm saying it will go.
YOU WILL NEED:
A computer where you have admin permissions. This is usually a computer you own or have the main login on. Sadly, a shared computer like the ones at universities and libraries will not work for this.
Enough space on your computer to install the programs listed below, if you don't have them already, and some space to save your downloaded files to. The files are pretty small because of the low video quality.
A simple text editing program. Notepad is the one that usually comes with Windows. If it lets you change fonts, it's too fancy. A notepad designed specifically to edit program code without messing it up is Notepad++, which you can download here.
A web browser. I use Firefox, which you can get here. Chrome or other Chrome-based browsers should also work. I haven't tested in Safari.
An Internet connection fast enough to load YouTube. A little buffering is fine. The downloads will happen much faster than streaming the entire video, unless your internet is very slow.
VLC Media Player, which you can get here. It's a free player for music and videos, available on Windows, Android, and iOS, and it can play almost any format of video or audio file that exists. We'll be using it for one of the central steps in this process.
If you want just the audio from a YouTube video, you'll need to download the video and then use a different program to copy the audio into its own file. At the end of this post, I'll have instructions for that, using a free sound editor called Audacity.
SETUP TO DOWNLOAD:
The first time you do this, you'll need to set VLC up so it can do what you want. This is where we need Notepad and admin permissions. You shouldn't need to repeat this process unless you're reinstalling VLC.
If VLC is open, close it.
In your computer's file system (File Explorer on Windows), go to C:\Program Files\VideoLAN\VLC\lua\playlist
If you're not familiar with File Explorer, you'll start by clicking where the left side shows (C:). Then in the big main window, you'll double-click each folder that you see in the file path, in order - so in this case, when you're in C: you need to look for Program Files. (There will be two of them. You want the one without the x86 at the end.) Then inside Program Files you're looking for VideoLAN, and so forth through the whole path.
Once you're inside the "playlist" folder, you'll see a lot of files ending in .luac - they're in alphabetical order. The one you want to edit is youtube.luac which is probably at the bottom.
You can't edit youtube.luac while it's in this folder. Click and drag it out of the playlist folder to somewhere else you can find it - your desktop, for instance. Your computer will ask for admin permission to move the file. Click the "Continue" button with the blue and yellow shield.
Now that the file is moved, double-click on it. The Microsoft Store will want you to search for a program to open the .luac file type with. Don't go to the Microsoft Store, just click on the blue "More apps" below that option, and you'll get a list that should include your notepad program. Click on it and click OK.
The file that opens up will be absolutely full of gibberish-looking code. That's fine. Use Ctrl+A to select everything inside the file, then Backspace or Delete to delete it. Don't close the file yet.
In your web browser, go to https://github.com/videolan/vlc/blob/master/share/lua/playlist/youtube.lua
Click in the part of the Github page that has a bunch of mostly blue code in it. Use Ctrl+A to select all of that code, Ctrl+C to copy it, then come back into your empty youtube.luac file and use Ctrl+P to paste the whole chunk of code into the file.
Save the youtube.luac file (Ctrl+S or File > Save in the upper left corner of the notepad program), then close the notepad program.
Drag youtube.luac back into the folder it came from. The computer will ask for admin permission again. Give it permission.
Now you can close Github and Notepad. You're ready to start downloading!
HOW TO DOWNLOAD:
First, get your YouTube link. It should look something like this: https://www.youtube.com/watch?v=abc123DEF45 If it's longer, you can delete any extra stuff after that first set of letters and numbers, but you don't have to.
Now open VLC. Go to Media > Open Network Stream and paste your YouTube link into the box that comes up. Click Play. Wait until the video starts to play, then you can pause it if you want so it's not distracting you during the next part.
(If nothing happens, you probably forgot to put youtube.luac back. coughs)
In VLC, go to Tools > Codec Information. At the bottom of the pop-up box you'll see a long string of gibberish in a box labeled Location. Click in the Location box. It won't look like it clicked properly, but when you press Ctrl+A, it should select all. Use Ctrl+C to copy it.
In your web browser, paste the entire string of gibberish and hit Enter. Your same YouTube video should come up, but without any of the YouTube interface around it. This is where the video actually lives on YouTube's servers. YouTube really, really doesn't like to show this address to humans, which is why we needed VLC to be like "hi I'm just a little video player" and get it for us.
Because, if you're looking at the place where the video actually lives, you can just right-click-download it, and YouTube can't stop you.
Right-click on your video. Choose "Save Video As". Choose where to save it to - I use my computer's built-in Music or Videos folders.
Give it a name other than "videoplayback" so you can tell it apart from your other downloads.
The "Save As Type" dropdown under the Name field will probably default to MP4. This is a good versatile video format that most video players can read. If you need a different format, you can convert the download later. (That's a whole other post topic.)
Click Save, and your video will start downloading! It may take a few minutes to fully download, depending on your video length and internet speed. Once the download finishes, congratulations! You have successfully downloaded a YouTube video!
If you'd like to convert your video into a (usually smaller) audio file, so you can put it on a music player, it's time to install and set up Audacity.
INSTALLING AUDACITY (first time setup for audio file conversion):
You can get Audacity here. If you're following along on Windows 10, choose the "64-bit installer (recommended)". Run the installer, but don't open Audacity at the end, or if it does open, close it again.
On that same Audacity download page, scroll down past the installers to the "Additional resources". You'll see a box with a "Link to FFmpeg library". This is where you'll get the add-on program that will let Audacity open your downloaded YouTube video, so you can tell it to make an audio-only file. The link will take you to this page on the Audacity support wiki, which will always have the most up-to-date information on how to install the file you need here.
From that wiki page, follow the link to the actual FFmpeg library. If you're not using an adblocker, be careful not to click on any of the ads showing you download buttons. The link you want is bold blue text under "FFmpeg Installer for Audacity 3.2 and later", and looks something like this: "FFmpeg_5.0.0_for_Audacity_on_Windows_x86.exe". Download and install it. Without this, Audacity won't be able to open MP4 files downloaded from YouTube.
CONVERTING TO AUDIO:
Make sure you know where to find your downloaded MP4 video file. This file won't go away when you "convert" it - you'll just be copying the audio into a different file.
Open up Audacity.
Go to File > Open and choose your video file.
You'll get one of those soundwave file displays you see in recording booths and so forth. Audacity is a good solid choice if you want to teach yourself to edit soundwave files, but that's not what we're here for right now.
Go to File > Export Audio. The File Name will populate to match the video's filename, but you can edit it if you want.
Click the Browse button next to the Folder box, and choose where to save your new audio file to. I use my computer's Music folder.
You can click on the Format dropdown and choose an audio file type. If you're not sure which one you want, MP3 is the most common and versatile.
If you'd like your music player to know the artist, album, and so forth for your audio track, you can edit that later in File Manager, or you can put the information in with the Edit Metadata button here. You can leave any of the slots blank, for instance if you don't have a track number because it's a YouTube video.
Once everything is set up, click Export, and your new audio file will be created. Go forth and listen!
#reference#vlc media player#youtube downloader#youtube#uh what other tags should i use idk#how to internet#long post
230 notes
·
View notes
Note
What would I specifically need to have downloaded to make ears like in your pinned post? Can I do any shape of ear? Are they playable? I just want my sona in Minecraft but hair obviously doesn’t give me what I need. (Also I’m not experienced in advanced skin making but I just want to know so I can poke around online with more specific questions later)
OKAY SO . the model in my pinned post is completely playable if you have figura. it's a mod for fabric (and maybe other mod loaders, unsure.) that's client side but if other people have figura they can also see the model you're using. There may be server setup needed, but i'm unsure- i'm not the admin of the server i use it on.
essentially you can add additional pieces to your skin/model with blockbench (3D modelling program tailored to minecraft, essentially.) or just make one from scratch! You can make virtually anything you put your mind to. Blockbench has a site with tutorials and such, and Figura has a dedicated discord server where you can learn relatively anything you need to know.
so, in short: - Yes, any shape of ears! it is playable as long as you have the figura mod in your game. This also includes any animations or scripting you want to add to your model. - What you need: Blockbench, Figura, and Lua (the coding language, for scripting, if you intend to do that.)
that's the most basic answer i can give without over-explaining too much. good luck on making your sona!
#not mc#hopefully this is understandable!#feel free to send a followup ask or reblog with more questions
42 notes
·
View notes
Text
It is not my Stuff I am just animated.
The idea and art style itself @mxboxlocks
She has a very good comic in which wilson and wynslow end up on the island of fairies.
The first page
I hope I don't offend you with this little animation. I just saw your post today and I saw this drawing.
The post

And then I felt like I had to do this. This is funny. I don't know the lua programming language. I can only do animation. No matter how difficult the programming language is. With patience and perseverance, you can learn everything.
I hope you like the animation.
Btw: Yes, I know the hearts are falling behind.
33 notes
·
View notes
Text
i need more mutuals who are into coding and engineering!! more info under the cut!!
I planned to become an electrical engineer like my stepdad but then I decided to change my path to programming. I'm currently studying at technikum (<- wikipedia link so I don't have to explain the whole polish learning system), programmer major.
this year I have exams from web development (10th Jan - theory, 16th Jan - practical exams) and next year I have exams from App development (both mobile and desktop).
I know C family languages, Java, Python and those ones I am currently using. I also know a bit of Kotlin and I think I will continue learning it.
For web dev I know HTML and CSS ofc but also PHP and JS.
Planning on learning more languages I can use for App and operating system development as well as just to know them cause I want to after this year's exams!
my learning list:
Lua (I heard it's easy but I can't really get myself to read anything about this atm idk why)
Ruby
Assembly
Rust
As for electrical engineering I don't know much tbh but I would like to learn! I just used CAD programs for technical drawings (dad taught me some basic things when I was still thinking about going his path) helped my dad fix things on his Solar farm, houses of our neighbors and I made a few very simple circuits for fun a few years ago. Now I'm mostly focused on programming but since I learned most of the things I need for exams I have more time to do whatever I want now!
I'd like to get to know more people so I can share and mostly learn new things since even though I'm coding for years I consider myself a beginner and I am a total beginner when it comes to electrical engineering.
I'm willing to be friends or at least mutuals with anyone who codes or makes websites or is in STEM! no matter what your specialty/interest is exactly and no matter if you are a total beginner or a professional ^__^
I'd also like to have some mutuals who are into old web development and retro computing!!!!!!!!
edit: I forgot but I'm also interested in physics and quantum physics
#dear.diaryŕ¨ŕ§#stemblr#women in stem#stem#programming#coding#web development#web design#old web#retrocomputing#computing#engineering#technology#techindustry#computers#computer#templeos#terry a davis#terry davis#linux#open source#github#calculus#physics#quantum physics#mathblr#mathematics
38 notes
·
View notes
Note
Any advice on getting in to game dev? Like from a very basic basic level. I love seeing the games you make and it’s making we wanna try do my own
Do it! It's a top tier hobby!
I've been using love2d lately and I feel like it'd be a decent place to start!
I wrote a super super basic love2d script for you! Download love2d, then download this lua file, then put the lua file in a folder, then drag the folder onto love.exe!
Congratulations! You're running a love2d program! No compiling or anything required! Move the little cat emoticon around with the arrow keys!
There are definitely love2d tutorials online, but you can also just modify that script (I use Notepad++, but you could even just open it in the notepad that comes with windows) to make it do different stuff and do a google search each time there's something new that you want to know how to do. I find that's usually more appealing than following a step by step guide (that could just be me being weird tho lmao idk).
As for other options:
Unity is probably the most popular option rn, but it's proprietary (godot exists though as basically a free and open source equivelant) and pretty bloated for making a little 2d game (I really feel like making something simple and 2d is the best way to get started).
GameMaker and RPG Maker (also proprietary) could be cool too if you're really intimidated by needing to code (how do kids these days even learn html anymore now that Neopets is out of fashion?) and would feel more at home navigating menus and things like that (you can still end up writing code in either of them eventually though).
27 notes
·
View notes
Text
I’ve been thinking about this for a little while — something I’d want to do if I had the time and money would be to design a Motorola 68000-powered tiny (10” or smaller) laptop. Modern CMOS 68K implementations are very power-efficient and decently well-suited to handheld and portable devices (see: TI-92 series), and if combined with a crisp, modern monochrome OLED display, could get you days of continuous usage without needing a recharge! Add a few megabytes of RAM, some peripherals (IDE/CF controller, ISA or S-100 slots, DMA controller, SPI bus, RS-232 port, SD or CF slot, PS/2 port for a mouse, text mode + hires monochrome video card, etc…), and you have a nice, flexible system that can be rarely charged, doesn’t require ventilation, and can be just thick enough to fit the widest port or slot on it.
The main issue would be software support: nearly all existing operating systems that ran on a 68K were either intended for very specific hardware (Classic Mac OS, AmigaOS) or required more than a flat 68000 (NetBSD, Linux, or any other UNIX requiring MMU paging). So, it would probably end up being a custom DOS with some multitasking and priv level capability, or perhaps CP/M-68K (but I don’t know how much software was ever written for that — also, it provides a “bare minimum” hardware abstraction of a text-mode console and disk drive). A custom DOS, with a nice, standard C library capable of running compiled software, would probably be the way to go.
The software question perhaps raises another, harder question: What would I use this for? Programming? Then I’d want a text editor, maybe vi(m) or something like that. OK. Vim just needs termcap/(n)curses or whatever to draw the text, and not much else. That’s doable! You’d just need to provide text-mode VT100 emulation and termcap/curses should “just work” without too much issue. I like writing C, so I’d need a compiler. Now, I’m assuming this simplistic operating system would be entirely written in a combination of assembly language (to talk to hardware and handle specific tasks such as switching processes and privilege management and whatnot) and C (to handle most of the logic and ABI). I could probably cross-compile GCC and be good to go, aside from handling library paths and executable formats that don’t comply with POSIX (I have no intention of making yet another UNIX-like system). Hopefully, most other command-line software (that I actually use) will follow suit without too much trouble. I don’t know how much work it is to get Python or Lua to a new platform (though NetBSD on the 68K already supports both), but Python (or Lua) support would bring a lot of flexibility to the platform. Despite me being a Python hater, I must admit it’s quite an attractive addition.
What about graphics? All the software I’ve mentioned so far is text-mode only, yet historical 68K-based systems like the Mac and Amiga had beautiful graphics! Implementing X11 would be a massive pain in the ass, considering how much it relies on UNIXy features like sockets (not to mention the memory usage), and I really don’t want Wayland to have anything to do with this. I guess I’d have to roll my own graphics stack and window manager to support a WIMP interface. I could copy Apple’s homework there: they also made a monochrome graphics interface for a M68K configured with a handful of MiB of RAM. I could probably get a simple compositing window manager (perhaps make it tiling for a modern vibe ;3). Overall, outside of very simple and custom applications, functionality with real software would be problematic. Is that a big problem? Maybe I want an underpowered notebook I can put ideas and simple scripts down on, then flesh them out more fully later on. An operating system allowing more direct access to the hardware, plus direct framebuffer access, could yield some pretty cool graphing/basic design utility.
I’d need a way to communicate with the outside world. An RS-232 UART interface, similar to the HP-48 calculator (or the TI-92’s GraphLink, only less proprietary) would help for providing a remote machine language monitor in the early stages, and a real link to a more powerful (and networked) machine later on. I think real networking would defeat the purpose of the machine — to provide a way to remove yourself from modern technology and hardware, while retaining portability, reliability, and efficiency of modern semiconductor manufacturing techniques. Giving it a CF or SD slot could provide a nice way to move files around between it and a computer, maybe providing software patches. A floppy drive would be amazing: it would provide a way to store code and text, and would be just about the right storage size for what I want to do. Unfortunately, there’s not really a good way to maintain the size of the laptop while sticking a 3.5” (or worse, 5.25”) floppy drive in the middle of it. To my knowledge, 3.5” floppy drives never got thin enough to properly fit with all the other expansion slots, socketed components, and user-modifiable parts I’d want. A completely solid-state design would likely be the best option.
Anyway, uhh… I hope this made some semblance of sense and I don’t sound insane for going on a rant about building a modern computer with a 1979 CPU.
5 notes
·
View notes
Note
Would you possibly give us the cliffnotes for what the plan was for the rest of this fic? I've been following early on (like 2015??), it really truly has an important space in my heart. I even have it saved offline in case there was ever a time where it would be removed!! Even if it will never be finished, I still like to re-read it, maladaptive daydream about it, etc. I'd love to know where it would have gone in the end!! Or if you would release any drafts or whatever have you!!
I will write down what I remember! I think I've lost any outlines we had but:
Yes, Alistair was the shitty neighbor the entire time. It was so silly, we were obsessed with it.
After Liv leaves his hospital room, she spends days locked in her house, triggered bc of her parents and just generally shut down.
When she opens her door and sees Alistair standing there, she basically blue screens because he's a) real b) extremely good-looking and c) he's her what? I don't remember much about what comes next but I know they spend a few hours hashing things out, talking, putting together all the context of their friendship (discussing everyone they have in common, lmao).
Liv goes back to running away from her problems, tells him she's had all of her fears about being with him confirmed for her.
Ultimately, he talks her into giving him a chance to at least take her on a date. She walks him to her front door and he asks if he can kiss her. They do, and he's very convincing. :)
They spend a few days(?) flirting through windows at each other. For their date, he sets up a scavenger hunt for her to find the location for the date? And it was going to be so cute, he has her go to Andrastea to find a clue to the next location, which is Druffy's, and so on and so forth, he leaves clues at the places he's recommended to her. The final date I think was going to be at the beach. Liv ultimately realizes that she'd rather be with him and risk losing him than be alone and dreaming of police lights forever. It gets steamy. :)
After that, I mostly remember the two of them doing a tour around to all their friends and giving the update that they're a thing. Happy endings abound!
There was going to be an epilogue where they go on a road trip with Cullen and Lua, and we planned to commission different artists to make polaroids of them having a good time. Thedas Space Program 4 lyfe.
We really were at the finish line, and I'm so sad we didn't get to tell the rest of it. I have some small things like playlists, previously unposted sketches, and snippets that I'll leave in this Google Doc if you still want more. Emrys may have files I don't, so I welcome her to share them if she wants to.
I also welcome anyone who wants to play in the space to go buck wild, and if you do I would love to see them if you message me @bucket-fucker. I'm replaying Liv's canon as we speak, and I hope to write her again, I still had much more to say!
Thank you all for showing interest in my lil OC. And thank you for still caring. It's been a blast, and I appreciate you all.
-A.
22 notes
·
View notes
Note
Yarn Cat is really cute and cool! Do you have any advice you’d give to someone looking to give Pico-8 programming a go?
thanks so much! i had a lot of fun making it
so first i'll say, i think pico-8 is a great platform/system/thingy to make games with, and there are plentiful resources to help teach anyone all the things they need to know; nerdy teachers' guide is pretty comprehensive, and lazy devs on youtube also covers a lot, including things like genre and scope choices to avoid newbie pitfalls. pico-8 code is pretty bare bones and therefore easy to pickup the basics of, if you've never done ANY programming before, following some beginners guides for lua (on which pico-8 is based) is probably a good idea, to at least wrap your head around variables, if statements, for loops, and functions; that's all you'll really need.
then my advice bifurcates: if you haven't already cut your teeth making a few games, i'd encourage you to just dive in, mess around, and have fun with no expectations of making a good or even releasable game. i think a seriously pervasive trap a lot of creative people fall into is feeling the need to do it right the first time; agonising over making their first project in a new art medium the perfect one that has what it takes to become an indie darling, and in the process, they waste a lot of creative energy and learn little because they're not doing all the reckless experimentation needed to really learn.
the first step towards being successful in a medium is knowing yourself and how you create in it, which you'll never pick up first attempt at a thing, it takes iteration and reflection. people think that undertale/stardew valley/cave story struck gold on the first try, but i can guarantee you that's just because all the awkward experimentation of their lone devs didn't make it to the spotlight, or even release.
i made at least 3-4 (poorly) finished games long before yarn cat, and even in the 20 years i wasn't really 'trying to make games', i'd still tinker around with ideas that took my fancy to see what worked. even yarn cat started out as one of those messing around projects, until i landed on some fun mechanics that had potential and got serious. so if you're staring out, don't put pressure on yourself to do great, just have fun as if you were doodling in the margins of your school books, and see what you learn about how you make games.
on the other side; if you've already done all the messing around in game dev with a bunch of prototypes and such and want to make a pico-8 game, my advice is this: be earnest about it.
the bbs is full of proofs-of-concept and weekend game jam demos with 4 levels and things that feel more like shitposts and memes than games, because i think people see the limitations of pico-8 and then don't take seriously any project they create in it. to me, it's not just "limitations breed creativity" that makes pico-8 great, but that the limitations are a breath of fresh, focused air in this day and age. when you can download unity or whatever and have gigabytes of assets and scripts and built-in verlet integration physics engines to texture-map flat meshes for your faux 2d pixel-art game.... well, a blank canvas is intimidating, but an infinite blank canvas stretching off into the void when you have an expectation to use 4k textures and run at 120fps is soul crushing. whereas pico-8 says: there is a hard cap of code size, do your best within that.... and i think unfortunately, most people chose to use only a tiny section of it for a small sketch of a game, or push it to do things it's not meant to (yes it runs doom) so they can flex their code skills. i would implore you to do neither; just look at what is possible, feel out what you think you can do within it, and cram in as much of that in there as possible to make the best, fullest game you can.
i very easily could have made yarn cat 8 levels long with a silly party time ending and joke dialogue or something, but i wanted to do more - in gameplay and mood - and have a sort of thematic/emotional through line and a sense of melancholy journey far from the comforts of home... whether or not anyone sees it in the end product, i reached for it, rather than stopping short because "pico-8 is so limited anyway". conversely; there's only enough space on the map builder to have 32 screens in there; but i squeezed out just over double that by using some pretty basic 'unpack arbitrary data from a string' techniques, and ended up almost exactly landing on the code size limit, and if you look at multi-cart loading there is much, much more you can achieve... but honestly, having that limit there in front of me made it possible to finish at all. with an infinite canvas i probably would have quit without finishing a third through, but knowing there was a finite space to fill made me excited to see what i could fill it with, and make it count.
anyway, i ramble.
basically; have fun, experiment, see what you can do, and do what you can. and as with any art; know what you want to say, how you plan to say it, and ask if the thing you've made so far says that at every step along the way.
10 notes
·
View notes
Note
How much use does Rust (the programming language) see in game development?
I haven't ever seen it used. Game dev still primarily runs on C++ to do the heavy lifting. We often build internal tools with C#, Python, or Perl. Some games will run interpreted scripting languages like Lua for designers to script out encounters and such. RPG Maker utilizes Ruby or Javascript for its scripting language, depending on the version. To my knowledge, nobody uses Rust, Swift, or Go in game development.
[Join us on Discord] and/or [Support us on Patreon]
Got a burning question you want answered?
Short questions: Ask a Game Dev on Twitter
Short questions: Ask a Game Dev on BlueSky
Long questions: Ask a Game Dev on Tumblr
Frequent Questions: The FAQ
13 notes
·
View notes
Text
this is enough
Summary: yusei had a massive problem, and he tries to enlist his friends to help.
Rating: G
Ships: Yusei Fudo/Aki Izayoi
Notes: written for @ygoadvent.
read on ao3 / support me on kofi / join my discord (18+)
What would she want for Christmas?
Yusei had little experience with buying gifts. Normally he'd make gifts - usually through welding or some delicate paper stars... perhaps even a simple game he'd programmed. This wasn't like before, though. He'd had a relationship before, sure, but it wasn't like this. This was something that filled him and made him feel oh so alive. He didn't dread coming home - he hadn't known that was possible before. So whatever he got Aki for Christmas had to be perfect, like she was. Perhaps it had been a mistake, however, to ask Jack to subtly ask for her wishlist. Really - that was on him. He'd known Jack for most of his life. "She insisted she didn't need anything," Jack had said, looking almost angry about it. "No matter what I said! I don't know why you don't just ask her directly. Why do I have to be your messenger?"
Really, he should've expected as much. Aki had said similar whenever he asked what she wanted - she didn't need anything. Sometimes it was complete with a 'I'm just happy you didn't die in the Ark Cradle; I don't need anything else' which didn't really help with his guilt about that. The look on all his friends' faces when he'd come back home alive had been enough to last him a lifetime. "Jack, what exactly did you say to her?"
"I said that people are going to want to buy her gifts for the holidays and she should just make it easier for the rest of us," Jack said, rolling his eyes as if this was the obvious thing to do. He crossed his arms, huffing. "She had the nerve to say all of us being in one place for the holidays would make her happy. Can you believe her?"
Yusei just sighed. "Did Carly manage any better?"
"No," Jack replied, and then he smirked. "But I at least know what Carly wants for Christmas."
With that, Jack left before Yusei could show him a different kind of "deck the halls" leaving him to settle for throwing his wrench at the wall.
"I tried, man," Crow said over the phone. "All she would say is that if we're all home for the holidays, she'd be happy. How do you think I felt? I'm stuck here in Austria for this tournament. It's not enough that I hear it from the kids and Sherry, I gotta hear it from Aki too?"
Currently, Sherry was watching over the orphanage, and she was overwhelmed by it. Normally she had Crow around, but well, when Crow was offered this chance, he had to take it. At the time, Sherry had expressed her sincere support but Yusei got the feeling that sometimes she deeply regretted not taking Martha's offer to take over. Yusei decided to not mention any of this to Crow. "Sorry, she just misses you," Yusei said, glancing behind him at the door in case Aki walked in. "We all do. Are you at least winning?"
"Yeah, absolutely," Crow said with a laugh. "These Austrian Duelists don't have shit on me, you know. Tell Aki to not worry - I'll try to be home for the holidays. Hey! I guess that covers a gift for her! Ah, shit, I need to go. Later!"
The line went dead, and Yusei frowned. He wasn't sure how he felt about Crow finding a gift for Aki before he did.
"I think you're taking this too seriously, Yusei," Luka said from the bench, tilting her head and kicking her feet. She'd tossed her book bag on the floor, and was mainly just watching him fix Lua's Duel Board from yet another wreck. No matter how many times Yusei had told Lua to be careful, he kept managing to get into some pretty bad accidents. Yusei dreaded the day that Lua was old enough for a proper Duel Runner - he could only imagine the injuries. "I'm sure Aki will like whatever you get her."
"You don't know what she wants either, do you?"
Luka let out a frustrated sigh, flopping backwards. "She said that I shouldn't worry about what to get any of you guys! What am I supposed to do with that?" She sat back up, staring intensely at Yusei. "Are you going to tell me what you want for Christmas?"
Yusei grinned, shaking his head. "I don't need you to get me anything, Luka," he said, checking the balance on the board. Was there a way he could ensure that Lua could at least get into fewer accidents? Besides just outright taking the Duel Board away from him, anyway. "All I need from the two of you is to not get hurt."
"Ugh, you're worse than Aki," she groaned, rolling her eyes. "She told me to not tell you this, but she would give me her wish list in exchange for yours." She got up, storming over to him with a glare. "So are you going to hand it over or am I just not going to be able to get you Aki's wish list?"
So she was playing the same game he was. It snapped into place - why no one else seemed to be able to get her wish list out of her. The problem with this, however, is that Yusei genuinely had nothing he wanted for Christmas besides seeing Aki happy and knowing his friends were safe and sound. He frowned at this, staring at the Duel Board but not really focused on it anymore. "I don't have anything I want," he admitted. "I just want my friends to be happy."
Luka stomped her foot. "You and Aki were made for each other," she yelled before storming off.
He supposed that was fair. That just left one problem: what was he going to get Aki for Christmas?
#faithshipping#faithshipping: canon divergent#5ds: canon divergent#ygoadvent2024#series: yusei and aki's first holiday season#rating: g
11 notes
·
View notes
Note
how do u make ur own programming language??
PERSISTENCE .
if youre making an interpreted language it's 2 major parts: the compiler (which is tied to the lexer and its abstract syntax tree), and the virtual machine (which may also include a garbage collector). I started with what syntax and features i wanted the language to be at its core and built the AST / lexer to fit it. Then from there the compiler + virtual machine were built piece by piece based on what was needed. Then finally the garbage collector was made.
Go look at the source for Lua and Duktape (the open source embeddable JS implementation); they were my inspirations
Also the hardest part by far was the garbage collector. It's on rewrite number 6 and I hope i never have to touch it again
8 notes
·
View notes
Text
[ID: drawing of the "i guess we doing circles" meme with a cube machine with an opening rolling out logos of Lua programming language, Blender, Wonderdraft and Krita on an assemblyline, behind the line is a simple drawing of a catgirl with one eye. She says "I guess we doing programming 3d modeling cartography digital art" with everything except digital art crossed out. The machine is labeled Brain END ID]
My brain has been jumping from things a lot this year. What's interesting is the hyperfocus i devote to each thing for like a month or two but the interests never go away and i still do map making, 3d modeling and programming from time to time but like the like hyperfocus shifts.
Brain decides it wants to do a thing and I go "oh I guess we doing this now"
11 notes
·
View notes
Text
Balatro-Inspired Spinning Card Tweetcart Breakdown
I recently made a tweetcart of a spinning playing card inspired by finally playing Balatro, the poker roguelike everybody is talking about.
If you don't know what a tweetcart is, it's a type of size-coding where people write programs for the Pico-8 fantasy console where the source code is 280 characters of less, the length of a tweet.
I'm actually not on twitter any more, but I still like 280 characters as a limitation. I posted it on my mastodon and my tumblr.
Here's the tweetcart I'm writing about today:
And here is the full 279 byte source code for this animation:
a=abs::_::cls()e=t()for r=0,46do for p=0,1,.025do j=sin(e)*20k=cos(e)*5f=1-p h=a(17-p*34)v=a(23-r)c=1+min(23-v,17-h)%5/3\1*6u=(r-1)/80z=a(p-.2)if(e%1<.5)c=a(r-5)<5and z<u+.03and(r==5or z>u)and 8or 8-sgn(h+v-9)/2 g=r+39pset((64+j)*p+(64-j)*f,(g+k)*p+(g-k)*f,c)end end flip()goto _
This post is available with much nicer formatting on the EMMA blog. You can read it here.
You can copy/paste that code into a blank Pico-8 file to try it yourself. I wrote it on Pico-8 version 0.2.6b.
I'm very pleased with this cart! From a strictly technical perspective I think it's my favorite that I've ever made. There is quite a bit going on to make the fake 3D as well as the design on the front and back of the card. In this post I'll be making the source code more readable as well as explaining some tools that are useful if you are making your own tweetcarts or just want some tricks for game dev and algorithmic art.
Expanding the Code
Tweetcarts tend to look completely impenetrable, but they are often less complex than they seem. The first thing to do when breaking down a tweetcart (which I highly recommend doing!) is to just add carriage returns after each command.
Removing these line breaks is a classic tweetcart method to save characters. Lua, the language used in Pico-8, often does not need a new line if a command does not end in a letter, so we can just remove them. Great for saving space, bad for readability. Here's that same code with some line breaks, spaces and indentation added:
a=abs ::_:: cls() e=t() for r=0,46 do for p=0,1,.025 do j=sin(e)*20 k=cos(e)*5 f=1-p h=a(17-p*34) v=a(23-r) c=1+min(23-v,17-h)%5/3\1*6 u=(r-1)/80 z=a(p-.2) if(e%1<.5) c= a(r-5) < 5 and z < u+.03 and (r==5 or z>u) and 8 or 8-sgn(h+v-9)/2 g=r+39 pset((64+j)*p+(64-j)*f,(g+k)*p+(g-k)*f,c) end end flip()goto _
Note: the card is 40 pixels wide and 46 pixels tall. Those number will come up a lot. As will 20 (half of 40) and 23 (half of 46).
Full Code with Variables and Comments
Finally, before I get into what each section is doing, here is an annotated version of the same code. In this code, variables have real names and I added comments:
[editor's note. this one came out terribly on tumblr. Please read the post on my other blog to see it]
This may be all you need to get a sense of how I made this animation, but the rest of this post will be looking at how each section of the code contributes to the final effect. Part of why I wanted to write this post is because I was happy with how many different tools I managed to use in such a small space.
flip() goto_
This pattern shows up in nearly every tweetcart:
::_:: MOST OF THE CODE flip()goto _
This has been written about in Pixienop's Tweetcart Basics which I highly recommend for anybody curious about the medium! The quick version is that using goto is shorter than declaring the full draw function that Pico-8 carts usually use.
Two Spinning Points
The card is drawn in rows starting from the top and going to the bottom. Each of these lines is defined by two points that move around a center point in an elliptical orbit.
The center of the top of the card is x=64 (dead center) and y=39 (a sort of arbitrary number that looked nice).
Then I get the distance away from that center that my two points will be using trigonometry.
x_dist = sin(time)*20 y_dist = cos(time)*5
Here are those points:
P1 adds x_dist and y_dist to the center point and P2 subtracts those same values.
Those are just the points for the very top row. The outer for loop is the vertical rows. The center x position will be the same each time, but the y position increases with each row like this: y_pos = row+39
Here's how it looks when I draw every 3rd row going down:
It is worth noting that Pico-8 handles sin() and cos() differently than most languages. Usually the input values for these functions are in radians (0 to two pi), but in Pico-8 it goes from 0 to 1. More info on that here. It takes a little getting used to but it is actually very handy. More info in a minute on why I like values between 0 and 1.
Time
In the shorter code, e is my time variable. I tend to use e for this. In my mind it stands for "elapsed time". In Pico-8 time() returns the current elapsed time in seconds. However, there is a shorter version, t(), which obviously is better for tweetcarts. But because I use the time value a lot, even the 3 characters for t() is often too much, so I store it in the single-letter variable e.
Because it is being used in sine and cosine for this tweetcart, every time e reaches 1, we've reached the end of a cycle. I would have liked to use t()/2 to slow this cart down to be a 2 second animation, but after a lot of fiddling I wound up being one character short. So it goes.
e is used in several places in the code, both to control the angle of the points and to determine which side of the card is facing the camera.
Here you can see how the sine value of e controls the rotation and how we go from showing the front of the card to showing the back when e%1 crosses the threshold of 0.5.
Drawing and Distorting the Lines
Near the top and bottom of the loop we'll find the code that determines the shape of the card and draws the horizontal lines that make up the card. Here is the loop for drawing a single individual line using the code with expanded variable names:
for prc = 0,1,.025 do x_dist = sin(time)*20 y_dist = cos(time)*5 ... y_pos = row+39 pset( (64+x_dist)*prc + (64-x_dist)*(1-prc), (y_pos+y_dist)*prc + (y_pos-y_dist)*(1-prc), color) end
You might notice that I don't use Pico-8's line function! That's because each line is drawn pixel by pixel.
This tweetcart simulates a 3D object by treating each vertical row of the card as a line of pixels. I generate the points on either side of the card(p1 and p2 in this gif), and then interpolate between those two points. That's why the inner for loop creates a percentage from 0 to 1 instead of pixel positions. The entire card is drawn as individual pixels. I draw them in a line, but the color may change with each one, so they each get their own pset() call.
Here's a gif where I slow down this process to give you a peek at how these lines are being drawn every frame. For each row, I draw many pixels moving across the card between the two endpoints in the row.
Here's the loop condition again: for prc = 0,1,.025 do
A step of 0.025 means there are 40 steps (0.025 * 40 = 1.0). That's the exact width of the card! When the card is completely facing the camera head-on, I will need 40 steps to make it across without leaving a gap in the pixels. When the card is skinnier, I'm still drawing all 40 pixels, but many of them will be in the same place. That's fine. The most recently drawn one will take priority.
Getting the actual X and Y position
I said that the position of each pixel is interpolated between the two points, but this line of code may be confusing:
y_pos = row+39 pset( (64+x_dist)*prc + (64-x_dist)*(1-prc), (y_pos+y_dist)*prc + (y_pos-y_dist)*(1-prc), color)
So let's unpack it a little bit. If you've ever used a Lerp() function in something like Unity you've used this sort of math. The idea is that we get two values (P1 and P2 in the above example), and we move between them such that a value of 0.0 gives us P1 and 1.0 gives us P2.
Here's a full cart that breaks down exactly what this math is doing:
::_:: cls() time = t()/8 for row = 0,46 do for prc = 0,1,.025 do x_dist = sin(time)*20 y_dist = cos(time)*5 color = 9 + row % 3 p1x = 64 + x_dist p1y = row+39 + y_dist p2x = 64 - x_dist p2y = row+39 - y_dist x = p2x*prc + p1x*(1-prc) y = p2y*prc + p1y*(1-prc) pset( x, y, color) end end flip()goto _
I'm defining P1 and P2 very explicitly (getting an x and y for both), then I get the actual x and y position that I use by multiplying P2 by prc and P1 by (1-prc) and adding the results together.
This is easiest to understand when prc is 0.5, because then we're just taking an average. In school we learn that to average a set of numbers you add them up and then divide by how many you had. We can think of that as (p1+p2) / 2. This is the same as saying p1*0.5 + p2*0.5.
But the second way of writing it lets us take a weighted average if we want. We could say p1*0.75 + p2*0.25. Now the resulting value will be 75% of p1 and 25% of p2. If you laid the two values out on a number line, the result would be just 25% of the way to p2. As long as the two values being multiplied add up to exactly 1.0 you will get a weighted average between P1 and P2.
I can count on prc being a value between 0 and 1, so the inverse is 1.0 - prc. If prc is 0.8 then 1.0-prc is 0.2. Together they add up to 1!
I use this math everywhere in my work. It's a really easy way to move smoothly between values that might otherwise be tricky to work with.
Compressing
I'm using a little over 400 characters in the above example. But in the real cart, the relevant code inside the loops is this:
j=sin(e)*20 k=cos(e)*5 g=r+39 pset((64+j)*p+(64-j)*f,(g+k)*p+(g-k)*f,c)
which can be further condensed by removing the line breaks:
j=sin(e)*20k=cos(e)*5g=r+39pset((64+j)*p+(64-j)*f,(g+k)*p+(g-k)*f,c)
Because P1, P2 and the resulting interpolated positions x and y are never used again, there is no reason to waste chars by storing them in variables. So all of the interpolation is done in the call to pset().
There are a few parts of the calculation that are used more than once and are four characters or more. Those are stored as variables (j, k & g in this code). These variables tend to have the least helpful names because I usually do them right at the end to save a few chars so they wind up with whatever letters I have not used elsewhere.
Spinning & Drawing
Here's that same example, but with a checker pattern and the card spinning. (Keep in mind, in the real tweetcart the card is fully draw every frame and would not spin mid-draw)
This technique allows me to distort the lines because I can specify two points and draw my lines between them. Great for fake 3D! Kind of annoying for actually drawing shapes, because now instead of using the normal Pico-8 drawing tools, I have to calculate the color I want based on the row (a whole number between0 and 46) and the x-prc (a float between 0 and 1).
Drawing the Back
Here's the code that handles drawing the back of the card:
h=a(17-p*34) v=a(23-r) c=1+min(23-v,17-h)%5/3\1*6
This is inside the nested for loops, so r is the row and p is a percentage of the way across the horizontal line.
c is the color that we will eventually draw in pset().
h and v are the approximate distance from the center of the card. a was previously assigned as a shorthand for abs() so you can think of those lines like this:
h=abs(17-p*34) v=abs(23-r)
v is the vertical distance. The card is 46 pixels tall so taking the absolute value of 23-r will give us the distance from the vertical center of the card. (ex: if r is 25, abs(23-r) = 2. and if r is 21, abs(23-r) still equals 2 )
As you can probably guess, h is the horizontal distance from the center. The card is 40 pixels wide, but I opted to shrink it a bit by multiplying p by 34 and subtracting that from half of 34 (17). The cardback just looks better with these lower values, and the diamond looks fine.
The next line, where I define c, is where things get confusing. It's a long line doing some clunky math. The critical thing is that when this line is done, I need c to equal 1 (dark blue) or 7 (white) on the Pico-8 color pallette.
Here's the whole thing: c=1+min(23-v,17-h)%5/3\1*6
Here is that line broken down into much more discrete steps.
c = 1 --start with a color of 1 low_dist = min(23-v,17-h) --get the lower inverted distance from center val = low_dist % 5 --mod 5 to bring it to a repeating range of 0 to 5 val = val / 3 --divide by 3. value is now 0 to 1.66 val = flr(val) --round it down. value is now 0 or 1 val = val * 6 --multiply by 6. value is now 0 or 6 c += val --add value to c, making it 1 or 7
The first thing I do is c=1. That means the entire rest of the line will either add 0 or 6 (bumping the value up to 7). No other outcome is acceptable. min(23-v,17-h)%5/3\1*6 will always evaluate to 0 or 6.
I only want the lower value of h and v. This is what will give it the nice box shape. If you color the points inside a rectangle so that ones that are closer to the center on their X are one color and ones that are closer to the center on their Y are a different color you'll get a pattern with clean diagonal lines running from the center towards the corners like this:
You might think I would just use min(v,h) instead of the longer min(23-v,17-h) in the actual code. I would love to do that, but it results in a pattern that is cool, but doesn't really look like a card back.
I take the inverted value. Instead of having a v that runs from 0 to 23, I flip it so it runs from 23 to 0. I do the same for h. I take the lower of those two values using min().
Then I use modulo (%) to bring the value to a repeating range of 0 to 5. Then I divide that result by 3 so it is 0 to ~1.66. The exact value doens't matter too much because I am going round it down anyway. What is critical is that it will become 0 or 1 after rounding because then I can multiply it by a specific number without getting any values in between.
Wait? If I'm rounding down, where is flr() in this line: c=1+min(23-v,17-h)%5/3\1*6?
It's not there! That's because there is a sneaky tool in Pico-8. You can use \1 to do the same thing as flr(). This is integer division and it generally saves a 3 characters.
Finally, I multiply the result by 6. If it is 0, we get 0. If it is 1 we get 6. Add it to 1 and we get the color we want!
Here's how it looks with each step in that process turned on or off:
A Note About Parentheses
When I write tweetcarts I would typically start by writing this type of line like this: c=1+ (((min(23-v,17-h)%5)/3) \1) *6
This way I can figure out if my math makes sense by using parentheses to ensure that my order of operations works. But then I just start deleting them willy nilly to see what I can get away with. Sometimes I'm surprised and I'm able to shave off 2 characters by removing a set of parentheses.
The Face Side
The face side with the diamond and the "A" is a little more complex, but basically works the same way as the back. Each pixel needs to either be white (7) or red (8). When the card is on this side, I'll be overwriting the c value that got defined earlier.
Here's the code that does it (with added white space). This uses the h and v values defined earlier as well as the r and p values from the nested loops.
u=(r-1)/80 z=a(p-.2) if(e%1<.5) c= a(r-5) < 5 and z < u+.03 and (r==5 or z>u) and 8 or 8-sgn(h+v-9)/2
Before we piece out what this is doing, we need to talk about the structure for conditional logic in tweetcarts.
The Problem with If Statements
The lone line with the if statement is doing a lot of conditional logic in a very cumbersome way designed to avoid writing out a full if statement.
One of the tricky things with Pico-8 tweetcarts is that the loop and conditional logic of Lua is very character intensive. While most programming language might write an if statement like this:
if (SOMETHING){ CODE }
Lua does it like this:
if SOMETHING then CODE end
Using "then" and "end" instead of brackets means we often want to bend over backwards to avoid them when we're trying to save characters.
Luckily, Lua lets you drop "then" and "end" if there is a single command being executed inside the if.
This means we can write
if(e%1 < 0.5) c=5
instead of
if e%1 < 0.5 then c=5 end
This is a huge savings! To take advantage of this, it is often worth doing something in a slightly (or massively) convoluted way if it means we can reduce it to a single line inside the if. This brings us to:
Lua's Weird Ternary Operator
In most programming language there is an inline syntax to return one of two values based on a conditional. It's called the Ternary Operator and in most languages I use it looks like this:
myVar = a>b ? 5 : 10
The value of myVar will be 5 if a is greater than b. Otherwise is will be 10.
Lua has a ternary operator... sort of. You can read more about it here but it looks something like this:
myVar = a>b and 5 or 10
Frankly, I don't understand why this works, but I can confirm that it does.
In this specific instance, I am essentially using it to put another conditional inside my if statement, but by doing it as a single line ternary operation, I'm keeping the whole thing to a single line and saving precious chars.
The Face Broken Out
The conditional for the diamond and the A is a mess to look at. The weird syntax for the ternary operator doesn't help. Neither does the fact that I took out any parentheses that could make sense of it.
Here is the same code rewritten with a cleaner logic flow.
--check time to see if we're on the front half if e%1 < .5 then --this if checks if we're in the A u=(r-1)/80 z=a(p-.2) if a(r-5) < 5 and z < u+.03 and (r==5 or z>u) then c = 8 --if we're not in the A, set c based on if we're in the diamond else c = 8-sgn(h+v-9)/2 end end
The first thing being checked is the time. As I explained further up, because the input value for sin() in Pico-8 goes from 0 to 1, the midpoint is 0.5. We only draw the front of the card if e%1 is less than 0.5.
After that, we check if this pixel is inside the A on the corner of the card or the diamond. Either way, our color value c gets set to either 7 (white) or 8 (red).
Let's start with diamond because it is easier.
The Diamond
This uses the same h and v values from the back of the card. The reason I chose diamonds for my suit is that they are very easy to calculate if you know the vertical and horizontal distance from a point! In fact, I sometimes use this diamond shape instead of proper circular hit detection in size-coded games.
Let's look at the line: c = 8-sgn(h+v-9)/2
This starts with 8, the red color. Since the only other acceptable color is 7 (white), tha means that sgn(h+v-9)/2 has to evaluate to either 1 or 0.
sgn() returns the sign of a number, meaning -1 if the number is negative or 1 if the number is positive. This is often a convenient way to cut large values down to easy-to-work-with values based on a threshold. That's exactly what I'm doing here!
h+v-9 takes the height from the center plus the horizontal distance from the center and checks if the sum is greater than 9. If it is, sgn(h+v-9) will return 1, otherwise -1. In this formula, 9 is the size of the diamond. A smaller number would result in a smaller diamond since that's the threshold for the distance being used. (note: h+v is NOT the actual distance. It's an approximation that happens to make a nice diamond shape.)
OK, but adding -1 or 1 to 8 gives us 7 or 9 and I need 7 or 8.
That's where /2 comes in. Pico-8 defaults to floating point math, so dividing by 2 will turn my -1 or 1 into -0.5 or 0.5. So this line c = 8-sgn(h+v-9)/2 actually sets c to 7.5 or 8.5. Pico-8 always rounds down when setting colors so a value of 7.5 becomes 7 and 8.5 becomes 8. And now we have white for most of the card, and red in the space inside the diamond!
The A
The A on the top corner of the card was the last thing I added. I finished the spinning card with the card back and the diamond and realized that when I condensed the whole thing, I actually had about 50 characters to spare. Putting a letter on the ace seemed like an obvious choice. I struggled for an evening trying to make it happen before deciding that I just couldn't do it. The next day I took another crack at it and managed to get it in, although a lot of it is pretty ugly! Luckily, in the final version the card is spinning pretty fast and it is harder to notice how lopsided it is.
I mentioned earlier that my method of placing pixels in a line between points is great for deforming planes, but makes a lot of drawing harder. Here's a great example. Instead of just being able to call print("a") or even using 3 calls to line() I had to make a convoluted conditional to check if each pixel is "inside" the A and set it to red if it is.
I'll do my best to explain this code, but it was hammered together with a lot of trial and error. I kept messing with it until I found an acceptable balance between how it looked and how many character it ate up.
Here are the relevant bits again:
u=(r-1)/80 z=a(p-.2) if a(r-5) < 5 and z < u+.03 and (r==5 or z>u) then c = 8
The two variables above the if are just values that get used multiple times. Let's give them slightly better names. While I'm making edits, I'll expand a too since that was just a replacement for abs().
slope = (r-1)/80 dist_from_center = abs(p-.2) if abs(r-5) < 5 and dist_from_center < slope+.03 and (r==5 or dist_from_center>slope) then c = 8
Remember that r is the current row and p is the percentage of the way between the two sides where this pixel falls.
u/slope here is basically how far from the center line of the A the legs are at this row. As r increases, so does slope (but at a much smaller rate). The top of the A is very close to the center, the bottom is further out. I'm subtracting 1 so that when r is 0, slope is negative and will not be drawn. Without this, the A starts on the very topmost line of the card and looks bad.
z/dist_from_center is how far this particular p value is from the center of the A (not the center of the card), measured in percentage (not pixels). The center of the A is 20% of the way across the card. This side of the card starts on the right (0% is all the way right, 100% is all the way left), which is why you see the A 20% away from the right side of the card.
These values are important because the two legs of the A are basically tiny distance checks where the slope for a given r is compared against the dist_from_center. There are 3 checks used to determine if the pixel is part of the A.
if a(r-5) < 5 and z < u+.03 and (r==5 or z>u) then
The first is abs(r-5) < 5. This checks if r is between 1 and 9, the height of my A.
The second is dist_from_center < slope+.03. This is checking if this pixel's x distance from the center of the A is no more than .03 bigger than the current slope value. This is the maximum distance that will be considered "inside" the A. All of this is a percentage, so the center of the A is 0.20 and the slope value will be larger the further down the A we get.
Because I am checking the distance from the center point (the grey line in the image above), this works on either leg of the A. On either side, the pixel can be less than slope+.03 away.
Finally, it checks (r==5 or dist_from_center>slope). If the row is exactly 5, that is the crossbar across the A and should be red. Otherwise, the distance value must be greater than slope (this is the minimum value it can have to be "inside" the A). This also works on both sides thanks to using distance.
Although I am trying to capture 1-pixel-wide lines to draw the shape of the A, I could not think of a cleaner way than doing this bounding check. Ignoring the crossbar on row 5, you can think about the 2nd and 3rd parts of the if statement essentially making sure that dist_from_center fits between slope and a number slightly larger than slope. Something like this:
slope < dist_from_center < slope+0.03
Putting it Together
All of this logic needed to be on a single line to get away with using the short form of the if statement so it got slammed into a single ternary operator. Then I tried removing parentheses one at a time to see what was structurally significant. I wish I could say I was more thoughtful than that but I wasn't. The end result is this beefy line of code:
if(e%1<.5)c=a(r-5)<5and z<u+.03and(r==5or z>u)and 8or 8-sgn(h+v-9)/2
Once we've checked that e (our time value) is in the phase where we show the face, the ternary operator checks if the pixel is inside the A. If it is, c is set to 8 (red). If it isn't, then we set c = 8-sgn(h+v-9)/2, which is the diamond shape described above.
That's It!
Once we've set c the tweetcart uses pset to draw the pixel as described in the section on drawing the lines.
Here's the full code and what it looks like when it runs again. Hopefully now you can pick out more of what's going on!
a=abs::_::cls()e=t()for r=0,46do for p=0,1,.025do j=sin(e)*20k=cos(e)*5f=1-p h=a(17-p*34)v=a(23-r)c=1+min(23-v,17-h)%5/3\1*6u=(r-1)/80z=a(p-.2)if(e%1<.5)c=a(r-5)<5and z<u+.03and(r==5or z>u)and 8or 8-sgn(h+v-9)/2 g=r+39pset((64+j)*p+(64-j)*f,(g+k)*p+(g-k)*f,c)end end flip()goto _
I hope this was helpful! I had a lot of fun writing this cart and it was fun to break it down. Maybe you can shave off the one additional character needed to slow it down by using e=t()/2 a bit. If you do, please drop me a line on my mastodon or tumblr!
And if you want to try your hand at something like this, consider submitting something to TweetTweetJam which just started! You'll get a luxurious 500 characters to work with!
Links and Resources
There are some very useful posts of tools and tricks for getting into tweetcarts. I'm sure I'm missing many but here are a few that I refer to regularly.
Pixienop's tweetcart basics and tweetcart studies are probably the single best thing to read if you want to learn more.
Trasevol_Dog's Doodle Insights are fascinating, and some of them demonstrate very cool tweetcart techniques.
Optimizing Character Count for Tweetcarts by Eli Piilonen / @2DArray
Guide for Making Tweetcarts by PrincessChooChoo
The official documentation for the hidden P8SCII Control Codes is worth a read. It will let you do wild things like play sound using the print() command.
I have released several size-coded Pico-8 games that have links to heavily annotated code:
Pico-Mace
Cold Sun Surf
1k Jump
Hand Cram
And if you want to read more Pico-8 weirdness from me, I wrote a whole post on creating a networked Pico-8 tribute to Frog Chorus.
18 notes
·
View notes
Text
Hi, help me make a living (Looking for programming work)
Portfolio Contact Donate
One of the two projects I've been a part of is on a sudden hiatus and it's left my pay hundreds short of what I'd usually make to cover rent and bills. And since my car is currently out of commission preventing me from traveling, I'm looking for dev work I can do remotely for the time being. The lead of the other project I'm on has agreed to pay me more at the end of the month, but it'll start to affect them financially after too long, so I don't want to keep that going.
I have programming experience with many game engines (what I name off is in no particular order); Godot, MonoGame, Unity, and plenty of custom-made solutions. Additionally, I have experience writing C, C++, C#, GDScript, Rust, Lua, and more. The time I've put into engine programming and porting things has helped me become very versatile, and it's gone hand in hand with my strong attention to detail and ability to identify patterns. While I specialize in dealing with graphics and audio programming, I can comfortably and confidently touch most any part of the stack if needed. Check the portfolio link at the top of this post to see a sample of my skills and projects.
If you're a team member or lead looking for someone new to bring on, and think my skill set and experience would benefit your work, don't hesitate to contact me via email with the link at the top of here!
If not, share this post wherever you can, and see if others know anyone that needs a programmer. If you would still like to help me financially in the meantime, I have a PayPal you can donate to, link's at the top.
Thank you for reading this through <3
9 notes
·
View notes