This convention aims to:
- Clearly define actor boundaries (state vs responsibility)
- Make message flow via
requesteasy to follow - Reduce misinterpretation during reviews and maintenance
This is a project-level convention, not a language restriction.
- Indentation: 4 spaces or tabs
- Tabs are forbidden
- Line length guideline: 120 characters
- Break lines when exceeded
- Allman style
actor Foo
{
action bar
{
}
}
- Extension:
.mn - File name:
PascalCaseExample:EnemyAI.mn
-
Not mandatory, but recommended
-
Strongly recommended for:
- Large projects
- Libraries / plugins
- Long-term maintenance
namespace Game::AI;
-
If used, place all
usingdeclarations:- At the top of the file
- Immediately after
namespace
-
Avoid overuse to keep dependencies explicit
PascalCase- Use nouns that clearly describe responsibility
Examples:
EnemyController,BattleService
lowerCamelCase- Verb-first naming is recommended
- The convention does not define or restrict
onXxxnaming
Recommended examples:
initialize,main,think,updateattack,acquireTarget
lowerCamelCaseExample:targetId,retryCount
mLowerCamelCaseExample:mState,mTargetId
- All constants must use the
kprefix - Format:
kPascalCase constdeclaration is mandatory
const int kMaxRetry = 3;
const int kThinkPriority = 50;
kXxxrepresents immutable rules, constraints, thresholds, or default values They are not actor state and must never be modified.
- Prohibited by default
- Allowed only as explicit exceptions
gprefix is mandatory- Format:
gLowerCamelCase
int gFrameCounter;
bool gIsDebugMode;
When a gXxx variable is used:
- The owner (actor / action responsible for writing) must be documented
- Writes should be limited to as few locations as possible (ideally one)
- Must not be used for core gameplay logic (debugging, diagnostics, statistics only)
// Owned by DebugController::update
bool gIsDebugDrawEnabled;
In
request(priority, Target->action()), the first argument always represents priority
- It does not represent delay, frame count, or time
request(100, Enemy->think());
request(10, Enemy->idle());
- Avoid magic numbers
- Prefer constants (
kXxx)
const int kThinkPriority = 50;
request(kThinkPriority, Enemy->think());
request(
kThinkPriority,
Enemy->think()
);
-
One action = one intent
-
mainshould act as an orchestrator- Avoid embedding complex logic directly
-
If request chains grow long:
- Split into multiple actions
- Use phased execution
-
Comments should primarily explain “why”, not “what”
-
For actors, short comments describing:
- Responsibility
- Meaning of held state
- Key outgoing requests are strongly recommended