ENIGMA Forums

General fluff => Announcements => Topic started by: Josh @ Dreamland on June 09, 2010, 09:00:53 pm

Title: Around the Clock
Post by: Josh @ Dreamland on June 09, 2010, 09:00:53 pm
Hardly. I've worked on Thank You cards to six million people. My cousin's graduation party is Sunday, which I will apparently be attending. Today I took a trip north with my dad, solely to visit my grandparents. Made the mistake of committing my code so I could work on ENIGMA there from my laptop. Didn't have much time to do so, ultimately. What's more, I came back to a certain someone informing me that the code I committed mid-sentence doesn't compile. <___<"

No, the instance system is not done. But I do have a surprise for you all.

I've seen questions going around of how GM handles events. Specifically, questions regarding the order in which they are executed. I myself used to wonder what exactly went on to implement hspeed and vspeed that ruined my first slope-using platformer. Well, that won't be a problem in ENIGMA.

I have implemented a file for R4 that contains a list of all events, the code executed in them, and some other details and trivia. I know a few are thinking right now, "great, another document for Josh to not maintain." Well, HAH. This one will always be current. Why? Because it's the file ENIGMA actually uses to determine what events were passed.

This is a beautiful thing for a number of reasons, one of the most important being that anyone can correct an event or add an event that a new version of GM implements. This is a snippet of the file, for demonstration purposes:

Code: (Events) [Select]
beginstep: 3
Group: Step
Name: Begin Step
Mode: Special
Case: 1

alarm: 2
Group: Alarm
Name: Alarm %1
Mode: Stacked
Sub Check: { if ((alarm[%1] == -1) or (alarm[%1]--)) return 0; }


# Keyboard events. These are simple enough.

keyboard: 5
Group: Keyboard
Name: Keyboard <%1>
Type: Key
Mode: Stacked
Super Check: keyboard_check(%1)

#...

step: 3
Name: Step
Mode: Special
Case: 0
Constant: {
x += hspeed, y += vspeed;
speed -= friction;
vspeed += sin(gravity_direction * pi/180),
hspeed += cos(gravity_direction * pi/180);
}

#...

collision: 4
Group: Collision
Name: %1
Type: Object
Mode: Stacked
Super Check: instance_number(%1)
Sub Check: place_meeting(x,y,%1)

That code will serve to bring an end to the hard-coded, undocumented GM method of event management.

Anyway, I'm back to work.
Title: Re: Around the Clock
Post by: Rusky on June 09, 2010, 09:52:08 pm
"great, another document for Josh to not maintain parse." :P
Title: Re: Around the Clock
Post by: Josh @ Dreamland on June 09, 2010, 10:03:31 pm
:troll:

