Untitled adventure game, Milestone 2: Basic gameplay
Moderator: Moderators
- FrankenGraphics
- Formerly WheelInventor
- Posts: 2064
- Joined: Thu Apr 14, 2016 2:55 am
- Location: Gothenburg, Sweden
- Contact:
Re: Untitled adventure game, Milestone 2: Basic gameplay
Love the demo! Nice mechanics, it's evident you've spent lots of care. thanks for showcasing. Also interesting to see how you've implemented stuff and how you ease editing with a basic-like syntax where practical.
- samophlange
- Posts: 50
- Joined: Sun Apr 08, 2018 11:45 pm
- Location: Southern California
Re: Untitled adventure game, Milestone 2: Basic gameplay
Wow, that looks absolutely fantastic. The asset too looks very versatile and easy to use, and its really neat how it allows you to visualize occluders, collision, etc. I'm impressed with how much gameplay you're able to create via scripting.
How did you add support for copy/paste from Aseprite?
How did you add support for copy/paste from Aseprite?
- darryl.revok
- Posts: 520
- Joined: Sat Jul 25, 2015 1:22 pm
Re: Untitled adventure game, Milestone 2: Basic gameplay
Hey there!
I'm still watching the video now but I wanted to chime in, that if you did these graphics yourself, then they're definitely good enough.
I understand if you just don't have the time to do all of the graphics, or if these are place-holder graphics from another source. But people can tend to be harder on their own work than that of others, and I wouldn't exclude these graphics from use for reasons of quality.
The graphics in this work-in-progress are definitely better than average for commercially released NES games. If they're something that you just ripped from another source then I apologize for the misplaced compliment.
I'm still watching the video now but I wanted to chime in, that if you did these graphics yourself, then they're definitely good enough.
I understand if you just don't have the time to do all of the graphics, or if these are place-holder graphics from another source. But people can tend to be harder on their own work than that of others, and I wouldn't exclude these graphics from use for reasons of quality.
The graphics in this work-in-progress are definitely better than average for commercially released NES games. If they're something that you just ripped from another source then I apologize for the misplaced compliment.
Re: Untitled adventure game, Milestone 2: Basic gameplay
Thanks for the kind words. Aseprite is open source, so it is quite easy to see how the "encode" their clipboard data. I can send you my C# code if you want. It is essentially a bunch of image data, compressed using a DEFLATE type algorithm. Super simple. My "convention" when working in aseprite is that color 0 is transparent, 1,2,3 is the first palette, 4,5,6 is the 2nd, and so on.samophlange wrote:How did you add support for copy/paste from Aseprite?
-Mat
Re: Untitled adventure game, Milestone 2: Basic gameplay
Thanks. They are, in fact, heavily inspired by a bunch of stuff I found on google images, pinterest, etc. But most of the stuff you find online uses way too many colors to fit on the NES. So even when you want to "steal" stuff, it takes a lot of work to make it look nice.darryl.revok wrote:The graphics in this work-in-progress are definitely better than average for commercially released NES games. If they're something that you just ripped from another source then I apologize for the misplaced compliment.
-Mat
Re: Untitled adventure game, Milestone 2: Basic gameplay
Looks good. Will be interesting to see how it progress
Re: Untitled adventure game, Milestone 2: Basic gameplay
The art reminds me of Pokemon.
- FrankenGraphics
- Formerly WheelInventor
- Posts: 2064
- Joined: Thu Apr 14, 2016 2:55 am
- Location: Gothenburg, Sweden
- Contact:
Re: Untitled adventure game, Milestone 2: Basic gameplay
yeah i forgot to comment about the graphics, but those are nice - i especially liked the walking animation for the patrolling bug, it has lots of nice character to it.
-
- Posts: 29
- Joined: Mon Nov 11, 2013 2:23 pm
Re: Untitled adventure game, Milestone 2: Basic gameplay
Saw this over and Twitter and wanted to pop in to say WOW! Very nice graphics, and the rest looks solid as well!
Re: Untitled adventure game, Milestone 2: Basic gameplay
Ha thanks man.FrankenGraphics wrote:yeah i forgot to comment about the graphics, but those are nice - i especially liked the walking animation for the patrolling bug, it has lots of nice character to it.
Lol, one of my 3 followers. Hahah. Baby steps i guess. Thanks for the support man.SoleGooseProductions wrote:Saw this over and Twitter and wanted to pop in to say WOW! Very nice graphics, and the rest looks solid as well!
-Mat
Re: Untitled adventure game, Milestone 2: Basic gameplay
Sure. I was looking for simplest language to implement and i remembered BASIC, which is the 1st language i learned as a kid (im old).yaros wrote:I love it, I love the graphics too. Can you provide more details on the code generation of your script language?
I drew inspiration from ubasic (https://github.com/adamdunkels/ubasic), which is a very small BASIC interpreter. But I essentially re-wrote the whole thing in C#, which is what my tools are written it, and converted it into a compiler, instead of an interpreter. I made up the bytecode. I support stuff like math operation, test conditions, jumps, loops, etc. I also support calling "engine functions". The engine in ASM can expose functions that can be called from the script, using a well defined calling convention. Also, the script can implement a certain number of entry points (or events) which are all the "on_xxx" functions. These are called by the assemble code when stuff happens.
In assembly, bytecode is implemented as a simple jump table. each opcode will fetch the arguments it needs and do whatever it needs to do. I allocate a small "heap" of 32-byte for the script. This includes global variable, local variables, temporary variables. Temporary variables are needed for things like "4 + (2 + 3)". Behind the scene temporary variables will be allocated to hold temporary results of the addition. This is all done at compile time.
That's about it really, its <1000 lines of ASM, a bit more on the tool side. But it really opens up the possibilities for prototyping ideas.
-Mat
Re: Untitled adventure game, Milestone 2: Basic gameplay
Me too. I kind of made up the bytecode as I went along. Maybe the best way to go about it is with an example? This is an event that gets called when the player successfully hacks the keypad.yaros wrote:I am able to write simple parser, lexer or interpreter. When it comes to bytecode/machine code generation my brain shuts down. Could you advise some resources you used and learned from?
Code: Select all
function on_game_event(event, param)
if event = GAME_EVENT_KEYPAD_SUCCESS then
set_timer(60)
end if
end function
This is the bytecode I use right now, and the disassembly next to it. There are generally two types of bytecode: stack based and register based, this is definitely register based.
The first byte is always the opcode.
Code: Select all
; on_game_event
.byte $0e, $01 ; 0: get_arg0 event
.byte $05, $01, $82 ; 2: compare_equal_byte event 0
.byte $0a, $0a ; 5: jump_if_false 10
.byte $13, $05, $8a ; 7: invoke_r0 set_timer(60)
.byte $1a ; 10: end
- $0e = reads argument 0 passed from the engine, puts in variable slot $01 (i have 32 variable slots). Note that the compiler detected we never access the second argument, so it ignores it. Minor optimization.
- $05 = equality comparison. Compares whatever is in variable $01 (what we just read) to constant $02 (when the minus bit, $80, is set, it means that its not a variable, but a constant stored in a table somewhere else. Whenever I encounter an hardcoded constant at compile-time, I look to see if I've seen it before and add it to that table if its new. Constants like "0" comes back quite often, so this is efficient).
- $0a = jump to the location indicated (10, which is the end) if the last test condition was false. My conditional statements are optimized for "ORs of ANDs" (or "Disjunctive normal form" if you want to sound pretentious).
- $13 = calls an engine function (engine function $05 is "set_timer") that takes a single argument and puts in in "r0" (a zero page variable in my engine), which is the constant table at location $0a.
- $1a = end.
-Mat
Re: Untitled adventure game, Milestone 2: Basic gameplay
One thing that tripped me up while reading your "assembly language" in the comments to the right was that most architectures' equality comparison behaves as != instead of ==: a subtraction that is true if they are different or false if not. That way, the interpreter can use the same logic for compare and subtract.bleubleu wrote:
- $0e = reads argument 0 passed from the engine, puts in variable slot $01 (i have 32 variable slots). Note that the compiler detected we never access the second argument, so it ignores it. Minor optimization.
- $05 = equality comparison. Compares whatever is in variable $01 (what we just read) to constant $02 (when the minus bit, $80, is set, it means that its not a variable, but a constant stored in a table somewhere else. Whenever I encounter an hardcoded constant at compile-time, I look to see if I've seen it before and add it to that table if its new. Constants like "0" comes back quite often, so this is efficient).
- $0a = jump to the location indicated (10, which is the end) if the last test condition was false. My conditional statements are optimized for "ORs of ANDs" (or "Disjunctive normal form" if you want to sound pretentious).
- $13 = calls an engine function (engine function $05 is "set_timer") that takes a single argument and puts in in "r0" (a zero page variable in my engine), which is the constant table at location $0a.
- $1a = end.
Re: Untitled adventure game, Milestone 2: Basic gameplay
I see your point. But I really made it up as I went along. There was no masterplan, I didn't try to copy any existing architecture really.tepples wrote:One thing that tripped me up while reading your "assembly language" in the comments to the right was that most architectures' equality comparison behaves as != instead of ==: a subtraction that is true if they are different or false if not. That way, the interpreter can use the same logic for compare and subtract.
Also, reusing the same opcodes for multiple things wasnt much of a concern. I favored large and very specific op-code that do a lot of things, as opposed to micro-ops that can be reused. The idea was to keep the bytecode compact, and have the ASM code be quite efficient. This mean that I probably have a lot more code in my interpreter, but that's ok.
-Mat