Episode Transcript
Available transcripts are automatically generated. Complete accuracy is not guaranteed.
Speaker 1 (00:01):
Hello everyone and
welcome to another episode of
Code and the Code Encoders.
Who Code it?
I'm your host, drew Bragg, andI'm thrilled today to be joined
by Amir Rajan from DragonRubyRuby community as a whole.
Anyone who's not familiar withyou, could you do a brief
introduction about what you do?
Speaker 2 (00:18):
I'm Amir Rajan and
the short version is I'm a code
hobo and I just kind of work onrandom things and sometimes
interesting things happen.
I'm a code hobo and I just kindof work on random things and
sometimes interesting thingshappen.
And one of those interestingthings happens to be DragonRuby
Game Toolkit, which is a gameengine built on Ruby, and I've
been doing indie gamedevelopment like commercial,
full-time indie game developmentwith Ruby for the past 10 years
now, and so I've got sixcommercial titles, my claim to
(00:41):
fame being a port of a dark room, which hit the number one spot
in the iOS app store, number twoon Android has a console
release and I just last yearreleased to Steam, and so I'm a
game dev using Ruby.
Speaker 1 (00:55):
That's super awesome
and not something you hear every
day.
I also love code hobo as like aword for describing like I
don't work on one particularthing, I just move from code
base to code base.
That's awesome I am sointerested in.
I'm not a game developer.
If I ever had anythingresembling free time, I would
(01:15):
love to give it a try, butthat's a lot of math and that
was how I got into programmingwas cheating on math tests, so
maybe not.
But also the idea of being ableto use Ruby for game
development is so awesome.
So was it?
You were a game developer andwanted to use Ruby, or you were
Ruby-ous and wanted to buildgames, and that's how everything
was born.
Speaker 2 (01:36):
Ruby, especially
dynamic languages, specifically
Ruby.
People talk about Ruby and theysay it's a beautiful language
or it's an expressive languageand there's like an artistic
flair to the language that whenI started doing game dev with
Ruby like versus app developmentit's like working with oil
paints, I think of.
Like statically type languagesare like C sharp, you're working
with marble and a chisel, youmake a mistake and the
(01:59):
correction is so difficult andthe exploration's much harder.
But with Ruby it's just workingwith oil paints.
You just kind of work with thecanvas and nudge things around.
And the dynamic capabilities ofthe language, the DSL, the
expressivity of the language itreally works really well for
game dev and a lot of thosenuances is what I discovered
when starting to build gameswith the language itself.
Speaker 1 (02:21):
So how did that come
to be?
As far as I'm a Rubyist, I wantto build games.
Okay, now what?
Speaker 2 (02:28):
What was the spark
that was like I can do it this
way, or like was it just nonstopinvestigation until I was doing
corporate development right outof college and I got really
burned out and I was like I'mjust going to take a sabbatical
and just kind of do my own thingfor a little bit, live off the
savings, and then, once I'mrefreshed, then go back into a
cubicle writing tax software.
(02:48):
And so I'm going to build agame.
And there's a product calledRuby Motion which allows you to
use Ruby for building iOS apps.
And I was like, okay, I can doiOS development.
And I found a game on web-basedgame called A Dark Room it's
like an incremental kind ofASCII-based roguelike built by
Michael Townsend and I emailedhim and said, hey, let me port
(03:08):
this over to iOS and see if wecan do something.
So then I used RubyMotion Rubyand started porting this game
over.
And then that's kind of how itstarted.
And then I was like, wow, gamedev is actually kind of fun.
It's interesting, surprise,surprise.
And so after that I startedbuilding additional commercial
titles, especially with thesuccess of the first game.
And then it came into like, okay, well, with respect to Ruby
(03:31):
motion and just building gameswith Ruby, you're right, it was
kind of like that exploratoryprocess where you make a lot of
mistakes, trying to discoverlike patterns, and I had a
mental like do, a huge mentalshift from like app development
to game development and therewere a lot of challenges there.
But then I think it was like,yeah, from 2013 to 2017 was when
(03:51):
I built a lot of commercialtitles and then I was like, okay
, I'm seeing these patternsemerge and I'm seeing the things
that I like about Ruby and Idon't like about existing game
engines and those eventuallycodified into Dragon Ruby.
So like from 2013 to 2017 wasjust building commercial games
and the onus of beingcross-platform and then
(04:14):
releasing to the Nintendo Switchwas that final straw that broke
the camel's back.
I was like, okay, I need toreally think about what this
environment will look like.
And then all those lessons Ilearned just got extracted or
codified into the engine thatyou see today.
That's so cool.
Speaker 1 (04:30):
That's such a neat
starting with this app-based
game and then moving into.
Okay, we're going to go fullsteam ahead, building a game
engine that becomes DragonRuby.
Speaker 2 (04:42):
The really
interesting part, especially in
this domain, is like Ruby's avery mature language, especially
for app development, and sothere's a lot of established
patterns and a lot of ways youdo things, like of course,
you're going to build yourcontroller or your MVC
application in this specific way.
And with respect to game dev,there's established patterns,
but they're always in thecontext of I'm using a
(05:03):
statically typed, rigid languagethat can't do what ruby can do,
and so trying to just takethose same patterns and apply to
the language ended.
I was like wait, this feelsexcessive, like there's no
reason to have, uh, all theselike different aspects of
boilerplate and they establishpatterns.
Speaker 1 (05:19):
And then that
discovery process was it has
that same feel of upheaval, fromlike using spring to rails
right, look at all the stuff I'mnot doing kind of vibe to it so
the way that the episodesnormally work because that ended
up being like a really longintro because I was just so
excited to start picking yourbrain about dragon ruby but
normally the way that the showworks is I will ask you three
(05:41):
questions in addition to likethe nine I just asked you what
are you working on?
Yeah, what are you working on?
What kind of blockers do youhave?
It could be a current blocker.
Or if you don't have one, likewhat's a recent blocker, how'd
you go around solving it?
And then the last one is what'ssomething cool, new or
interesting that you've recentlylearned or discovered or built?
It doesn't have to be codingrelated I have a feeling it
(06:04):
might be in this case but itdoesn't have to be so, just to
make sure we don't get lost,because I will go down so many
rabbit holes if we don't stickto the program.
Amir, what are you?
Speaker 2 (06:15):
working on?
What am I working on?
So I have a game inpre-production and it's called
the Little Probe and have youread we Are Legion, we Are Bob.
No, it's a great book.
So think, hitchhiker's Guide tothe Galaxy meets Von Neumann
Probes.
So Von Neumann Probes is thisidea of your own consciousness
is put into a machine and thenthat machine can replicate.
(06:36):
So then you start replicatingyour consciousness across time
and then can search the universe.
So the Little Probe is ametroidvania where you're a Von
Neumann probe exploring a deadcivilization and a dead planet
and you get power-ups and allthe different facets of
platforming and kind of thinkMetroid, right, it's a
Metroidvania, and that's whatI'm working on.
(06:56):
As far as, like, the hurdles,the biggest hurdle it's math,
it's always math, it's alwaysmath, it's always math.
That's one of the reasons why Ido 2D games is because the math
is way simpler.
I was afraid of math, but itreally isn't that bad.
You need to have a good trickfoundation.
So if you know trigonometry,trigonometry, geometry and
algebra, those things togethergives you pretty much 80% of
(07:18):
what you need for building 2Dgames.
So the most recent hurdle I hadwas ramps Ramp collision like
how do you move up a ramp butkeep the player pinned to the
ground while gravity is beingapplied and stuff.
But I figured it out, I figuredit out.
There are quite a few blogposts out there that kind of
show different approaches tousing ramp collision and the
(07:38):
math around that.
But that was my most recenthurdle.
Speaker 1 (07:42):
Yeah, that's a
blocker that not a lot of people
have said on this show, becausemost of my guests do app
development.
What do you think the biggestdifference between the mental
model you use for doing appdevelopment and the mental model
you use for game development is?
Speaker 2 (08:00):
I think the biggest
difference is you have long
running state when it comes to agame and that state is updated
at 60 times a second.
So if you think like acontroller action, it feels kind
of transaction.
You got the HTTP request comingin, you rehydrate, you have
some short running state for thelife of that function, maybe
you have some session stuff, butoutside of that you're in and
(08:22):
out and that's it.
But for game dev, this gameobject, this singleton, stays
around for hours.
It could pretend you knowsomeone having a long play
session that ends up stayingaround for hours and then the
facet of it being at 60 framesper second or running this
function at so many times.
When it comes to debugging, thecommon debugging approaches are
(08:44):
like the testing approaches thatwe use for app dev.
It's much harder for game devbecause you make an action and
it's 80 frames later that thebug or like some compounding
stuff ends up surfacing to yourapp.
And where the bug appears isnot necessarily the frame where
the cause exists.
So you're not dealing with onlybacktraces but time traces to
try to figure out wheresomething breaks.
(09:05):
So yeah, your approaches totesting and regression.
It's different.
Speaker 1 (09:10):
What do you do for
testing in game dev?
Can you unit test a game?
Can you do a system test?
Because I can think of how Itest a web-based application,
but, like you just said, whenyou're testing a web-based
application, you're testingessentially a part of a
transaction, right?
That sounds like it would be alot more difficult to test bits
(09:30):
of the game in isolation.
But maybe that is how you do it.
How does that work?
Speaker 2 (09:35):
So I think for
turn-based games where it's kind
of like a tactical if you getlike a tactical top-down RPG or
something like that a lot of thetesting practices that you
would use for app dev mostlyapply right, and the reason for
that is that you can codify thatslice of time.
You can say okay, here's mysetup, here's where the player
is, are they close to the enemy?
Then the attack option shouldshow up there.
(09:57):
What gets really tricky andwhat gets much harder to test is
real time games.
So anything with physics inthere becomes a little bit
trickier.
Because I've had situationswith that ramp collision.
I'm going to have nightmaresabout ramp collision for a very
long time, but it feels great.
Right, the player jumps, heruns up the map, he runs down
dashes, all that stuff.
(10:17):
But there's a situation whereif I do a frame perfect input of
pressing forward and then atthe same time press jump, he
would tunnel through the rampand fall out the other end.
And it's like, okay, I have toreplicate a frame perfect input
of hitting left, then right andjump at the exact same time on
the same frame and then he dropsdown through the ramp.
(10:38):
This is ridiculous.
So as far as applying that.
The cool thing is that and itgoes to this idea of the status
quo of game engines today theyjust accept that this is
something that you have to dealwith, though they know I'm
putting a replay system intoDragonRuby so you can actually
say all right, I'm going tostart a replay.
It resets your game and thenyou fiddle around with it until
(10:59):
you get the bug and it capturesthat input history.
You can have the replay runevery time you save code.
So DragonRuby is all hot loaded, because Ruby is amazing like
that.
And so what I would do is Iwould say, okay, well, what if I
set the gravity to zero beforeI execute the jump function?
So I'll set the gravity to zeroand it would automatically run
(11:21):
the replay and then go throughthose steps and then see if the
player drops down through thestage or not.
That's kind of how you have todo some of these regression
facets.
It's almost like systemstesting or end-to-end testing,
but it's just a differentmindset with respect to that.
And backfilling with a unit test.
There's so much context thathas to be communicated within
that unit test that it's justhard to say let me do a frame,
(11:43):
perfect jump and then the valueof gravity should be zero at the
next frame and you get afailure.
And then you're like, okay,it's a failure, but I wrote this
test three months ago and Ihave no idea why this is a
failure or not.
So that's one facet of it.
Another tricky facet of it isthat, like I was building a
racing game, and a racing gameis called a car that turns my
(12:03):
game names are ridiculous, soit's a car that turns and I'm
playing around and you take thatfirst corner, how can you like
deterministically quantify ordescribe it?
Doesn't feel right, right,right, it's a little stiff, or
it doesn't float as nicely as Iwanted to.
And then you tweak some numbersand, okay, it feels good now,
(12:24):
but what's the regression testfor that?
And then you're like, okay,well, it feels right for this
turn, but the next turn doesn'tfeel right.
And then you tweak the valuesagain.
You're like, okay, both turnsfeel good, but now your unit
test fails because the valuesthat you originally set up are
not the same.
And then you're like, well,test it assert that game is fun.
So those kinds of facets of it.
And then one challenge I hadwith a car that turned the game
(12:48):
was that I had a really goodinitial release and I was like,
okay, this feels good and I madethe controls a little bit more
floaty and it felt really nice.
But because I did that, therewas a part of a track that is
impossible to get around becausethe corner is too tight.
That is impossible to getaround because the corner is too
tight.
So now you've got thisoverarching issue of okay, with
the values and how I've changedthem, is it still possible to
(13:09):
complete the 15 tracks that Ihave in this game?
I don't know the answer to that.
Speaker 1 (13:14):
That's why I came in
and was like, please help me,
please.
Well, actually, speaking ofhelp, there's actually a pretty
cool.
I got to shout out my podcasthost, buzzsprout, which is a
Rails app.
So yay for using Ruby productsin the wild.
There is actually a link in theshow notes.
When you're viewing that,buzzsprout automatically adds it
.
You can text the show.
(13:35):
So if you're hearing what'sgoing on with Mir and like, oh,
I know how to solve that, Idon't know if anybody does Text
when you're listening to thisepisode and I will relay it to
him and we will use this supercool new feature from Buzzsprout
.
Maybe we can get you unblockedwith a text message.
Speaker 2 (13:54):
I love the idea of
live streams, it's lots of fun.
And so another facet of thetesting thing is like, of course
we're both apparently Zeldalinked to the past or Zelda fans
.
And so the other facet of it isthat when it comes to games,
humans find games interestingfor a specific problem domain.
If it's a puzzle game where itjust takes mental compute to try
(14:17):
to figure out like move coversto try to figure out the answer,
then it's apparently thosegames are more boring to play
than games like Zelda, andthere's like a really old
write-up of Zelda.
And the problem then it'sapparently those games are more
boring to play than games likeZelda and there's like a really
old write-up of Zelda and theproblem domain that it exists in
and apparently it's an NP-hardproblem.
Zelda, a Link to the Past, isNP-hard and that algorithmic
(14:37):
problem space is something thatcomputers just have a very
difficult time solving.
So how do you write a test tosolve Legend of Zelda when it
can't be solved?
There's this facet of you can'teven write an end-to-end or
system level test that says beatZelda for me and make sure that
it can be done.
And there's, of course,advancements that are happening
(14:59):
there, but these are the kind ofthe challenges that games have.
It's just that what we findinteresting ends up being really
difficult problems thatcomputers have a hard time
solving.
So that's another challengewith this idea of like testing
and regression parallel to appdev too.
Speaker 1 (15:25):
But like, how do you
come up with an idea for a game?
I know you said you originallydid a port and a car racing game
is at least a solid enoughconcept that when you're like
it's a car racing game, it'slike okay, there might be a
unique thing there, but it'sprobably a car racing game.
Yeah, a metroid like platformerI can sort of visualize playing
it in my head.
But like, how do you come upwith the idea for everything
(15:47):
else other than it's aplatformer?
We're going to go from one endof the screen to the other and
fight bad guys, everything elsethat goes into a game.
Before you can even come upwith writing the code, you have
to have some idea of what'sgoing on.
How does that work?
Speaker 2 (16:00):
And you're right,
it's got a lot of correlations
to app dev and the overarchingtheme is to fail fast.
So fail fast and control scopeis kind of my overarching tips.
But what I end up doing is Ithink of games that I like.
So an example would be, let'ssay, legend of Zelda, and I
think about that game and Ithink about all the things that
I appreciate about it and I takesomething away from Legend of
(16:22):
Zelda.
Maybe I take away a bunch ofthe items.
Is it still a game that I wouldplay?
And so you're trying to distillan experience down to the parts
that you find that you connectmost strongly with, and so
that's kind of how I decided onan idea or a concept pull out
(16:43):
from the feature set and thinkabout the feel of the game.
So what I tell people to do isthink about your perfect
five-star review.
What does it say?
It's not going to say I likethis game because it had
procedurally generated maps, andit's not going to say that
right, it's going to have morefacets of like.
When I first picked up thatsword and left and was able to
charge it and throw out a firebeam, I felt like a powerful,
(17:07):
godlike hero, and thinking ofthe five-star review is what
helps you figure out that forestfor the trees kind of idea.
So you have your distillationto control scope, you've got the
feel of the game to help guideyour approach to the actual
mechanics and stuff.
And then the final thing is a20-second demo where you
communicate that hook withinthat 20-second period.
(17:29):
So the challenges though,especially within the game
development.
I'm not nintendo, so the playeris not going to give me the
benefit of the doubt and waittwo to three hours before that
big, nice facet of gamemechanics comes in.
And so, with respect to likelive ops and what people and the
industry and how they measuremetrics, so from the point that
they open the application, menu,screens, controls, splash
(17:49):
screens, all that you have 20seconds before the falloff rate
ends up being more than 90%.
So you have to say get theminto the action, communicate why
they should continue playingyour game within that first 20
second period.
So that's how my initialprototyping ends up happening,
and then from there I expand onthis.
Oh yeah, I've hooked them forthe first 20 seconds.
How can I keep them playing?
(18:12):
I've communicated why theyshould or shouldn't play the
game, and then it's aboutexpanding on that longer game
loop.
But that's kind of how Iapproach ideas.
I think about game.
You know, draw inspiration fromliterature, like we Are Legion,
we Are Bob games that I enjoyedplaying, and then distill it
down and focus in on thosethings that I found valuable and
then the final thing is findingthose niche audience that value
(18:32):
the same things you do.
Speaker 1 (18:34):
You were pretty
successful with at least one of
your games.
A Dark Room was up there, butis there.
I know why that got supersuccessful it was because I have
no idea why you have no idea.
Okay, it was one of those viralphenomenons or just the right
person tweeted about it, okay.
Speaker 2 (18:54):
The interesting thing
, though, is that, with respect
to my subsequent games, thesuccess is primarily long tail
and hyper niche.
So the idea there is that I'mnot trying to compete with the
big AAA companies there.
What I'm trying to focus in onis there's an underserved niche
community that loves XYZ andcannot provide a digital
interactive experience for themthat they end up appreciating.
(19:16):
So the definition of successends up being about not trying
to put all your eggs in onebasket and hope for that lottery
ticket, but to focus in onthose hyper niche experiences,
create your wheelhouse, youridentity from that perspective,
and then service those airquotes smaller communities.
So our dark room was out there,like whatever.
So then the question was can Icapture lightning in a bottle
(19:38):
twice?
And so I ended up making apre-sequel, and that ended up in
the top five of the app store,so it did really well.
And then I was like okay, can Icapture lightning a third time
of the app store?
So it did really well, and thenI was like okay, can I capture
lightning a third time?
And so what I ended up doing wasI created a narrative,
satirical, rhythm-based gamebased off of a book that was
written in the 1800s calledFlatland Romance of Many
(19:59):
Dimensions and it's about this2D world and it basically was a
satire on Versailles and howroyalty and the life of
Versailles was like.
You know what I'm going to takethis idea of a 2D world and the
concepts in there and then do asatirical commentary of the
20th century in the context of agame, and it ended up doing
well too.
So it made it into, I think itwas like number nine overall and
(20:23):
it's been in the top 100.
So I would like to say thatmaybe this model can work, this
idea of digitalization find yourunique audience, find your
voice and cater to those people.
Speaker 1 (20:34):
But I have no idea
what I'm doing basically, it
sounds like a lot like app devfrom the startup perspective of
like keep your mvp very smalland very tight and like focused.
You're not going after googleor you're not going after Amazon
.
The StoryGraph did not go afterAmazon.
It went after Goodreads, whichis a lot smaller of a thing but
(20:55):
it was a lot slimmer and it wasa lot tighter and it kept its
focus on its audience and that'swhy Naughty's been so
successful with it.
It solved a problem that peoplehad.
Yeah, goodreads is an amazonproduct, but she wasn't going
after amazon.
Speaker 2 (21:10):
You're not going to
make the next witcher game the
other challenge that you have islike, with an app idea, if you
pitch it to someone say, hey,wouldn't it be cool if you had
xyz?
That made this part of yourlife easier.
And you're like yes, pleasemake this and take my money.
And when it comes to games likewhat do you think about a
satirical commentary of the 20thcentury as a top-down 2D
(21:31):
rhythm-based game, they're likeI guess I don't know, I guess
it's sort of like pitching booksto a degree.
Speaker 1 (21:37):
Like I have this idea
for the story, you don't write
the whole novel beforevalidating the idea, but you
have to convey it.
Speaker 2 (21:49):
There's a really good
book called the Mom Test and
it's this idea of ideageneration and then vetting your
ideas and taking it to market.
I was like, okay, this isdefinitely going to help me.
And then halfway through thebook it says this is great and
all, but it's not going toreally work for games.
I'm like, ah, shakes face.
But yeah, that's one weirdfacet of it and that's why I say
you build a 20-secondexperience and hook them and
make sure that you have the ideaof your perfect five-star
review in your head, so you knowwhat kind of emotions and
(22:11):
feelings you're trying to convey, and then you need to
communicate that very quicklyand I think that helps mitigate
the risk, but it's justdifficult.
Speaker 1 (22:18):
So the power of
Dragon Ruby.
Like we're talking 2D games,not 3D.
So for anyone who's not like asuper big gamer and doesn't
quite understand what we'retalking about is not like a
super big gamer and doesn'tquite understand what we're
talking about, If you think of,like the new Final Fantasy 7
games that just were rebuilt,like that's very 3D animations
versus a game like StardewValley is a 2D game.
(22:39):
The big difference there, asidefrom like the computational
stuff of like 3D math, MathRight Is the assets.
The sprite is, I believe, whatthey're called in 2D math, Math
Right Is the assets.
The sprite is, I believe, whatthey're called in 2D games.
Yes, or I might be aging myselfback when, like we used to play
games in the browser butsprites those little 2D guys
(22:59):
versus that full-blown likeBlender 3D animation model Yep.
How does that work inside ofDragon Ruby?
Is it just like, hey, I've gotthese pictures, these PNGs or
SVGs or whatever file format,and you upload them?
And then you're like, okay, andyou're going to move like this,
and when you're doing this,it's this sprite, and if it's
(23:22):
standing still it's this spriteand it's just to get it look the
way that you want.
You're just uploading assets,or does DragonRuby have
something in it where it's likehere's how we build a Sprite
pixel by pixel.
Speaker 2 (23:34):
So the tech behind it
is really cool and so we have a
core dependency on LiveSDL.
So SDL stands for Simple DirectMedia Layer and it's a C
library that it's been aroundfor 20, 25 years, like Valve.
Steam Client is built withLoveSDL.
So when it comes to likebattle-hardened kind of thing,
that's where the magic happens.
So what SDL does is that it's aabstraction over all the
(23:58):
operating systems out theremobile, android, web PC, mac,
linux, console, et cetera.
And so you tell SDL render thisair quotes sprite and it figures
out how to render it on thatspecific operating system.
And so the air quotes officialterm is that it's a texture and
for 3D I think it's calledmaterial.
But you're basically sayingokay, when you say, render this
(24:20):
PNG on the screen.
Behind the scenes, what we'resaying okay, get the PNG, load
all the bytes from it, create atexture out of that PNG, cache
it and then tell SDL to renderthis texture at this specific
location with these specificdimensions.
And so what SDL does behind thescenes is it takes that RGBA I
(24:44):
forgot the explicit format butthat byte array and that
specific byte array and thattexture it's a common construct
for across gpus, so gpusunderstand this data structure
of an array of bytes thatrepresents rgb values, rgba
values, on a screen.
So what stl does behind thescenes is it says, okay, you
have this texture and I'm goingto give you another program
(25:06):
which is called a shader, and Iwant, hey, gpu, I want you to
take the shader program and thistexture and do the work to
present it onto the screen.
So what a shader is?
It's kind of a C-based program,it's a C-based dialect.
That is, I guess, highlyparallel.
So the value of a GPU and itspower and what it brings to the
(25:27):
table is that it can run a verysmall function extremely fast
across all pixels on the screen.
So what happens is that texturethat has 8K worth of values
gets sent to the GPU and theprogram gets run for each pixel
on the screen.
So, yeah, you think about that8K texture.
Yeah, yeah, yeah, it's sayingfor each pixel, give me the RGB,
(25:50):
run this thing.
And so for Windows, the shaderlanguage is Vulkan or Direct3D.
For Linux it's OpenGL.
For iOS and Mac it's Metal.
And then your consoles havevarious ones.
They're all kind ofconsolidating on Vulkan.
But that's the GPU tech thathappens behind the scenes.
So the great thing in DragonRuby, is you just shuffle a hash
into an array, that's my nextquestion how much does Dragon
(26:16):
Ruby help me with this Cause?
Speaker 1 (26:17):
I'm lost already.
Speaker 2 (26:19):
Yeah, you give it an
X, so we have a logical canvas
of 1280 by 720 and it'sgeometric.
So zero, zeros in the bottomleft-hand corner.
So if I want to render a spritein the bottom left-hand corner,
we've got a argument calledoutputs and it's an array and
you just do outputs and then youshovel a hash or an object that
responds to X, y, width, heightand path, which is your PNG
(26:40):
path, and it'll render it to thescreen and that's all you have
to do.
So when it comes to animationsand we talk about sprite sheets,
it's frame by frame, so you cantake the option of like okay,
attack animation is across threePNGs.
So then you've got your framethat the action happened, and
you can say okay, I want to holdeach one of these PNGs for four
(27:01):
frames, and the duration of theentire thing is eight frames.
And so you can tell DragonRubyeight frames, and so you can
tell DragonRuby do the renderingacross this collection of
sprites on the screen.
So when you do an attack, itcycles through those, do those
specific animations?
And it's a matter of providingobjects that respond to that
specific contract, which is thebeauty of Ruby, right?
It doesn't have to be a spriteclass or whatever.
(27:22):
It's just hey, if it respondsto these functions, these
properties, we're good.
Speaker 1 (27:26):
That's so interesting
, the thought of just like, yeah
, I've got a bunch of staticpictures and then I load them
into this program and then youpress a button on your keyboard
or controller and then it movesand it's so cool.
Yeah, it's such a cool concept.
Speaker 2 (27:41):
What's really
interesting is that and a
difference that I saw withAppDev and GameDev is, with
GameDev, a lot of it is kind ofdata-oriented.
Like this it's like your gamestate is a function, what's
rendered to the screen is a purefunction that's derived based
off of your game state, and soit feels data oriented and
functional.
It's an interesting paradigmshift that also existed when
(28:04):
going from like app dev to gamedev.
So, yeah, a lot of theDragonRuby APIs are around this
data oriented approach where youhave referential transparency
on what is actually going to besent to the renderer and whatnot
, and it's cool.
It's really cool to kind of seeall that in action.
And then the simplicity of itof saying I can just have a
value type that representswhat's rendered to the screen
(28:25):
and not have to think aboutimmutability and a lot of the
other complexities that existout there.
Speaker 1 (28:32):
So Ruby, if you ask a
non-Rubyist, is notorious for
being slow, so how is it that wecan run a game at 60 frames per
second in a slow language?
Air quotes slow language.
Speaker 2 (28:48):
Yeah, I've given up.
So I was to a point where I wasgoing to do like a white paper
and we'll talk to that first andthen I'll give you what I show
them now.
So the idea is that the initialresponse I run as fast as the
NET Core CLR runtime that does abitcode compilation in JIT.
(29:14):
It's just not going to run thatfast and so this idea of a
language can't be fast or slow.
It's a runtime implementationthat makes it fast or slow With
Ruby and this whole oh Ruby isslow.
We're talking about MRI Rubyfrom.
Like the 1.8, 1.9 days 1.8, 1.9days, which is like ancient Ruby
at this point.
And so the runtimeimplementation with like Ruby
(29:35):
3.3 is a different runtime.
It's got a different executionprofile.
For DragonRuby we use mruby asour primary dependency.
So we took mruby and thengutted the core lib and
polyfilled it with a lot of thelibSDL stuff so that it could do
cross-platform stuff.
So you've got your file classand you do filereadfile.
(29:56):
The mRuby, cruby, all thoseassume that you're working with
an operating system that's PC,mac, linux that has a regular
file system that isn't lockeddown the way that consoles or
isolated storage or those otherenvironments are.
So we had to gut a lot of thosethings.
And then those core libs arereplaced with these across
platform dependencies yeah,language can't be slow.
And then with this, I guess,extraction and replacement
(30:18):
process that's another facet ofwhat makes the language fast is
what is the implementation ofyour core lib?
What is the speed of the Cfunction that is being invoked
through that foreign functioninterface?
I went through all thesedetails and it showed the
employees like yeah, but Ruby'sslow, and I'm like okay.
Speaker 1 (30:35):
Okay, yeah.
Speaker 2 (30:37):
So what I ended up
doing was I was like, okay, I'm
going to create a YouTube videoand I'm going to have a scene
where it renders as many spriteson the screen as I possibly can
.
And so the YouTube video yeah,if you do DragonRuby performance
, it'll come up and what I showis rendering, I think, like 10
to 20,000.
I give a profile, I say, okay,what's the speed of rendering?
5,000 sprites on the screenthat are moving across and have
(30:57):
some concept of collision, andthey'll wrap around.
And so I do 5,000 sprites.
And then, okay, I'm going tobump it to 10,000 sprites, 20,
80, 40, like 80,000 sprites.
Dragon Ruby got around 20 to 30frames per second, and I did the
exact same thing with Unity andit got four frames per second.
And so the conversation ended,All the white people, all the
(31:21):
explanations, the details.
I'm like watch this YouTubevideo.
And they're like okay, there'sstill people like I don't
believe that.
So I did another one for manyto many collisions.
So it's like you don't believethat.
So I did another one for manyto many collisions.
So it's like you've gotcollisions on your page and how
do you construct something thatvisually shows that this object
collided with these otherobjects and 1500 sprites with
many, many collisions at 60 FPS.
(31:42):
You need to get one frame asecond.
It's completely broken fromthat perspective.
It just goes back to that ideaof like runtime implementation
and your core lib implementationand the runtimes I'm picking on
Unity because that's usuallywhat people think of, yeah, sure
, what people think of and theruntime implementation is, at
this point, a 15-year-old forkof mono, of C-sharp mono, the
(32:06):
C-sharp mono runtime.
And then the way they dealt withcross-platform compatibility
was through a transpiler thattakes the intermediate
representation of C-sharp andemits C code.
So you're taking C-sharp codewhich gets converted into this
intermediate representation.
It's kind of like your virtualmachine, and that virtual
(32:26):
machine those specific opcodesare then code-gen as C code and
then that C code then getscompiled.
So you've got the C sharp to ILtransition, the IL to C
transition, the C tointermediate representation
transition, and then that getstranslated into the compiler.
And once you've done all thosetranspilations, you've lost any
(32:47):
semblance of optimization atthat point.
And so their runtimeimplementation.
It's a good and bad thing,right, you have BitRot and it's
a longer running project, butthey can't take advantage of all
the advancements and compilersthat we have today, and so
that's why it's faster.
It's just, our runtime is justthat way.
Speaker 1 (33:05):
Speaking of taking
advantage of newer things, are
you able to take advantage ofthe new stuff in Ruby 3.3 and
what's coming out in 3.4, likethe new parser, the new YJIT and
things like that?
Or is that not quite in yourpurview, because you're using
mRuby and then sort of guttingit?
Speaker 2 (33:22):
We're able to take
advantage of those things as
those changes make it over tothe mRuby.
Now, the biggest benefit ofmRuby is that it's embedded.
It's fairly trivial to put thatinto a C program and have it
run everywhere.
So there's no OS leveldependencies from that
perspective or assumptions thatare made that you're running on
like a server class machine.
(33:42):
And so when you think aboutlike YJIT and the native or the
assembly code that it emits, yes, that will work on Windows and
they've got it working onEmscripten, but the backend
compilers that are used forconsoles, it's not going to work
there.
Speaker 1 (33:56):
Or at least not yet.
Speaker 2 (33:57):
Not yet.
Speaker 1 (33:58):
And now we're getting
into NDAs and all that crazy
stuff.
Speaker 2 (34:03):
So there's a facet of
that.
So those changes, if they makeit into MRuby, then we can look
at co-opting them.
And for us we're kind of likein this parallel stream where
there are some things that wecan send back to upstream saying
that, hey, this change makesXYZ better or faster.
But it's difficult to say, ohyeah, your file IOs is actually
not cross-platform.
(34:23):
Take this dependency on 250,000lines of C code which is libSDL
.
So that maintenance burden iswhy the product exists.
Right, it's what makes thisprocess sustainable on our end.
That's why you pay for theengine.
We can take advantage of somethings.
I love Prism.
I love the traversal of thespecific recursive descent
parser that's used in Prism.
(34:45):
It's good.
But mRuby was built later,which means that it has a nicer
parser than what Ruby originallyhad, so it doesn't have as much
as the other cruft that wasthere.
So there's benefits that existand it's just that balancing act
of okay, how much are we goingto invest in that parser facet?
Can we collaborate withupstream to help that process?
And someone's got to take thelead.
(35:07):
If they're going to start withthe prison port, I'm there,
right, I want to make sure thatthat happens.
But doing that work and thenpushing it upstream.
It's that question of whetherMRuby is positioned to accept
those kinds of changes.
But it's really cool and ourparity is with MRuby.
So once the feature, thatsyntax, comes into MRuby, then
we can leverage it.
(35:27):
One interesting thing and I'dlove to hear your thoughts on
this is that with DragonRuby andthe ideas that I have around it
, we can break Ruby from thatperspective.
Dragonruby is a Ruby, but itdoesn't have the same onus of
backwards compatibility ormission critical applications.
So what are some experimentalthings that could be added to
like DragonRuby?
Maybe we do create a pipeforward operator or maybe we
(35:50):
actually do introduce someexperimental syntax that doesn't
have the onus and the airquotes red tape that exists with
CRuby or MRuby.
So it's an environment forexperimentation and it's a safe
environment because you're notbuilding medical software with
it, right?
Speaker 1 (36:07):
That's interesting.
I didn't think about the factthat you're sort of isolated
from what goes on in Rubybecause you have your own.
Would that be considered likehaving your own dialect in a way
of like you know, sort of inthe way that Americans speak
English and the English speak.
English and they are not thesame language.
(36:28):
There are similarities, butthey're not the same.
That's interesting.
Speaker 2 (36:33):
It's a world for
experimentation and potential
innovation, and I think that's abig challenge for Ruby today is
that we have the maturity andthe ideas that have been set in
place, but there's a trade-off,right.
That maturity I won't saystifles, but it stifles
innovation.
Right, you're slower toinnovate, no-transcript.
You're slower to innovatebecause you don't want to break
things.
But DragonRuby has this uniqueenvironment where it's like okay
, it's games, we don't have 25years of code to think about.
(36:56):
We're building a new experienceand the opportunities to
innovate on what exists outthere are, there, they're closer
.
Speaker 1 (37:03):
Have you done any
experimenting yet, or is there a
bit of it where you're like weactually added this syntax that
if you're writing Dragon Rubycode, you can do this, but you
can't do that in regular Ruby.
Speaker 2 (37:14):
We've done an
experimentation and it's
actually went really well aroundthe core lib.
So in Dragon Ruby, hash isquack-like attribute accessors.
So you can use the bracketsymbol, whatever to access a key
in a dictionary, or you canjust do x and what it will do is
it does the method missing thepre-cache and all those facets
(37:34):
to where you'll actually get thex key value from, and it
forwards to get key.
Basically.
And the interesting thing thereis that with this approach you
don't have to air quotes, paythe tax of creating a class to
represent one of your gameentities.
You can say I'm just going tocreate a hash with XY armor that
has this name and stuff andjust create that dictionary
(37:56):
structure, invoke it as if therewere attributes and then later
evolve to using a class.
And the nice thing there isthat because we've done those
polyfills, you're not changingthe call sites.
You can continue to keep thosespecific properties that you
decided these objects would haveand just transition to a class.
So those kind of things, samething right.
Like if I sent the pr that saidhey, hashes, quack like classes
(38:19):
with respect to attributeaccessors, decline, right,
they'll immediately.
Speaker 1 (38:23):
Nope nope, you've got
data classes.
You've got structs, like thereare ways to do it, but not
hashes.
Sorry, no dice, but dice.
Speaker 2 (38:30):
But from our
perspective we're like, yeah, we
can do this, we can try thisapproach and see how it feels.
And it's fun because we'll haveRuby devs that come in there
and say, man, this is reallynice, though I can just treat a
hash like a full-blown class andyou end up missing it.
And I was like, yeah, Iprobably feel I opened up the
hash and did the same thing andlike more crime.
Yeah, those are primarily theexperimentations that we've
(38:51):
taken is expanding the core libfrom that perspective.
Speaker 1 (38:54):
It's sort of like
when someone goes from doing
primarily Rails dev work to justraw Ruby and they're like I
can't do any.
It's like, yep, that's activesupport.
Sorry, that's exactly Yep.
I don't want to not do myfavorite question, so we're
going to do it now.
Let's do it Before any morerabbit holes.
What is something cool, new orinteresting that you've recently
(39:15):
learned or discovered or builtDoesn't have to be coding
related.
What do you got?
Speaker 2 (39:21):
It's really the
shader tech, so how the GPUs
work and everything.
So there's shader language forOpenGL is different than the
shader language for Direct3D,which is different than Metal.
And then you're like okay, well, if I want to do this cool
ripple effect or visual effect,I have to write five different
versions of this program.
That's not fun.
But there's something calledthe Spear V toolchain, which is
(39:44):
a cross compiler where you writeI think it's Vulkan, you write
your shader in Vulkankan and itwill create the OpenGL, Metal,
Direct3D variants of thatspecific shader language.
So we're getting into a worldwhere we've got fragmentation at
the language to hardware leveland each one of these companies
is saying, no, our language isthe best and we're not going to
(40:06):
consolidate onto one.
So of course someone said, no,we're going to do that and then
provide that transpilation.
But that's been some of thereally interesting stuff that
I've been exploring.
We think about CPU and justlanguages that target CPU, but
now we're getting into GPUlanguages and then their idioms
and their highly parallelapproach and paradigms are just,
they're fascinating and they'redifferent.
(40:28):
There's a website like, if youwant some idea of like what that
looks like.
There's a website called ShaderToy and there's a scene of a
tree with like leaves waving inthe wind and like a grassy
landscape and there's like aday-night cycle and clouds and
everything Like how the hell didthey do this?
And you look at the program andyou're like what is this?
It's just all math.
But all the way down, all theway down.
(40:55):
But the fact that someone cantake this highly parallel
concept of every pixel is run inparallel with every other pixel
, and how you form a programthat can make a tree, it's just
mind-blowing.
But yeah, shader toy, you canlose hours just looking at all
the cool little tech demos thatexist out there.
It changes your brain right.
It exposes you to a domain thatyou haven't been exposed to and
it'll make you a betterdeveloper across the board.
Speaker 1 (41:17):
Yeah, I will include
that in the show notes and then
I will go waste hours staring atit here in a little bit.
So if someone wanted to getstarted doing game dev, they
have a little idea or they justwant to tinker and they want to
use everyone's favorite language, Ruby and Dragon Ruby.
Like, how do you recommendgetting started aside from?
Like go buy Dragon Ruby so youhave the Dragon Ruby engine and
(41:40):
get started.
But like how do you recommendgoing from I have nothing on the
screen to hello world withDragon Ruby?
Speaker 2 (41:47):
So, just an aside,
anyone that listens to the
podcast, you send me an emailsaying that you heard about it.
I'll hook you up with a freelicense, no big deal there.
We also have income assistanceif you're unemployed or in
school under 18 or a parent thatwants to teach a kid Any one of
those like heartwarming, goodfeeling stuff.
Just send me an email and I'llget you set up.
So I'm not trying to put anyoneout financially.
(42:08):
But yeah, you download it, youdouble click to unzip and that's
it.
There's no dependencyinstallation, it's all
self-contained.
And there's a book that one ofour community members wrote that
I recommend and it's in ourdocs.
But you end up building like aside-scrolling shooter and like
a Flappy Bird clone is also afacet of it and kind of work
(42:29):
through that book.
And if you're familiar withcoding I think you'll get up to
speed pretty quickly by workingthrough that.
Aside from that, we've got Ithink like 150 plus sample
applications that go inincreasing difficulty.
So it kind of teaches the basic.
Then we dig into some of theadvanced rendering concepts and
then we have genre-specificreference implementations.
If you want to do a platformer,here are some reference
(42:55):
implementations of how to do aplatformer, like a Mario Star or
platformer, or if you're doinglike a tactical RPG, we actually
have a sample app where it'slike a green sprite walking
around the screen and it's thefirst area of Legend of Zelda
from the NES.
And then you enter a cave andit's like here, take the sword,
take this.
So we actually have that aslike as a sample app and that's
kind of like your springboardwith respect to starting on a
game.
I think that's like a bigobservation that I found is that
(43:17):
with Rails applications, thescaffolding is extremely
productive.
I mean, we're building CRUDapps, we're taking data,
sticking it into a database.
It's formulaic, at least atthat level.
But when it comes to games,it's difficult to create that
kind of scaffolding.
So how we compensate for thatis saying, okay, here's
springboards to creating atop-down game or a platformer or
(43:37):
a turn-based or ascii-basedroguelike or a bullet hell
shooter or twin stick shooterand all those variations and
that ends up working pretty well.
And our discord community isabsolutely phenomenal.
The idea of Minus is there andit's so great because there's so
many people that it's Ruby istheir first language, right?
They're like I've never usedRuby before.
(43:59):
That clicking happens.
You see that magic that we feltand they're like this is so
awesome.
And so if you're ever stuck,you come to the Discord
community.
You're going to find a lot ofhelp there, and I think a
combination of those threethings is the best way to get
going Super cool.
Speaker 1 (44:12):
This has been great.
Thank you so much for coming onand reaching out and asking to
come on, because this was somuch fun getting to pick your
brain on it and learn more aboutit and it's such a cool project
and I love that.
We can do literally anythingwith Ruby.
It's not just web stuff, it'sfull blown applications and
games.
Just web stuff, it's full blownapplications and games.
Speaker 2 (44:31):
And commercial games.
This is putting food on mytable, right, right, right, yeah
.
So it's wonderful and theinnovations I think that the
language will bring to game devis sorely needed and it's good
and it's an investment in thatfuture.
I think the future like kidsand students and things like
that, and education, and I thinkthat's where I feel the
renaissance and that resurgenceand what we discovered again.
Speaker 1 (44:54):
Bringing developer
happiness to game devs sounds
pretty important.
Cool, is there anything elseyou wanted to talk about before
we do the wrap up?
Take?
Speaker 2 (45:03):
the time, feed your
soul.
I know people say like, oh, Igot to learn the next new hot
tech.
And just step back and justremember that, why you decided
to become a developer.
Right, the love of the craftand the encoding, and I think
game dev is a wonderful way todo that well.
Speaker 1 (45:17):
Thank you so much for
coming on.
Where can people find you anddragon ruby on the internet?
Speaker 2 (45:22):
yeah, we have our
discord server, so dragonrubyorg
has a link to that.
I'm on the artist formerlyknown as twitter at amirazan.
I on Mastodon, on rubysocial,on Mastodon.
Shoot me an email, also DMswelcome.
All those great thingsExcellent.
Speaker 1 (45:38):
Yeah, I'll put all
that stuff in the show notes so
that people have access to it.
And again, thanks for coming on.
It was a blast having you onand hopefully I'll get an
opportunity to do some tinkeringof my own and then maybe even
have you on again to pick aparthow bad my game code is.
Oh, my game code is terrible,don't worry.
Great Well, audience members,don't forget to text in if you
(45:59):
liked the show, if you havecomments, questions, concerns,
or if you'd like to be on theshow, shoot me a text.
I'd love to talk more to you.
Otherwise, see you in the nextepisode.
Bye, everyone.