u toll
Title: Re: Around the Clock
Post by: retep998 on June 09, 2010, 10:16:07 pm
Quote
What's more, I came back to a certain someone informing me that the code I committed mid-sentence doesn't compile.
I'm glad that someone isn't me :D
Quote
u toll
(http://davidiseman.files.wordpress.com/2009/02/toll-booth-worker.jpg)
Title: Re: Around the Clock
Post by: Josh @ Dreamland on June 10, 2010, 01:55:53 am
Indeed. Kinda laughed.

Anyway. This new instance system is beautiful. What was 55 lines is now 17. This unified iterator thing didn't look half as powerful on paper. Damn, what an idea.
Title: Re: Around the Clock
Post by: notachair on June 10, 2010, 07:02:35 am
What is that --> I see up top doing :raise:
Title: Re: Around the Clock
Post by: score_under on June 10, 2010, 07:40:11 am
:troll:

u toll
(http://www.poster.net/zak-martin/zak-martin-na-toll-2407507.jpg)
[tr. "Oh great."]
Title: Re: Around the Clock
Post by: IsmAvatar on June 10, 2010, 11:29:55 am
Code: (ini) [Select]
[root]
order = beginstep, alarm, keyboard, step, collision

[beginstep]
name = Begin Step
group_id = 3
case = 1
group = Step
mode = Special

[alarm]
name = Alarm %1
group_id = 2
group = Alarm
mode = Stacked
subCheck = { if ((alarm[%1] == -1) or (alarm[%1]--)) return 0; }

; Keyboard events. These are simple enough.

[keyboard]
name = Keyboard <%1>
group_id = 5
group = Keyboard
type = Key
mode = Stacked
superCheck = keyboard_check(%1)

;...

[step]
name = Step
group_id = 3
case = 0
mode = Special
constant = { x += hspeed, y += vspeed; speed -= friction; vspeed += sin(gravity_direction * pi/180), hspeed += cos(gravity_direction * pi/180); }

;...

[collision]
name = %1
group_id = 4
group = Collision
type = Object
mode = Stacked
superCheck = instance_number(%1)
subCheck = place_meeting(x,y,%1)

Although your format is already very much like YAML.
Title: Re: Around the Clock
Post by: IsmAvatar on June 10, 2010, 12:23:52 pm
To make it more accurate in YAML, a few changes:
* Documents should begin with --- and may end with ...
* Use - to indicate ordered lists.
* a tree structure is achieved by starting the parent node's value with a newline, not a value
  * As such, the value should be given a variable, which I will call 'Group Id'
* The linux-friendly id-name (e.g. 'beginstep') can either stay (in which case it'd be largely lost as simply an element) or become a scalar value belonging to a variable.
* Multiline blocks should either use pipe or right angle bracket, depending on if you wish to preserve newlines and spacing, or replace newlines with spaces (e.g. a simple block of quoted text), respectively, and each line of the block should be indented
* To avoid complications with [] and such in code, code should either use the multiline block mentioned above, or single quote the code, doubling any internal single quotes (that is, two single quotes, not a double quote): 'wtf''quote'

Code: (yaml) [Select]
---
-beginstep:
  Group Id: 3
  Group: Step
  Name: Begin Step
  Mode: Special
  Case: 1

-alarm:
  Group Id: 2
  Group: Alarm
  Name: Alarm %1
  Mode: Stacked
  Sub Check: '{ if ((alarm[%1] == -1) or (alarm[%1]--)) return 0; }'


# Keyboard events. These are simple enough.

-keyboard:
  Group Id: 5
  Group: Keyboard
  Name: Keyboard <%1>
  Type: Key
  Mode: Stacked
  Super Check: keyboard_check(%1)

#...

-step:
  Group Id: 3
  Name: Step
  Mode: Special
  Case: 0
  Constant: |
    {
      x += hspeed, y += vspeed;
      speed -= friction;
      vspeed += sin(gravity_direction * pi/180),
      hspeed += cos(gravity_direction * pi/180);
    }

#...

-collision:
  Group Id: 4
  Group: Collision
  Name: %1
  Type: Object
  Mode: Stacked
  Super Check: instance_number(%1)
  Sub Check: place_meeting(x,y,%1)
...
Title: Re: Around the Clock
Post by: Josh @ Dreamland on June 10, 2010, 01:08:13 pm
-Sigh-
I like the format how it is. It's humanly readable now without the %YAML, ---, -, \nGroup ID:, and ....
In fact, it's close enough to YAML that I'm comfortable calling it that anyway. Or at least YAML-like. I'll outline all six differences in the docs regarding the events file, if you like.  ::)

YAML highlighters are grotesque at best; I'd get better highlighting if I named the file *.sh. I don't see much benefit to trying to comply...
Title: Re: Around the Clock
Post by: Micah on June 12, 2010, 08:08:31 pm
I don't see much benefit to trying to comply...
There are good libraries for YAML written already. I'd say that's a pretty huge benefit.
Title: Re: Around the Clock
Post by: IsmAvatar on June 14, 2010, 07:54:22 pm
Bug:
While holding down the Z key, the following function calls give the following return values
//uppercase Z
keyboard_check(ord('Z')) = 0
keyboard_check(90) = 0
//lowercase Z
keyboard_check(ord('z')) = 1
keyboard_check(122) = 1

GM checks the uppercase ('Z' or 90). Enigma should probably emulate this behavior. I wouldn't object to both uppercase and lowercase returning true on key down, since the lowercase is never used, and can be a source of confusion.

Accompanying the key with the Shift key does not alter these results. (that is, shift+z does not trigger uppercase 'Z' to return true, although lowercase 'z' continues to return true.
Title: Re: Around the Clock
Post by: Josh @ Dreamland on June 15, 2010, 01:01:52 am
There are parsers for YAML taking thousands of lines and requiring several awkward symbols to be added to my file, which I think is beautiful as it is. The parser for it barely takes 200 lines. It's just not that complicated. YAML introduces what seems to be hundreds of features we don't use, requires symbols to make explicit what should be implied, and lacks (for sake of versatility on a scale not required here) a feature the current format uses. It would be easier for me (perhaps even at this point) to include some huge YAML nonsense, but I don't think I'll be doing so. If Ism, however, indicates in any way an intention to share this file with me, I will, via a simple regexp, make the file into YAML, and either revise my parser to use YAML's | and >, or perhaps even break habit and include some fucking huge thing and piss with its API to get the info I need. The question is whether I want the format to be YAML or to be YAML compliant, assuming I want it to be related to YAML at all (which I slightly do, since Ism reports that the format being YAML-ready would slightly improve her odds of working with it).

Ism:
That's a bug, yes. Should work like GM. And yes, Shift wouldn't change anything; I get the keycode raw and convert it myself via large array. This array is -not- cross API, meaning it may work find on Winblows even though I screwed up on X. I'd prefer not to add checking for both at first glance due to the unfolding of code that would have to transpire (either unfolding an array by segment, keeping a second array, or just adding a special check), but I will look into doing so all the same. If I did, I would probably mandate that a correction be implemented just above the API level (as soon as I have a key code), so no additional checking is done each keyboard_check. Hoping this isn't the work of XLookupKeyCode, or whatever that function was.